Passed
Push — develop ( 535216...2a3c68 )
by Paul
07:18
created

Plugin::constant()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 10
cc 2
nc 2
nop 2
crap 2
1
<?php
2
3
namespace GeminiLabs\SiteReviews;
4
5
use GeminiLabs\SiteReviews\Helpers\Arr;
6
use GeminiLabs\SiteReviews\Helpers\Cast;
7
use GeminiLabs\SiteReviews\Helpers\Str;
8
9
/**
10
 * @property string $id
11
 * @property string $name
12
 * @method array filterArray($hook, ...$args)
13
 * @method bool filterBool($hook, ...$args)
14
 * @method float filterFloat($hook, ...$args)
15
 * @method int filterInt($hook, ...$args)
16
 * @method object filterObject($hook, ...$args)
17
 * @method string filterString($hook, ...$args)
18
 */
19
trait Plugin
20
{
21
    /**
22
     * @var static|null
23
     */
24
    protected static $instance;
25
26
    protected $basename;
27
    protected $file;
28
    protected $languages;
29
    protected $testedTo;
30
    protected $version;
31
32 44
    public function __call($method, $args)
33
    {
34 44
        $isFilter = str_starts_with($method, 'filter');
35 44
        $to = Helper::buildMethodName(Str::removePrefix($method, 'filter'), 'to');
36 44
        if ($isFilter && method_exists(Cast::class, $to)) {
37 44
            $filtered = call_user_func_array([$this, 'filter'], $args);
38 44
            return Cast::$to($filtered);
39
        }
40
        throw new \BadMethodCallException("Method [$method] does not exist.");
41
    }
42
43
    public function __construct()
44
    {
45
        $file = wp_normalize_path((new \ReflectionClass($this))->getFileName());
46
        $this->file = str_replace('plugin/Application', $this->id, $file);
47
        $this->basename = plugin_basename($this->file);
48
        $plugin = get_file_data($this->file, [
49
            'languages' => 'Domain Path',
50
            'name' => 'Plugin Name',
51
            'testedTo' => 'Tested up to',
52
            'version' => 'Version',
53
        ], 'plugin');
54
        array_walk($plugin, function ($value, $key) {
55
            if (property_exists($this, $key)) {
56
                $this->$key = $value;
57
            }
58
        });
59
    }
60
61 46
    public function __get($property)
62
    {
63 46
        $instance = new \ReflectionClass($this);
64 46
        if ($instance->hasProperty($property)) {
65 34
            $prop = $instance->getProperty($property);
66 34
            if ($prop->isPublic() || $prop->isProtected()) {
67 34
                return $this->$property;
68
            }
69
        }
70 46
        $constant = strtoupper($property);
71 46
        if ($instance->hasConstant($constant)) {
72 46
            return $instance->getConstant($constant);
73
        }
74
    }
75
76
    /**
77
     * @param mixed $args,...
78
     */
79 39
    public function action(string $hook, ...$args): void
80
    {
81 39
        do_action_ref_array($this->id.'/'.$hook, $args);
82
    }
83
84
    /**
85
     * @param mixed $args
86
     */
87 26
    public function args($args = []): Arguments
88
    {
89 26
        return new Arguments($args);
90
    }
91
92 9
    public function build(string $view, array $data = []): string
93
    {
94 9
        ob_start();
95 9
        $this->render($view, $data);
96 9
        return trim(ob_get_clean());
97
    }
98
99
    public function catchFatalError(): void
100
    {
101
        $error = error_get_last();
102
        if (E_ERROR === Arr::get($error, 'type') && str_contains(Arr::get($error, 'message'), $this->path())) {
103
            glsr_log()->error($error['message']);
104
        }
105
    }
106
107
    public function config(string $name, bool $filtered = true): array
108
    {
109
        $path = $this->filterString('config', 'config/'.$name.'.php');
110
        $configFile = $this->path($path);
111
        $config = file_exists($configFile)
112
            ? include $configFile
113
            : [];
114
        // Don't filter the settings config!
115
        // Settings can be filtered with the "site-reviews/settings" filter hook
116
        if ($filtered && 'settings' !== $name) {
117
            $config = $this->filterArray('config/'.$name, $config);
118
        }
119
        return $config;
120
    }
121
122
    /**
123
     * @return mixed
124
     */
125 39
    public function constant(string $property, string $className = 'static')
126
    {
127 39
        $property = strtoupper($property);
128 39
        $constant = $className.'::'.$property;
129 39
        return defined($constant)
130 39
            ? $this->filterString('const/'.$property, constant($constant))
131 39
            : '';
132
    }
133
134 9
    public function file(string $view): string
135
    {
136 9
        $view .= '.php';
137 9
        $filePaths = [];
138 9
        if (str_starts_with($view, 'templates/')) {
139 9
            $filePaths[] = $this->themePath(Str::removePrefix($view, 'templates/'));
140
        }
141 9
        $filePaths[] = $this->path($view);
142 9
        $filePaths[] = $this->path('views/'.$view);
143 9
        foreach ($filePaths as $file) {
144 9
            if (file_exists($file)) {
145 9
                return $file;
146
            }
147
        }
148
        return '';
149
    }
150
151
    /**
152
     * @param mixed $args,...
153
     * @return mixed
154
     */
155 44
    public function filter(string $hook, ...$args)
156
    {
157 44
        return apply_filters_ref_array($this->id.'/'.$hook, $args);
158
    }
159
160
    /**
161
     * @param mixed $args,...
162
     */
163 8
    public function filterArrayUnique(string $hook, ...$args): array
164
    {
165 8
        $filtered = apply_filters_ref_array($this->id.'/'.$hook, $args);
166 8
        return array_unique(array_filter(Cast::toArray($filtered)));
167
    }
168
169
    /**
170
     * @return static
171
     */
172 46
    public static function load()
173
    {
174 46
        if (empty(static::$instance)) {
175
            static::$instance = new static();
176
        }
177 46
        return static::$instance;
178
    }
179
180
    /**
181
     * @param mixed $fallback
182
     * @return mixed
183
     */
184
    public function option(string $path = '', $fallback = '', string $cast = '')
185
    {
186
        return glsr_get_option($path, $fallback, $cast);
187
    }
188
189 36
    public function path(string $file = '', bool $realpath = true): string
190
    {
191 36
        $path = plugin_dir_path($this->file);
192 36
        if (!$realpath) {
193 3
            $path = trailingslashit(WP_PLUGIN_DIR).basename(dirname($this->file));
194
        }
195 36
        $path = trailingslashit($path).ltrim(trim($file), '/');
196 36
        return $this->filterString('path', $path, $file);
197
    }
198
199 9
    public function render(string $view, array $data = []): void
200
    {
201 9
        $view = $this->filterString('render/view', $view, $data);
202 9
        $file = $this->filterString('views/file', $this->file($view), $view, $data);
203 9
        if (!file_exists($file)) {
204
            glsr_log()->error(sprintf('File not found: (%s) %s', $view, $file));
205
            return;
206
        }
207 9
        $data = $this->filterArray('views/data', $data, $view);
208 9
        extract($data);
209 9
        include $file;
210
    }
211
212
    /**
213
     * @param mixed $args
214
     */
215
    public function request($args = []): Request
216
    {
217
        return new Request($args);
218
    }
219
220
    /**
221
     * @return mixed|false
222
     */
223
    public function runIf(string $className, ...$args)
224
    {
225
        return class_exists($className)
226
            ? call_user_func_array([glsr($className), 'handle'], $args)
227
            : false;
228
    }
229
230 9
    public function themePath(string $file = ''): string
231
    {
232 9
        return get_stylesheet_directory().'/'.$this->id.'/'.ltrim(trim($file), '/');
233
    }
234
235
    public function url(string $path = ''): string
236
    {
237
        $url = esc_url(plugin_dir_url($this->file).ltrim(trim($path), '/'));
238
        return $this->filterString('url', $url, $path);
239
    }
240
241 34
    public function version(string $versionLevel = ''): string
242
    {
243 34
        $pattern = '/^v?(\d{1,5})(\.\d++)?(\.\d++)?(.+)?$/i';
244 34
        preg_match($pattern, $this->version, $matches);
245
        switch ($versionLevel) {
246 34
            case 'major':
247 34
                $version = Arr::get($matches, 1);
248 34
                break;
249
            case 'minor':
250
                $version = Arr::get($matches, 1).Arr::get($matches, 2);
251
                break;
252
            case 'patch':
253
                $version = Arr::get($matches, 1).Arr::get($matches, 2).Arr::get($matches, 3);
254
                break;
255
        }
256 34
        return empty($version)
257
            ? $this->version
258 34
            : $version;
259
    }
260
}
261