Passed
Branch version-bump (36e4b3)
by Matt
04:39
created

ShortcodeManager::alias()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 16
c 0
b 0
f 0
rs 10
cc 4
nc 4
nop 2
1
<?php
2
3
namespace Maiorano\Shortcodes\Manager;
4
5
use Maiorano\Shortcodes\Contracts\AliasInterface;
6
use Maiorano\Shortcodes\Contracts\AttributeInterface;
7
use Maiorano\Shortcodes\Contracts\ContainerAwareInterface;
8
use Maiorano\Shortcodes\Contracts\ShortcodeInterface;
9
use Maiorano\Shortcodes\Exceptions\DeregisterException;
10
use Maiorano\Shortcodes\Exceptions\RegisterException;
11
use Maiorano\Shortcodes\Parsers\DefaultParser;
12
use Maiorano\Shortcodes\Parsers\ParserInterface;
13
14
/**
15
 * Class ShortcodeManager.
16
 */
17
class ShortcodeManager extends BaseManager
18
{
19
    /**
20
     * @var DefaultParser|ParserInterface
21
     */
22
    protected $parser;
23
24
    /**
25
     * ShortcodeManager constructor.
26
     *
27
     * @param array                $shortcodes
28
     * @param ParserInterface|null $parser
29
     */
30
    public function __construct(array $shortcodes = [], ParserInterface $parser = null)
31
    {
32
        $this->parser = $parser ?? new DefaultParser();
33
        $this->registerAll($shortcodes);
34
    }
35
36
    /**
37
     * @param ShortcodeInterface $shortcode
38
     * @param string|null        $name
39
     *
40
     * @throws RegisterException
41
     *
42
     * @return static
43
     */
44
    public function register(ShortcodeInterface $shortcode, ?string $name = null): ManagerInterface
45
    {
46
        parent::register($shortcode, $name);
47
        if ($shortcode instanceof AliasInterface) {
48
            foreach ($shortcode->getAlias() as $alias) {
49
                if (!$this->isRegistered($alias)) {
50
                    parent::register($shortcode, $alias);
51
                }
52
            }
53
        }
54
55
        return $this;
56
    }
57
58
    /**
59
     * @param array $shortcodes
60
     *
61
     * @return static
62
     */
63
    public function registerAll(array $shortcodes): ManagerInterface
64
    {
65
        foreach ($shortcodes as $k => $s) {
66
            $this[$k] = $s;
67
        }
68
69
        return $this;
70
    }
71
72
    /**
73
     * @param string $name
74
     * @param bool   $includeAlias
75
     *
76
     * @throws DeregisterException
77
     *
78
     * @return static
79
     */
80
    public function deregister(string $name, bool $includeAlias = true): ManagerInterface
81
    {
82
        $shortcode = $this->shortcodes[$name] ?? false;
83
        if ($shortcode && $shortcode instanceof AliasInterface) {
84
            if ($name === $shortcode->getName() && $includeAlias) {
85
                foreach ($shortcode->getAlias() as $alias) {
86
                    parent::deregister($alias);
87
                }
88
            }
89
        }
90
91
        return parent::deregister($name);
92
    }
93
94
    /**
95
     * @param string $name
96
     * @param string $alias
97
     *
98
     * @throws RegisterException
99
     *
100
     * @return static
101
     */
102
    public function alias(string $name, string $alias): ManagerInterface
103
    {
104
        if (!$this->isRegistered($name)) {
105
            throw RegisterException::missing($name);
106
        }
107
        if (!($this[$name] instanceof AliasInterface)) {
108
            throw RegisterException::noAlias();
109
        }
110
111
        $this[$name]->alias($alias);
0 ignored issues
show
Bug introduced by
The method alias() does not exist on Maiorano\Shortcodes\Contracts\ShortcodeInterface. It seems like you code against a sub-type of Maiorano\Shortcodes\Contracts\ShortcodeInterface such as Maiorano\Shortcodes\Library\Ipsum or Maiorano\Shortcodes\Contracts\AliasInterface or Maiorano\Shortcodes\Library\SimpleShortcode or Maiorano\Shortcodes\Library\SimpleShortcode or anonymous//tests/Contracts/AliasTest.php$1. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

111
        $this[$name]->/** @scrutinizer ignore-call */ 
112
                      alias($alias);
Loading history...
112
113
        if (!$this[$name] instanceof ContainerAwareInterface) {
114
            parent::register($this[$name], $alias);
115
        }
116
117
        return $this;
118
    }
119
120
    /**
121
     * @param string       $content
122
     * @param string|array $tags
123
     *
124
     * @return bool
125
     */
126
    public function hasShortcode(string $content, $tags = []): bool
127
    {
128
        $tags = $this->preProcessTags($tags);
129
        $matches = $this->parser->parseShortcode($content, $tags);
130
131
        return !empty($matches);
132
    }
133
134
    /**
135
     * @param string       $content
136
     * @param string|array $tags
137
     * @param bool         $deep
138
     *
139
     * @return string
140
     */
141
    public function doShortcode(string $content, $tags = [], bool $deep = false): string
142
    {
143
        $tags = $this->preProcessTags($tags);
144
        $handler = function (string $tag, ?string $content = null, array $atts = []) {
145
            $shortcode = $this[$tag];
146
            if ($shortcode instanceof AttributeInterface) {
147
                $atts = array_merge($shortcode->getAttributes(), $atts);
148
149
                return $shortcode->handle($content, $atts);
150
            }
151
152
            return $shortcode->handle($content);
153
        };
154
        $content = $this->parser->parseShortcode($content, $tags, $handler);
155
156
        if ($deep && $this->hasShortcode($content, $tags)) {
0 ignored issues
show
Bug introduced by
It seems like $content can also be of type array and array; however, parameter $content of Maiorano\Shortcodes\Mana...Manager::hasShortcode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

156
        if ($deep && $this->hasShortcode(/** @scrutinizer ignore-type */ $content, $tags)) {
Loading history...
157
            return $this->doShortcode($content, $tags, $deep);
0 ignored issues
show
Bug introduced by
It seems like $content can also be of type array and array; however, parameter $content of Maiorano\Shortcodes\Mana...eManager::doShortcode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

157
            return $this->doShortcode(/** @scrutinizer ignore-type */ $content, $tags, $deep);
Loading history...
158
        }
159
160
        return $content;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $content could return the type array which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
161
    }
162
163
    /**
164
     * @param string|array $tags
165
     *
166
     * @return array
167
     */
168
    private function preProcessTags($tags): array
169
    {
170
        if (!$tags) {
171
            return $this->getRegistered();
172
        }
173
174
        if (is_string($tags)) {
175
            $tags = explode('|', $tags);
176
        }
177
178
        return array_filter($tags, [$this, 'isRegistered']);
179
    }
180
}
181