/** * Update the DB based on previously recorded changes * * @param boolean do we want to auto track the mod date? * @param boolean Update slug? - We want to PREVENT updating slug when item dbupdate is called, * because of the item canonical url title was changed on the slugs edit form, so slug update is already done. * If slug update wasn't done already, then this param has to be true. * @param boolean Update excerpt? - We want to PREVENT updating exerpts when the item content wasn't changed ( e.g. only item canonical slug was changed ) * @return boolean true on success */ function dbupdate($auto_track_modification = true, $update_slug = true, $update_excerpt = true) { global $DB, $Plugins; $DB->begin('SERIALIZABLE'); if ($this->status != 'draft') { // The post is getting published in some form, set the publish date so it doesn't get auto updated in the future: $this->set('dateset', 1); } // Check whether any db change has been executed $db_changed = false; // save Item settings if (isset($this->ItemSettings)) { $db_changed = $this->ItemSettings->dbupdate() || $db_changed; } // validate url title / slug if ($update_slug) { // item canonical slug wasn't updated outside from this call, if it was changed or it wasn't set yet, we must update the slugs if (empty($this->urltitle) || isset($this->dbchanges['post_urltitle'])) { // Url title has changed or is empty, we do need to update the slug: $edited_slugs = $this->update_slugs(); $db_changed = true; } } $db_changed = $this->update_renderers_from_Plugins() || $db_changed; if ($update_excerpt) { // We want to update the excerpt: if (empty($this->excerpt) || $this->excerpt_autogenerated && isset($this->dbchanges['post_content'])) { // Item excerpt is empty or the content was changed and the excerpt is autogenerated: $this->update_excerpt(); $db_changed = true; } } // TODO: dh> allow a plugin to cancel update here (by returning false)? $Plugins->trigger_event('PrependItemUpdateTransact', $params = array('Item' => &$this)); $dbchanges = $this->dbchanges; // we'll save this for passing it to the plugin hook $result = true; // fp> note that dbchanges isn't actually 100% accurate. At this time it does include variables that actually haven't changed. if (isset($this->dbchanges['post_status']) || isset($this->dbchanges['post_title']) || isset($this->dbchanges['post_content'])) { // One of the fields we track in the revision history has changed: // Save the "current" (soon to be "old") data as a version before overwriting it in parent::dbupdate: // fp> TODO: actually, only the fields that have been changed should be copied to the version, the other should be left as NULL // Get next version ID $iver_SQL = new SQL(); $iver_SQL->SELECT('MAX( iver_ID )'); $iver_SQL->FROM('T_items__version'); $iver_SQL->WHERE('iver_itm_ID = ' . $this->ID); $iver_ID = (int) $DB->get_var($iver_SQL->get()) + 1; $sql = 'INSERT INTO T_items__version( iver_ID, iver_itm_ID, iver_edit_user_ID, iver_edit_datetime, iver_status, iver_title, iver_content ) SELECT "' . $iver_ID . '" AS iver_ID, post_ID, post_lastedit_user_ID, post_datemodified, post_status, post_title, post_content FROM T_items__item WHERE post_ID = ' . $this->ID; $result = $DB->query($sql, 'Save a version of the Item') !== false; $db_changed = true; } if ($auto_track_modification && count($dbchanges) > 0 && !isset($dbchanges['last_touched_ts'])) { // Update last_touched_ts field only if it wasn't updated yet and the datemodified will be updated for sure. $this->set_last_touched_ts(); } $parent_update = parent::dbupdate($auto_track_modification); if ($result && $parent_update !== false) { // We could update the item object: $db_changed = $db_changed || $parent_update !== NULL; if (isset($this->dbchanges_flags['extra_cat_IDs'])) { // Let's handle the extracats: $result = $this->insert_update_extracats('update'); $db_changed = true; } if ($result && isset($this->dbchanges_flags['tags'])) { // Let's handle the tags: $this->insert_update_tags('update'); $db_changed = true; } // Let's handle the slugs: // TODO: dh> $result handling here feels wrong: when it's true already, it should not become false (add "|| $result"?) // asimo>dh The result handling is in a transaction. If somehow the new slug creation fails, then the item insertion should rollback as well if ($result && !empty($edited_slugs)) { // if we have new created $edited_slugs, we have to insert it into the database: foreach ($edited_slugs as $edited_Slug) { if ($edited_Slug->ID == 0) { // Insert only new created slugs $edited_Slug->dbinsert(); } } if (isset($edited_slugs[0]) && $edited_slugs[0]->ID > 0) { // Make first slug from list as main slug for this item $this->set('canonical_slug_ID', $edited_slugs[0]->ID); $this->set('urltitle', $edited_slugs[0]->get('title')); $result = parent::dbupdate(); } } // Update last touched date of this Item and also all categories of this Item $this->update_last_touched_date(false, false); } // Check if there were failed nested transaction $result = $result && !$DB->has_failed_transaction(); if ($result === false) { // Update failed $DB->rollback(); $db_changed = false; } else { // Update was successful if ($db_changed) { // There were some db modification, delete prerendered content $this->delete_prerendered_content(); } $DB->commit(); $Plugins->trigger_event('AfterItemUpdate', $params = array('Item' => &$this, 'dbchanges' => $dbchanges)); } if ($db_changed) { // There were db modificaitons, needs cache invalidation // Load the blog we're in: $Blog =& $this->get_Blog(); // BLOCK CACHE INVALIDATION: BlockCache::invalidate_key('cont_coll_ID', $Blog->ID); // Content has changed if ($this->is_intro() || $this->is_featured()) { // Content of intro or featured post has changed BlockCache::invalidate_key('intro_feat_coll_ID', $Blog->ID); } } // set_coll_ID // Settings have not changed return $result; }
/** * Update the DB based on previously recorded changes * * @return boolean true on success */ function dbupdate() { global $DB, $Plugins; $DB->begin(); // validate url title if (empty($this->urltitle) || isset($this->dbchanges['post_urltitle'])) { // Url title has changed or is empty // echo 'updating url title'; $this->set('urltitle', urltitle_validate($this->urltitle, $this->title, $this->ID, false, $this->dbprefix, $this->dbIDname, $this->dbtablename)); } $this->update_renderers_from_Plugins(); // TODO: dh> allow a plugin to cancel update here (by returning false)? $Plugins->trigger_event('PrependItemUpdateTransact', $params = array('Item' => &$this)); $dbchanges = $this->dbchanges; // we'll save this for passing it to the plugin hook if ($result = parent::dbupdate()) { // We could update the item object.. // Let's handle the extracats: $this->insert_update_extracats('update'); // Let's handle the extracats: $this->insert_update_tags('update'); // Empty pre-rendered content cache - any item property may have influence on it: $DB->query('DELETE FROM T_items__prerendering WHERE itpr_itm_ID = ' . $this->ID); $this->content_prerendered = NULL; $DB->commit(); $Plugins->trigger_event('AfterItemUpdate', $params = array('Item' => &$this, 'dbchanges' => $dbchanges)); } else { $DB->commit(); } return $result; }