* $fromRecord = Versioned::get_version('SiteTree', $pageID, $fromVersion); * $toRecord = Versioned::get_version('SiteTree, $pageID, $toVersion); * $diff = new DataDifferencer($fromRecord, $toRecord); * * * And then it can be used in a number of ways. You can use the ChangedFields() method in a template: *
 * 
* <% control Diff.ChangedFields %> *
$Title
*
$Diff
* <% end_control %> *
*
* * Or you can get the diff'ed content as another DataObject, that you can insert into a form. * * $form->loadDataFrom($diff->diffedData()); * * * If there are fields whose changes you aren't interested in, you can ignore them like so: * * $diff->ignoreFields('AuthorID', 'Status'); * */ class DataDifferencer extends ViewableData { protected $fromRecord; protected $toRecord; protected $ignoredFields = array("ID","Version","RecordID"); function __construct($fromRecord, $toRecord) { $this->fromRecord = $fromRecord; $this->toRecord = $toRecord; } /** * Specify some fields to ignore changes from. Repeated calls are cumulative. * @param $ignoredFields An array of field names to ignore. Alternatively, pass the field names as * separate args. */ function ignoreFields($ignoredFields) { if(!is_array($ignoredFields)) $ignoredFields = func_get_args(); $this->ignoredFields = array_merge($this->ignoredFields, $ignoredFields); } /** * Get a DataObject with altered values replaced with HTML diff strings, incorporating * and tags. */ function diffedData() { $diffed = clone $this->fromRecord; $fields = array_keys($diffed->getAllFields()); foreach($fields as $field) { if(in_array($field, $this->ignoredFields)) continue; if($this->fromRecord->$field != $this->toRecord->$field) { $diffed->$field = Diff::compareHTML($this->fromRecord->$field, $this->toRecord->$field); } } return $diffed; } /** * Get a DataObjectSet of the changed fields. * Each element is an array data containing * - Name: The field name * - Title: The human-readable field title * - Diff: An HTML diff showing the changes * - From: The older version of the field * - To: The newer version of the field */ function ChangedFields() { $changedFields = new DataObjectSet(); $fields = array_keys($this->fromRecord->getAllFields()); foreach($fields as $field) { if(in_array($field, $this->ignoredFields)) continue; if($this->fromRecord->$field != $this->toRecord->$field) { $changedFields->push(new ArrayData(array( 'Name' => $field, 'Title' => $this->fromRecord->fieldLabel($field), 'Diff' => Diff::compareHTML($this->fromRecord->$field, $this->toRecord->$field), 'From' => $this->fromRecord->$field, 'To' => $this->toRecord->$field, ))); } } return $changedFields; } /** * Get an array of the names of every fields that has changed. * This is simpler than {@link ChangedFields()} */ function changedFieldNames() { $diffed = clone $this->fromRecord; $fields = array_keys($diffed->getAllFields()); $changedFields = array(); foreach($fields as $field) { if(in_array($field, $this->ignoredFields)) continue; if($this->fromRecord->$field != $this->toRecord->$field) { $changedFields[] = $field; } } return $changedFields; } }