BBCodeModuleAbstract   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 263
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 0
Metric Value
wmc 28
lcom 2
cbo 1
dl 0
loc 263
rs 10
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A __call() 0 14 3
A transform() 0 3 1
A getTags() 0 3 1
A getSingleTags() 0 3 1
A getNoparse() 0 3 1
A randomID() 0 3 1
A clearEOL() 0 6 1
A clearPseudoClosingTags() 0 5 1
A getAttribute() 0 3 3
A bbtag() 0 3 1
A bbtagIn() 0 3 1
A eol() 0 3 1
A attributeIn() 0 7 4
A attributeKeyIn() 0 5 4
A tagIn() 0 5 3
1
<?php
2
/**
3
 * Class BBCodeModuleAbstract
4
 *
5
 * @filesource   BBCodeModuleAbstract.php
6
 * @created      24.04.2018
7
 * @package      chillerlan\BBCode\Output
8
 * @author       smiley <[email protected]>
9
 * @copyright    2018 smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\BBCode\Output;
14
15
use chillerlan\Settings\SettingsContainerInterface;
16
use Psr\Log\LoggerInterface;
17
use Psr\SimpleCache\CacheInterface;
18
19
abstract class BBCodeModuleAbstract implements BBCodeModuleInterface{
20
21
	/**
22
	 * The current bbcode tag
23
	 *
24
	 * @var string
25
	 */
26
	protected $tag;
27
28
	/**
29
	 * The attributes of the current bbcode
30
	 *
31
	 * @var array
32
	 */
33
	protected $attributes;
34
35
	/**
36
	 * The content of the current bbcode
37
	 *
38
	 * @var string
39
	 */
40
	protected $content;
41
42
	/**
43
	 * The full matched string of the current bbcode
44
	 *
45
	 * @var
46
	 */
47
	protected $match;
48
49
	/**
50
	 * The callback counter
51
	 *
52
	 * @var
53
	 */
54
	protected $callback_count;
55
56
	/**
57
	 * An array of tags the module is able to process
58
	 *
59
	 * @var array
60
	 */
61
	protected $tags = [];
62
63
	/**
64
	 * Holds an array of singletags
65
	 *
66
	 * @var array
67
	 */
68
	protected $singletags = [];
69
70
	/**
71
	 * Holds an array of noparse tags
72
	 *
73
	 * @var array
74
	 */
75
	protected $noparse = [];
76
77
	/**
78
	 * @var \chillerlan\BBCode\BBCodeOptions
79
	 */
80
	protected $options;
81
82
	/**
83
	 * @var \Psr\SimpleCache\CacheInterface
84
	 */
85
	protected $cache;
86
87
	/**
88
	 * @var \Psr\Log\LoggerInterface
89
	 */
90
	protected $logger;
91
92
	/**
93
	 * BBCodeModuleAbstract constructor.
94
	 *
95
	 * @param \chillerlan\Settings\SettingsContainerInterface $options
96
	 * @param \Psr\SimpleCache\CacheInterface                 $cache
97
	 * @param \Psr\Log\LoggerInterface                        $logger
98
	 */
99
	public function __construct(SettingsContainerInterface $options, CacheInterface $cache, LoggerInterface $logger){
100
		$this->options = $options;
0 ignored issues
show
Documentation Bug introduced by
$options is of type object<chillerlan\Settin...ingsContainerInterface>, but the property $options was declared to be of type object<chillerlan\BBCode\BBCodeOptions>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
101
		$this->cache   = $cache;
102
		$this->logger  = $logger;
103
	}
104
105
	/**
106
	 * @param $name
107
	 * @param $arguments
108
	 *
109
	 * @return string
110
	 */
111
	public function __call($name, $arguments):string{
112
113
		if(in_array($name, $this->tags, true)){
114
			[$this->tag, $this->attributes, $this->content, $this->match, $this->callback_count] = $arguments;
115
116
			if(method_exists($this, $name)){
117
				return call_user_func([$this, $name]);
118
			}
119
120
			return $this->transform();
121
		}
122
123
		return  '';//$this->match;
124
	}
125
126
	/**
127
	 * this is the catch-all method for __call()
128
	 *
129
	 * @inheritdoc
130
	 */
131
	protected function transform():string{
132
		return $this->match; // do nothing
133
	}
134
135
	/**
136
	 * @inheritdoc
137
	 */
138
	public function getTags():array {
139
		return $this->tags;
140
	}
141
142
	/**
143
	 * @inheritdoc
144
	 */
145
	public function getSingleTags():array {
146
		return $this->singletags;
147
	}
148
149
	/**
150
	 * @inheritdoc
151
	 */
152
	public function getNoparse():array {
153
		return $this->noparse;
154
	}
155
156
	/**
157
	 * @return string
158
	 */
159
	protected function randomID():string {
160
		return hash('crc32b', random_bytes(64));
161
	}
