Test Failed
Push — develop ( 6f947a...7aea1a )
by Paul
18:36
created

Plugin::filter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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