NewsPublisher Edit Button

Hi @bobray,

Having failed to crack this nut after after repeated attempts over the past couple years I’m back to try yet again. In short, I have things working about 99% the way I want but I’m struggling with one finicky aspect.

Using ownpagesonly I’m able to show the NpEditThisButton only for articles written by the respective user (creator) when that particular user is signed-in. For example, in a “members only” folder (container) the user is shown a listing of only their articles, each entry with its own edit button. Alternatively, when viewing the public-facing article (resource) the edit button is also shown, but only if/when the user is signed-in. So far, so good.

The problem is on one specific public-facing page where a listing shows all the articles for all users using pdoResources/pdoPage. In this case the edit button is only shown for signed-in Admin users, except that it shows an edit button for all articles written by everyone, Admin and members alike.

Conversely, when a Member is signed-in no edit buttons are shown on the page, not even for articles they created.

Keep in mind this oddity only happens on this one particular page, everywhere else an edit button is displayed, be it on a public-facing page or a specific “member only” page everything works as expected for the respective signed-in user, be they Admin or Member. Why it doesn’t work on this one page has me baffled beyond reason.

Here is the pdoPage/Resources call in the Resource template:

[[!pdoPage@pdoPagination?
	&elementClass=`modSnippet`
	&element=`pdoResources`
	&tpl=`Category Article Row`
	&hideContainers=`1`
	&pageVarKey=`page`
	&parents=`[[*id]]`
	&includeTVs=`1`
	&includeContent=`1`
	&limit=`6`
    &pageLimit=`5`
    &pageNavVar=`page.nav`
]]

And in the &tpl Chunk (above) I have the NpEditThisButton call:

[[!NpEditThisButton?
	&np_id=`9`
	&np_edit_id=`[[+id]]`
	&ownpagesonly=`1`
]]

Any insight would sure be appreciated.

Looking at the code of the snippet NpEditThisButton, it seems that the check if the user owns the page happens only for the current resource ($modx->resource – in your case the resource with the listing where pdoResources is called) and not for the individual resources that pdoResources returns.

if (!empty($ownPagesOnly)) {
    if ($modx->resource->get('createdby') !== $modx->user->get('id')) {
        $defaultButtonCaption = $modx->lexicon('np_not_your_page');
    }
}

Ah, well spotted. That is interesting and I’m inclined to believe that is the crux of the issue except for one thing.

Unlike the public facing article (resource) created by the member, in the member-only area the resource that contains the pdoResource listing is for one particular user only and was created by an Admin, not the member. That being the case I would expect to see the same button related issue as on the other page but I don’t, it works perfectly.

So both resources that contain pdoResource listings were created by an Admin yet one displays the edit button correctly and the other doesn’t. And as far as I can tell the only notable differences between the two listings is that one resource only shows the articles for one specific user while the other contains articles from multiple users, and one resource listing is publicly accessible while the other requires a signed-in user.

The snippet NpEditThisButton has a property debug that “Displays the button on all pages with either the $buttonCaption, or a message explaining why it would not be shown.” You could set this property to true to test why the snippet fails.

[[!NpEditThisButton?
	&np_id=`9`
	&np_edit_id=`[[+id]]`
	&ownpagesonly=`1`
	&debug=`1`
]]

The snippet also does some other permission checks, so maybe one of these fails.

Good idea…

Ok, it shows “Disallowed - Not your page” which isn’t completely surprising. What’s odd is that the error is displayed for every item in the listing, even the article that was created by the signed-in user.

I think you’re correct in that it has to do with the (listing) resource having been created by a different user.

Maybe you could try doing something like this:

  • Duplicate the snippet NpEditThisButton and call it something different (like MyNpEditThisButton).
  • Then change the code I posted above to the following …
if (!empty($ownPagesOnly)) {
    $createdby = $modx->getOption('createdby', $props, '-1', true); //read the property 'createdby'
    if ($createdby != $modx->user->get('id')) { //and compare it to the ID of the current user
        $defaultButtonCaption = $modx->lexicon('np_not_your_page');
    }
}
  • … and change the call to NpEditThisButton to the new snippet and provide the createdby-property:
[[!MyNpEditThisButton?
	&np_id=`9`
	&np_edit_id=`[[+id]]`
	&ownpagesonly=`1`
	&createdby=`[[+createdby]]`
	&debug=`1`
]]

If I’m understanding correctly, the items in your listing page are a generated list of links to other pages. Is there anything in that resulting html that identifies each linked item with the linked page’s creator? If not, there would be no way for the button snippet to determine the button should be shown to that linked page’s logged in creator.

Hi @lucy, that’s a good point. However, the Chunk containing the edit button for each article in the listing does reference [[+createdby]] in this call;

[[!setUserPlaceholders? <!-- Part of ClassExtender Extra -->
    &userId=`[[+createdby]]`
]]

And while the edit button does not appear for a signed-in Member, all the edit buttons appear for the signed-in Admin so each listing entry is being properly linked to its respective creator.

Hmmm, did you say the admin page shows links to everyone’s articles, and that the admin sees the edit buttons on each of those links?

As a test: what happens if you put links from other members on a particular member’s page. I’m guessing they will see edit buttons for all the links even the articles that aren’t theirs. Because the button snippet is simply checking the relationship between logged in user and that page’s creator. It’s not also checking each link and respective button in the listing. (I’m not looking at the code right now so I might be wrong… actually I could be wrong even when I am looking at the code.)

I think it would be helpful too if you post the exact markup generated by the resources call so we can see the actual listing html. Even if the creator ID is printed in that list, does the button snippet know what it is?

I believe halftrainedharry is correct. The ownpagesonly option only works for standalone pages. I hadn’t anticipated it being used together with the np_edit_id option. I think his solution should work.

@halftrainedharry that worked perfectly! Well done. I’m not kidding when I say I’ve been revisiting this for at least two years with zero progress so a huge Thank You!

@bobray It sure did work.

Would be great if this became a proper NP feature/option in a future update.

@todd.b

Could you try this code in the original edit button snippet (back it up first)? If it works, you should be able to use the same snippet tag on all pages if you only send the createdby placeholder for the aggregate page.

/* get 'createdby' if sent */
$createdby = $modx->getOption('createdby', $props, '-1', true); 

if (!empty($ownPagesOnly)) {
    if ($createdby !== '-1') {
        /* compare it to the ID of the current user */
        if ($createdby != $modx->user->get('id')) { 
            $defaultButtonCaption = $modx->lexicon('np_not_your_page');
        }
    } else {
        if ($modx->resource->get('createdby') !== $modx->user->get('id')) {
            $defaultButtonCaption = $modx->lexicon('np_not_your_page');
        }
    }
}

So far so good, @bobray.

Thanks! Let me know if you run into any problems.

Have you tried it without the call to setUserPlaceholders? I think either getResources or pdoResources will set the +createdby placeholder.

The NPEdit button works without setUserPlaceholders but I still need it to display a custom (ClassExtender) field elsewhere on the page.

I thought so. I wanted to make sure people who saw this didn’t think it was required.

BTW, I don’t think you need &np_id. IIRC, it’s supposed to be set automatically. You would only need it if you have multiple NewsPublisher form pages (which maybe you do). :wink:

I do have multiple forms. Six. A create and edit form per category (3).

I’ve been thinking of streamlining things by going the in-page editing route (using TW) but just haven’t gotten around to it.

Had also considered going the Fred route but TW/NP offers a level of customization I don’t think Fred is capable of, at least not at the moment.

You can create a TV called NpId containing the appropriate NP ID and use

&np_id=`[[NpId]]`

but I’m not sure that would make things any easier.