add('name', VERSIONING_TITLE); $propbag->add('description', VERSIONING_DESC); $propbag->add('event_hooks', array( 'backend_publish' => true, 'backend_save' => true, 'backend_display' => true, 'backend_entry_updertEntry' => true, 'backend_entry_presave' => true, 'backend_entryform' => true, 'backend_entry_iframe' => true, 'entry_display' => true )); $propbag->add('author', 'Garvin Hicking'); $propbag->add('version', '0.11.2'); $propbag->add('requirements', array( 'serendipity' => '0.8', 'smarty' => '2.6.7', 'php' => '4.1.0' )); $propbag->add('stackable', false); $propbag->add('groups', array('BACKEND_EDITOR', 'BACKEND_FEATURES')); $propbag->add('configuration', array('public','version_date')); } function introspect_config_item($name, &$propbag) { global $serendipity; switch ($name) { case 'public': $propbag->add('type', 'boolean'); $propbag->add('name', VERSIONING_PUBLIC); $propbag->add('description', ''); $propbag->add('default', false); break; case 'version_date': $propbag->add('type', 'radio'); $propbag->add('name', VERSIONING_DATE_FORMAT); $propbag->add('var', 'version_date_format'); $propbag->add('radio_per_row', 2); $propbag->add('radio', array('value' => array('long','short'), 'desc' => array(VERSIONING_DATE_LONG,VERSIONING_DATE_SHORT))); break; default: return false; } return true; } function setupDB() { global $serendipity; $built = $this->get_config('db_built', null); $fresh = false; if ((empty($built)) && (!defined('VERSIONING_UPGRADE_DONE'))) { serendipity_db_schema_import("CREATE TABLE {$serendipity['dbPrefix']}versioning ( id {AUTOINCREMENT} {PRIMARY}, entry_id int(11) default '0', version int(4) default '1', body text, extended text, version_date int(11) default '0', version_author int(4) default '0' )"); $this->set_config('db_built', '1'); @define('VERSIONING_UPGRADE_DONE', true); } } function generate_content(&$title) { $title = VERSIONING_TITLE; } function install() { $this->setupDB(); } function &getVersions($entry = null, $selected = null) { global $serendipity; $versions = array(); if (empty($entry)) { return $versions; } $versions = serendipity_db_query("SELECT v.id, v.version, a.realname, v.version_date FROM {$serendipity['dbPrefix']}versioning AS v LEFT OUTER JOIN {$serendipity['dbPrefix']}authors AS a ON a.authorid = v.version_author WHERE v.entry_id = " . (int)$entry . " ORDER BY v.version DESC"); return $versions; } function &getCurrent($entry) { global $serendipity; $q = "SELECT max(v.version) AS maxVer, v.id, a.realname, v.version_date FROM {$serendipity['dbPrefix']}versioning AS v LEFT OUTER JOIN {$serendipity['dbPrefix']}authors AS a ON a.authorid = v.version_author WHERE entry_id = " . (int)$entry . " GROUP BY v.entry_id, v.id, a.realname, v.version_date ORDER BY v.version DESC"; $maxVer = serendipity_db_query($q, true, 'assoc'); if (is_string($maxVer)) { echo 'Error: ' . $maxVer . '. Postgresql is driving me nuts.
'; } return $maxVer; } function &getVersion($entry, $version = null, $version_col = 'v.version') { global $serendipity; if ($version == null) { $maxVer =& $this->getCurrent($entry); $version = $maxVer['maxVer']; } $q = "SELECT v.id, v.body, v.extended, v.version, v.entry_id, a.realname, v.version_date FROM {$serendipity['dbPrefix']}versioning AS v LEFT OUTER JOIN {$serendipity['dbPrefix']}authors AS a ON a.authorid = v.version_author WHERE v.entry_id = " . (int)$entry . " AND $version_col = " . (int)$version . " LIMIT 1"; $entry = serendipity_db_query($q, true, 'assoc'); return $entry; } function storeVersion(&$entry, &$newEntry, $cache = array()) { global $serendipity; if (!isset($cache['body'])) { $cache['body'] = $newEntry['body']; $cache['extended'] = $newEntry['extended']; } serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}versioning (entry_id, version, body, extended, version_date, version_author) VALUES (" . (int)$newEntry['id'] . ", " . ($entry['version']+1) . ", '" . serendipity_db_escape_string($cache['body']) . "', '" . serendipity_db_escape_string($cache['extended']) . "', " . time() . ", " . (int)$serendipity['authorid'] . ")"); } function recoverVersion(&$entry, $version) { global $serendipity; $recovery = $this->getVersion($entry['id'], $version, 'v.id'); $entry['body'] = $recovery['body']; $entry['extended'] = $recovery['extended']; return true; } function event_hook($event, &$bag, &$eventData, $addData = null) { global $serendipity; $hooks = &$bag->get('event_hooks'); if (isset($hooks[$event])) { switch($this->get_config('version_date')) { case 'long': $date_time_format = DATE_FORMAT_ENTRY; break; case 'short': $date_time_format = DATE_FORMAT_SHORT; break; default: $date_time_format = DATE_FORMAT_SHORT; break; } switch ($event) { case 'backend_entry_updertEntry': $this->cache['body'] = $addData['body']; $this->cache['extended'] = $addData['extended']; if ($serendipity['POST']['versioning'] > 0 && !empty($serendipity['POST']['versioning_change']) && !empty($addData['id'])) { $eventData[] = sprintf(VERSIONING_REVISION_CONTROL, (int)$serendipity['POST']['versioning']); } break; case 'backend_entry_iframe': // Serendipity 1.0: Prevent iframe creation. if ($serendipity['POST']['versioning'] > 0 && !empty($serendipity['POST']['versioning_change'])) { $eventData = false; } break; case 'backend_entry_presave': break; case 'backend_entryform': // Should we restore a version? if ($serendipity['POST']['versioning'] > 0 && !empty($serendipity['POST']['versioning_change']) && !empty($eventData['id'])) { $this->recoverVersion($eventData, $serendipity['POST']['versioning']); } break; case 'entry_display': if (!is_array($eventData)) { return false; } if (serendipity_db_bool($this->get_config('public')) && $addData['extended']) { if ($serendipity['GET']['version_selected'] > 0) { $this->recoverVersion($eventData[0], (int)$serendipity['GET']['version_selected']); } $versions = &$this->getVersions($eventData[0]['id']); if (count($versions) < 1 || empty($versions[0])) { return true; } $msg = '
' . VERSIONING_TITLE . ':
%s
'; $html = ''; $eventData[0]['add_footer'] .= sprintf($msg, $html); unset($eventData[0]['properties']['ep_cache_body']); unset($eventData[0]['properties']['ep_cache_extended']); } return true; break; case 'backend_save': case 'backend_publish': $this->setupDB(); if (empty($eventData['id'])) { return true; } // Get the last version $entry = &$this->getVersion($eventData['id']); if ($entry['body'] != $this->cache['body'] || $entry['extended'] != $this->cache['extended']) { $this->storeVersion($entry, $eventData, $this->cache); } break; case 'backend_display': $versions = &$this->getVersions($eventData['id'], $serendipity['POST']['versioning']); if (count($versions) < 1) { return true; } ?>
');" />