Jump to content

Recommended Posts

Posted
Hello,

Recently I ran into some weird behavior with the find() method, when using it within the context of a single $page.

Although this is easy (and perhaps more correct) to work around using the get(), child() or children() methods, I'd still like to understand what is happening here.

This is an example of a piece of code, where $page is trying to get its child with a specific template, using the find() method, but returns nothing instead.



<?php

// Prepare PW
$_SERVER['SERVER_NAME'] = 'localhost';
$_SERVER['HTTP_HOST'] = 'localhost';
$_SERVER['REQUEST_URI'] = '/index.php';

// get Wire'd
require_once dirname(__FILE__).'/../../www_composer/index.php';

// get some entries where the template failed to laod
$data = file_get_contents('failed_entries.json');
$data = json_decode($data);

foreach ( $data as $row )
{
$entry = wire('pages')->get('template=offers-page, email='. $row->email);

echo sprintf("This page has the id %d, it contains meta-data for an email\n", $entry->id);
echo sprintf("\t- it has %d child (with ID %d), which is a template ('email-base'),\n",
$entry->numChildren(),
$entry->child()->id
);
echo sprintf("\t- the child (template) has %d children (which are blocks in the template),\n", $entry->child()->numChildren());
echo "We want to get the child that uses the 'email-base' template (because in theory there could be many children to this page)\n";
echo sprintf(
"\tWhy is find() returning '%s' when filtering with template name,\n",
($entry->find('template=email-base')->count()? $entry->find('template=email-base')->count(): 'NOTHING')
);
echo sprintf(
"\twhile get() returns the expected page with id: %d\n",
$entry->get('template=email-base')->id
);
echo "When further researching this, it would seem that using find on \$page, actually returns it\'s grandchildren\n";
$i=1;
foreach ( $entry->find() as $gc ) {
echo sprintf("\t- I'm a grandchild, and my parent is %d and not %d\n",
$gc->parent()->id,
$entry->id
);
$i++;
}

break;// casue we only need to look at one..
}


Even more interesting is that sometimes this $page->find('template=tpl-name')->first()->id returned an id, and sometimes it threw a notice.

The above code is a test CLI script, which produces weird results.

On the other hand when I tested using find() in a template, it worked while testing, but later our users reported an error that is caused by $page->find('template=tpl-name')->first()->id throwing a notice.

What is the behavior of find() supposed to be in this case? 

Am I missing something?

post-2624-0-67739700-1439471998_thumb.pn

Posted

My guess: the child is hidden. $page->find() finds all descendants from the $page. If logged in as a  superuser, you see any page on the site. If logged in as a guest, the pages set to hidden (and/or other settings you have on the page) ar invisible. find() finds 6 pages — child + 5 grandchildren, but child is hidden for guest, thus returning only the 5 grandchildren.

Posted

I checked that as well. 

At least according to the admin panel the page is published, visible and accessible by guest.

post-2624-0-10082700-1439493376_thumb.pn

Posted

The difference between find and get is in this case the different selectors that get build:

$entry->find() -> $pages->find("has_parent=$entry->id");
$entry->get() -> $pages->find("parent_id=$entry->id");

If you'd supply a selector, it will be added to the one shown above. If you still find an issue with these, then Ryan needs to check the PageFinder. 

One useful info: Which version of PW are you using? There where issues with the table holding information about page parents when copying pages.

Posted

The version is 2.5.3

I tested with

$pages->find("has_parent=$entry->id");

and

$pages->find("parent_id=$entry->id");

The later returned the template page as expected, and the first query returned the 5 grandchildren

Posted

Could you try if moving those pages in the page tree and setting them back in place does change the behavior? Are those pages created via the api / backend / copied?

Posted
- This project isn't multi-language.

- The pages are created through the api.

When I moved all the grandchildren down one level, so that $page only has children and no grandchildren: $pages->find("has_parent=$entry->id") returned empty.

I also tested this in a template, while being logged in as admin



var_dump( $page->children('template=email-base')->first()->id );
var_dump( $page->get('template=email-base')->id );
var_dump( $page->child()->id );
var_dump( $page->find('template=email-base')->first()->id );


The 3 first ones return the page id.

The last one throws an error (since first() isn't a method of null).

Posted

It actually returns an empty PageArray.

And the error (notice), is probably about the '->id' 

EDIT, Here's a bit of the var_dump for $page->find('template=email-base'):

---

object(PageArray)[297]
protected 'numTotal' => int 0
protected 'numLimit' => int 0
protected 'numStart' => int 0
protected 'selectors' =>
object(Selectors)[292]
protected 'selectorStr' => string 'has_parent=1754, template=email-base' (length=48)
protected 'quotes' =>
array (size=5)
'"' => string '"' (length=1)
''' => string ''' (length=1)
'[' => string ']' (length=1)
'{' => string '}' (length=1)
'(' => string ')' (length=1)

..

---

Posted

I spent some time dumping and analyzing the SQL queries that PW does when doing the find.

It seems that find() works fine. Instead the issue appears when we save pages via the API.

The page that cannot be found with find is missing entries in the pages_parents table,

The first query is a broken page, and the second one is a sibling which works as expected.

mysql> SELECT * FROM pages_parents WHERE pages_id=1754;
Empty set (0.00 sec)

mysql> SELECT * FROM pages_parents WHERE pages_id=1407;
+----------+------------+
| pages_id | parents_id |
+----------+------------+
|     1407 |          1 |
|     1407 |       1172 |
|     1407 |       1193 |
+----------+------------+
3 rows in set (0.00 sec)

I'll post a conclusion here if I ever manage to duplicate this issue consistently.

Posted

That's exactly the issue I wanted to check on by lettings you move these pages, as this should trigger an update to the parents table. Maybe you should open an issue over at github about this and include how you're saving those pages, which fail to have parents assigned.

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...