Jump to content

Finding Page id After a new Page Has Been Saved


bekasa
 Share

Recommended Posts

Hi,

This question relates to finding the page id after a new page has been saved. A new page is generated as in the code below.

		$p = new Page();
        $p->template = 'page_template';
        $p->parent = wire("pages")->get(parent_id);
        $p->addStatus(Page::statusUnpublished);
        $p->field = $something;
		/*set more fields*/
		$p->save();

Straightforward, but because the new page has fields which include page reference fields it has to be saved at this stage then further page reference fields added . Again straightforward and page reference fields can be added.

		$p->reference_field = $something;
		$p->reference_field->save();

This works without a hitch, after the first $p->save() operation, the $p->id (the page id ie of the new page just saved to disc) becomes available.

It seems that $p has changed from referencing an in memory object (new page) to an actual page (on disc). I thought I would have to execute a 'find' operation to discover the new page just saved to actually acquire the stored $page reference to continue editing.

Has anyone an explanation of how this change in referencing takes place?  I was concerned about this because there is the possibility that numerous pages could be added at the same time and that it may not be 'safe' to rely on $p as being the $page reference even though it seems to work.

Thanks in advance and to all forum contributors

 

 

Link to comment
Share on other sites

There's no change in referencing. A PHP variable referencing a page is always an in-memory object. When you call $page->save() for the first time, PW executes an INSERT on the pages table and populates that page object's id with the last inserted id. last_insert_id is scoped to the current database connection, so other PHP threads / browser sessions inserting pages can never influence each other. There's no need to worry.

  • Like 3
Link to comment
Share on other sites

When you save a new page with $p->save(), page is saved to the database and last insert id is assigned to the page. 

<?php
// /wire/core/PagesEditor.php

protected function savePageQuery(Page $page, array $options) {
    // ...
    // save the page to the database
    // ...
  
    if($result && ($isNew || !$page->id)) $page->id = $database->lastInsertId();
    if($options['forceID']) $page->id = (int) $options['forceID'];

    return $result;
}

Since fields and pages are uncoupled (referencing takes place by page ids), once the page is saved, its ID becomes available and its fields are ready to save as well.

<?php
// /wire/core/PagesEditor.php

/**
 * Save individual Page fields and supporting actions
 *
 * triggers hooks: saved, added, moved, renamed, templateChanged
 *
 * @param Page $page
 * @param bool $isNew
 * @param array $options
 * @return bool
 *
 */
protected function savePageFinish(Page $page, $isNew, array $options) {
    // ...
  
    // save each individual Fieldtype data in the fields_* tables
    foreach($page->fieldgroup as $field) {
        $name = $field->name;
        if($options['noFields'] || isset($corruptedFields[$name]) || !$field->type || !$page->hasField($field)) {
            unset($changes[$name]);
            unset($changesValues[$name]);
        } else {
            try {
                $field->type->savePageField($page, $field);
            } catch(\Exception $e) {
                $error = sprintf($this->_('Error saving field "%s"'), $name) . ' - ' . $e->getMessage();
                $this->trackException($e, true, $error);
            }
        }
    }
  
    // ...
}

There are a lot of missing parts, but feel free to read PagesEditor class, the source is quite readable.

Also, you don't have to explicitly call $page->referenceField->save(), saving page already takes care of that.

<?php namespace ProcessWire;

$p = new Page();
$p->template = 'page_template';
$p->parent = $parentPageOrItsId; // parent id is enough
$p->addStatus(Page::statusUnpublished);
$p->field = $someValue;

$p->reference_field = $somePage;
// $p->reference_field->save(); // not necessary

$p->save();

 

  • Like 2
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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...