162
163
	/**
164
	 * Clears all EOL placeholders from self::$content with the base modules EOL token
165
	 *
166
	 * @param string $eol [optional] custom EOL token
0 ignored issues
show
Documentation introduced by
Should the type for parameter $eol not be null|string?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
167
	 *
168
	 * @return $this
169
	 */
170
	protected function clearEOL(string $eol = null){
171
		$eol = $eol ?? PHP_EOL;
172
		$this->content = str_replace($this->options->placeholder_eol, $eol, $this->content);
173
174
		return $this;
175
	}
176
177
	/**
178
	 * Clears all pseudo closing single tag bbcodes like [/br]
179
	 *
180
	 * @return $this
181
	 */
182
	protected function clearPseudoClosingTags(){
183
		$this->content = preg_replace('#\[/('.implode('|', array_merge(['br', 'hr'], $this->singletags)).')]#is', '', $this->content);
184
185
		return $this;
186
	}
187
	/**
188
	 * Retrieves an attribute's value by it's name
189
	 *
190
	 * @param string $name     the desired attributes name
191
	 * @param mixed  $default  [optional] a default value in case the attribute isn't set, defaults to false
192
	 *
193
	 * @return mixed the attribute's value in case it exists, otherwise $default
194
	 */
195
	protected function getAttribute(string $name, $default = false){
196
		return isset($this->attributes[$name]) && !empty($this->attributes[$name]) ? $this->attributes[$name] : $default;
197
	}
198
199
	/**
200
	 * shorthand for self::getAttribute('__BBTAG__')
201
	 *
202
	 * @param mixed $default
203
	 *
204
	 * @return mixed $this->attributes['__BBTAG__']
205
	 */
206
	protected function bbtag($default = false){
207
		return $this->getAttribute($this->options->placeholder_bbtag, $default);
208
	}
209
210
	/**
211
	 * shorthand for self::attributeIn('__BBTAG__', $array)
212
	 *
213
	 * @param array $array
214
	 * @param mixed $default
215
	 *
216
	 * @return mixed
217
	 */
218
	protected function bbtagIn(array $array, $default = false){
219
		return $this->attributeIn($this->options->placeholder_bbtag, $array, $default);
220
	}
221
222
	/**
223
	 * Replaces the EOL placeholder in the given string with a custom token
224
	 *
225
	 * @param string $str   haystack
226
	 * @param string $eol   [optional] custom EOL token, default: ''
227
	 * @param int    $count [optional] replace first $count occurences
0 ignored issues
show
Documentation introduced by
Should the type for parameter $count not be null|integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
228
	 *
229
	 * @return string
230
	 */
231
	protected function eol(string $str, string $eol = '', int $count = null):string{
232
		return str_replace($this->options->placeholder_eol, $eol, $str, $count);
233
	}
234
235
	/**
236
	 * Retrieves an attribute's value by it's name and checks if it's whitelisted
237
	 *
238
	 * @param string $name      the desired attributes name
239
	 * @param array  $whitelist an array with whitelisted values
240
	 * @param mixed  $default   [optional] a default value in case the attribute isn't set, defaults to false
241
	 *
242
	 * @return mixed boolean if no $default is set, otherwise the attribute's value in case it exists and is whitelisted or $default
243
	 */
244
	protected function attributeIn(string $name, array $whitelist, $default = false){
245
		return isset($this->attributes[$name]) && in_array($this->attributes[$name], $whitelist)
246
			? $default !== false
247
				? $this->attributes[$name]
248
				: true
249
			: $default;
250
	}
251
252
	/**
253
	 * Checks if an attribute exists and if it exists as key in a whitelist
254
255
	 * @param string $name      the desired attributes name
256
	 * @param array  $whitelist an array with whitelisted key -> value pairs
257
	 * @param mixed  $default   [optional] a default value in case the attribute isn't set, defaults to false
258
	 *
259
	 * @return mixed boolean if no $default is set, otherwise the whitelist value to the given key in case it exists or $default
260
	 */
261
	protected function attributeKeyIn(string $name, array $whitelist, $default = false){
262
		return isset($this->attributes[$name]) && array_key_exists($this->attributes[$name], $whitelist)
263
			? $default !== false ? $whitelist[$this->attributes[$name]] : true
264
			: $default;
265
	}
266
267
	/**
268
	 * Checks if the current tag is whitelisted
269
	 *
270
	 * @param array $whitelist an array with whitelisted tag names
271
	 * @param mixed $default   [optional] a default value in case the tag isn't whitelisted
272
	 *
273
	 * @return mixed boolean if no $default is set, otherwise the whitelisted tag or $default
274
	 */
275
	protected function tagIn(array $whitelist, $default = false){
276
		return in_array($this->tag, $whitelist)
277
			? $default !== false ? $this->tag : true
278
			: $default;
279
	}
280
281
}
282