add('name', PLUGIN_EVENT_AUTOSAVE_TITLE); $propbag->add('description', PLUGIN_EVENT_AUTOSAVE_DESC); $propbag->add('stackable', false); $propbag->add('author', 'Jay Bertrand'); $propbag->add('requirements', array( 'serendipity' => '0.9', 'smarty' => '2.6.7', 'php' => '4.1.0' )); $propbag->add('version', '0.2.2'); $propbag->add('configuration', array()); $propbag->add('event_hooks', array( 'backend_entryform' => true, 'external_plugin' => true, 'backend_entry_presave' => true, 'backend_save' => true )); $propbag->add('configuration', array('frequency','path')); $propbag->add('groups', array('BACKEND_EDITOR')); } function introspect_config_item($name, &$propbag) { switch($name) { case 'frequency': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_AUTOSAVE_INTERVAL); $propbag->add('description', PLUGIN_EVENT_AUTOSAVE_INTERVAL_DESC); $propbag->add('validate', '/^[0-9]+$/'); $propbag->add('validate_error', PLUGIN_EVENT_AUTOSAVE_INTERVAL_ERROR); $propbag->add('default', '300'); break; case 'path': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_AUTOSAVE_HTTPATH); $propbag->add('description', PLUGIN_EVENT_AUTOSAVE_HTTPATH_DESC); $propbag->add('validate', '/[^\\*|]/'); $propbag->add('validate_error', PLUGIN_EVENT_AUTOSAVE_HTTPATH_ERROR); $propbag->add('default', 'plugins/serendipity_event_autosave'); break; default: return false; break; } return true; } function generate_content(&$title) { $title = PLUGIN_EVENT_AUTOSAVE_TITLE; } function event_hook($event, &$bag, &$eventData, $addData = null) { global $serendipity; $hooks = &$bag->get('event_hooks'); if (isset($hooks[$event])) { switch($event) { case 'backend_entry_presave': if(isset($serendipity['POST']['shadowed']) && is_numeric($serendipity['POST']['shadowed'])) // update last_modified to make sure the shadow copy is more recent than the original post $eventData['last_modified'] = time(); break; case 'backend_save': // dirty hack to confirm an entry has been saved $this->saveSuccessfull = true; // entry has been successfully saved, delete shadow copies of it (if any) // REM: this hook is also called when saving the shadow copy $ret = serendipity_db_query("SELECT value FROM {$serendipity['dbPrefix']}entryproperties ". "WHERE entryid={$eventData['id']} AND property='".PLUGIN_EVENT_AUTOSAVE_PROP_SHADOW."'", true /*single*/); if(is_array($ret)) { // drop shadow copy and extra properties serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}entries WHERE id=".(int)current($ret)); serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}entryproperties ". "WHERE entryid={$eventData['id']} AND property='".PLUGIN_EVENT_AUTOSAVE_PROP_SHADOW."'", true /*single*/); } break; case 'backend_entryform': ?>
'.PLUGIN_EVENT_AUTOSAVE_BAD_SHADOW.''); } else { // fetch the autosaved entry and replace the original one by the shadow copy "on the fly" :-) $entry = serendipity_fetchEntry('id', $_GET['autosave']['id'], 1, 1); if(is_array($entry)) { // modify (partly) the entry on the fly with backed up data :-) foreach($entry as $key=>$value) if($key != 'id' && $key != 'isdraft') $eventData[$key] = $value; } else { echo(''.PLUGIN_EVENT_AUTOSAVE_RECOVER_FAILED); echo((strlen(trim($entry)) ? ' ('.$entry.')' : '').''); } } } // end if ?>
'; echo ''; echo ''; $fd = fopen(dirname(__FILE__).'/debug.log', 'w'); fwrite($fd, ob_get_contents()); fclose($fd); ob_end_flush(); } elseif(strncmp($serendipity['GET']['adminAction'], 'save', 4)==0) { //----------------------------------------------------------- // saving an entry //----------------------------------------------------------- // handling of shadow copies if(isset($serendipity['POST']['shadowed']) && is_numeric($serendipity['POST']['shadowed'])) { // save the id of the "real" post (should be a valid id !) $realEntryId = (int)$serendipity['POST']['id']; // prevent overwritting of published post $serendipity['POST']['id'] = (int)$serendipity['POST']['shadowed']; if($serendipity['POST']['id']==0) $serendipity['POST']['id'] = ''; } // just to be sure the user is aware that it is an autosaved entry :-) if(strncmp($serendipity['POST']['title'], PLUGIN_EVENT_AUTOSAVE_PREFIX, strlen(PLUGIN_EVENT_AUTOSAVE_PREFIX)) != 0) $serendipity['POST']['title'] = PLUGIN_EVENT_AUTOSAVE_PREFIX.$serendipity['POST']['title']; // save entry here (just including the file will do it :-)) but discard output // (althoug we won't get a precise message if an error occurs ;-() ob_start(); // /!\ awfull hack: there's no simple way (?) to know if an entry has been // successfully saved, so we use a flag that is toggled when backend_save is // called since backend_save is the latest event hook called when "upderting" // an entry (see serendipity_updertEntry() in functions_entries.inc.php) $this->saveSuccessfull = false; require_once S9Y_INCLUDE_PATH.'include/admin/entries.inc.php'; if(false == $this->saveSuccessfull) $entry = array('id' => 0); ob_end_clean(); if(isset($realEntryId) && is_numeric($realEntryId)) { // "updert" a property on original entry to link it to the shadow copy serendipity_db_query("UPDATE {$serendipity['dbPrefix']}entryproperties SET value=".(int)$entry['id']." ". "WHERE entryid=".(int)$realEntryId." AND property='".PLUGIN_EVENT_AUTOSAVE_PROP_SHADOW."'"); serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}entryproperties (entryid,property,value) ". "VALUES (".(int)$realEntryId.", '".PLUGIN_EVENT_AUTOSAVE_PROP_SHADOW."',".(int)$entry['id'].")"); } // send back the generated id to the client (or 0 if save failed, whatever the reason) echo ''; echo ''; echo ''; } exit(); break; default: return false; break; } // event has been handled :-) return true; } return false; } } /* vim: set sts=4 ts=4 expandtab : */