bekasa Posted September 19, 2017 Posted September 19, 2017 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
BitPoet Posted September 19, 2017 Posted September 19, 2017 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. 3
abdus Posted September 19, 2017 Posted September 19, 2017 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(); 2
bekasa Posted September 19, 2017 Author Posted September 19, 2017 Thank you for your replies that clarifies the situation completely. Processwire is genius but equally it's forum contributors. 1
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now