diff --git a/application/controllers/BranchController.php b/application/controllers/BranchController.php index 760fdcec..4ac526cf 100644 --- a/application/controllers/BranchController.php +++ b/application/controllers/BranchController.php @@ -5,18 +5,15 @@ namespace Icinga\Module\Director\Controllers; use gipfl\Diff\HtmlRenderer\SideBySideDiff; use gipfl\Diff\PhpDiff; use gipfl\IcingaWeb2\Widget\NameValueTable; -use Icinga\Module\Director\Data\Db\DbObject; -use Icinga\Module\Director\Data\Json; -use Icinga\Module\Director\Db\Branch\IcingaObjectModification; -use Icinga\Module\Director\Db\Branch\ObjectModification; +use Icinga\Module\Director\Data\Db\DbObjectTypeRegistry; +use Icinga\Module\Director\Db\Branch\BranchActivity; use Icinga\Module\Director\IcingaConfig\IcingaConfig; use Icinga\Module\Director\Objects\IcingaObject; +use Icinga\Module\Director\PlainObjectRenderer; use Icinga\Module\Director\Web\Controller\ActionController; use Icinga\Module\Director\Web\Controller\BranchHelper; +use Icinga\Module\Director\Web\Widget\IcingaConfigDiff; use ipl\Html\Html; -use ipl\Html\ValidHtml; -use Ramsey\Uuid\Uuid; -use Ramsey\Uuid\UuidInterface; class BranchController extends ActionController { @@ -29,66 +26,75 @@ class BranchController extends ActionController public function activityAction() { $this->assertPermission('director/showconfig'); - $uuid = Uuid::fromString($this->params->getRequired('uuid')); + $ts = $this->params->getRequired('ts'); $this->addSingleTab($this->translate('Activity')); $this->addTitle($this->translate('Branch Activity')); - $activity = $this->loadBranchActivity($uuid); + $activity = BranchActivity::load($ts, $this->db()); $this->content()->add($this->prepareActivityInfo($activity)); $this->showActivity($activity); } - protected function prepareActivityInfo($activity) + protected function prepareActivityInfo(BranchActivity $activity) { - $modification = ObjectModification::fromSerialization(json_decode($activity->change_set)); - /** @var IcingaObject $class IDE hint, it's a string */ - $class = $modification->getClassName(); - $keyParams = (array) $modification->getKeyParams(); // TODO: verify type - $dummy = $class::create($keyParams); - $table = new NameValueTable(); $table->addNameValuePairs([ - $this->translate('Author') => 'branch owner', - $this->translate('Date') => date('Y-m-d H:i:s', $activity->change_time / 1000), - $this->translate('Action') => $modification->getAction() - . ' ' . $dummy->getShortTableName() - . ' ' . $dummy->getObjectName(), - $this->translate('Change UUID') => Uuid::fromBytes($activity->uuid)->toString(), + $this->translate('Author') => $activity->getAuthor(), + $this->translate('Date') => date('Y-m-d H:i:s', $activity->getTimestamp()), + $this->translate('Action') => $activity->getAction() + . ' ' . preg_replace('/^icinga_/', '', $activity->getObjectTable()) + . ' ' . $activity->getObjectName(), // $this->translate('Actions') => ['Undo form'], ]); return $table; } - protected function showActivity($activity) + protected function leftFromActivity(BranchActivity $activity) { - $modification = ObjectModification::fromSerialization(Json::decode($activity->change_set)); - /** @var string|DbObject $class */ - $class = $modification->getClassName(); - - // TODO: Show JSON-Diff for non-IcingaObject's - $keyParams = (array) $modification->getKeyParams(); // TODO: verify type - $dummy = $class::create($keyParams, $this->db()); - if ($modification->isCreation()) { - $left = $this->createEmptyConfig(); - $right = $dummy->setProperties( - (array) $modification->getProperties()->jsonSerialize() - )->toSingleIcingaConfig(); - } elseif ($modification->isDeletion()) { - $left = $class::load($keyParams, $this->db())->toSingleIcingaConfig(); - $right = $this->createEmptyConfig(); - } else { - // TODO: highlight properties that have been changed in the meantime - // TODO: Deal with missing $existing - $existing = $class::load($keyParams, $this->db()); - $left = $existing->toSingleIcingaConfig(); - $right = clone($existing); - IcingaObjectModification::applyModification($modification, $right, $this->db()); - $right = $right->toSingleIcingaConfig(); + if ($activity->isActionCreate()) { + return null; } - $changes = $this->getConfigDiffs($left, $right); - foreach ($changes as $filename => $diff) { + $object = DbObjectTypeRegistry::newObject($activity->getObjectTable(), [], $this->db()); + foreach ($activity->getFormerProperties()->jsonSerialize() as $key => $value) { + $object->set($key, $value); + } + + return $object; + } + + protected function rightFromActivity(BranchActivity $activity) + { + if ($activity->isActionDelete()) { + return null; + } + $object = DbObjectTypeRegistry::newObject($activity->getObjectTable(), [], $this->db()); + if (! $activity->isActionCreate()) { + foreach ($activity->getFormerProperties()->jsonSerialize() as $key => $value) { + $object->set($key, $value); + } + } + foreach ($activity->getModifiedProperties()->jsonSerialize() as $key => $value) { + $object->set($key, $value); + } + + return $object; + } + + protected function showActivity(BranchActivity $activity) + { + $left = $this->leftFromActivity($activity); + $right = $this->rightFromActivity($activity); + if ($left instanceof IcingaObject || $right instanceof IcingaObject) { + $this->content()->add(new IcingaConfigDiff( + $left ? $left->toSingleIcingaConfig() : $this->createEmptyConfig(), + $right ? $right->toSingleIcingaConfig() : $this->createEmptyConfig() + )); + } else { $this->content()->add([ - Html::tag('h3', $filename), - $diff + Html::tag('h3', $this->translate('Modification')), + new SideBySideDiff(new PhpDiff( + PlainObjectRenderer::render($left->getProperties()), + PlainObjectRenderer::render($right->getProperties()) + )) ]); } } @@ -97,47 +103,4 @@ class BranchController extends ActionController { return new IcingaConfig($this->db()); } - - /** - * @param IcingaConfig $oldConfig - * @param IcingaConfig $newConfig - * @return ValidHtml[] - */ - protected function getConfigDiffs(IcingaConfig $oldConfig, IcingaConfig $newConfig) - { - $oldFileNames = $oldConfig->getFileNames(); - $newFileNames = $newConfig->getFileNames(); - - $fileNames = array_merge($oldFileNames, $newFileNames); - - $diffs = []; - foreach ($fileNames as $filename) { - if (in_array($filename, $oldFileNames)) { - $left = $oldConfig->getFile($filename)->getContent(); - } else { - $left = ''; - } - - if (in_array($filename, $newFileNames)) { - $right = $newConfig->getFile($filename)->getContent(); - } else { - $right = ''; - } - if ($left === $right) { - continue; - } - - $diffs[$filename] = new SideBySideDiff(new PhpDiff($left, $right)); - } - - return $diffs; - } - - protected function loadBranchActivity(UuidInterface $uuid) - { - $db = $this->db()->getDbAdapter(); - return $db->fetchRow( - $db->select()->from('director_branch_activity')->where('uuid = ?', $uuid->getBytes()) - ); - } }