titanium

$page->save('parent') does not work - why?

Recommended Posts

I noticed that $page->setAndSave('parent', 1000); does not work. Reason is, that $page->save('parent') does not work either.

In /wire/core/Page.php:

public function save($field = null, array $options = array()) {
    if(is_array($field) && empty($options)) {
        $options = $field;
        $field = null;
    }
    if(!is_null($field)) {
        if($this->hasField($field)) {
            return $this->wire('pages')->saveField($this, $field, $options);
        } else if(is_string($field) && (isset($this->settings[$field]) || parent::get($field) !== null)) {
            $options['noFields'] = true; 	
            return $this->wire('pages')->save($this, $options);
        } else {
            return false;
        }
    }
    return $this->wire('pages')->save($this, $options);
}

"parent" is no field and no key in $this->settings[$field], so the functions must return false for $page->save('parent').
Possible keys in $this->settings[$field] seem to be:

["id"]
["name"]
["status"]
["numChildren"]
["sort"]
["sortfield"]
["modified_users_id"]
["created_users_id"]
["created"]
["modified"]
["published"]

Why is parent missing here?

Share this post


Link to post
Share on other sites

"parent" is not the name of a field.

If you are trying to set the parent of the page you'll need to do this:

$page->parent = 'x';
$page->save();

 

  • Like 1

Share this post


Link to post
Share on other sites

Thanks, @adrian. I always did what you described, but recently I wondered why

$page->setAndSave('sort', 3);

works, but

$page->setAndSave('parent', 3);

does not - both are native properties of the page. This seems somewhat equivalent to me, so they should behave the same, shouldn't they? But I'm not sure if I fully understand it.

What I originally tried to achieve was to save the page with a maximum of performance, because I have to deal with a cron job which imports/changes thousands of pages. I guess I have to experiment with $page->save(['noFields' => true]). Any hints for optimized performance of page manipulation are welcome.

Share this post


Link to post
Share on other sites
55 minutes ago, Zeka said:

@titanium Have you tried 


$page->setAndSave('parent_id', 3);

?

It doesn't work 🙂

Share this post


Link to post
Share on other sites

@Zeka, thanks for the hint. I gave it a shot some minutes ago and it does not work either.

I dived deeper now. /wire/core/Page.php contains a method $page->set($key, $value):

            case 'parent':
            case 'parent_id':
                if(is_object($value) && $value instanceof Page) {
                    // ok
                    $this->setParent($value);
                } else if($value && !$this->_parent &&
                    ($key == 'parent_id' || is_int($value) || (is_string($value) && ctype_digit("$value")))) {
                    // store only parent ID so that parent is lazy loaded,
                    // but only if parent hasn't already been previously loaded
                    $this->_parent_id = (int) $value;
                } else if($value && (is_string($value) || is_int($value))) {
                    $value = $this->_pages('get', $value);
                    $this->setParent($value);
                }
                break;

So there is definitely support for $page->set('parent', $id) here. Proof: the following works:

$page->set('parent', 3);
$page->save();

In the head of /wire/core/Page.php is a definition of $settings:

    /**
     * Page-specific settings which are either saved in pages table, or generated at runtime.
     *
     * @var array
     *
     */
    protected $settings = array(
        'id' => 0,
        'name' => '',
        'status' => 1,
        'numChildren' => 0,
        'sort' => -1,
        'sortfield' => 'sort',
        'modified_users_id' => 0,
        'created_users_id' => 0,
        'created' => 0,
        'modified' => 0,
        'published' => 0,
        );

I think 'parent' is missing here. I added it and tried again - now this works:

$page->setAndSave('parent', 3);

So I guess it's a bug.

  • Like 1

Share this post


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

So I guess it's a bug

File a report here please.

Share this post


Link to post
Share on other sites
21 hours ago, titanium said:

I guess I have to experiment with $page->save(['noFields' => true]). Any hints for optimized performance of page manipulation are welcome.

I am curious what you discover testing this. I haven't ever played with the noFields option. If is doesn't work out fast, you might be better off with direct DB manipulation of parent_id field, but if you do take that approach be aware that you'll also need to update the pages_parents table as well.

Sorry I missed your more recent posts about the discovered bug. Thanks for digging into that!

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.