Jump to content
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

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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...