PluginProbe
User Access Manager / 2.3.19
User Access Manager v2.3.19
2.3.20 2.3.19 2.3.18 2.3.17 2.3.16 2.3.15 2.3.14 2.3.13 trunk 0.6 0.6.1 0.6.2 0.7 0.7 Beta 0.7.0.1 0.8 0.8.0.1 0.8.0.2 0.9 0.9.1 0.9.1.1 0.9.1.2 0.9.1.3 0.9.1.4 1.0 All 136 releases
user-access-manager / src / Controller / Backend / Administration / SettingsController.php

SettingsController.php in User Access Manager 2.3.19, at src/Controller/Backend/Administration/SettingsController.php

501 lines 16.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace UserAccessManager\Controller\Backend\Administration;
6
7 use Exception;
8 use UserAccessManager\Cache\Cache;
9 use UserAccessManager\Config\MainConfig;
10 use UserAccessManager\Config\WordpressConfig;
11 use UserAccessManager\Controller\Backend\ControllerTabNavigationTrait;
12 use UserAccessManager\Controller\Controller;
13 use UserAccessManager\File\FileHandler;
14 use UserAccessManager\Form\Form;
15 use UserAccessManager\Form\FormFactory;
16 use UserAccessManager\Form\FormHelper;
17 use UserAccessManager\Form\Element\Radio;
18 use UserAccessManager\Form\Element\ValueSetFormElement;
19 use UserAccessManager\Object\ObjectHandler;
20 use UserAccessManager\Wrapper\Php;
21 use UserAccessManager\Wrapper\Wordpress;
22 use WP_Post_Type;
23 use WP_Taxonomy;
24
25 class SettingsController extends Controller
26 {
27 use ControllerTabNavigationTrait;
28
29 public const GROUP_POST_TYPES = 'post_types';
30 public const GROUP_TAXONOMIES = 'taxonomies';
31 public const GROUP_FILES = 'file';
32 public const SECTION_FILES = 'file';
33 public const GROUP_AUTHOR = 'author';
34 public const SECTION_AUTHOR = 'author';
35 public const GROUP_CACHE = 'cache';
36 public const GROUP_OTHER = 'other';
37 public const SECTION_OTHER = 'other';
38
39 protected ?string $template = 'AdminSettings.php';
40
41 public function __construct(
42 Php $php,
43 Wordpress $wordpress,
44 WordpressConfig $wordpressConfig,
45 private MainConfig $mainConfig,
46 private Cache $cache,
47 private FileHandler $fileHandler,
48 private FormFactory $formFactory,
49 private FormHelper $formHelper
50 ) {
51 parent::__construct($php, $wordpress, $wordpressConfig);
52 }
53
54 public function getTabGroups(): array
55 {
56 $activeCacheProvider = $this->mainConfig->getActiveCacheProvider();
57 $cacheProviderSections = [$activeCacheProvider];
58 $cacheProviders = $this->cache->getRegisteredCacheProviders();
59
60 foreach ($cacheProviders as $cacheProvider) {
61 if ($cacheProvider->getId() !== $activeCacheProvider) {
62 $cacheProviderSections[] = $cacheProvider->getId();
63 }
64 }
65
66 if (!in_array(MainConfig::CACHE_PROVIDER_NONE, $cacheProviderSections)) {
67 $cacheProviderSections[] = MainConfig::CACHE_PROVIDER_NONE;
68 }
69
70 return [
71 self::GROUP_POST_TYPES => array_merge([MainConfig::DEFAULT_TYPE], array_keys($this->getPostTypes())),
72 self::GROUP_TAXONOMIES => array_merge([MainConfig::DEFAULT_TYPE], array_keys($this->getTaxonomies())),
73 self::GROUP_FILES => [self::SECTION_FILES],
74 self::GROUP_AUTHOR => [self::SECTION_AUTHOR],
75 self::GROUP_CACHE => $cacheProviderSections,
76 self::GROUP_OTHER => [self::SECTION_OTHER]
77 ];
78 }
79
80 private function getPages(): array
81 {
82 $pages = $this->wordpress->getPages('sort_column=menu_order');
83 return is_array($pages) ? $pages : [];
84 }
85
86 /**
87 * @return WP_Post_Type[]
88 */
89 private function getPostTypes(): array
90 {
91 return $this->wordpress->getPostTypes(['public' => true], 'objects');
92 }
93
94 /**
95 * @return WP_Taxonomy[]
96 */
97 private function getTaxonomies(): array
98 {
99 return $this->wordpress->getTaxonomies(['public' => true], 'objects');
100 }
101
102 public function getText(string $key, bool $description = false): string
103 {
104 return $this->formHelper->getText($key, $description);
105 }
106
107 public function getGroupText(string $key, bool $description = false): string
108 {
109 return $this->getText($key, $description);
110 }
111
112 public function getGroupSectionText(string $key): string
113 {
114 return ($key === MainConfig::DEFAULT_TYPE) ?
115 TXT_UAM_SETTINGS_GROUP_SECTION_DEFAULT : $this->getObjectName($key);
116 }
117
118 public function getObjectName(string $objectKey): string
119 {
120 $objects = $this->getPostTypes() + $this->getTaxonomies();
121
122 return $objects[$objectKey]->labels->name ?? $objectKey;
123 }
124
125 /**
126 * @throws Exception
127 */
128 private function getPostSettingsForm(string $postType = MainConfig::DEFAULT_TYPE): Form
129 {
130 $textarea = null;
131 $configParameters = $this->mainConfig->getConfigParameters();
132
133 if (isset($configParameters["{$postType}_content"]) === true) {
134 $configParameter = $configParameters["{$postType}_content"];
135 $textarea = $this->formFactory->createTextarea(
136 $configParameter->getId(),
137 $configParameter->getValue(),
138 $this->formHelper->getParameterText($configParameter, false, $postType),
139 $this->formHelper->getParameterText($configParameter, true, $postType)
140 );
141 }
142
143 $parameters = ($postType !== MainConfig::DEFAULT_TYPE) ? ["{$postType}_use_default"] : [];
144 $parameters = array_merge($parameters, [
145 "hide_$postType",
146 "hide_{$postType}_title",
147 "{$postType}_title",
148 $textarea,
149 "hide_{$postType}_comment",
150 "{$postType}_comment_content",
151 "{$postType}_comments_locked",
152 "show_{$postType}_content_before_more"
153 ]);
154
155 return $this->formHelper->getSettingsForm($parameters, $postType);
156 }
157
158 /**
159 * @throws Exception
160 */
161 private function getTaxonomySettingsForm(string $taxonomy = MainConfig::DEFAULT_TYPE): Form
162 {
163 $parameters = ($taxonomy !== MainConfig::DEFAULT_TYPE) ? ["{$taxonomy}_use_default"] : [];
164 $parameters = array_merge($parameters, [
165 "hide_empty_$taxonomy"
166 ]);
167
168 return $this->formHelper->getSettingsForm($parameters, $taxonomy);
169 }
170
171 private function isXSendFileAvailable(): bool
172 {
173 // On nginx, X-Accel-Redirect is always available — no HTTP test needed.
174 if ($this->wordpress->isNginx()) {
175 return true;
176 }
177
178 $content = $this->php->fileGetContents($this->wordpress->getSiteUrl() . '?testXSendFile');
179 $this->fileHandler->removeXSendFileTestFile();
180
181 return ($content === 'success');
182 }
183
184 private function configureXSendFileOption(Form $form): void
185 {
186 $formElements = $form->getElements();
187
188 if (isset($formElements['download_type']) === false) {
189 return;
190 }
191
192 /** @var ValueSetFormElement $downloadType */
193 $downloadType = $formElements['download_type'];
194 $possibleValues = $downloadType->getPossibleValues();
195
196 if (isset($possibleValues['xsendfile']) === false) {
197 return;
198 }
199
200 if ($this->wordpress->isNginx() === true) {
201 $possibleValues['xsendfile']->setLabel(TXT_UAM_DOWNLOAD_TYPE_XACCELREDIRECT);
202 } elseif ($this->isXSendFileAvailable() === false) {
203 $possibleValues['xsendfile']->markDisabled();
204 }
205 }
206
207 private function addLockFileTypes(array $configParameters, array &$parameters): void
208 {
209 if (isset($configParameters['lock_file_types']) === false) {
210 return;
211 }
212
213 $parameters['lock_file_types'] = [
214 'selected' => 'locked_file_types',
215 'not_selected' => 'not_locked_file_types'
216 ];
217
218 if ($this->wordpress->isNginx() === false
219 && $this->wordpress->gotModRewrite() === false
220 ) {
221 $parameters[] = 'file_pass_type';
222 }
223 }
224
225 /**
226 * @throws Exception
227 */
228 private function getFilesSettingsForm(): Form
229 {
230 $fileProtectionFileName = $this->fileHandler->getFileProtectionFileName();
231 $fileContent = (file_exists($fileProtectionFileName) === true) ?
232 file_get_contents($fileProtectionFileName) : '';
233
234 $configParameters = $this->mainConfig->getConfigParameters();
235
236 $parameters = [
237 'lock_file',
238 'download_type',
239 'inline_files',
240 'no_access_image_type' => ['custom' => 'custom_no_access_image'],
241 'use_custom_file_handling_file',
242 $this->formFactory->createTextarea(
243 'custom_file_handling_file',
244 $fileContent,
245 TXT_UAM_CUSTOM_FILE_HANDLING_FILE,
246 TXT_UAM_CUSTOM_FILE_HANDLING_FILE_DESC
247 ),
248 'locked_directory_type' => ['custom' => 'custom_locked_directories']
249 ];
250
251 $this->addLockFileTypes($configParameters, $parameters);
252
253 $form = $this->formHelper->getSettingsForm($parameters);
254
255 $this->configureXSendFileOption($form);
256
257 return $form;
258 }
259
260 /**
261 * @throws Exception
262 */
263 private function getAuthorSettingsForm(): Form
264 {
265 $parameters = [
266 'authors_has_access_to_own',
267 'authors_can_add_posts_to_groups',
268 'full_access_role'
269 ];
270
271 return $this->formHelper->getSettingsForm($parameters);
272 }
273
274 private function addCustomPageRedirectFormElement(array $configParameters, array &$values): void
275 {
276 if (isset($configParameters['redirect_custom_page']) === false) {
277 return;
278 }
279
280 $redirectCustomPage = $configParameters['redirect_custom_page'];
281 $redirectCustomPageValue = $this->formFactory->createMultipleFormElementValue(
282 'custom_page',
283 TXT_UAM_REDIRECT_TO_PAGE
284 );
285
286 $possibleValues = [];
287
288 foreach ($this->getPages() as $page) {
289 $possibleValues[] = $this->formFactory->createValueSetFormElementValue(
290 (int) $page->ID,
291 $page->post_title
292 );
293 }
294
295 $formElement = $this->formFactory->createSelect(
296 $redirectCustomPage->getId(),
297 $possibleValues,
298 (int) $redirectCustomPage->getValue()
299 );
300
301 try {
302 $redirectCustomPageValue->setSubElement($formElement);
303 $values[] = $redirectCustomPageValue;
304 } catch (Exception) {
305 }
306 }
307
308 private function addCustomUrlRedirectFormElement(array $configParameters, array &$values): void
309 {
310 if (isset($configParameters['redirect_custom_url']) === false) {
311 return;
312 }
313
314 try {
315 $values[] = $this->formHelper->createMultipleFormElementValue(
316 'custom_url',
317 TXT_UAM_REDIRECT_TO_URL,
318 $configParameters['redirect_custom_url']
319 );
320 } catch (Exception) {
321 }
322 }
323
324 /**
325 * @throws Exception
326 */
327 private function getRedirectFormElement(array $configParameters): ?Radio
328 {
329 if (isset($configParameters['redirect']) === false) {
330 return null;
331 }
332
333 $values = [
334 $this->formFactory->createMultipleFormElementValue('false', TXT_UAM_NO),
335 $this->formFactory->createMultipleFormElementValue('blog', TXT_UAM_REDIRECT_TO_BLOG),
336 $this->formFactory->createMultipleFormElementValue('login', TXT_UAM_REDIRECT_TO_LOGIN),
337 $this->formFactory->createMultipleFormElementValue('origin', TXT_UAM_REDIRECT_TO_ORIGIN)
338 ];
339
340 $this->addCustomPageRedirectFormElement($configParameters, $values);
341 $this->addCustomUrlRedirectFormElement($configParameters, $values);
342
343 $configParameter = $configParameters['redirect'];
344
345 return $this->formFactory->createRadio(
346 $configParameter->getId(),
347 $values,
348 $configParameter->getValue(),
349 TXT_UAM_REDIRECT,
350 TXT_UAM_REDIRECT_DESC
351 );
352 }
353
354 /**
355 * @throws Exception
356 */
357 private function getOtherSettingsForm(): Form
358 {
359 $redirect = $this->getRedirectFormElement($this->mainConfig->getConfigParameters());
360
361 $parameters = [
362 'lock_recursive',
363 'protect_feed',
364 $redirect,
365 'append_redirect_to_parameter',
366 'blog_admin_hint',
367 'blog_admin_hint_text',
368 'show_assigned_groups',
369 'hide_edit_link_on_no_access',
370 'extra_ip_header'
371 ];
372
373 return $this->formHelper->getSettingsForm($parameters);
374 }
375
376 private function getSettingsFormPerType(array $types, array $ignoredTypes, callable $buildForm): array
377 {
378 $groupForms = [MainConfig::DEFAULT_TYPE => $buildForm()];
379
380 foreach (array_diff(array_keys($types), $ignoredTypes) as $type) {
381 $groupForms[$type] = $buildForm($type);
382 }
383
384 return $groupForms;
385 }
386
387 /**
388 * @throws Exception
389 */
390 private function getFullPostSettingsForm(): array
391 {
392 return $this->getSettingsFormPerType(
393 $this->getPostTypes(),
394 [ObjectHandler::ATTACHMENT_OBJECT_TYPE],
395 fn(string $type = MainConfig::DEFAULT_TYPE): Form => $this->getPostSettingsForm($type)
396 );
397 }
398
399 /**
400 * @throws Exception
401 */
402 private function getFullTaxonomySettingsForm(): array
403 {
404 return $this->getSettingsFormPerType(
405 $this->getTaxonomies(),
406 [ObjectHandler::POST_FORMAT_TYPE],
407 fn(string $type = MainConfig::DEFAULT_TYPE): Form => $this->getTaxonomySettingsForm($type)
408 );
409 }
410
411 /**
412 * @throws Exception
413 */
414 private function getFullCacheProvidersForm(): array
415 {
416 $groupForms = [];
417 $cacheProviders = $this->cache->getRegisteredCacheProviders();
418 $groupForms[MainConfig::CACHE_PROVIDER_NONE] = null;
419
420 foreach ($cacheProviders as $cacheProvider) {
421 $groupForms[$cacheProvider->getId()] = $this->formHelper->getSettingsFormByConfig(
422 $cacheProvider->getConfig()
423 );
424 }
425
426 return $groupForms;
427 }
428
429 /**
430 * @return Form[]
431 */
432 public function getCurrentGroupForms(): array
433 {
434 try {
435 return match ($this->getCurrentTabGroup()) {
436 self::GROUP_POST_TYPES => $this->getFullPostSettingsForm(),
437 self::GROUP_TAXONOMIES => $this->getFullTaxonomySettingsForm(),
438 self::GROUP_FILES => [self::SECTION_FILES => $this->getFilesSettingsForm()],
439 self::GROUP_AUTHOR => [self::SECTION_AUTHOR => $this->getAuthorSettingsForm()],
440 self::GROUP_CACHE => $this->getFullCacheProvidersForm(),
441 self::GROUP_OTHER => [self::SECTION_OTHER => $this->getOtherSettingsForm()],
442 default => []
443 };
444 } catch (Exception $exception) {
445 $this->addErrorMessage(sprintf(TXT_UAM_ERROR, $exception->getMessage()));
446 }
447
448 return [];
449 }
450
451 private function updateFileProtectionFile(array $configParameters): void
452 {
453 $key = 'custom_file_handling_file';
454 $customFileHandlingFile = $configParameters[$key] ?? null;
455 unset($configParameters[$key]);
456
457 $this->mainConfig->setConfigParameters($configParameters);
458
459 if ($this->mainConfig->lockFile() === false) {
460 $this->fileHandler->deleteFileProtection();
461 } elseif ($this->mainConfig->useCustomFileHandlingFile() === false) {
462 $this->fileHandler->createFileProtection();
463 } elseif ($customFileHandlingFile !== null) {
464 $this->php->filePutContents(
465 $this->fileHandler->getFileProtectionFileName(),
466 htmlspecialchars_decode($customFileHandlingFile)
467 );
468 }
469 }
470
471 public function updateSettingsAction(): void
472 {
473 $this->verifyNonce('uamUpdateSettings');
474 $group = $this->getCurrentTabGroup();
475 $newConfigParameters = $this->getRequestParameter('config_parameters');
476
477 if ($group === self::GROUP_CACHE) {
478 $section = $this->getCurrentTabGroupSection();
479 $cacheProviders = $this->cache->getRegisteredCacheProviders();
480
481 if (isset($cacheProviders[$section]) === true) {
482 $cacheProviders[$section]->getConfig()->setConfigParameters($newConfigParameters);
483 $newConfigParameters = ['active_cache_provider' => $section];
484 } elseif ($section === MainConfig::CACHE_PROVIDER_NONE) {
485 $newConfigParameters = ['active_cache_provider' => $section];
486 }
487 }
488
489 $this->updateFileProtectionFile($newConfigParameters);
490 $this->wordpress->doAction('uam_update_options', $this->mainConfig);
491 $this->setUpdateMessage(TXT_UAM_UPDATE_SETTINGS);
492 }
493
494 public function isPostTypeGroup(string $key): bool
495 {
496 $postTypes = $this->getPostTypes();
497
498 return isset($postTypes[$key]);
499 }
500 }
501