Jump to content

[possible bug] Page fieldtype with Custom selector to find selectable pages returns error while saving page


arjen
 Share

Recommended Posts

Hey,

Brand new install running dev 2.3.7. No code modifications.
 
I've setup a simple download system like this:
 
Template: company
Fields: title and company
 
Field label: company
Field type: Page
Dereference in API as Multiple pages
Custom selector to find selectable pages: template=user, roles=company, sort=name
 
I add a few users with the guest and company roles.
 
When viewing the company page in the admin the companies show up. But when saving there is an error: Page 1015 is not valid for company. It doesn't matter if there is one or more options selected. I also tried all the "Input field types". I've read PageListSelect input field types are  currently not compatible.
 
When I change the custom selector to empty and use the "Parent of selectable page(s)" or "Template of selectable page(s)" the saving is fine. Am I overlooking something? 
 
post-365-0-60591700-1386015987_thumb.png post-365-0-11237900-1386015989_thumb.pngpost-365-0-96886900-1386015990_thumb.png
Link to comment
Share on other sites

Thanks for stepping in, Martijn :)

Isn't Roles (built in field) a Page field type? I think you can approach this like any other Page field. When I remove the roles field from the selector the saving does work fine.

Link to comment
Share on other sites

Using the ID here works.

I'm not sure what's wrong, cause the selector using the "roles=name" obviously works to find the pages and they are the right users. So they should also be valid!

Try this script as a testcase in a template to see what happens:

$selector = "template=user, roles=company, sort=name";
$pa = $pages->find($selector);

foreach($pa as $p){
    echo "user: " . $p->name;
    if(!$p->matches($selector)){
        echo " (not valid)<br>";
    } else {
        echo " (valid)<br>";
    }
}

gives me

user: testuser1 (not valid)

user: testuser2 (not valid)

Also using subfield doesn't give valid pages

$selector = "template=user, roles.name=company, sort=name";

only changing selector to using the id of the role works

$selector = "template=user, roles=1027, sort=name";

Seems strange to me that matches doesn't valid pages that are returned using find() using the exact same selector.

  • Like 1
Link to comment
Share on other sites

Also worth noting that the same selector works when you enter custom php code for a page field:

return $pages->find("template=user, roles=company, sort=name");

But there's a note in the source code that :

if($field->findPagesCode) {
            // TODO: we don't currently validate these
        }
  • Like 1
Link to comment
Share on other sites

You'd have to use the ID for the selector in this case. When no subfield is specified in a database-querying selector, a Page field will attempt to match the name or title of a selectable page if the given value is not numeric or a /path/. This is specifically for making it easier to do imports, like with ImportPagesCSV, where you'd be unlikely to maintain IDs in a spreadsheet. The reason it's not working in the above case is because the selector in question is not a database querying selector, just an in-memory one validating that the page matches the selector. Clearly it should in this case, and I think I can add support for this to the in-memory selectors. But I've been a little shy on this one because name and/or title aren't guaranteed to be unique in a set of selectable pages. So while they are convenient for things like importing, they aren't ideal for most definitions like this. Though the name is guaranteed to be unique, if the Page selection is limited by a parent. Roles is limited by a parent, so it would be fine in this case, but it could get you into trouble in other cases. 

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
I really have a hard time unstanding the database-querying selector vs in-memory selector 

The goal is that there would be no difference from our perspective. But the reality is they are two totally different things behind-the-scenes, so there are sometimes minor differences. In time, hopefully there won't even be minor differences. But either way, it's good to know the difference just because database-querying selectors are more expensive to execute in terms of resources. Any function that accepts a selector and returns pages from the $pages or $page API variable is a database-querying selector. Whereas in-memory selectors are primarily used by PageArrays, as they represent a group of pages already loaded in memory and selectors are used to filter through them. 

$results = $pages->find("selector"); // database-querying
$results = $results->find("selector"); // in-memory

$children = $page->children; // database-querying
$children = $page->children("selector"); // database-querying
$children = $children->filter("selector"); // in-memory
$children = $page->children->find("selector"); // database AND in-memory (just use children w/selector instead)
  • Like 9
Link to comment
Share on other sites

  • 3 months later...

I hit this issue too with a custom selector that's similar to the "templates=user,roles=company" example given above.  The custom selector was working in 2.3.1 and started to fail after I upgraded to 2.4.0.  Seems like a regression.  I worked around it with the custom php code workaround.

  --Sharon

Link to comment
Share on other sites

  • 6 months later...

sorry i don't get it:

custom PHP selector to find children of a sibling to the editing page:

return $page->parent->siblings("template=LU-Stamm")->first()->children();

give me the pages from the wantet structur:

don't can go with the id or choose the parentpage with the pagetree since i've more different parents with the same subtree like this

-parent one

--sub

---here we are editing (has the pagefield should show only children of this branch)

--sub (template=LU-Stamm)

---here we choose (this is shown in the pagefield)

---here we choose (this is shown in the pagefield)

-parent two

--sub

---here we are editing (has the pagefield should show only children of this branch)

--sub (template=LU-Stamm)

---here we choose (this is shown in the pagefield)

---here we choose (this is shown in the pagefield)

Error Page xxx is not valid?

How can i get this working?

Link to comment
Share on other sites

I'm with mr-fan -- I have an analogous data structure.

Reading the code in InputfieldPage.module isValidPage(), I come to the conclusion that the field's option to select pages using "Custom PHP code to find selectable pages" should not be used until you can actually save the pages, which you can't right now because they don't validate.

I just replaced

if($field->findPagesCode) {
  // TODO: we don't currently validate these
} 

with

if($field->findPagesCode) {
  // DONE
  $inputField = $field->getInputfield( $editPage, $field);
  $validPages = $inputField->findPagesCode( $editPage );
  // if the page is in the list, it's valid. No more questions asked!
  return $validPages->get( 'id=' . $page->id) ? true : false;
}
Can't it be this simple?  I must be missing something?  Is it a performance issue?

I'll submit a patch and see whether it passes mustard with the head dogs   :)

  • Like 1
Link to comment
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
 Share

×
×
  • Create New...