Index: textpattern/include/txp_article.php
===================================================================
--- textpattern/include/txp_article.php (revision 2651)
+++ textpattern/include/txp_article.php (working copy)
@@ -12,6 +12,7 @@
*/
include_once(txpath.'/lib/classMarkup.php');
+include_once(txpath.'/lib/txplib_revisions.php');
if (!defined('txpinterface')) die('txpinterface is undefined.');
@@ -150,6 +151,8 @@
uid = '".md5(uniqid(rand(),true))."',
feed_time = now()"
);
+
+ add_article_revision($ID);
if ($Status>=4) {
@@ -273,6 +276,8 @@
"ID = $ID"
);
+ add_article_revision($ID);
+
if($Status >= 4) {
if ($oldArticle['Status'] < 4) {
do_pings();
@@ -301,6 +306,8 @@
} else {
$ID = gps('ID');
}
+
+ $rev = gps('revision');
// switch to 'text' view upon page load and after article post
if(!$view || gps('save') || gps('publish')) {
@@ -317,14 +324,26 @@
&& $from_view != 'html') {
$ID = assert_int($ID);
- $article = safe_row(
- "*, unix_timestamp(Posted) as sPosted,
- unix_timestamp(Expires) as sExpires,
- unix_timestamp(LastMod) as sLastMod",
- "textpattern",
- "ID=$ID"
- );
+
+ if (!empty($rev)) {
+ $article_rev = get_revision($ID,$rev);
+ if ($article_rev) {
+ $article = $article_rev['data'];
+ $article['sPosted'] = strtotime($article['Posted']);
+ $article['sExpires'] = ($article['Expires'] == '0000-00-00 00:00:00') ? 0 : strtotime($article['Expires']);
+ $article['sLastMod'] = strtotime($article['LastMod']);
+ }
+ } else {
+ $article = safe_row(
+ "*, unix_timestamp(Posted) as sPosted,
+ unix_timestamp(Expires) as sExpires,
+ unix_timestamp(LastMod) as sLastMod",
+ "textpattern",
+ "ID=$ID"
+ );
+ }
+
extract($article);
$article['reset_time'] = $article['publish_now'] = ($Status < 4);
@@ -389,11 +408,14 @@
{
echo hInput('store', base64_encode(serialize($article)));
}
+
+ $revision = gps('revision');
echo hInput('ID', $ID).
eInput('article').
sInput($step).
''.
+ (!empty($revision) ? hInput('revision', $revision) : '').
startTable('edit').
@@ -454,8 +476,29 @@
echo '';
}
+ echo '';
- echo '';
+ $revisions = get_revisions($ID);
+
+ if (!empty($revisions)) {
+ echo '
'.
+ '';
+
+ $rev_count = 1;
+ foreach ($revisions as $rev)
+ {
+ if ($rev_count++ == 1)
+ {
+ echo n.t.'
';
+ } else {
+ echo n.t.'
';
+ }
+ }
+
+ echo '
';
+ }
}
else
@@ -481,12 +524,17 @@
{
echo '';
- if ( ($Status == 4 or $Status == 5) and $step != 'create') {
+ $revision = gps('revision');
+
+ if ( ($Status == 4 or $Status == 5) and $step != 'create' and empty($revision)) {
include_once txpath.'/publish/taghandlers.php';
echo sp.sp.'['.gTxt('view').']';
}
+ if (!empty($revision))
+ echo sp.sp.'['.gTxt('Revision',array($revision)).']';
+
echo '
'.
n.'
';
}
@@ -1010,4 +1058,29 @@
}
}
-?>
+
+//--------------------------------------------------------------
+ function add_article_revision($ID)
+ {
+ global $prefs;
+
+ if ($ID) {
+ // get the new article
+ $rs = safe_row('*', 'textpattern', "ID = $ID");
+
+ if ($rs) {
+ // get the article's last version
+ $rev = get_revision($ID);
+
+ if (isset($prefs['custom_article_compare_func']) and is_callable($prefs['custom_article_compare_func']))
+ $changed = call_user_func($prefs['custom_article_compare_func'], array($rs, $rev));
+ else
+ $changed = true;
+
+ if ($changed)
+ add_revision($ID, $rs);
+ }
+ }
+ }
+
+?>
\ No newline at end of file
Index: textpattern/lib/txplib_revisions.php
===================================================================
--- textpattern/lib/txplib_revisions.php (revision 0)
+++ textpattern/lib/txplib_revisions.php (revision 0)
@@ -0,0 +1,149 @@
+limit(1) : " AND version = $ver") );
+
+ if ($rev)
+ $rev['data'] = decode_revision_data($rev['data']);
+ }
+
+ return $rev;
+ }
+
+//-------------------------------------------------------------
+ function get_revision_count($id, $type='article')
+ {
+ if (empty($id))
+ return false;
+
+ $id = assert_int($id);
+ $type = doSlash($type);
+
+ if ($id !== false && !empty($type))
+ return safe_count('txp_revisions', "type = '$type' AND id = $id");
+
+ return false;
+ }
+
+//-------------------------------------------------------------
+ function get_next_revision_number($id, $type='article')
+ {
+ global $DB;
+
+ if (empty($id))
+ return false;
+
+ $id = assert_int($id);
+ $type = doSlash($type);
+
+ $rev = 0;
+
+ if ($id !== false && !empty($type)) {
+ $rev = safe_field('version', 'txp_revisions', "type = '$type' AND id = $id ORDER BY version DESC " . $DB->limit(1));
+
+ if (!$rev)
+ $rev = 0;
+
+ }
+
+ return $rev + 1;
+ }
+
+//-------------------------------------------------------------
+ function add_revision($id, $data, $type='article', $user='')
+ {
+ global $txp_user;
+
+ if (empty($id))
+ return false;
+
+ if (empty($user)) $user = $txp_user;
+
+ $id = assert_int($id);
+
+ $data = encode_revision_data($data);
+
+ if ($id !== false && !empty($type) && !empty($user)) {
+
+ $version = get_next_revision_number($id, $type);
+
+ $id = doSlash($id);
+ $version = doSlash($version);
+ $type = doSlash($type);
+ $user = doSlash($user);
+
+ return safe_insert('txp_revisions', "id = $id, version = $version, type = '$type', user = '$user', modified = now(), data = '$data'");
+ }
+
+ return false;
+ }
+?>
\ No newline at end of file
Index: textpattern/model/txp_tables.php
===================================================================
--- textpattern/model/txp_tables.php (revision 2651)
+++ textpattern/model/txp_tables.php (working copy)
@@ -449,4 +449,27 @@
}
+class txp_revisions_table extends zem_table
+{
+
+ var $_table_name = 'txp_revisions';
+
+ var $_cols = array(
+ 'id' => ZEM_FOREIGN_KEY .' NOT NULL',
+ 'version' => "smallint NOT NULL default '1'",
+ 'type' => "varchar(64) NOT NULL default ''",
+ 'user' => "varchar(64) NOT NULL default ''",
+ 'modified' => ZEM_DATETIME . " NOT NULL default '0000-00-00 00:00:00'",
+ 'data' => ZEM_MEDIUMTEXT,
+ );
+
+ var $_primary_key = '';
+
+ function create_table(){
+ parent::create_table();
+ safe_upgrade_index($this->_table_name,'revision_version','UNIQUE','type,id,version');
+ }
+}
+
+
?>
\ No newline at end of file
Index: textpattern/setup/txpsql.php
===================================================================
--- textpattern/setup/txpsql.php (revision 2651)
+++ textpattern/setup/txpsql.php (working copy)
@@ -28,6 +28,7 @@
$datetime = 'timestamp without time zone';
$autoinc = 'SERIAL NOT NULL';
$mediumtext = 'text';
+ $longtext = 'text';
$tinytext = 'text';
$tabletype = '';
$incval = 'DEFAULT';
@@ -53,6 +54,7 @@
$datetime = 'datetime';
$autoinc = 'INT NOT NULL AUTO_INCREMENT';
$incval = 'NULL';
+ $longtext = 'longtext';
$mediumtext = 'mediumtext';
$tinytext = 'tinytext';
}
@@ -64,6 +66,7 @@
$zerodatetime = $zerodate.' 00:00:00';
$datetime = 'datetime';
$autoinc = 'INTEGER';
+ $longtext = 'text';
$mediumtext = 'text';
$tinytext = 'text';
$tabletype = '';
@@ -416,6 +419,16 @@
$create_sql[] = "INSERT INTO ".PFX."txp_prefs VALUES (1, 'dbupdatetime', '1122194504', 2, 'publish', 'text_input', 0)";
$create_sql[] = "INSERT INTO ".PFX."txp_prefs VALUES (1, 'version', '1.0rc4', 2, 'publish', 'text_input', 0)";
+$create_sql[] = "CREATE TABLE ".PFX."txp_revisions (
+ id bigint NOT NULL,
+ version smallint NOT NULL default '1',
+ type varchar(64) NOT NULL default '',
+ user varchar(64) NOT NULL default '',
+ modified $datetime NOT NULL default '$zerodatetime',
+ data $mediumtext NOT NULL default '',
+ KEY (id, version, type)
+) $tabletype";
+
$create_sql[] = "CREATE TABLE ".PFX."txp_section (
name varchar(128) NOT NULL default '',
page varchar(128) NOT NULL default '',
Index: textpattern/textpattern.css
===================================================================
--- textpattern/textpattern.css (revision 2651)
+++ textpattern/textpattern.css (working copy)
@@ -522,6 +522,17 @@
height: 85px;
}
+#revisions {
+border-top: 1px dashed #ccc;
+}
+
+.revision {
+padding-top: .5em;
+padding-bottom: .5em;
+border-bottom: 1px dashed #ccc;
+}
+
+
/* comments
----------------------------------------------- */