PluginProbe
User Access Manager / 2.3.14
User Access Manager v2.3.14
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 / SettingsController.php

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

511 lines 16.8 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;
6
7 use Exception;
8 use UserAccessManager\Cache\Cache;
9 use UserAccessManager\Config\MainConfig;
10 use UserAccessManager\Config\WordpressConfig;
11 use UserAccessManager\Controller\Controller;
12 use UserAccessManager\File\FileHandler;
13 use UserAccessManager\Form\Form;
14 use UserAccessManager\Form\FormFactory;
15 use UserAccessManager\Form\FormHelper;
16 use UserAccessManager\Form\ValueSetFormElement;
17 use UserAccessManager\Object\ObjectHandler;
18 use UserAccessManager\Wrapper\Php;
19 use UserAccessManager\Wrapper\Wordpress;
20 use WP_Post_Type;
21 use WP_Taxonomy;
22
23 class SettingsController extends Controller
24 {
25 use ControllerTabNavigationTrait;
26
27 public const GROUP_POST_TYPES = 'post_types';
28 public const GROUP_TAXONOMIES = 'taxonomies';
29 public const GROUP_FILES = 'file';
30 public const SECTION_FILES = 'file';
31 public const GROUP_AUTHOR = 'author';
32 public const SECTION_AUTHOR = 'author';
33 public const GROUP_CACHE = 'cache';
34 public const GROUP_OTHER = 'other';
35 public const SECTION_OTHER = 'other';
36
37 protected ?string $template = 'AdminSettings.php';
38
39 public function __construct(
40 Php $php,
41 Wordpress $wordpress,
42 WordpressConfig $wordpressConfig,
43 private MainConfig $mainConfig,
44 private Cache $cache,
45 private FileHandler $fileHandler,
46 private FormFactory $formFactory,
47 private FormHelper $formHelper
48 ) {
49 parent::__construct($php, $wordpress, $wordpressConfig);
50 }
51
52 public function getTabGroups(): array
53 {
54 $activeCacheProvider = $this->mainConfig->getActiveCacheProvider();
55 $cacheProviderSections = [$activeCacheProvider];
56 $cacheProviders = $this->cache->getRegisteredCacheProviders();
57
58 foreach ($cacheProviders as $cacheProvider) {
59 if ($cacheProvider->getId() !== $activeCacheProvider) {
60 $cacheProviderSections[] = $cacheProvider->getId();
61 }
62 }
63
64 if (!in_array(MainConfig::CACHE_PROVIDER_NONE, $cacheProviderSections)) {
65 $cacheProviderSections[] = MainConfig::CACHE_PROVIDER_NONE;
66 }
67
68 return [
69 self::GROUP_POST_TYPES => array_merge([MainConfig::DEFAULT_TYPE], array_keys($this->getPostTypes())),
70 self::GROUP_TAXONOMIES => array_merge([MainConfig::DEFAULT_TYPE], array_keys($this->getTaxonomies())),
71 self::GROUP_FILES => [self::SECTION_FILES],
72 self::GROUP_AUTHOR => [self::SECTION_AUTHOR],
73 self::GROUP_CACHE => $cacheProviderSections,
74 self::GROUP_OTHER => [self::SECTION_OTHER]
75 ];
76 }
77
78
79 private function getPages(): array
80 {
81 $pages = $this->wordpress->getPages('sort_column=menu_order');
82 return is_array($pages) !== false ? $pages : [];
83 }
84
85 /**
86 * @return WP_Post_Type[]
87 */
88 private function getPostTypes(): array
89 {
90 return $this->wordpress->getPostTypes(['public' => true], 'objects');
91 }
92
93 /**
94 * @return WP_Taxonomy[]
95 */
96 private function getTaxonomies(): array
97 {
98 return $this->wordpress->getTaxonomies(['public' => true], 'objects');
99 }
100
101 public function getText(string $key, bool $description = false): string
102 {
103 return $this->formHelper->getText($key, $description);
104 }
105
106 public function getGroupText(string $key): string
107 {
108 return $this->getText($key);
109 }
110
111 public function getGroupSectionText(string $key): string
112 {
113 return ($key === MainConfig::DEFAULT_TYPE) ?
114 TXT_UAM_SETTINGS_GROUP_SECTION_DEFAULT : $this->getObjectName($key);
115 }
116
117 public function getObjectName(string $objectKey): string
118 {
119 $objects = $this->wordpress->getPostTypes(['public' => true], 'objects')
120 + $this->wordpress->getTaxonomies(['public' => true], 'objects');
121
122 return (isset($objects[$objectKey]) === true) ? $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 = @file_get_contents($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 // X-Accel-Redirect is always available on nginx — just relabel the option.
202 $possibleValues['xsendfile']->setLabel(TXT_UAM_DOWNLOAD_TYPE_XACCELREDIRECT);
203 } elseif ($this->isXSendFileAvailable() === false) {
204 $possibleValues['xsendfile']->markDisabled();
205 }
206 }
207
208 private function addLockFileTypes(array $configParameters, array &$parameters): void
209 {
210 if (isset($configParameters['lock_file_types']) === true) {
211 $parameters['lock_file_types'] = [
212 'selected' => 'locked_file_types',
213 'not_selected' => 'not_locked_file_types'
214 ];
215
216 if ($this->wordpress->isNginx() === false
217 && $this->wordpress->gotModRewrite() === false
218 ) {
219 $parameters[] = 'file_pass_type';
220 }
221 }
222 }
223
224 /**
225 * @throws Exception
226 */
227 private function getFilesSettingsForm(): Form
228 {
229 $fileProtectionFileName = $this->fileHandler->getFileProtectionFileName();
230 $fileContent = (file_exists($fileProtectionFileName) === true) ?
231 file_get_contents($fileProtectionFileName) : '';
232
233 $configParameters = $this->mainConfig->getConfigParameters();
234
235 $parameters = [
236 'lock_file',
237 'download_type',
238 'inline_files',
239 'no_access_image_type' => ['custom' => 'custom_no_access_image'],
240 'use_custom_file_handling_file',
241 $this->formFactory->createTextarea(
242 'custom_file_handling_file',
243 $fileContent,
244 TXT_UAM_CUSTOM_FILE_HANDLING_FILE,
245 TXT_UAM_CUSTOM_FILE_HANDLING_FILE_DESC
246 ),
247 'locked_directory_type' => ['custom' => 'custom_locked_directories']
248 ];
249
250 $this->addLockFileTypes($configParameters, $parameters);
251
252 $form = $this->formHelper->getSettingsForm($parameters);
253
254 $this->configureXSendFileOption($form);
255
256 return $form;
257 }
258
259 /**
260 * @throws Exception
261 */
262 private function getAuthorSettingsForm(): Form
263 {
264 $parameters = [
265 'authors_has_access_to_own',
266 'authors_can_add_posts_to_groups',
267 'full_access_role'
268 ];
269
270 return $this->formHelper->getSettingsForm($parameters);
271 }
272
273 private function addCustomPageRedirectFormElement(array $configParameters, array &$values): void
274 {
275 if (isset($configParameters['redirect_custom_page']) === true) {
276 $redirectCustomPage = $configParameters['redirect_custom_page'];
277 $redirectCustomPageValue = $this->formFactory->createMultipleFormElementValue(
278 'custom_page',
279 TXT_UAM_REDIRECT_TO_PAGE
280 );
281
282 $possibleValues = [];
283 $pages = $this->getPages();
284
285 foreach ($pages as $page) {
286 $possibleValues[] = $this->formFactory->createValueSetFromElementValue(
287 (int) $page->ID,
288 $page->post_title
289 );
290 }
291
292 $formElement = $this->formFactory->createSelect(
293 $redirectCustomPage->getId(),
294 $possibleValues,
295 (int) $redirectCustomPage->getValue()
296 );
297
298 try {
299 $redirectCustomPageValue->setSubElement($formElement);
300 $values[] = $redirectCustomPageValue;
301 } catch (Exception) {
302 }
303 }
304 }
305
306 /**
307 * @throws Exception
308 */
309 private function getOtherSettingsForm(): Form
310 {
311 $redirect = null;
312 $configParameters = $this->mainConfig->getConfigParameters();
313
314 if (isset($configParameters['redirect'])) {
315 $values = [
316 $this->formFactory->createMultipleFormElementValue('false', TXT_UAM_NO),
317 $this->formFactory->createMultipleFormElementValue('blog', TXT_UAM_REDIRECT_TO_BLOG),
318 $this->formFactory->createMultipleFormElementValue('login', TXT_UAM_REDIRECT_TO_LOGIN),
319 $this->formFactory->createMultipleFormElementValue('origin', TXT_UAM_REDIRECT_TO_ORIGIN)
320 ];
321
322 $this->addCustomPageRedirectFormElement($configParameters, $values);
323
324 if (isset($configParameters['redirect_custom_url']) === true) {
325 try {
326 $values[] = $this->formHelper->createMultipleFromElement(
327 'custom_url',
328 TXT_UAM_REDIRECT_TO_URL,
329 $configParameters['redirect_custom_url']
330 );
331 } catch (Exception) {
332 }
333 }
334
335 $configParameter = $configParameters['redirect'];
336
337 $redirect = $this->formFactory->createRadio(
338 $configParameter->getId(),
339 $values,
340 $configParameter->getValue(),
341 TXT_UAM_REDIRECT,
342 TXT_UAM_REDIRECT_DESC
343 );
344 }
345
346 $parameters = [
347 'lock_recursive',
348 'protect_feed',
349 $redirect,
350 'blog_admin_hint',
351 'blog_admin_hint_text',
352 'show_assigned_groups',
353 'hide_edit_link_on_no_access',
354 'extra_ip_header'
355 ];
356
357 return $this->formHelper->getSettingsForm($parameters);
358 }
359
360 private function getFullSettingsFrom(array $types, array $ignoredTypes, callable $formFunction): array
361 {
362 $groupForms = [];
363 $groupForms[MainConfig::DEFAULT_TYPE] = $formFunction();
364
365 foreach ($ignoredTypes as $ignoredType) {
366 unset($types[$ignoredType]);
367 }
368
369 foreach ($types as $type => $typeObject) {
370 $groupForms[$type] = $formFunction($type);
371 }
372
373 return $groupForms;
374 }
375
376 /**
377 * @throws Exception
378 */
379 private function getFullPostSettingsForm(): array
380 {
381 return $this->getFullSettingsFrom(
382 $this->getPostTypes(),
383 [ObjectHandler::ATTACHMENT_OBJECT_TYPE],
384 function ($type = MainConfig::DEFAULT_TYPE) {
385 return $this->getPostSettingsForm($type);
386 }
387 );
388 }
389
390 /**
391 * @throws Exception
392 */
393 private function getFullTaxonomySettingsForm(): array
394 {
395 return $this->getFullSettingsFrom(
396 $this->getTaxonomies(),
397 [ObjectHandler::POST_FORMAT_TYPE],
398 function ($type = MainConfig::DEFAULT_TYPE) {
399 return $this->getTaxonomySettingsForm($type);
400 }
401 );
402 }
403
404 /**
405 * @throws Exception
406 */
407 private function getFullCacheProvidersForm(): array
408 {
409 $groupForms = [];
410 $cacheProviders = $this->cache->getRegisteredCacheProviders();
411 $groupForms[MainConfig::CACHE_PROVIDER_NONE] = null;
412
413 foreach ($cacheProviders as $cacheProvider) {
414 $groupForms[$cacheProvider->getId()] = $this->formHelper->getSettingsFormByConfig(
415 $cacheProvider->getConfig()
416 );
417 }
418
419 return $groupForms;
420 }
421
422 /**
423 * @return Form[]
424 */
425 public function getCurrentGroupForms(): array
426 {
427 $group = $this->getCurrentTabGroup();
428
429 try {
430 $formMap = [
431 self::GROUP_POST_TYPES => function () {
432 return $this->getFullPostSettingsForm();
433 },
434 self::GROUP_TAXONOMIES => function () {
435 return $this->getFullTaxonomySettingsForm();
436 },
437 self::GROUP_FILES => function () {
438 return [self::SECTION_FILES => $this->getFilesSettingsForm()];
439 },
440 self::GROUP_AUTHOR => function () {
441 return [self::SECTION_AUTHOR => $this->getAuthorSettingsForm()];
442 },
443 self::GROUP_CACHE => function () {
444 return $this->getFullCacheProvidersForm();
445 },
446 self::GROUP_OTHER => function () {
447 return [self::SECTION_OTHER => $this->getOtherSettingsForm()];
448 }
449 ];
450
451 if (isset($formMap[$group]) === true) {
452 return $formMap[$group]();
453 }
454 } catch (Exception $exception) {
455 $this->addErrorMessage(sprintf(TXT_UAM_ERROR, $exception->getMessage()));
456 }
457
458 return [];
459 }
460
461 private function updateFileProtectionFile(array $configParameters): void
462 {
463 $key = 'custom_file_handling_file';
464 $customFileHandlingFile = isset($configParameters[$key]) === true ? $configParameters[$key] : null;
465 unset($configParameters[$key]);
466
467 $this->mainConfig->setConfigParameters($configParameters);
468
469 if ($this->mainConfig->lockFile() === false) {
470 $this->fileHandler->deleteFileProtection();
471 } elseif ($this->mainConfig->useCustomFileHandlingFile() === false) {
472 $this->fileHandler->createFileProtection();
473 } elseif ($customFileHandlingFile !== null) {
474 $this->php->filePutContents(
475 $this->fileHandler->getFileProtectionFileName(),
476 htmlspecialchars_decode($customFileHandlingFile)
477 );
478 }
479 }
480
481 public function updateSettingsAction(): void
482 {
483 $this->verifyNonce('uamUpdateSettings');
484 $group = $this->getCurrentTabGroup();
485 $newConfigParameters = $this->getRequestParameter('config_parameters');
486
487 if ($group === self::GROUP_CACHE) {
488 $section = $this->getCurrentTabGroupSection();
489 $cacheProviders = $this->cache->getRegisteredCacheProviders();
490
491 if (isset($cacheProviders[$section]) === true) {
492 $cacheProviders[$section]->getConfig()->setConfigParameters($newConfigParameters);
493 $newConfigParameters = ['active_cache_provider' => $section];
494 } elseif ($section === MainConfig::CACHE_PROVIDER_NONE) {
495 $newConfigParameters = ['active_cache_provider' => $section];
496 }
497 }
498
499 $this->updateFileProtectionFile($newConfigParameters);
500 $this->wordpress->doAction('uam_update_options', $this->mainConfig);
501 $this->setUpdateMessage(TXT_UAM_UPDATE_SETTINGS);
502 }
503
504 public function isPostTypeGroup(string $key): bool
505 {
506 $postTypes = $this->getPostTypes();
507
508 return isset($postTypes[$key]);
509 }
510 }
511