PluginProbe
User Access Manager / 2.3.15
User Access Manager v2.3.15
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.15, at src/Controller/Backend/SettingsController.php

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