Completed
Pull Request — master (#750)
by Sean
04:23
created

StateMachineFactory::forDNDeployment()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 79
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 79
rs 8.8701
c 0
b 0
f 0
cc 2
eloc 60
nc 2
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
use Finite\State\StateInterface;
4
5
class StateMachineFactory extends Object {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
6
7
	private static $handlers = [];
0 ignored issues
show
Unused Code introduced by
The property $handlers is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
8
9
	private static $initialised = [];
10
11
	public function forDNDeployment(\DNDeployment $obj) {
12
		$loader = new Finite\Loader\ArrayLoader([
13
			'class'   => 'DNDeployment',
14
			'states'  => [
15
				DNDeployment::STATE_NEW => ['type' => StateInterface::TYPE_INITIAL],
16
				DNDeployment::STATE_SUBMITTED => ['type' => StateInterface::TYPE_NORMAL],
17
				DNDeployment::STATE_INVALID => ['type' => StateInterface::TYPE_NORMAL],
18
				DNDeployment::STATE_APPROVED => ['type' => StateInterface::TYPE_NORMAL],
19
				DNDeployment::STATE_REJECTED => ['type' => StateInterface::TYPE_NORMAL],
20
				DNDeployment::STATE_QUEUED => ['type' => StateInterface::TYPE_NORMAL],
21
				DNDeployment::STATE_DEPLOYING => ['type' => StateInterface::TYPE_NORMAL],
22
				DNDeployment::STATE_ABORTING => ['type' => StateInterface::TYPE_NORMAL],
23
				DNDeployment::STATE_COMPLETED => ['type' => StateInterface::TYPE_FINAL],
24
				DNDeployment::STATE_FAILED => ['type' => StateInterface::TYPE_FINAL],
25
			],
26
			'transitions' => [
27
				DNDeployment::TR_NEW => ['from' => [DNDeployment::STATE_SUBMITTED], 'to' => DNDeployment::STATE_NEW],
28
				DNDeployment::TR_SUBMIT => ['from' => [DNDeployment::STATE_NEW], 'to' => DNDeployment::STATE_SUBMITTED],
29
				DNDeployment::TR_QUEUE => [
30
					'from' => [
31
						DNDeployment::STATE_NEW, // @deprecated. Remove this when DNRoot::startDeploy() is removed.
32
						DNDeployment::STATE_APPROVED
33
					],
34
					'to' => DNDeployment::STATE_QUEUED
35
				],
36
				DNDeployment::TR_INVALIDATE  => [
37
					'from' => [
38
						DNDeployment::STATE_NEW,
39
						DNDeployment::STATE_SUBMITTED,
40
						DNDeployment::STATE_APPROVED,
41
						DNDeployment::STATE_REJECTED
42
					],
43
					'to' => DNDeployment::STATE_INVALID
44
				],
45
				DNDeployment::TR_APPROVE => ['from' => [
46
						DNDeployment::STATE_NEW,
47
						DNDeployment::STATE_SUBMITTED
48
					],
49
					'to' => DNDeployment::STATE_APPROVED
50
				],
51
				DNDeployment::TR_REJECT => ['from' => [DNDeployment::STATE_SUBMITTED], 'to' => DNDeployment::STATE_REJECTED],
52
				DNDeployment::TR_DEPLOY => ['from' => [DNDeployment::STATE_QUEUED], 'to' => DNDeployment::STATE_DEPLOYING],
53
				DNDeployment::TR_ABORT => [
54
					'from' => [
55
						DNDeployment::STATE_QUEUED,
56
						DNDeployment::STATE_DEPLOYING,
57
						DNDeployment::STATE_ABORTING
58
					],
59
					'to' => DNDeployment::STATE_ABORTING
60
				],
61
				DNDeployment::TR_COMPLETE => ['from' => [DNDeployment::STATE_DEPLOYING], 'to' => DNDeployment::STATE_COMPLETED],
62
				DNDeployment::TR_FAIL  => [
63
					'from' => [
64
						DNDeployment::STATE_NEW,
65
						DNDeployment::STATE_SUBMITTED,
66
						DNDeployment::STATE_INVALID,
67
						DNDeployment::STATE_REJECTED,
68
						DNDeployment::STATE_APPROVED,
69
						DNDeployment::STATE_QUEUED,
70
						DNDeployment::STATE_DEPLOYING,
71
						DNDeployment::STATE_ABORTING
72
					],
73
					'to' => DNDeployment::STATE_FAILED
74
				],
75
			]
76
		]);
77
		$stateMachine = Injector::inst()->get('Finite\StateMachine\StateMachine', true, [$obj]);
78
79
		// if we have already initialised a state machine for the given \DNDeployment
80
		// then don't re-initialise it again, as this causes bugs with transition events
81
		// being called multiple times.
82
		if (empty(self::$initialised[$obj->ID])) {
83
			$loader->load($stateMachine);
84
			$stateMachine->initialize();
85
			$this->addHandlers($stateMachine);
86
			self::$initialised[$obj->ID] = true;
87
		}
88
		return $stateMachine;
89
	}
90
91
	protected function addHandlers($machine) {
92
		$class = get_class($machine->getObject());
93
		if (empty($this->config()->handlers[$class])) return;
94
95
		// this is the "internal" state listener that logs all state transitions
96
		$machine->getDispatcher()->addListener(
97
			'finite.post_transition',
98
			[Injector::inst()->get('DNDeploymentHandlers'), 'onAfterTransition']
99
		);
100
101
		$transitions = $this->config()->handlers[$class];
102
		foreach ($transitions as $transName => $handlers) {
103
			if (!is_array($handlers)) {
104
				throw new Exception(sprintf('Transition %s must be configured as an assoc array.', $transName));
105
			}
106
107
			foreach ($handlers as $handlerClass => $handlerMethod) {
108
				$handlerObj = Injector::inst()->get($handlerClass);
109
				if (!is_callable([$handlerObj, $handlerMethod])) {
110
					throw new Exception(sprintf('Handler %s is not callable on %s.', $handlerMethod, $handlerClass));
111
				}
112
				$machine->getDispatcher()->addListener(
113
					sprintf('finite.post_transition.%s', $transName),
114
					[$handlerObj, $handlerMethod]
115
				);
116
			}
117
		}
118
	}
119
120
}
121