Jump to content
formulate

[solved] page reference field - unpublished pages not visible by non-superuser roles/users

Recommended Posts

I have a page reference field with the "include unpublished" checked. Non-superuser accounts still can't see unpublished pages. I went through the permissions for the role and couldn't see anything related. Do I need to create some kind of custom permission to get this working?

Share this post


Link to post
Share on other sites

No, not hidden. I also messed with doing a custom selector both in the input tab and ready.php - doesn't work.

Share this post


Link to post
Share on other sites

Is this an autocomplete inputfield? I just ran into the same problem (a page field not finding unpublished pages for non-superusers, even though Include unpublished is checked).

I managed to isolate the issue to ProcessWire's internal admin search that is used behind the scenes of autocomplete fields. Not sure if anything from the last major search update in 3.0.108 might play a role here.

 

This is what's worked for me:

Copy the core search module folder from /wire/modules/Process/ProcessPageSearch to /site/modules/Process/ProcessPageSearch/

After lines 422–425 in ProcessPageSearch.module…

if(!$status && !$hasInclude && $superuser) {
    // superuser only
    $selectors[] = "include=all, status<" . Page::statusTrash;
}

…insert this:

// FIX: include unpublished pages for non-superusers
else if(!$status && !$hasInclude && !$superuser) {
    $selectors[] = "include=all, status<" . Page::statusTrash;
}

Back in the admin, refresh the module cache (Navigation » Modules » Refresh). ProcessWire will then ask you which version to use for the search module. Pick the one you modified in the /site/ folder.

This will basically make it work the same for superusers and non-superusers.

I can't report any negative side effects at this point, but in my case it beats promoting all content editors to superusers.

  • Like 2

Share this post


Link to post
Share on other sites

Sorry guys, in a rush but perhaps including "check_access=0" in the selector for the page field will do the trick here. I might be totally off track and it might be a bug, but worth a shot.

Share this post


Link to post
Share on other sites

I am having a separate issue at the moment where my custom selector isn't working (either in the Input or ready.php). Once I get that hashed out I'll try the two above solutions and report back.

Share this post


Link to post
Share on other sites
2 minutes ago, adrian said:

Sorry guys, in a rush but perhaps including "check_access=0" in the selector for the page field will do the trick here. I might be totally off track and it might be a bug, but worth a shot.

From my cursory reading of the source, check_access also seems limited to superusers:

// don't allow setting of check_access property, except for superuser
if($lowerName == 'check_access' && !$superuser) continue; 

 

Share this post


Link to post
Share on other sites
2 minutes ago, formulate said:

I am having a separate issue at the moment where my custom selector isn't working (either in the Input or ready.php). Once I get that hashed out I'll try the two above solutions and report back.

I'm pretty sure that anything beyond basic template selection will not work in autocomplete inputs. I found this comment in the InputfieldPage source regarding custom PHP selectors: Not compatible with PageListSelect or Autocomplete input field types.

Also, the field for adding custom code is disabled for autocomplete and page list selects:

$field->showIf = 'inputfield!=InputfieldPageAutocomplete|InputfieldPageListSelect|InputfieldPageListSelectMultiple';

 

Share this post


Link to post
Share on other sites

 

15 minutes ago, d'Hinnisdaël said:

I'm pretty sure that anything beyond basic template selection will not work in autocomplete inputs. I found this comment in the InputfieldPage source regarding custom PHP selectors: Not compatible with PageListSelect or Autocomplete input field types.

 

 

Well, that would explain my custom selector not working. Problem is that the page reference is pulling several thousand pages. Very impractical for anything but the autocomplete search from a usability standpoint. Not sure what I'll do for a solution - will put on my thinking cap.

Share this post


Link to post
Share on other sites

Not sure if this helps, but this works for me:

image.thumb.png.287d3e1c5dce3974f5fbef4d9370f31c.png

Share this post


Link to post
Share on other sites

Strange, any custom selector I try and specify doesn't work. Even when using standard select vs auto complete. Running a clean install of 3.0.108. I'll try a different version PW install and see what happens. Once I get my selector working I can then test check_access.

EDIT: Turns out using a standard selector works after all, but using page list or auto complete doesn't seem to use custom selectors. My experience here confirms what d'Hinnisdael has said above.

Share this post


Link to post
Share on other sites
11 minutes ago, adrian said:

Not sure if this helps, but this works for me

Unfortunately, this doesn't seem to work for non-superusers. I've been up and down the source of ProcessWire's internal admin search (which powers the page autocomplete input) and it really seems to limit the selection of unpublished pages to superusers.

Would be great to have autocomplete inputs respect the Include unpublished setting of a Page field.

Share this post


Link to post
Share on other sites

Ok, I can confirm the following:

1. Adrian's advice above about check_access=0 works, provided you're doing #2 below.

2. Custom Selectors and therefore the solution from #1 above, will NOT work using page list or auto complete. You need to use good old fashioned select drop down.

Adrian, in your example above, how do you think you were able to circumvent issue #2 that myself and d'Hinnisdael seem to be experiencing? Was your screen shot from a superuser or non-superuser role?

Share this post


Link to post
Share on other sites

I put this in my ready.php file:

