Example #1
0
 /**
  * Writes a content-changelog entry.
  *
  * @param string $action Must be one of 'INSERT', 'UPDATE', or 'DELETE'.
  * @param string $contenttype The contenttype setting to log.
  * @param int $contentid ID of the content item to log.
  * @param array $newContent For 'INSERT' and 'UPDATE', the new content;
  *                          null for 'DELETE'.
  *
  * For the 'UPDATE' and 'DELETE' actions, this function fetches the
  * previous data from the database; this means that you must call it
  * _before_ running the actual update/delete query; for the 'INSERT'
  * action, this is not necessary, and since you really want to provide
  * an ID, you can only really call the logging function _after_ the update.
  * @throws \Exception
  */
 private function writeChangelog($action, $contenttype, $contentid, $newContent = null)
 {
     $allowed = array('INSERT', 'UPDATE', 'DELETE');
     if (!in_array($action, $allowed)) {
         throw new \Exception("Invalid action '{$action}' specified for changelog (must be one of [ " . implode(', ', $allowed) . " ])");
     }
     if ($this->app['config']->get('general/changelog/enabled')) {
         $tablename = $this->getTablename($contenttype);
         if ($action === 'INSERT') {
             $oldContent = null;
         } else {
             $oldContent = $this->app['db']->fetchAssoc("SELECT * FROM {$tablename} WHERE id = ?", array($contentid));
         }
         if (empty($oldContent) && empty($newContent)) {
             throw new \Exception("Tried to log something that cannot be: both old and new content are empty");
         }
         if (empty($oldContent) && in_array($action, array('UPDATE', 'DELETE'))) {
             throw new \Exception("Cannot log action {$action} when old content doesn't exist");
         }
         if (empty($newContent) && in_array($action, array('INSERT', 'UPDATE'))) {
             throw new \Exception("Cannot log action {$action} when new content is empty");
         }
         switch ($action) {
             case 'UPDATE':
                 $diff = DeepDiff::deep_diff($oldContent, $newContent);
                 foreach ($diff as $item) {
                     list($k, $old, $new) = $item;
                     if (isset($newContent[$k])) {
                         $data[$k] = array($old, $new);
                     }
                 }
                 break;
             case 'INSERT':
                 foreach ($newContent as $k => $val) {
                     $data[$k] = array(null, $val);
                 }
                 break;
             case 'DELETE':
                 foreach ($oldContent as $k => $val) {
                     $data[$k] = array($val, null);
                 }
                 break;
         }
         if ($newContent) {
             $content = new Content($this->app, $contenttype, $newContent);
         } else {
             $content = new Content($this->app, $contenttype, $oldContent);
         }
         $title = $content->getTitle();
         if (empty($title)) {
             $content = $this->getContent("{$contenttype}/{$contentid}");
             $title = $content->getTitle();
         }
         $str = json_encode($data);
         $user = $this->app['users']->getCurrentUser();
         $entry['title'] = $title;
         $entry['date'] = date('Y-m-d H:i:s');
         $entry['ownerid'] = $user['id'];
         $entry['contenttype'] = $contenttype;
         $entry['contentid'] = $contentid;
         $entry['mutation_type'] = $action;
         $entry['diff'] = $str;
         $this->app['db']->insert($this->getTablename('content_changelog'), $entry);
     }
 }
Example #2
0
 /**
  * Get the context data.
  *
  * @param array $context
  *
  * @return array
  */
 protected function getData(array $context)
 {
     $data = [];
     switch ($context['action']) {
         case 'UPDATE':
             $diff = DeepDiff::diff($context['old'], $context['new']);
             foreach ($diff as $item) {
                 list($k, $old, $new) = $item;
                 if (isset($context['new'][$k])) {
                     $data[$k] = [$old, $new];
                 }
             }
             break;
         case 'INSERT':
             foreach ($context['new'] as $k => $val) {
                 $data[$k] = [null, $val];
             }
             break;
         case 'DELETE':
             foreach ($context['old'] as $k => $val) {
                 $data[$k] = [$val, null];
             }
             break;
     }
     return $data;
 }
Example #3
0
 /**
  * @dataProvider deepDiffProvider
  */
 public function testDeepDiff($a, $b, $expected)
 {
     $actual = DeepDiff::diff($a, $b);
     $this->assertEquals($expected, $actual);
 }
Example #4
0
 protected function write(array $record)
 {
     // Simply exit if we're not enabled
     if (!$this->app['config']->get('general/changelog/enabled')) {
         return;
     }
     // Initialise ourselves if not already
     if (!$this->initialized) {
         $this->initialize();
     }
     // Check for a valid call
     if (!in_array($record['context']['action'], $this->allowed)) {
         throw new \Exception("Invalid action '{$record['context']['action']}' specified for changelog (must be one of [ " . implode(', ', $this->allowed) . " ])");
     }
     if (empty($record['context']['old']) && empty($record['context']['new'])) {
         throw new \Exception("Tried to log something that cannot be: both old and new content are empty");
     }
     if (empty($record['context']['old']) && in_array($record['context']['action'], ['UPDATE', 'DELETE'])) {
         throw new \Exception("Cannot log action '{$record['context']['action']}' when old content doesn't exist");
     }
     if (empty($record['context']['new']) && in_array($record['context']['action'], ['INSERT', 'UPDATE'])) {
         throw new \Exception("Cannot log action '{$record['context']['action']}' when new content is empty");
     }
     $data = [];
     switch ($record['context']['action']) {
         case 'UPDATE':
             $diff = DeepDiff::diff($record['context']['old'], $record['context']['new']);
             foreach ($diff as $item) {
                 list($k, $old, $new) = $item;
                 if (isset($record['context']['new'][$k])) {
                     $data[$k] = [$old, $new];
                 }
             }
             break;
         case 'INSERT':
             foreach ($record['context']['new'] as $k => $val) {
                 $data[$k] = [null, $val];
             }
             break;
         case 'DELETE':
             foreach ($record['context']['old'] as $k => $val) {
                 $data[$k] = [$val, null];
             }
             break;
     }
     if ($record['context']['new']) {
         $content = new Content($this->app, $record['context']['contenttype'], $record['context']['new']);
     } else {
         $content = new Content($this->app, $record['context']['contenttype'], $record['context']['old']);
     }
     $title = $content->getTitle();
     if (empty($title)) {
         /** @var \Bolt\Content $content */
         $content = $this->app['storage']->getContent($record['context']['contenttype'] . '/' . $record['context']['id']);
         $title = $content->getTitle();
     }
     // Don't store datechanged, or records that are only datechanged
     unset($data['datechanged']);
     if (empty($data)) {
         return;
     }
     $str = json_encode($data);
     $user = $this->app['users']->getCurrentUser();
     try {
         $this->app['db']->insert($this->tablename, ['date' => $record['datetime']->format('Y-m-d H:i:s'), 'ownerid' => $user['id'], 'title' => $title, 'contenttype' => $record['context']['contenttype'], 'contentid' => $record['context']['id'], 'mutation_type' => $record['context']['action'], 'diff' => $str, 'comment' => $record['context']['comment']]);
     } catch (\Exception $e) {
         // Nothing.
     }
 }