1
|
|
|
<?php |
2
|
|
|
namespace rtens\domin\reflection; |
3
|
|
|
|
4
|
|
|
use rtens\domin\Action; |
5
|
|
|
use rtens\domin\Parameter; |
6
|
|
|
use rtens\domin\reflection\types\TypeFactory; |
7
|
|
|
use watoki\factory\Factory; |
8
|
|
|
use watoki\factory\Injector; |
9
|
|
|
use watoki\reflect\PropertyReader; |
10
|
|
|
|
11
|
|
|
abstract class ObjectAction implements Action { |
12
|
|
|
|
13
|
|
|
/** @var PropertyReader */ |
14
|
|
|
private $reader; |
15
|
|
|
|
16
|
|
|
/** @var \ReflectionClass */ |
17
|
|
|
protected $class; |
18
|
|
|
|
19
|
|
|
/** @var CommentParser */ |
20
|
|
|
private $parser; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* @param string $class |
24
|
|
|
* @param TypeFactory $types |
25
|
|
|
* @param CommentParser $parser |
26
|
|
|
*/ |
27
|
|
|
public function __construct($class, TypeFactory $types, CommentParser $parser) { |
28
|
|
|
$this->reader = new PropertyReader($types, $class); |
29
|
|
|
$this->class = new \ReflectionClass($class); |
30
|
|
|
$this->parser = $parser; |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Called by execute() with the instantiated object |
35
|
|
|
* |
36
|
|
|
* @param object $object |
37
|
|
|
* @return mixed |
38
|
|
|
*/ |
39
|
|
|
abstract protected function executeWith($object); |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @return string |
43
|
|
|
*/ |
44
|
|
|
public function caption() { |
45
|
|
|
return preg_replace('/(.)([A-Z0-9])/', '$1 $2', $this->class->getShortName()); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @return string|null |
50
|
|
|
*/ |
51
|
|
|
public function description() { |
52
|
|
|
$docComment = $this->class->getDocComment(); |
53
|
|
|
if (!$docComment) { |
54
|
|
|
return null; |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
return $this->parser->parse(implode("\n", array_map(function ($line) { |
58
|
|
|
return ltrim($line, " *\r\n\t"); |
59
|
|
|
}, array_slice(explode("\n", $docComment), 1, -1)))); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Fills out partially available parameters |
64
|
|
|
* |
65
|
|
|
* @param array $parameters Available values indexed by name |
66
|
|
|
* @return array Filled values indexed by name |
67
|
|
|
*/ |
68
|
|
|
public function fill(array $parameters) { |
69
|
|
View Code Duplication |
foreach ($this->reader->readInterface() as $property) { |
|
|
|
|
70
|
|
|
if (!array_key_exists($property->name(), $parameters)) { |
71
|
|
|
$parameters[$property->name()] = $property->defaultValue(); |
72
|
|
|
} |
73
|
|
|
} |
74
|
|
|
return $parameters; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* @return Parameter[] |
79
|
|
|
* @throws \Exception |
80
|
|
|
*/ |
81
|
|
|
public function parameters() { |
82
|
|
|
$parameters = []; |
83
|
|
|
foreach ($this->reader->readInterface() as $property) { |
84
|
|
|
if ($property->canSet()) { |
85
|
|
|
$parameters[] = (new Parameter($property->name(), $property->type(), $property->isRequired())) |
86
|
|
|
->setDescription($this->parser->parse($property->comment())); |
87
|
|
|
} |
88
|
|
|
} |
89
|
|
|
return $parameters; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* @return boolean True if the action modifies the state of the application |
94
|
|
|
*/ |
95
|
|
|
public function isModifying() { |
96
|
|
|
return true; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* @param mixed[] $parameters Values indexed by name |
101
|
|
|
* @return mixed the result of the execution |
102
|
|
|
* @throws \Exception if Action cannot be executed |
103
|
|
|
*/ |
104
|
|
|
public function execute(array $parameters) { |
105
|
|
|
return $this->executeWith($this->createInstance($parameters)); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
protected function createInstance(array $parameters) { |
109
|
|
|
$injector = new Injector(new Factory()); |
110
|
|
|
$instance = $injector->injectConstructor($this->class->name, $parameters, function () { |
111
|
|
|
return false; |
112
|
|
|
}); |
113
|
|
|
|
114
|
|
View Code Duplication |
foreach ($this->reader->readInterface() as $property) { |
|
|
|
|
115
|
|
|
if ($property->canSet() && array_key_exists($property->name(), $parameters)) { |
116
|
|
|
$property->set($instance, $parameters[$property->name()]); |
117
|
|
|
} |
118
|
|
|
} |
119
|
|
|
return $instance; |
120
|
|
|
} |
121
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.