Jump to content

Repeater Items - How to filter "ready items" - Bug?


Luke Solar
 Share

Recommended Posts

Good evening!

I added a repeater field to a template of mine with "ready items" set to 1. So one item is always in the DB with a status 3073. I cannot find that status in the cheatsheet or anywhere else... seems its "unpublished" and "hidden"

The problem is when I iterate over the items, the "empty" one is also included. Is this behaviour intended? How can I filter out the "unpublished" repeater items?

foreach ($page->subitems as $item) {
    echo "id: {$item->id}<br/>";
    echo "status: {$item->status}<br/>";
}
 
My current solution is to do a 
$page->subitems->filter("status=1")
Furthermore would be nice to know more about how to handle status in general and related to repeaters. I did a search of course but found not much.
 
Thanks a lot!
  • Like 1
Link to comment
Share on other sites

I think i can at least shed some light on where status 3073 is coming from in the DB. If you take a a look at Page.php (in the wire/core folder) you see this:

	/*
	 * The following constant flags are specific to a Page's 'status' field. A page can have 1 or more flags using bitwise logic. 
	 * Status levels 1024 and above are excluded from search by the core. Status levels 16384 and above are runtime only and not 
	 * stored in the DB unless for logging or page history.
	 *
	 * If the under 1024 status flags are expanded in the future, it must be ensured that the combined value of the searchable flags 
	 * never exceeds 1024, otherwise issues in Pages::find() will need to be considered. 
	 *
	 * The status levels 16384 and above can safely be changed as needed as they are runtime only. 
	 *
	 */
	const statusOn = 1; 			// base status for all pages
	const statusLocked = 4; 		// page locked for changes. Not enforced by the core, but checked by Process modules. 
	const statusSystemID = 8; 		// page is for the system and may not be deleted or have it's id changed (everything else, okay)
	const statusSystem = 16; 		// page is for the system and may not be deleted or have it's id, name, template or parent changed
	const statusHidden = 1024;		// page is excluded selector methods like $pages->find() and $page->children() unless status is specified, like "status&1"
	const statusUnpublished = 2048; 	// page is not published and is not renderable. 
	const statusTrash = 8192; 		// page is in the trash
	const statusDeleted = 16384; 		// page is deleted (runtime only)
	const statusSystemOverride = 32768; 	// page is in a state where system flags may be overridden
	const statusCorrupted = 131072; 	// page was corrupted at runtime and is NOT saveable: see setFieldValue() and $outputFormatting. (runtime)
	const statusMax = 9999999;		// number to use for max status comparisons, runtime only

So i think 3073 comes from the combined values of statusOn, statusHidden and statusUnpublished. One would assume that pages, like readypages, with a code > 1024 would be excluded by default in finding and listing repeater items. I have looked through the FieldtypeRepeater code to see what's going on but this is beyond my php skills and knowledge of the core system. Maybe Ryan can comment on this.

For the moment i think your filter solution seems fine.

I you want to read more on status stuff i suggest you do a 'find in files' for 'status'. Tools like Sublime Text then give a nice overview of the search results. Not really slick docs..but good for learning :) :)

Link to comment
Share on other sites

http://processwire.com/api/cheatsheet/?filter=status&advanced

It's correct the status is a bitmask of on (default) hidden and unpublished as you can see from the cheatsheet. ;)

Usually you can check or set with $page == Page::statusUnpublished.

However I think there's something mysterious that you get the unpublished ready repeaters, not sure what is about, but usually you don't get unpublished pages when doing finds, but since you do a direct call, I can imagine that this is the problem. Ryan help! :)

I think it may also work if you do this?

foreach ($page->find("subitems") as $item) {     echo "id: {$item->id}<br/>";     echo "status: {$item->status}<br/>"; }

Edit: Just realized doesn't make sense "$page->find("subitems")" lol

Looking at repeaters code there's something going on with the status, not sure since repeaters are little special this code may the key:

in wakeupValue() function

// #499 FieldtypeRepeater.module
// hidden pages (assumed to be a ready page) should never be included when page is being viewed (outputFormatting)
if($hidden && $outputFormatting) $pageArray->remove($p);

// unpublished items may only be included if the page is also unpublished (and presumably being previewed)
if($outputFormatting && $unpublished && !$page->is(Page::statusUnpublished)) $pageArray->remove($p);
 
Link to comment
Share on other sites

So I think the behaviour you get shouldn't be unless you have the page unpublished and preview it as superuser? Could also be something with viewing it as superuser logged in? 

Link to comment
Share on other sites

So far I can't reproduce what you're saying that the "ready" repeaters are included when foreach the repeater field.

What version are you using? I think there was a bug some time ago fixed.

Link to comment
Share on other sites

Thanks for your answers!

Strange that you cannot reproduce it Soma, I use ProcessWire 2.2.9.

To reproduce it maybe you have to set the ready items to a different number and then create an item in order to trigger the function which creates the items: Set the ready items to 3 (for example). then go to a page using the repeater, ADD an item (if you had set ready items to zero you have to save the page immediatly), well ADD the repeater item then save. 3 empty items are added. Access them with 


foreach($page->repeateritems as $repeateritem){
    echo $repeateritem->titel; // empty for new items
    echo $repeateritem->id; // its set to a new page id
    echo $repeateritem->status; // returns 3073 for "ready items"
}

echo count($page->repeateritems); // count includes new "ready items"

Thanks for comments.

Link to comment
Share on other sites

  • 1 year later...

Same "problem" here but only when use PW in a shell script, latest dev.

A repeater with 5 items (count = 5) used in a template returns 5 items. When call it in a shell script (that update dates and other things) it return 8 items (a problem when I want use its latest item to set a other fields, in this case 1/1/70).

Your solution works well, but is this the correct behavior?

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