BBCodeOutputAbstract::transform()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 5
1
<?php
2
/**
3
 * Class BBCodeOutputAbstract
4
 *
5
 * @filesource   BBCodeOutputAbstract.php
6
 * @created      23.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 BBCodeOutputAbstract implements BBCodeOutputInterface{
20
21
	/**
22
	 * @var string[]
23
	 */
24
	protected $modules = [];
25
26
	/**
27
	 * @var string[]
28
	 */
29
	protected $tagmap = [];
30
31
	/**
32
	 * Holds an array of singletags
33
	 *
34
	 * @var string[]
35
	 */
36
	protected $singletags = [];
37
38
	/**
39
	 * Holds an array of noparse tags
40
	 *
41
	 * @var string[]
42
	 */
43
	protected $noparse = [];
44
45
	/**
46
	 * @var string
47
	 */
48
	protected $eol = PHP_EOL;
49
50
	/**
51
	 * @var \chillerlan\BBCode\BBCodeOptions
52
	 */
53
	protected $options;
54
55
	/**
56
	 * @var \Psr\SimpleCache\CacheInterface
57
	 */
58
	protected $cache;
59
60
	/**
61
	 * @var \Psr\Log\LoggerInterface
62
	 */
63
	protected $logger;
64
65
	/**
66
	 * @var \chillerlan\BBCode\Output\BBCodeModuleInterface[]
67
	 */
68
	protected $moduleInterfaces = [];
69
70
	/**
71
	 * BBCodeOutputInterface constructor.
72
	 *
73
	 * @param \chillerlan\Settings\SettingsContainerInterface $options
74
	 * @param \Psr\SimpleCache\CacheInterface  $cache
75
	 * @param \Psr\Log\LoggerInterface         $logger
76
	 */
77
	public function __construct(SettingsContainerInterface $options, CacheInterface $cache, LoggerInterface $logger){
78
		$options->replacement_eol = $options->replacement_eol ?? $this->eol;
0 ignored issues
show
Bug introduced by
Accessing replacement_eol on the interface chillerlan\Settings\SettingsContainerInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
79
80
		$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...
81
		$this->cache   = $cache;
82
		$this->logger  = $logger;
83
84
		foreach($this->modules as $module){
85
			/** @var \chillerlan\BBCode\Output\BBCodeModuleInterface $moduleInterface */
86
			$moduleInterface = new $module($this->options, $this->cache, $this->logger);
87
88
			foreach($moduleInterface->getTags() as $tag){
89
				$this->tagmap[$tag] = $module;
90
			}
91
92
			$this->noparse    = array_merge($this->noparse, $moduleInterface->getNoparse());
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge($this->nopar...nterface->getNoparse()) of type array is incompatible with the declared type array<integer,string> of property $noparse.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
93
			$this->singletags = array_merge($this->singletags, $moduleInterface->getSingleTags());
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge($this->singl...rface->getSingleTags()) of type array is incompatible with the declared type array<integer,string> of property $singletags.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
94
95
			$this->moduleInterfaces[$module] = $moduleInterface;
96
		}
97
98
	}
99
100
	/**
101
	 * @inheritdoc
102
	 */
103
	public function getTags():array {
104
		return array_keys($this->tagmap);
105
	}
106
107
	/**
108
	 * @inheritdoc
109
	 */
110
	public function getSingleTags():array {
111
		return $this->singletags;
112
	}
113
114
	/**
115
	 * @inheritdoc
116
	 */
117
	public function getNoparse():array{
118
		return $this->noparse;
119
	}
120
121
	/**
122
	 * @return string
123
	 */
124
	public function getEOL():string{
125
		return $this->options->replacement_eol;
126
	}
127
128
	/**
129
	 * @inheritdoc
130
	 */
131
	public function transform(string $tag, array $attributes, string $content, string $match, int $callback_count):string{
132
133
		if(!in_array($tag, array_keys($this->tagmap), true)){
134
			return $match; // $content
135
		}
136
137
		return call_user_func_array([$this->moduleInterfaces[$this->tagmap[$tag]], $tag], [$tag, $attributes, $content, $match, $callback_count]);
138
	}
139
140
}
141