Completed
Pull Request — master (#67)
by
unknown
02:21
created

ParametersPart::generateParamDocblock()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4.0058

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 13
cts 14
cp 0.9286
rs 9.52
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 4.0058
1
<?php
2
declare(strict_types=1);
3
4
namespace gossi\codegen\model\parts;
5
6
use gossi\codegen\model\PhpParameter;
7
use gossi\codegen\model\PhpTypeInterface;
8
use gossi\docblock\Docblock;
9
use gossi\docblock\tags\ParamTag;
10
use phootwork\collection\Map;
11
12
/**
13
 * Parameters Part
14
 *
15
 * For all models that can have parameters
16
 *
17
 * @author Thomas Gossmann
18
 */
19
trait ParametersPart {
20
21
	/** @var PhpParameter[] */
22
	private $parameters = [];
23
24 44
	private function initParameters() {
25
// 		$this->parameters = new ArrayList();
26 44
	}
27
28
	/**
29
	 * Sets a collection of parameters
30
	 *
31
	 * Note: clears all parameters before setting the new ones
32
	 *
33
	 * @param PhpParameter[] $parameters
34
	 * @return $this
35
	 */
36 1
	public function setParameters(array $parameters) {
37 1
		$this->parameters = [];
38 1
		foreach ($parameters as $parameter) {
39 1
			$this->addParameter($parameter);
40
		}
41
42 1
		return $this;
43
	}
44
45
	/**
46
	 * Adds a parameter
47
	 *
48
	 * @param PhpParameter $parameter
49
	 * @return $this
50
	 */
51 20
	public function addParameter(PhpParameter $parameter) {
52 20
		$this->parameters[] = $parameter;
53
54 20
		return $this;
55
	}
56
57
	/**
58
	 * Checks whether a parameter exists
59
	 *
60
	 * @param string $name parameter name
61
	 * @return bool `true` if a parameter exists and `false` if not
62
	 */
63 2
	public function hasParameter(string $name): bool {
64 2
		foreach ($this->parameters as $param) {
65 2
			if ($param->getName() == $name) {
66 2
				return true;
67
			}
68
		}
69
70 2
		return false;
71
	}
72
73
	/**
74
	 * A quick way to add a parameter which is created from the given parameters
75
	 *
76
	 * @param string      $name
77
	 * @param null|Map|string[]|PhpTypeInterface[] $types
78
	 * @param mixed       $defaultValue omit the argument to define no default value
79
	 *
80
	 * @return $this
81
	 */
82 1
	public function addSimpleParameter(string $name, $types = null, $defaultValue = null) {
83 1
		$parameter = new PhpParameter($name);
84 1
		$parameter->setTypes($types);
85
86 1
		if (2 < func_num_args()) {
87 1
			$parameter->setValue($defaultValue);
88
		}
89
90 1
		$this->addParameter($parameter);
91 1
		return $this;
92
	}
93
94
	/**
95
	 * A quick way to add a parameter with description which is created from the given parameters
96
	 *
97
	 * @param string      $name
98
	 * @param string[]|PhpTypeInterface[] $types
99
	 * @param null|string $typeDescription
100
	 * @param mixed       $defaultValue omit the argument to define no default value
101
	 *
102
	 * @return $this
103
	 */
104 1
	public function addSimpleDescParameter(string $name, $types = null, string $typeDescription = null, $defaultValue = null) {
105 1
		$types = (array)$types;
106 1
	    $parameter = new PhpParameter($name);
107 1
		$parameter->setTypes($types);
108 1
		$parameter->setTypeDescription($typeDescription);
109
110 1
		if (3 < func_num_args() == 3) {
111 1
			$parameter->setValue($defaultValue);
112
		}
113
114 1
		$this->addParameter($parameter);
115 1
		return $this;
116
	}
117
118
	/**
119
	 * Returns a parameter by index or name
120
	 *
121
	 * @param string|int $nameOrIndex
122
	 * @throws \InvalidArgumentException
123
	 * @return PhpParameter
124
	 */
125 9
	public function getParameter($nameOrIndex): PhpParameter {
126 9
		if (is_int($nameOrIndex)) {
127 2
			$this->checkPosition($nameOrIndex);
128 1
			return $this->parameters[$nameOrIndex];
129
		}
130
131 8
		foreach ($this->parameters as $param) {
132 7
			if ($param->getName() === $nameOrIndex) {
133 7
				return $param;
134
			}
135
		}
136
137 1
		throw new \InvalidArgumentException(sprintf('There is no parameter named "%s".', $nameOrIndex));
138
	}
139
140
	/**
141
	 * Replaces a parameter at a given position
142
	 *
143
	 * @param int $position
144
	 * @param PhpParameter $parameter
145
	 * @throws \InvalidArgumentException
146
	 * @return $this
147
	 */
148 2
	public function replaceParameter(int $position, PhpParameter $parameter) {
149 2
		$this->checkPosition($position);
150 1
		$this->parameters[$position] = $parameter;
151
152 1
		return $this;
153
	}
154
155
	/**
156
	 * Remove a parameter at a given position
157
	 *
158
	 * @param int|string|PhpParameter $param
159
	 * @return $this
160
	 */
161 2
	public function removeParameter($param) {
162 2
		if (is_int($param)) {
163 2
			$this->removeParameterByPosition($param);
164 1
		} else if (is_string($param)) {
165 1
			$this->removeParameterByName($param);
166 1
		} else if ($param instanceof PhpParameter) {
167 1
			$this->removeParameterByName($param->getName());
168
		}
169
170 1
		return $this;
171
	}
172
173 2
	private function removeParameterByPosition($position) {
174 2
		$this->checkPosition($position);
175 1
		unset($this->parameters[$position]);
176 1
		$this->parameters = array_values($this->parameters);
177 1
	}
178
179 1
	private function removeParameterByName($name) {
180 1
		$position = null;
181 1
		foreach ($this->parameters as $index => $param) {
182 1
			if ($param->getName() == $name) {
183 1
				$position = $index;
184
			}
185
		}
186
187 1
		if ($position !== null) {
188 1
			$this->removeParameterByPosition($position);
189
		}
190 1
	}
191
192 4
	private function checkPosition($position) {
193 4
		if ($position < 0 || $position > count($this->parameters)) {
194 3
			throw new \InvalidArgumentException(sprintf('The position must be in the range [0, %d].', count($this->parameters)));
195
		}
196 1
	}
197
198
	/**
199
	 * Returns a collection of parameters
200
	 *
201
	 * @return PhpParameter[]
202
	 */
203 30
	public function getParameters() {
204 30
		return $this->parameters;
205
	}
206
207
	/**
208
	 * Returns the docblock
209
	 *
210
	 * @return Docblock
211
	 */
212
	abstract protected function getDocblock(): Docblock;
213
214
	/**
215
	 * Generates docblock for params
216
	 */
217 12
	protected function generateParamDocblock(array $noTypeHint = []) {
218 12
		$docblock = $this->getDocblock();
219 12
		$tags = $docblock->getTags('param');
220 12
		foreach ($this->parameters as $param) {
221 7
		    if (!empty($noTypeHint[$param->getName()])) {
222
                continue;
223
            }
224 7
			$ptag = $param->getDocblockTag();
225
226
			$tag = $tags->find($ptag, function (ParamTag $tag, ParamTag $ptag) {
227 1
				return $tag->getVariable() == $ptag->getVariable();
228 7
			});
229
230
			// try to update existing docblock first
231 7
			if ($tag !== null) {
232 1
				$tag->setDescription($ptag->getDescription());
233 1
				$tag->setType($ptag->getType());
234
			}
235
236
			// ... append if it doesn't exist
237
			else {
238 6
				$docblock->appendTag($ptag);
239
			}
240
		}
241 12
	}
242
243
}
244