PluginProbe
User Access Manager / 2.3.13
User Access Manager v2.3.13
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.13, at src/Controller/Backend/SettingsController.php

510 lines 16.7 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 ];
320
321 $this->addCustomPageRedirectFormElement($configParameters, $values);
322
323 if (isset($configParameters['redirect_custom_url']) === true) {
324 try {
325 $values[] = $this->formHelper->createMultipleFromElement(
326 'custom_url',
327 TXT_UAM_REDIRECT_TO_URL,
328 $configParameters['redirect_custom_url']
329 );
330 } catch (Exception) {
331 }
332 }
333
334 $configParameter = $configParameters['redirect'];
335
336 $redirect = $this->formFactory->createRadio(
337 $configParameter->getId(),
338 $values,
339 $configParameter->getValue(),
340 TXT_UAM_REDIRECT,
341 TXT_UAM_REDIRECT_DESC
342 );
343 }
344
345 $parameters = [
346 'lock_recursive',
347 'protect_feed',
348 $redirect,
349 'blog_admin_hint',
350 'blog_admin_hint_text',
351 'show_assigned_groups',
352 'hide_edit_link_on_no_access',
353 'extra_ip_header'
354 ];
355
356 return $this->formHelper->getSettingsForm($parameters);
357 }
358
359 private function getFullSettingsFrom(array $types, array $ignoredTypes, callable $formFunction): array
360 {
361 $groupForms = [];
362 $groupForms[MainConfig::DEFAULT_TYPE] = $formFunction();
363
364 foreach ($ignoredTypes as $ignoredType) {
365 unset($types[$ignoredType]);
366 }
367
368 foreach ($types as $type => $typeObject) {
369 $groupForms[$type] = $formFunction($type);
370 }
371
372 return $groupForms;
373 }
374
375 /**
376 * @throws Exception
377 */
378 private function getFullPostSettingsForm(): array
379 {
380 return $this->getFullSettingsFrom(
381 $this->getPostTypes(),
382 [ObjectHandler::ATTACHMENT_OBJECT_TYPE],
383 function ($type = MainConfig::DEFAULT_TYPE) {
384 return $this->getPostSettingsForm($type);
385 }
386 );
387 }
388
389 /**
390 * @throws Exception
391 */
392 private function getFullTaxonomySettingsForm(): array
393 {
394 return $this->getFullSettingsFrom(
395 $this->getTaxonomies(),
396 [ObjectHandler::POST_FORMAT_TYPE],
397 function ($type = MainConfig::DEFAULT_TYPE) {
398 return $this->getTaxonomySettingsForm($type);
399 }
400 );
401 }
402
403 /**
404 * @throws Exception
405 */
406 private function getFullCacheProvidersForm(): array
407 {
408 $groupForms = [];
409 $cacheProviders = $this->cache->getRegisteredCacheProviders();
410 $groupForms[MainConfig::CACHE_PROVIDER_NONE] = null;
411
412 foreach ($cacheProviders as $cacheProvider) {
413 $groupForms[$cacheProvider->getId()] = $this->formHelper->getSettingsFormByConfig(
414 $cacheProvider->getConfig()
415 );
416 }
417
418 return $groupForms;
419 }
420
421 /**
422 * @return Form[]
423 */
424 public function getCurrentGroupForms(): array
425 {
426 $group = $this->getCurrentTabGroup();
427
428 try {
429 $formMap = [
430 self::GROUP_POST_TYPES => function () {
431 return $this->getFullPostSettingsForm();
432 },
433 self::GROUP_TAXONOMIES => function () {
434 return $this->getFullTaxonomySettingsForm();
435 },
436 self::GROUP_FILES => function () {
437 return [self::SECTION_FILES => $this->getFilesSettingsForm()];
438 },
439 self::GROUP_AUTHOR => function () {
440 return [self::SECTION_AUTHOR => $this->getAuthorSettingsForm()];
441 },
442 self::GROUP_CACHE => function () {
443 return $this->getFullCacheProvidersForm();
444 },
445 self::GROUP_OTHER => function () {
446 return [self::SECTION_OTHER => $this->getOtherSettingsForm()];
447 }
448 ];
449
450 if (isset($formMap[$group]) === true) {
451 return $formMap[$group]();
452 }
453 } catch (Exception $exception) {
454 $this->addErrorMessage(sprintf(TXT_UAM_ERROR, $exception->getMessage()));
455 }
456
457 return [];
458 }
459
460 private function updateFileProtectionFile(array $configParameters): void
461 {
462 $key = 'custom_file_handling_file';
463 $customFileHandlingFile = isset($configParameters[$key]) === true ? $configParameters[$key] : null;
464 unset($configParameters[$key]);
465
466 $this->mainConfig->setConfigParameters($configParameters);
467
468 if ($this->mainConfig->lockFile() === false) {
469 $this->fileHandler->deleteFileProtection();
470 } elseif ($this->mainConfig->useCustomFileHandlingFile() === false) {
471 $this->fileHandler->createFileProtection();
472 } elseif ($customFileHandlingFile !== null) {
473 $this->php->filePutContents(
474 $this->fileHandler->getFileProtectionFileName(),
475 htmlspecialchars_decode($customFileHandlingFile)
476 );
477 }
478 }
479
480 public function updateSettingsAction(): void
481 {
482 $this->verifyNonce('uamUpdateSettings');
483 $group = $this->getCurrentTabGroup();
484 $newConfigParameters = $this->getRequestParameter('config_parameters');
485
486 if ($group === self::GROUP_CACHE) {
487 $section = $this->getCurrentTabGroupSection();
488 $cacheProviders = $this->cache->getRegisteredCacheProviders();
489
490 if (isset($cacheProviders[$section]) === true) {
491 $cacheProviders[$section]->getConfig()->setConfigParameters($newConfigParameters);
492 $newConfigParameters = ['active_cache_provider' => $section];
493 } elseif ($section === MainConfig::CACHE_PROVIDER_NONE) {
494 $newConfigParameters = ['active_cache_provider' => $section];
495 }
496 }
497
498 $this->updateFileProtectionFile($newConfigParameters);
499 $this->wordpress->doAction('uam_update_options', $this->mainConfig);
500 $this->setUpdateMessage(TXT_UAM_UPDATE_SETTINGS);
501 }
502
503 public function isPostTypeGroup(string $key): bool
504 {
505 $postTypes = $this->getPostTypes();
506
507 return isset($postTypes[$key]);
508 }
509 }
510