From db8f0c54755792b2333b2d1a56c1b995a2248baa Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Tue, 22 Nov 2016 21:11:26 +0100 Subject: [PATCH] ProcessChanges,NodeAction(s): cleanup, docs --- library/Businessprocess/NodeAction.php | 84 +++++++++++++++++--- library/Businessprocess/NodeCreateAction.php | 46 +++++++++-- library/Businessprocess/NodeModifyAction.php | 35 +++++++- library/Businessprocess/NodeRemoveAction.php | 13 +++ library/Businessprocess/ProcessChanges.php | 83 ++++++++++++++++++- 5 files changed, 236 insertions(+), 25 deletions(-) diff --git a/library/Businessprocess/NodeAction.php b/library/Businessprocess/NodeAction.php index 88e0e34..3266574 100644 --- a/library/Businessprocess/NodeAction.php +++ b/library/Businessprocess/NodeAction.php @@ -4,41 +4,82 @@ namespace Icinga\Module\Businessprocess; use Icinga\Exception\ProgrammingError; +/** + * Abstract NodeAction class + * + * Every instance of a NodeAction represents a single applied change. Changes are pushed to + * a stack and consumed from there. When persisted, NodeActions are serialized with their name, + * node name and optionally additional properties according preserveProperties. For each property + * that should be preserved, getter and setter methods have to be defined. + * + * @package Icinga\Module\Businessprocess + */ abstract class NodeAction { - const TYPE_CREATE = 'create'; - - const TYPE_REMOVE = 'remove'; - - const TYPE_MODIFY = 'modify'; - - const TYPE_CHILD_ADD = 'childRemove'; - - const TYPE_CHILD_REMOVE = 'childAdd'; - - protected $nodeName; - + /** @var string Name of this action (currently create, modify, remove) */ protected $actionName; + /** @var string Name of the node this action applies to */ + protected $nodeName; + + /** @var array Properties which should be preeserved when serializing this action */ protected $preserveProperties = array(); + /** + * NodeAction constructor. + * + * @param Node|string $node + */ public function __construct($node) { $this->nodeName = (string) $node; } + /** + * Every NodeAction must be able to apply itself to a BusinessProcess + * + * @param BusinessProcess $bp + * @return mixed + */ abstract public function applyTo(BusinessProcess $bp); + /** + * Every NodeAction must be able to tell whether it could be applied to a BusinessProcess + * + * @param BusinessProcess $bp + * @return bool + */ + abstract public function appliesTo(BusinessProcess $bp); + + /** + * The name of the node this modification applies to + * + * @return string + */ public function getNodeName() { return $this->nodeName; } + /** + * Whether this is an instance of a given action name + * + * @param string $actionName + * @return bool + */ public function is($actionName) { return $this->getActionName() === $actionName; } + /** + * Create an instance of a given actionName for a specific Node + * + * @param string $actionName + * @param string $nodeName + * + * @return static + */ public static function create($actionName, $nodeName) { $classname = __NAMESPACE__ . '\\Node' . ucfirst($actionName) . 'Action'; @@ -46,6 +87,11 @@ abstract class NodeAction return $object; } + /** + * Returns a JSON-encoded serialized NodeAction + * + * @return string + */ public function serialize() { $object = (object) array( @@ -62,6 +108,12 @@ abstract class NodeAction return json_encode($object); } + /** + * Decodes a JSON-serialized NodeAction and returns an object instance + * + * @param $string + * @return NodeAction + */ public static function unserialize($string) { $object = json_decode($string); @@ -75,6 +127,13 @@ abstract class NodeAction return $action; } + /** + * Returns the defined action name or determines such from the class name + * + * @return string The action name + * + * @throws ProgrammingError when no such class exists + */ public function getActionName() { if ($this->actionName === null) { @@ -89,5 +148,4 @@ abstract class NodeAction return $this->actionName; } - } diff --git a/library/Businessprocess/NodeCreateAction.php b/library/Businessprocess/NodeCreateAction.php index c6e5a58..c95321e 100644 --- a/library/Businessprocess/NodeCreateAction.php +++ b/library/Businessprocess/NodeCreateAction.php @@ -2,64 +2,96 @@ namespace Icinga\Module\Businessprocess; +use stdClass; + class NodeCreateAction extends NodeAction { + /** @var string */ protected $parentName; + /** @var array */ protected $properties = array(); + /** @var array */ protected $preserveProperties = array('parentName', 'properties'); + /** + * @param Node $name + */ public function setParent(Node $name) { - $this->parentName = $name; + $this->parentName = (string) $name; } + /** + * @return bool + */ public function hasParent() { return $this->parentName !== null; } + /** + * @return string + */ public function getParentName() { return $this->parentName; } + /** + * @param string $name + */ public function setParentName($name) { $this->parentName = $name; } + /** + * @return array + */ public function getProperties() { return $this->properties; } - public function setProperties($properties) + /** + * @param stdClass $properties + * @return $this + */ + public function setProperties(stdClass $properties) { $this->properties = $properties; return $this; } + /** + * @inheritdoc + */ public function appliesTo(BusinessProcess $bp) { return ! $bp->hasNode($this->getNodeName()); } + /** + * @inheritdoc + */ public function applyTo(BusinessProcess $bp) { + $name = $this->getNodeName(); + $node = new BpNode($bp, (object) array( - 'name' => $this->getNodeName(), - 'operator' => $this->properties->operator, - 'child_names' => $this->properties->childNames + 'name' => $name, + 'operator' => $this->properties['operator'], + 'child_names' => $this->properties['childNames'] )); - foreach ($this->properties as $key => $val) { + foreach ($this->getProperties() as $key => $val) { $func = 'set' . ucfirst($key); $node->$func($val); } - $bp->addNode($this->getNodeName(), $node); + $bp->addNode($name, $node); if ($this->hasParent()) { $node->addParent($bp->getNode($this->getParentName())); } diff --git a/library/Businessprocess/NodeModifyAction.php b/library/Businessprocess/NodeModifyAction.php index da2e7fa..f50e166 100644 --- a/library/Businessprocess/NodeModifyAction.php +++ b/library/Businessprocess/NodeModifyAction.php @@ -10,11 +10,18 @@ class NodeModifyAction extends NodeAction protected $preserveProperties = array('formerProperties', 'properties'); -// Can be called multiple times - public function setNodeProperties(Node $node, $properties) + /** + * Set properties for a specific node + * + * Can be called multiple times + * + * @param Node $node + * @param array $properties + * + * @return $this + */ + public function setNodeProperties(Node $node, array $properties) { - $old = array(); - foreach (array_keys($properties) as $key) { $this->properties[$key] = $properties[$key]; @@ -30,6 +37,9 @@ class NodeModifyAction extends NodeAction return $this; } + /** + * @inheritdoc + */ public function appliesTo(BusinessProcess $bp) { $name = $this->getNodeName(); @@ -50,6 +60,9 @@ class NodeModifyAction extends NodeAction return true; } + /** + * @inheritdoc + */ public function applyTo(BusinessProcess $bp) { $node = $bp->getNode($this->getNodeName()); @@ -62,23 +75,37 @@ class NodeModifyAction extends NodeAction return $this; } + /** + * @param $properties + * @return $this + */ public function setProperties($properties) { $this->properties = $properties; return $this; } + /** + * @param $properties + * @return $this + */ public function setFormerProperties($properties) { $this->formerProperties = $properties; return $this; } + /** + * @return array + */ public function getProperties() { return $this->properties; } + /** + * @return array + */ public function getFormerProperties() { return $this->formerProperties; diff --git a/library/Businessprocess/NodeRemoveAction.php b/library/Businessprocess/NodeRemoveAction.php index 916265f..5c48279 100644 --- a/library/Businessprocess/NodeRemoveAction.php +++ b/library/Businessprocess/NodeRemoveAction.php @@ -2,13 +2,26 @@ namespace Icinga\Module\Businessprocess; +/** + * NodeRemoveAction + * + * Tracks removed nodes + * + * @package Icinga\Module\Businessprocess + */ class NodeRemoveAction extends NodeAction { + /** + * @inheritdoc + */ public function appliesTo(BusinessProcess $bp) { return $bp->hasNode($this->getNodeName()); } + /** + * @inheritdoc + */ public function applyTo(BusinessProcess $bp) { $bp->removeNode($this->getNodeName()); diff --git a/library/Businessprocess/ProcessChanges.php b/library/Businessprocess/ProcessChanges.php index 1fcf17c..cf1c2c5 100644 --- a/library/Businessprocess/ProcessChanges.php +++ b/library/Businessprocess/ProcessChanges.php @@ -3,22 +3,36 @@ namespace Icinga\Module\Businessprocess; use Icinga\Web\Session\SessionNamespace as Session; -use Icinga\Module\Businessprocess\NodeAction; class ProcessChanges { + /** @var NodeAction[] */ protected $changes = array(); + /** @var Session */ protected $session; + /** @var bool */ protected $hasBeenModified = false; + /** @var string Session storage key for this processes changes */ protected $sessionKey; + /** + * ProcessChanges constructor. + * + * Direct access is not allowed + */ private function __construct() { } + /** + * @param BusinessProcess $bp + * @param Session $session + * + * @return ProcessChanges + */ public static function construct(BusinessProcess $bp, Session $session) { $key = 'changes.' . $bp->getName(); @@ -35,6 +49,12 @@ class ProcessChanges return $changes; } + /** + * @param Node $node + * @param $properties + * + * @return $this + */ public function modifyNode(Node $node, $properties) { $action = new NodeModifyAction($node); @@ -42,6 +62,13 @@ class ProcessChanges return $this->push($action); } + /** + * @param Node|string $nodeName + * @param array $properties + * @param Node $parent + * + * @return $this + */ public function createNode($nodeName, $properties, Node $parent = null) { $action = new NodeCreateAction($nodeName); @@ -52,11 +79,23 @@ class ProcessChanges return $this->push($action); } + /** + * @param Node $node + * + * @return $this + */ public function deleteNode(Node $node) { return $this->push(new NodeDeleteAction($node)); } + /** + * Add a new action to the stack + * + * @param NodeAction $change + * + * @return $this + */ public function push(NodeAction $change) { $this->changes[] = $change; @@ -64,11 +103,22 @@ class ProcessChanges return $this; } + + /** + * Get all stacked actions + * + * @return NodeAction[] + */ public function getChanges() { return $this->changes; } + /** + * Forget all changes and remove them from the Session + * + * @return $this + */ public function clear() { $this->hasBeenModified = true; @@ -77,16 +127,31 @@ class ProcessChanges return $this; } + /** + * Whether there are no stacked changes + * + * @return bool + */ public function isEmpty() { return $this->count() === 0; } + /** + * Number of stacked changes + * + * @return bool + */ public function count() { return count($this->changes); } + /** + * Get the first change on the stack, false if empty + * + * @return NodeAction|boolean + */ public function shift() { if ($this->isEmpty()) { @@ -97,6 +162,11 @@ class ProcessChanges return array_shift($this->changes); } + /** + * Get the last change on the stack, false if empty + * + * @return NodeAction|boolean + */ public function pop() { if ($this->isEmpty()) { @@ -107,6 +177,11 @@ class ProcessChanges return array_pop($this->changes); } + /** + * The identifier used for this processes changes in our Session storage + * + * @return string + */ protected function getSessionKey() { return $this->sessionKey; @@ -117,6 +192,9 @@ class ProcessChanges return $this->hasBeenModified; } + /** + * @return array + */ public function serialize() { $serialized = array(); @@ -127,6 +205,9 @@ class ProcessChanges return $serialized; } + /** + * Persist to session on destruction + */ public function __destruct() { if (! $this->hasBeenModified()) {