Completed
Pull Request — master (#67)
by
unknown
13:16
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
11
/**
12
 * Parameters Part
13
 *
14
 * For all models that can have parameters
15
 *
16
 * @author Thomas Gossmann
17
 */
18
trait ParametersPart {
19
20
	/** @var PhpParameter[] */
21
	private $parameters = [];
22
23 44
	private function initParameters() {
24
// 		$this->parameters = new ArrayList();
25 44
	}
26
27
	/**
28
	 * Sets a collection of parameters
29
	 *
30
	 * Note: clears all parameters before setting the new ones
31
	 *
32
	 * @param PhpParameter[] $parameters
33
	 * @return $this
34
	 */
35 1
	public function setParameters(array $parameters) {
36 1
		$this->parameters = [];
37 1
		foreach ($parameters as $parameter) {
38 1
			$this->addParameter($parameter);
39
		}
40
41 1
		return $this;
42
	}
43
44
	/**
45
	 * Adds a parameter
46
	 *
47
	 * @param PhpParameter $parameter
48
	 * @return $this
49
	 */
50 20
	public function addParameter(PhpParameter $parameter) {
51 20
		$this->parameters[] = $parameter;
52
53 20
		return $this;
54
	}
55
56
	/**
57
	 * Checks whether a parameter exists
58
	 *
59
	 * @param string $name parameter name
60
	 * @return bool `true` if a parameter exists and `false` if not
61
	 */
62 2
	public function hasParameter(string $name): bool {
63 2
		foreach ($this->parameters as $param) {
64 2
			if ($param->getName() == $name) {
65 2
				return true;
66
			}
67
		}
68
69 2
		return false;
70
	}
71
72
	/**
73
	 * A quick way to add a parameter which is created from the given parameters
74
	 *
75
	 * @param string      $name
76
	 * @param string[]|PhpTypeInterface[] $types
77
	 * @param mixed       $defaultValue omit the argument to define no default value
78
	 *
79
	 * @return $this
80
	 */
81 1
	public function addSimpleParameter(string $name, $types = null, $defaultValue = null) {
82 1
	    $types = (array)$types;
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