bekasa Posted September 19, 2017 Share 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 Link to comment Share on other sites More sharing options...
BitPoet Posted September 19, 2017 Share 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 Link to comment Share on other sites More sharing options...
abdus Posted September 19, 2017 Share 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 Link to comment Share on other sites More sharing options...
bekasa Posted September 19, 2017 Author Share Posted September 19, 2017 Thank you for your replies that clarifies the situation completely. Processwire is genius but equally it's forum contributors. 1 Link to comment Share on other sites More sharing options...
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