Completed
Pull Request — development (#2329)
by Joshua
09:15
created

ParserWrapper::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 2
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 *
5
 * @name      ElkArte Forum
6
 * @copyright ElkArte Forum contributors
7
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
8
 *
9
 */
10
11
namespace BBC;
12
13
/**
14
 * Class ParserWrapper
15
 *
16
 * Wrap around the BBC parsers before we implement a DIC.
17
 * Deprecate in future versions in favor of a DIC
18
 */
19
class ParserWrapper
20
{
21
	/** @var array Disabled tags */
22
	protected $disabled = array();
23
	/** @var \BBC\Codes */
24
	protected $codes;
25
	/** @var  \BBC\BBCParser */
26
	protected $bbc_parser;
27
	/** @var  \BBC\SmileyParser */
28
	protected $smiley_parser;
29
	/** @var  \BBC\HtmlParser */
30
	protected $html_parser;
31
	/** @var  \BBC\Autolink */
32
	protected $autolink_parser;
33
	/** @var bool If smileys are enabled */
34
	protected $smileys_enabled = true;
35
	/** @var ParserWrapper */
36
	public static $instance;
37
38
	/**
39
	 * Find and return ParserWrapper instance if it exists,
40
	 * or create a new instance
41
	 *
42
	 * @return ParserWrapper
43
	 */
44 1
	public static function getInstance()
45
	{
46 1
		if (self::$instance === null)
47 1
		{
48
			self::$instance = new ParserWrapper;
49
		}
50
51 1
		return self::$instance;
52
	}
53
54
	/**
55
	 * ParserWrapper constructor.
56
	 */
57
	private function __construct()
58
	{
59
60
	}
61
62
	/**
63
	 * Check if the server load is too high to execute BBC parsing
64
	 *
65
	 * @return bool If the parser can execute
66
	 */
67 1
	protected function checkLoad()
68
	{
69 1
		global $modSettings, $context;
70
71 1
		if (!empty($modSettings['bbc']) && $modSettings['current_load'] >= $modSettings['bbc'])
72 1
		{
73
			$context['disabled_parse_bbc'] = true;
74
			return false;
75
		}
76
77 1
		return true;
78
	}
79
80
	/**
81
	 * Is BBC parsing enabled
82
	 *
83
	 * @return bool
84
	 */
85 1
	protected function isEnabled()
86
	{
87 1
		global $modSettings;
88
89 1
		return !empty($modSettings['enableBBC']);
90
	}
91
92
	/**
93
	 * Enable or disable smileys
94
	 *
95
	 * @param bool $toggle
96
	 * @return $this
97
	 */
98 1
	public function enableSmileys($toggle)
99
	{
100 1
		$this->smileys_enabled = (bool) $toggle;
101 1
		return $this;
102
	}
103
104
	/**
105
	 * Get parsers based on where it will be used
106
	 *
107
	 * @param string $area Where it is being called from
108
	 * @return array
109
	 */
110 1
	protected function getParsersByArea($area)
111
	{
112
		$parsers = array(
113 1
			'autolink' => false,
114 1
			'html' => false,
115 1
			'bbc' => false,
116 1
			'smiley' => false,
117 1
		);
118
119
		// First see if any hooks set a parser.
120 1
		foreach ($parsers as $parser_type => &$parser)
121
		{
122 1
			call_integration_hook('integrate_' . $area . '_' . $parser_type . '_parser', array(&$parser, $this));
123
124
			// If not, use the default one
125 1
			if ($parser === false)
126 1
			{
127 1
				$parser = call_user_func(array($this, 'get' . ucfirst($parser_type) . 'Parser'), $area);
128 1
			}
129 1
		}
130
131 1
		return $parsers;
132
	}
133
134
	/**
135
	 * Return the current message parsers
136
	 *
137
	 * @return array
138
	 */
139
	public function getMessageParser()
140
	{
141
		return $this->getParsersByArea('message');
142
	}
143
144
	/**
145
	 * Return the current signature parsers
146
	 *
147
	 * @return array
148
	 */
149
	public function getSignatureParser()
150
	{
151
		return $this->getParsersByArea('signature');
152
	}
153
154
	/**
155
	 * Return the news parsers
156
	 *
157
	 * @return array
158
	 */
159
	public function getNewsParser()
160
	{
161
		return $this->getParsersByArea('news');
162
	}
163
164
	/**
165
	 * Parse a string based on where it's being called from
166
	 *
167
	 * @param string $area Where this is being called from
168
	 * @param string $message The message to be parsed
169
	 * @return string The Parsed message
170
	 */
171 1
	protected function parse($area, $message)
0 ignored issues
show
Coding Style introduced by
parse uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
172
	{
173
		// If the load average is too high, don't parse the BBC.
174 1
		if (!$this->checkLoad())
175 1
		{
176
			return $message;
177
		}
178
179 1
		$parsers = $this->getParsersByArea($area);
180
181 1
		if (!$this->isEnabled())
182 1
		{
183
			// You need to run the smiley parser to get rid of the markers
184
			$parsers['smiley']
0 ignored issues
show
Bug introduced by
The method setEnabled cannot be called on $parsers['smiley'] (of type false).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
185
				->setEnabled($this->smileys_enabled && $GLOBALS['user_info']['smiley_set'] !== 'none')
186
				->parse($message);
187
188
			return $message;
189
		}
190
191 1
		$message = $parsers['bbc']->parse($message);
0 ignored issues
show
Bug introduced by
The method parse cannot be called on $parsers['bbc'] (of type false).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
192
193 1
		$parsers['smiley']
0 ignored issues
show
Bug introduced by
The method setEnabled cannot be called on $parsers['smiley'] (of type false).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
194 1
			->setEnabled($this->smileys_enabled && $GLOBALS['user_info']['smiley_set'] !== 'none')
195 1
			->parse($message);
196
197 1
		return $message;
198
	}
199
200
	/**
201
	 * Parse the BBC and smileys in messages
202
	 *
203
	 * @param string $message
204
	 * @param bool   $smileys_enabled
205
	 * @return string
206
	 */
207 1
	public function parseMessage($message, $smileys_enabled)
208
	{
209 1
		return $this->enableSmileys($smileys_enabled)->parse('message', $message);
210
	}
211
212
	/**
213
	 * Parse the BBC and smileys in signatures
214
	 *
215
	 * @param string $signature
216
	 * @param string $smileys_enabled
217
	 * @return string
218
	 */
219
	public function parseSignature($signature, $smileys_enabled)
220
	{
221
		return $this->enableSmileys($smileys_enabled)->parse('signature', $signature);
0 ignored issues
show
Documentation introduced by
$smileys_enabled is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
222
	}
223
224
	/**
225
	 * Parse the BBC and smileys in news items
226
	 *
227
	 * @param string $news
228
	 * @return string
229
	 */
230
	public function parseNews($news)
231
	{
232
		return $this->enableSmileys(true)->parse('news', $news);
233
	}
234
235
	/**
236
	 * Parse the BBC and smileys in emails
237
	 *
238
	 * @param string $email
239
	 * @return string
240
	 */
241
	public function parseEmail($email)
242
	{
243
		return $this->enableSmileys(false)->parse('email', $email);
244
	}
245
246
	/**
247
	 * Parse the BBC and smileys in custom profile fields
248
	 *
249
	 * @param string $field
250
	 * @return string
251
	 */
252
	public function parseCustomFields($field)
253
	{
254
		// @todo this should account for which field is being parsed and hook on that
255
256
		return $this->enableSmileys(true)->parse('customfields', $field);
257
	}
258
259
	/**
260
	 * Parse the BBC and smileys in poll questions/answers
261
	 *
262
	 * @param string $poll
263
	 * @return string
264
	 */
265
	public function parsePoll($poll)
266
	{
267
		return $this->enableSmileys(true)->parse('poll', $poll);
268
	}
269
270
	/**
271
	 * Parse the BBC and smileys in the registration agreement
272
	 *
273
	 * @param string $agreement
274
	 * @return string
275
	 */
276
	public function parseAgreement($agreement)
277
	{
278
		return $this->enableSmileys(true)->parse('agreement', $agreement);
279
	}
280
281
	/**
282
	 * Parse the BBC and smileys in personal messages
283
	 *
284
	 * @param string $pm
285
	 * @return string
286
	 */
287
	public function parsePM($pm)
288
	{
289
		return $this->enableSmileys(true)->parse('pm', $pm);
290
	}
291
292
	/**
293
	 * Parse the BBC and smileys in user submitted reports
294
	 *
295
	 * @param string $report
296
	 * @return string
297
	 */
298
	public function parseReport($report)
299
	{
300
		return $this->enableSmileys(true)->parse('report', $report);
301
	}
302
303
	/**
304
	 * Parse the BBC and smileys in package descriptions
305
	 *
306
	 * @param string $package
307
	 * @return string
308
	 */
309
	public function parsePackage($package)
310
	{
311
		return $this->enableSmileys(true)->parse('package', $package);
312
	}
313
314
	/**
315
	 * Parse the BBC and smileys in user verification controls
316
	 *
317
	 * @param string $question
318
	 * @return string
319
	 */
320
	public function parseVerificationControls($question)
321
	{
322
		return $this->enableSmileys(true)->parse('package', $question);
323
	}
324
325
	/**
326
	 * Parse the BBC and smileys in moderator notices to users
327
	 *
328
	 * @param string $notice
329
	 * @return string
330
	 */
331
	public function parseNotice($notice)
332
	{
333
		return $this->enableSmileys(true)->parse('notice', $notice);
334
	}
335
336
	/**
337
	 * Parse the BBC and smileys in board descriptions
338
	 *
339
	 * @param string $board
340
	 * @return string
341
	 */
342
	public function parseBoard($board)
343
	{
344
		return $this->enableSmileys(true)->parse('board', $board);
345
	}
346
347
	/**
348
	 * Set the disabled tags
349
	 *
350
	 * @param string[] $disabled (usually from $modSettings['disabledBBC'])
351
	 * @return $this
352
	 */
353
	public function setDisabled(array $disabled)
354
	{
355
		foreach ($disabled as $tag)
356
		{
357
			$this->disabled[trim($tag)] = true;
358
		}
359
360
		return $this;
361
	}
362
363
	/**
364
	 * Return the bbc code definitions for the parser
365
	 *
366
	 * @return Codes
367
	 */
368 1
	public function getCodes()
369
	{
370 1
		if ($this->codes === null)
371 1
		{
372 1
			$additional_bbc = array();
373 1
			call_integration_hook('integrate_additional_bbc', array(&$additional_bbc));
374 1
			$this->codes = new Codes($additional_bbc, $this->disabled);
375 1
		}
376
377 1
		return $this->codes;
378
	}
379
380
	/**
381
	 * Return an instance of the bbc parser
382
	 *
383
	 * @return BBCParser
384
	 */
385 1
	public function getBBCParser()
386
	{
387 1
		if ($this->bbc_parser === null)
388 1
		{
389 1
			$this->bbc_parser = new BBCParser($this->getCodes(), $this->getAutolinkParser());
390 1
		}
391
392 1
		return $this->bbc_parser;
393
	}
394
395
	/**
396
	 * Return an, that's right not and, just an, like a single instance of the autolink parser
397
	 *
398
	 * @return Autolink
399
	 */
400 1
	public function getAutolinkParser()
401
	{
402 1
		if ($this->autolink_parser === null)
403 1
		{
404 1
			$this->autolink_parser = new Autolink($this->getCodes());
405 1
		}
406
407 1
		return $this->autolink_parser;
408
	}
409
410
	/**
411
	 * Return an, that's right not and, just an, like a single instance of the Smiley parser
412
	 *
413
	 * @return SmileyParser
414
	 */
415 1
	public function getSmileyParser()
416
	{
417 1
		global $context;
418
419 1
		if ($this->smiley_parser === null)
420 1
		{
421 1
			$this->smiley_parser = new \BBC\SmileyParser($context['user']['smiley_path']);
422 1
			$this->smiley_parser->setEnabled($context['smiley_enabled']);
423 1
		}
424
425 1
		return $this->smiley_parser;
426
	}
427
428
	/**
429
	 * Return an, that's right not and, just an, like a single instance of the HTML parser
430
	 *
431
	 * @return HtmlParser
432
	 */
433 1
	public function getHtmlParser()
434
	{
435 1
		if ($this->html_parser === null)
436 1
		{
437 1
			$this->html_parser = new HtmlParser;
438 1
		}
439
440 1
		return $this->html_parser;
441
	}
442
}