This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
1 | <?php |
||
2 | |||
3 | namespace GeminiLabs\SiteReviews\Tinymce; |
||
4 | |||
5 | use GeminiLabs\SiteReviews\Contracts\ShortcodeContract; |
||
6 | use GeminiLabs\SiteReviews\Helper; |
||
7 | use GeminiLabs\SiteReviews\Helpers\Arr; |
||
8 | |||
9 | abstract class TinymceGenerator |
||
10 | { |
||
11 | public array $properties = []; |
||
12 | public ShortcodeContract $shortcode; |
||
13 | public string $tag = ''; |
||
14 | protected array $errors = []; |
||
15 | protected array $required = []; |
||
16 | |||
17 | abstract public function fields(): array; |
||
18 | |||
19 | 8 | public function register(): void |
|
20 | { |
||
21 | 8 | $this->shortcode = $this->shortcode(); |
|
22 | 8 | $this->tag = $this->shortcode->tag; |
|
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
23 | 8 | $fields = $this->getFields(); |
|
24 | 8 | $this->properties = [ |
|
25 | 8 | 'btn_close' => _x('Close', 'admin-text', 'site-reviews'), |
|
26 | 8 | 'btn_okay' => _x('Insert Shortcode', 'admin-text', 'site-reviews'), |
|
27 | 8 | 'errors' => $this->errors, |
|
28 | 8 | 'fields' => $fields, |
|
29 | 8 | 'label' => $this->shortcode->name, |
|
30 | 8 | 'required' => $this->required, |
|
31 | 8 | 'title' => $this->shortcode->name, |
|
32 | 8 | ]; |
|
33 | 8 | glsr()->append('mce', $this->properties, $this->tag); |
|
34 | 8 | } |
|
35 | |||
36 | abstract public function shortcode(): ShortcodeContract; |
||
37 | |||
38 | protected function generateFields(array $fields): array |
||
39 | 8 | { |
|
40 | $generatedFields = array_map(function ($field) { |
||
41 | 8 | if (empty($field)) { |
|
42 | 8 | return; |
|
43 | 8 | } |
|
44 | $type = Arr::getAs('string', $field, 'type', 'textbox'); |
||
45 | $method = Helper::buildMethodName('normalize', $type); |
||
46 | if (method_exists($this, $method)) { |
||
47 | return call_user_func([$this, $method], $field); |
||
48 | } |
||
49 | }, $fields); |
||
50 | return array_values(array_filter($generatedFields)); |
||
51 | } |
||
52 | |||
53 | protected function getFields(): array |
||
54 | 8 | { |
|
55 | $fields = $this->fields(); |
||
56 | 8 | $fields = glsr()->filterArray("tinymce/fields/{$this->shortcode->tag}", $fields); |
|
0 ignored issues
–
show
|
|||
57 | 8 | $fields = $this->generateFields($fields); |
|
58 | if (!empty($this->errors)) { |
||
59 | $errors = []; |
||
60 | foreach ($this->required as $name => $alert) { |
||
61 | if (false === Arr::searchByKey($name, $fields, 'name')) { |
||
62 | $errors[] = $this->errors[$name]; |
||
63 | } |
||
64 | } |
||
65 | $this->errors = $errors; |
||
66 | } |
||
67 | return empty($this->errors) |
||
68 | 8 | ? $fields |
|
69 | : $this->errors; |
||
70 | 8 | } |
|
71 | 8 | ||
72 | 8 | protected function hideOptions(): array |
|
73 | { |
||
74 | 8 | $hideOptions = $this->shortcode->options('hide'); |
|
75 | 8 | $options = []; |
|
76 | 8 | foreach ($hideOptions as $name => $tooltip) { |
|
77 | 8 | $options[] = [ |
|
78 | 'name' => "hide_{$name}", |
||
79 | 8 | 'text' => $name, |
|
80 | 8 | 'tooltip' => $tooltip, |
|
81 | 'type' => 'checkbox', |
||
82 | ]; |
||
83 | 8 | } |
|
84 | return $options; |
||
85 | 8 | } |
|
86 | 8 | ||
87 | protected function normalize(array $field, array $defaults): array |
||
88 | { |
||
89 | if (!$this->validate($field)) { |
||
90 | return []; |
||
91 | } |
||
92 | $field = shortcode_atts($defaults, $field); |
||
93 | return array_filter($field, fn ($value) => '' !== $value); |
||
94 | } |
||
95 | 8 | ||
96 | 8 | protected function normalizeCheckbox(array $field): array |
|
97 | 8 | { |
|
98 | return $this->normalize($field, [ |
||
99 | 'checked' => false, |
||
100 | 8 | 'label' => '', |
|
101 | 'minHeight' => '', |
||
102 | 8 | 'minWidth' => '', |
|
103 | 8 | 'name' => false, |
|
104 | 8 | 'text' => '', |
|
105 | 8 | 'tooltip' => '', |
|
106 | 8 | 'type' => '', |
|
107 | 8 | 'value' => '', |
|
108 | 8 | ]); |
|
109 | 8 | } |
|
110 | 8 | ||
111 | 8 | protected function normalizeContainer(array $field): array |
|
112 | 8 | { |
|
113 | if (!array_key_exists('html', $field) && array_key_exists('items', $field)) { |
||
114 | 8 | $field['items'] = $this->generateFields($field['items']); |
|
115 | } |
||
116 | return $field; |
||
117 | 8 | } |
|
118 | |||
119 | 8 | protected function normalizeListbox(array $field): array |
|
120 | { |
||
121 | $listbox = $this->normalize($field, [ |
||
122 | 8 | 'label' => '', |
|
123 | 8 | 'minWidth' => '', |
|
124 | 'name' => false, |
||
125 | 'options' => [], |
||
126 | 8 | 'placeholder' => esc_attr_x('— Select —', 'admin-text', 'site-reviews'), |
|
127 | 'tooltip' => '', |
||
128 | 8 | 'type' => 'listbox', |
|
129 | 8 | 'value' => '', |
|
130 | 8 | ]); |
|
131 | 8 | if (empty($listbox)) { |
|
132 | 8 | return []; |
|
133 | 8 | } |
|
134 | 8 | if (empty($listbox['options'])) { |
|
135 | 8 | return []; |
|
136 | 8 | } |
|
137 | 8 | if (!array_key_exists('', $listbox['options'])) { |
|
138 | 8 | $listbox['options'] = Arr::prepend($listbox['options'], $listbox['placeholder'], ''); |
|
139 | } |
||
140 | foreach ($listbox['options'] as $value => $text) { |
||
141 | 8 | $listbox['values'][] = [ |
|
142 | 'text' => $text, |
||
143 | 8 | 'value' => $value, |
|
144 | 8 | ]; |
|
145 | } |
||
146 | 8 | return $listbox; |
|
147 | } |
||
148 | |||
149 | 8 | protected function normalizeTextbox(array $field): array |
|
150 | { |
||
151 | 8 | return $this->normalize($field, [ |
|
152 | 8 | 'hidden' => false, |
|
153 | 8 | 'label' => '', |
|
154 | 8 | 'maxLength' => '', |
|
155 | 8 | 'minHeight' => '', |
|
156 | 8 | 'minWidth' => '', |
|
157 | 8 | 'multiline' => false, |
|
158 | 8 | 'name' => false, |
|
159 | 8 | 'size' => '', |
|
160 | 8 | 'text' => '', |
|
161 | 8 | 'tooltip' => '', |
|
162 | 'type' => 'textbox', |
||
163 | 'value' => '', |
||
164 | 8 | ]); |
|
165 | 8 | } |
|
166 | |||
167 | 8 | protected function validate(array $field): bool |
|
168 | 8 | { |
|
169 | 8 | $args = shortcode_atts([ |
|
170 | 8 | 'label' => '', |
|
171 | 8 | 'name' => false, |
|
172 | 'required' => false, |
||
173 | 8 | ], $field); |
|
174 | if (!$args['name']) { |
||
175 | return false; |
||
176 | 8 | } |
|
177 | return $this->validateErrors($args) && $this->validateRequired($args); |
||
178 | 8 | } |
|
179 | 8 | ||
180 | 8 | protected function validateErrors(array $args): bool |
|
181 | 8 | { |
|
182 | 8 | if (!isset($args['required']['error'])) { |
|
183 | 8 | return true; |
|
184 | 8 | } |
|
185 | 8 | $this->errors[$args['name']] = $this->normalizeContainer([ |
|
186 | 8 | 'html' => $args['required']['error'], |
|
187 | 8 | 'type' => 'container', |
|
188 | 8 | ]); |
|
189 | 8 | return false; |
|
190 | 8 | } |
|
191 | 8 | ||
192 | protected function validateRequired(array $args): bool |
||
193 | { |
||
194 | 8 | if (false == $args['required']) { |
|
195 | return true; |
||
196 | 8 | } |
|
197 | 8 | $alert = _x('Some of the shortcode options are required.', 'admin-text', 'site-reviews'); |
|
198 | 8 | if (isset($args['required']['alert'])) { |
|
199 | 8 | $alert = $args['required']['alert']; |
|
200 | 8 | } elseif (!empty($args['label'])) { |
|
201 | 8 | $alert = sprintf( |
|
202 | _x('The "%s" option is required.', 'the option label (admin-text)', 'site-reviews'), |
||
203 | str_replace(':', '', $args['label']) |
||
204 | 8 | ); |
|
205 | } |
||
206 | $this->required[$args['name']] = $alert; |
||
207 | 8 | return false; |
|
208 | } |
||
209 | } |
||
210 |