Create a revision archive for field values
From Achievo/ATK Wiki
|
ATK Howto: Create a revision archive for field values
|
Describes how to create a revision system so every change in selected fields in a node can be tracked.
First create a table:
CREATE TABLE IF NOT EXISTS `revision` ( `rev_table` varchar( 50 ) NOT NULL , `rev_field` varchar( 50 ) NOT NULL , `rev_atkprimkey` varchar( 200 ) NOT NULL , `rev_datetime` datetime NOT NULL , `rev_username` varchar( 25 ) NOT NULL , `rev_value` text, PRIMARY KEY ( `rev_table` , `rev_field` , `rev_datetime` , `rev_username` , `rev_atkprimkey` ))
Then use this baseclass instead of your usual atkNode. Add fields from your node to $this->m_revision_fields(array("field1","field")); Then every fieldchange in these fields will be saved to the database.
class watkNode extends atkNode { var $m_revision_fields=array(); //Add fields from your node here to track changes function watkNode($type, $flags="") { $this->atkNode($type, $flags); if (count($this->m_revision_fields)>0) $this->addFlag(NF_TRACK_CHANGES); } function postUpdate($record) { if (count($this->m_revision_fields)>0) $this->checkrevision($record); parent::postUpdate($record); return true; } function postAdd($record) { if (count($this->m_revision_fields)>0) $this->checkrevision($record); parent::postAdd($record); return true; } function checkrevision($record) { $save_revision_fields=array(); foreach($this->m_revision_fields as $revision_field) { if ($record[$revision_field]<>$record['atkorgrec'][$revision_field]) { $attrib=$this->getAttribute($revision_field); if (is_object($attrib)) { //Check that attribute exists if(stripos(get_class($attrib),'date')) {//date must be handled different $value=$attrib->display(array($revision_field=>$record[$revision_field]),"view"); $value_old=$attrib->display(array($revision_field=>$record['atkorgrec'][$revision_field]),"view"); if ($value_old<>$value) { $save_revision_fields[$revision_field]=$value; } } elseif(stripos(get_class($attrib),'manytoonerelation')) {//onetomanyrelation must be handled different $value=$attrib->display(array($revision_field=>$record[$revision_field]),"view"); $value_old=$attrib->display(array($revision_field=>$record['atkorgrec'][$revision_field]),"view"); if ($value_old<>$value and array_merge($record['atkorgrec'][$revision_field],$record[$revision_field])<>$record['atkorgrec'][$revision_field]) { $save_revision_fields[$revision_field]=$value; //If different descriptor and different PK's save } } else { $save_revision_fields[$revision_field]=$attrib->display(array($revision_field=>$record[$revision_field])); } } } } if (count($save_revision_fields)>0) $this->updaterevision($record['atkprimkey'],$save_revision_fields); } function updaterevision($rev_atkprimkey,$save_revision_fields) { global $g_user; $revnode=&atkGetNode("revision.revision"); $update_datetime=array('year'=>date('Y'), 'month'=>date('m'), 'day'=>date('d'), 'hours'=>date('H'), 'minutes'=>date('i'), 'seconds'=>date('s')); $rev_atkprimkey=str_replace("'",'',$rev_atkprimkey); foreach($save_revision_fields as $field=>$value) { $rec['rev_atkprimkey']=$rev_atkprimkey; $rec['rev_table']=$this->m_table; $rec['rev_field']=$field; $rec['rev_username']=$g_user["full_name"]; $rec['rev_datetime']= $update_datetime; $rec['rev_value']=$value; $revnode->addDb($rec); unset($rec); } }
The revision node:
useattrib("atkattribute"); useattrib("atkdatetimeattribute"); useattrib("atktextattribute"); class revision extends atkNode { function revision() { $this->atkNode("revision",NF_ADD_LINK); $this->add(new atkAttribute("rev_atkprimkey", AF_SEARCHABLE|AF_PRIMARY)); $this->add(new atkAttribute("rev_table", AF_SEARCHABLE|AF_PRIMARY)); $this->add(new atkAttribute("rev_field", AF_SEARCHABLE|AF_PRIMARY)); $this->add(new atkDateTimeAttribute("rev_datetime", AF_SEARCHABLE|AF_PRIMARY)); $this->add(new atkAttribute("rev_username", AF_SEARCHABLE)); $this->add(new atkTextAttribute("rev_value", AF_SEARCHABLE)); $this->setOrder("rev_table,rev_field,rev_datetime"); $this->setTable("revision"); } function rev_value_display($record,$mode) // Override the display function so the preformatted data is shown as saved in the database. { return $record['rev_value']; } }
What's missing here is a generic way of showing the different revisions.
An example of how this may look in the outlook theme is showed below.
This requires editing the edit & view handler, and the two templates.