// hack to overcome this: https://github.com/processwire/processwire-issues/issues/550
$this->addHookBefore('Pages::find', function(HookEvent $event) {
    $selector = $event->arguments(0);
    if(is_string($selector) && strpos($selector, 'template=user') !== false && strpos($selector, 'name|first_name|last_name%=') !== false) {
        $selector .= ', check_access=0';
    }
    $event->arguments(0, $selector);
});

You'll need to adjust to suit the needs of your selector, but this is how I got around it and make it work for non-superusers. Sorry I forgot about this above.

Definitely worth a read through that github issue as well: https://github.com/processwire/processwire-issues/issues/550

  • Like 2

Share this post


Link to post
Share on other sites
14 minutes ago, adrian said:

I put this in my ready.php file:


// hack to overcome this: https://github.com/processwire/processwire-issues/issues/550
$this->addHookBefore('Pages::find', function(HookEvent $event) {
    $selector = $event->arguments(0);
    if(is_string($selector) && strpos($selector, 'template=user') !== false && strpos($selector, 'name|first_name|last_name%=') !== false) {
        $selector .= ', check_access=0';
    }
    $event->arguments(0, $selector);
});

You'll need to adjust to suit the needs of your selector, but this is how I got around it and make it work for non-superusers. Sorry I forgot about this above.

Definitely worth a read through that github issue as well: https://github.com/processwire/processwire-issues/issues/550

Couldn't get this to work on my first attempt. Out of time tonight, but will try another crack at it in the morning. Thanks for the github link as well.

Share this post


Link to post
Share on other sites
3 minutes ago, formulate said:

Couldn't get this to work on my first attempt. Out of time tonight, but will try another crack at it in the morning. Thanks for the github link as well.

Start by removing the $selector check stuff so that it just appends the , check_access=0 bit and once it's working build back up to protect other instances of Pages::find

Share this post


Link to post
Share on other sites
13 minutes ago, adrian said:

Start by removing the $selector check stuff so that it just appends the , check_access=0 bit and once it's working build back up to protect other instances of Pages::find

Yeah, first thing I did was strip the conditional back. It appears that if I'm logged in as a superuser, your ready.php code works (as expected). If I'm logged in as any other role, a generic error is thrown and pages in the admin don't work. Below is the code I'm using. Note, I also tried removing the appending of check_access=0 line and it still throws an error (some issue with re-assigning the event arguments, which makes no sense to me).

$this->addHookBefore('Pages::find', function(HookEvent $event) {
    $selector = $event->arguments(0);
    $selector = ', check_access=0';
    $event->arguments(0, $selector);
});

Will look again tomorrow. Thanks Adrian.

Share this post


Link to post
Share on other sites

Maybe a typo, but you are missing the period in the $selector .= so that you are concatenating the check_access onto the selector.

 

Share this post


Link to post
Share on other sites
7 hours ago, adrian said:

I put this in my ready.php file:


// hack to overcome this: https://github.com/processwire/processwire-issues/issues/550
$this->addHookBefore('Pages::find', function(HookEvent $event) {
    $selector = $event->arguments(0);
    if(is_string($selector) && strpos($selector, 'template=user') !== false && strpos($selector, 'name|first_name|last_name%=') !== false) {
        $selector .= ', check_access=0';
    }
    $event->arguments(0, $selector);
});

Hooking ProcessPageSearch::findReady might be better because it's more specific to autocomplete and the method looks like it exists for just this sort of purpose.

$wire->addHookAfter('ProcessPageSearch::findReady', function(HookEvent $event) {
    $selector = $event->arguments(0);
    // Manipulate $selector as needed...
});
/**
 * Hookable function to optionally modify selector before it is sent to $pages->find()
 * 
 * Not applicable when Lister is handling the search/render. 
 * 
 * #pw-hooker
 *
 * @param string $selector Selector that will be used to find pages
 * @return string Must return the selector (optionally modified)
 *
 */
public function ___findReady($selector) {
	return $selector;
}

 

Edited by Robin S
Corrected to addHookAfter
  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
2 hours ago, Robin S said:

Hooking ProcessPageSearch::findReady might be better because it's more specific to autocomplete and the method looks like it exists for just this sort of purpose.


$wire->addHookAfter('ProcessPageSearch::findReady', function(HookEvent $event) {
    $selector = $event->arguments(0);
    // Manipulate $selector as needed...
});

 

Beautiful, that did the trick. Thanks! Much better than modifying the core search module, and it won't spill over into generic find() calls in the front-end.

No idea how I missed the findReady hook in the first place…

Final working implementation:

// Include unpublished participants in page fields for non-superusers

wire()->addHookAfter('ProcessPageSearch::findReady', function(HookEvent $event) {
    $selector = $event->arguments(0);
    if(strpos($selector, 'template=participant') !== false || strpos($selector, 'templates_id=76') !== false) {
        $selector .= ", check_access=0, include=all, status<" . Page::statusTrash;
    }
    $event->return = $selector;
});

 

  • Like 5

Share this post


Link to post
Share on other sites

Brilliant! In the end my code was more or less along the lines of what d'Hinnisdael posted above.

Thanks everyone for chipping in and resolving this issue.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...