vendor/pimcore/pimcore/bundles/AdminBundle/Controller/Admin/SettingsController.php line 65

Open in your IDE?
  1. <?php
  2. /**
  3. * Pimcore
  4. *
  5. * This source file is available under two different licenses:
  6. * - GNU General Public License version 3 (GPLv3)
  7. * - Pimcore Commercial License (PCL)
  8. * Full copyright and license information is available in
  9. * LICENSE.md which is distributed with this source code.
  10. *
  11. * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12. * @license http://www.pimcore.org/license GPLv3 and PCL
  13. */
  14. namespace Pimcore\Bundle\AdminBundle\Controller\Admin;
  15. use Pimcore\Bundle\AdminBundle\Controller\AdminController;
  16. use Pimcore\Cache;
  17. use Pimcore\Cache\Core\CoreCacheHandler;
  18. use Pimcore\Cache\Symfony\CacheClearer;
  19. use Pimcore\Config;
  20. use Pimcore\Event\SystemEvents;
  21. use Pimcore\File;
  22. use Pimcore\Localization\LocaleServiceInterface;
  23. use Pimcore\Model;
  24. use Pimcore\Model\Asset;
  25. use Pimcore\Model\Document;
  26. use Pimcore\Model\Element;
  27. use Pimcore\Model\Glossary;
  28. use Pimcore\Model\Metadata;
  29. use Pimcore\Model\Property;
  30. use Pimcore\Model\Staticroute;
  31. use Pimcore\Model\Tool\SettingsStore;
  32. use Pimcore\Model\WebsiteSetting;
  33. use Pimcore\Tool;
  34. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  35. use Symfony\Component\EventDispatcher\GenericEvent;
  36. use Symfony\Component\Filesystem\Filesystem;
  37. use Symfony\Component\HttpFoundation\JsonResponse;
  38. use Symfony\Component\HttpFoundation\Request;
  39. use Symfony\Component\HttpFoundation\Response;
  40. use Symfony\Component\HttpFoundation\StreamedResponse;
  41. use Symfony\Component\HttpKernel\KernelEvents;
  42. use Symfony\Component\HttpKernel\KernelInterface;
  43. use Symfony\Component\Routing\Annotation\Route;
  44. use Symfony\Component\Yaml\Yaml;
  45. /**
  46. * @Route("/settings")
  47. *
  48. * @internal
  49. */
  50. class SettingsController extends AdminController
  51. {
  52. private const CUSTOM_LOGO_PATH = 'custom-logo.image';
  53. /**
  54. * @Route("/display-custom-logo", name="pimcore_settings_display_custom_logo", methods={"GET"})
  55. *
  56. * @param Request $request
  57. *
  58. * @return StreamedResponse
  59. */
  60. public function displayCustomLogoAction(Request $request)
  61. {
  62. $mime = 'image/svg+xml';
  63. if ($request->get('white')) {
  64. $logo = PIMCORE_WEB_ROOT . '/bundles/pimcoreadmin/img/logo-claim-white.svg';
  65. } else {
  66. $logo = PIMCORE_WEB_ROOT . '/bundles/pimcoreadmin/img/logo-claim-gray.svg';
  67. }
  68. $stream = fopen($logo, 'rb');
  69. $storage = Tool\Storage::get('admin');
  70. if ($storage->fileExists(self::CUSTOM_LOGO_PATH)) {
  71. try {
  72. $mime = $storage->mimeType(self::CUSTOM_LOGO_PATH);
  73. $stream = $storage->readStream(self::CUSTOM_LOGO_PATH);
  74. } catch (\Exception $e) {
  75. // do nothing
  76. }
  77. }
  78. return new StreamedResponse(function () use ($stream) {
  79. fpassthru($stream);
  80. }, 200, ['Content-Type' => $mime]);
  81. }
  82. /**
  83. * @Route("/upload-custom-logo", name="pimcore_admin_settings_uploadcustomlogo", methods={"POST"})
  84. *
  85. * @param Request $request
  86. *
  87. * @return JsonResponse
  88. *
  89. * @throws \Exception
  90. */
  91. public function uploadCustomLogoAction(Request $request)
  92. {
  93. $fileExt = File::getFileExtension($_FILES['Filedata']['name']);
  94. if (!in_array($fileExt, ['svg', 'png', 'jpg'])) {
  95. throw new \Exception('Unsupported file format');
  96. }
  97. $storage = Tool\Storage::get('admin');
  98. $storage->writeStream(self::CUSTOM_LOGO_PATH, fopen($_FILES['Filedata']['tmp_name'], 'rb'));
  99. // set content-type to text/html, otherwise (when application/json is sent) chrome will complain in
  100. // Ext.form.Action.Submit and mark the submission as failed
  101. $response = $this->adminJson(['success' => true]);
  102. $response->headers->set('Content-Type', 'text/html');
  103. return $response;
  104. }
  105. /**
  106. * @Route("/delete-custom-logo", name="pimcore_admin_settings_deletecustomlogo", methods={"DELETE"})
  107. *
  108. * @param Request $request
  109. *
  110. * @return JsonResponse
  111. */
  112. public function deleteCustomLogoAction(Request $request)
  113. {
  114. if (Tool\Storage::get('admin')->fileExists(self::CUSTOM_LOGO_PATH)) {
  115. Tool\Storage::get('admin')->delete(self::CUSTOM_LOGO_PATH);
  116. }
  117. return $this->adminJson(['success' => true]);
  118. }
  119. /**
  120. * Used by the predefined metadata grid
  121. *
  122. * @Route("/predefined-metadata", name="pimcore_admin_settings_metadata", methods={"POST"})
  123. *
  124. * @param Request $request
  125. *
  126. * @return JsonResponse
  127. */
  128. public function metadataAction(Request $request)
  129. {
  130. $this->checkPermission('asset_metadata');
  131. if ($request->get('data')) {
  132. if ($request->get('xaction') == 'destroy') {
  133. $data = $this->decodeJson($request->get('data'));
  134. $id = $data['id'];
  135. $metadata = Metadata\Predefined::getById($id);
  136. $metadata->delete();
  137. return $this->adminJson(['success' => true, 'data' => []]);
  138. } elseif ($request->get('xaction') == 'update') {
  139. $data = $this->decodeJson($request->get('data'));
  140. // save type
  141. $metadata = Metadata\Predefined::getById($data['id']);
  142. $metadata->setValues($data);
  143. $existingItem = Metadata\Predefined\Listing::getByKeyAndLanguage($metadata->getName(), $metadata->getLanguage(), $metadata->getTargetSubtype());
  144. if ($existingItem && $existingItem->getId() != $metadata->getId()) {
  145. return $this->adminJson(['message' => 'rule_violation', 'success' => false]);
  146. }
  147. $metadata->minimize();
  148. $metadata->save();
  149. $metadata->expand();
  150. return $this->adminJson(['data' => $metadata->getObjectVars(), 'success' => true]);
  151. } elseif ($request->get('xaction') == 'create') {
  152. $data = $this->decodeJson($request->get('data'));
  153. unset($data['id']);
  154. // save type
  155. $metadata = Metadata\Predefined::create();
  156. $metadata->setValues($data);
  157. $existingItem = Metadata\Predefined\Listing::getByKeyAndLanguage($metadata->getName(), $metadata->getLanguage(), $metadata->getTargetSubtype());
  158. if ($existingItem) {
  159. return $this->adminJson(['message' => 'rule_violation', 'success' => false]);
  160. }
  161. $metadata->save();
  162. return $this->adminJson(['data' => $metadata->getObjectVars(), 'success' => true]);
  163. }
  164. } else {
  165. // get list of types
  166. $list = new Metadata\Predefined\Listing();
  167. if ($request->get('filter')) {
  168. $filter = $request->get('filter');
  169. $list->setFilter(function ($row) use ($filter) {
  170. foreach ($row as $value) {
  171. if (strpos($value, $filter) !== false) {
  172. return true;
  173. }
  174. }
  175. return false;
  176. });
  177. }
  178. $list->load();
  179. $properties = [];
  180. if (is_array($list->getDefinitions())) {
  181. foreach ($list->getDefinitions() as $metadata) {
  182. $metadata->expand();
  183. $properties[] = $metadata->getObjectVars();
  184. }
  185. }
  186. return $this->adminJson(['data' => $properties, 'success' => true, 'total' => $list->getTotalCount()]);
  187. }
  188. return $this->adminJson(['success' => false]);
  189. }
  190. /**
  191. * @Route("/get-predefined-metadata", name="pimcore_admin_settings_getpredefinedmetadata", methods={"GET"})
  192. *
  193. * @param Request $request
  194. *
  195. * @return JsonResponse
  196. */
  197. public function getPredefinedMetadataAction(Request $request)
  198. {
  199. $type = $request->get('type');
  200. $subType = $request->get('subType');
  201. $group = $request->get('group');
  202. $list = Metadata\Predefined\Listing::getByTargetType($type, [$subType]);
  203. $result = [];
  204. foreach ($list as $item) {
  205. $itemGroup = $item->getGroup() ?? '';
  206. if ($group === 'default' || $group === $itemGroup) {
  207. $item->expand();
  208. $result[] = $item->getObjectVars();
  209. }
  210. }
  211. return $this->adminJson(['data' => $result, 'success' => true]);
  212. }
  213. /**
  214. * @Route("/properties", name="pimcore_admin_settings_properties", methods={"POST"})
  215. *
  216. * @param Request $request
  217. *
  218. * @return JsonResponse
  219. */
  220. public function propertiesAction(Request $request)
  221. {
  222. if ($request->get('data')) {
  223. $this->checkPermission('predefined_properties');
  224. if ($request->get('xaction') == 'destroy') {
  225. $data = $this->decodeJson($request->get('data'));
  226. $id = $data['id'];
  227. $property = Property\Predefined::getById($id);
  228. $property->delete();
  229. return $this->adminJson(['success' => true, 'data' => []]);
  230. } elseif ($request->get('xaction') == 'update') {
  231. $data = $this->decodeJson($request->get('data'));
  232. // save type
  233. $property = Property\Predefined::getById($data['id']);
  234. if (is_array($data['ctype'])) {
  235. $data['ctype'] = implode(',', $data['ctype']);
  236. }
  237. $property->setValues($data);
  238. $property->save();
  239. return $this->adminJson(['data' => $property->getObjectVars(), 'success' => true]);
  240. } elseif ($request->get('xaction') == 'create') {
  241. $data = $this->decodeJson($request->get('data'));
  242. unset($data['id']);
  243. // save type
  244. $property = Property\Predefined::create();
  245. $property->setValues($data);
  246. $property->save();
  247. return $this->adminJson(['data' => $property->getObjectVars(), 'success' => true]);
  248. }
  249. } else {
  250. // get list of types
  251. $list = new Property\Predefined\Listing();
  252. if ($request->get('filter')) {
  253. $filter = $request->get('filter');
  254. $list->setFilter(function ($row) use ($filter) {
  255. foreach ($row as $value) {
  256. if ($value) {
  257. $cellValues = is_array($value) ? $value : [$value];
  258. foreach ($cellValues as $cellValue) {
  259. if (strpos($cellValue, $filter) !== false) {
  260. return true;
  261. }
  262. }
  263. }
  264. }
  265. return false;
  266. });
  267. }
  268. $list->load();
  269. $properties = [];
  270. if (is_array($list->getProperties())) {
  271. foreach ($list->getProperties() as $property) {
  272. $properties[] = $property->getObjectVars();
  273. }
  274. }
  275. return $this->adminJson(['data' => $properties, 'success' => true, 'total' => $list->getTotalCount()]);
  276. }
  277. return $this->adminJson(['success' => false]);
  278. }
  279. /**
  280. * @Route("/get-system", name="pimcore_admin_settings_getsystem", methods={"GET"})
  281. *
  282. * @param Request $request
  283. * @param Config $config
  284. *
  285. * @return JsonResponse
  286. */
  287. public function getSystemAction(Request $request, Config $config)
  288. {
  289. $this->checkPermission('system_settings');
  290. $valueArray = [
  291. 'general' => $config['general'],
  292. 'documents' => $config['documents'],
  293. 'assets' => $config['assets'],
  294. 'objects' => $config['objects'],
  295. 'branding' => $config['branding'],
  296. 'email' => $config['email'],
  297. ];
  298. $locales = Tool::getSupportedLocales();
  299. $languageOptions = [];
  300. $validLanguages = [];
  301. foreach ($locales as $short => $translation) {
  302. if (!empty($short)) {
  303. $languageOptions[] = [
  304. 'language' => $short,
  305. 'display' => $translation . " ($short)",
  306. ];
  307. $validLanguages[] = $short;
  308. }
  309. }
  310. $valueArray['general']['valid_language'] = explode(',', $valueArray['general']['valid_languages']);
  311. //for "wrong" legacy values
  312. if (is_array($valueArray['general']['valid_language'])) {
  313. foreach ($valueArray['general']['valid_language'] as $existingValue) {
  314. if (!in_array($existingValue, $validLanguages)) {
  315. $languageOptions[] = [
  316. 'language' => $existingValue,
  317. 'display' => $existingValue,
  318. ];
  319. }
  320. }
  321. }
  322. $response = [
  323. 'values' => $valueArray,
  324. 'config' => [
  325. 'languages' => $languageOptions,
  326. ],
  327. ];
  328. return $this->adminJson($response);
  329. }
  330. /**
  331. * @Route("/set-system", name="pimcore_admin_settings_setsystem", methods={"PUT"})
  332. *
  333. * @param Request $request
  334. * @param LocaleServiceInterface $localeService
  335. *
  336. * @return JsonResponse
  337. */
  338. public function setSystemAction(Request $request, LocaleServiceInterface $localeService)
  339. {
  340. $this->checkPermission('system_settings');
  341. $values = $this->decodeJson($request->get('data'));
  342. $existingValues = [];
  343. try {
  344. $file = Config::locateConfigFile('system.yml');
  345. $existingValues = Config::getConfigInstance($file, true);
  346. } catch (\Exception $e) {
  347. // nothing to do
  348. }
  349. // localized error pages
  350. $localizedErrorPages = [];
  351. // fallback languages
  352. $fallbackLanguages = [];
  353. $existingValues['pimcore']['general']['fallback_languages'] = [];
  354. $languages = explode(',', $values['general.validLanguages']);
  355. $filteredLanguages = [];
  356. foreach ($languages as $language) {
  357. if (isset($values['general.fallbackLanguages.' . $language])) {
  358. $fallbackLanguages[$language] = str_replace(' ', '', $values['general.fallbackLanguages.' . $language]);
  359. }
  360. // localized error pages
  361. if (isset($values['documents.error_pages.localized.' . $language])) {
  362. $localizedErrorPages[$language] = $values['documents.error_pages.localized.' . $language];
  363. }
  364. if ($localeService->isLocale($language)) {
  365. $filteredLanguages[] = $language;
  366. }
  367. }
  368. // check if there's a fallback language endless loop
  369. foreach ($fallbackLanguages as $sourceLang => $targetLang) {
  370. $this->checkFallbackLanguageLoop($sourceLang, $fallbackLanguages);
  371. }
  372. $settings['pimcore'] = [
  373. 'general' => [
  374. 'domain' => $values['general.domain'],
  375. 'redirect_to_maindomain' => $values['general.redirect_to_maindomain'],
  376. 'language' => $values['general.language'],
  377. 'valid_languages' => implode(',', $filteredLanguages),
  378. 'fallback_languages' => $fallbackLanguages,
  379. 'default_language' => $values['general.defaultLanguage'],
  380. 'debug_admin_translations' => $values['general.debug_admin_translations'],
  381. ],
  382. 'documents' => [
  383. 'versions' => [
  384. 'days' => $values['documents.versions.days'] ?? null,
  385. 'steps' => $values['documents.versions.steps'] ?? null,
  386. ],
  387. 'error_pages' => [
  388. 'default' => $values['documents.error_pages.default'],
  389. 'localized' => $localizedErrorPages,
  390. ],
  391. ],
  392. 'objects' => [
  393. 'versions' => [
  394. 'days' => $values['objects.versions.days'] ?? null,
  395. 'steps' => $values['objects.versions.steps'] ?? null,
  396. ],
  397. ],
  398. 'assets' => [
  399. 'versions' => [
  400. 'days' => $values['assets.versions.days'] ?? null,
  401. 'steps' => $values['assets.versions.steps'] ?? null,
  402. ],
  403. 'hide_edit_image' => $values['assets.hide_edit_image'],
  404. 'disable_tree_preview' => $values['assets.disable_tree_preview'],
  405. ],
  406. ];
  407. //branding
  408. $settings['pimcore_admin'] = [
  409. 'branding' =>
  410. [
  411. 'login_screen_invert_colors' => $values['branding.login_screen_invert_colors'],
  412. 'color_login_screen' => $values['branding.color_login_screen'],
  413. 'color_admin_interface' => $values['branding.color_admin_interface'],
  414. 'login_screen_custom_image' => $values['branding.login_screen_custom_image'],
  415. ],
  416. ];
  417. if (array_key_exists('email.debug.emailAddresses', $values) && $values['email.debug.emailAddresses']) {
  418. $settings['pimcore']['email']['debug']['email_addresses'] = $values['email.debug.emailAddresses'];
  419. }
  420. $settingsYml = Yaml::dump($settings, 5);
  421. $configFile = Config::locateConfigFile('system.yml');
  422. File::put($configFile, $settingsYml);
  423. // clear all caches
  424. $this->forward(self::class . '::clearCacheAction', [
  425. 'only_symfony_cache' => false,
  426. 'only_pimcore_cache' => false,
  427. 'env' => [\Pimcore::getKernel()->getEnvironment()],
  428. ]);
  429. return $this->adminJson(['success' => true]);
  430. }
  431. /**
  432. * @param string $source
  433. * @param array $definitions
  434. * @param array $fallbacks
  435. *
  436. * @throws \Exception
  437. */
  438. protected function checkFallbackLanguageLoop($source, $definitions, $fallbacks = [])
  439. {
  440. if (isset($definitions[$source])) {
  441. $targets = explode(',', $definitions[$source]);
  442. foreach ($targets as $l) {
  443. $target = trim($l);
  444. if ($target) {
  445. if (in_array($target, $fallbacks)) {
  446. throw new \Exception("Language `$source` | `$target` causes an infinte loop.");
  447. }
  448. $fallbacks[] = $target;
  449. $this->checkFallbackLanguageLoop($target, $definitions, $fallbacks);
  450. }
  451. }
  452. } else {
  453. throw new \Exception("Language `$source` doesn't exist");
  454. }
  455. }
  456. /**
  457. * @Route("/get-web2print", name="pimcore_admin_settings_getweb2print", methods={"GET"})
  458. *
  459. * @param Request $request
  460. *
  461. * @return JsonResponse
  462. */
  463. public function getWeb2printAction(Request $request)
  464. {
  465. $this->checkPermission('web2print_settings');
  466. $values = Config::getWeb2PrintConfig();
  467. $valueArray = $values->toArray();
  468. $optionsString = [];
  469. if ($valueArray['wkhtml2pdfOptions']) {
  470. foreach ($valueArray['wkhtml2pdfOptions'] as $key => $value) {
  471. $tmpStr = '--'.$key;
  472. if ($value !== null && $value !== '') {
  473. $tmpStr .= ' '.$value;
  474. }
  475. $optionsString[] = $tmpStr;
  476. }
  477. }
  478. $valueArray['wkhtml2pdfOptions'] = implode("\n", $optionsString);
  479. $response = [
  480. 'values' => $valueArray,
  481. ];
  482. return $this->adminJson($response);
  483. }
  484. /**
  485. * @Route("/set-web2print", name="pimcore_admin_settings_setweb2print", methods={"PUT"})
  486. *
  487. * @param Request $request
  488. *
  489. * @return JsonResponse
  490. */
  491. public function setWeb2printAction(Request $request)
  492. {
  493. $this->checkPermission('web2print_settings');
  494. $values = $this->decodeJson($request->get('data'));
  495. if ($values['wkhtml2pdfOptions']) {
  496. $optionArray = [];
  497. $lines = explode("\n", $values['wkhtml2pdfOptions']);
  498. foreach ($lines as $line) {
  499. $parts = explode(' ', substr($line, 2));
  500. $key = trim($parts[0]);
  501. if ($key) {
  502. $value = trim($parts[1] ?? '');
  503. $optionArray[$key] = $value;
  504. }
  505. }
  506. $values['wkhtml2pdfOptions'] = $optionArray;
  507. }
  508. $configFile = \Pimcore\Config::locateConfigFile('web2print.php');
  509. File::putPhpFile($configFile, to_php_data_file_format($values));
  510. return $this->adminJson(['success' => true]);
  511. }
  512. /**
  513. * @Route("/clear-cache", name="pimcore_admin_settings_clearcache", methods={"DELETE"})
  514. *
  515. * @param Request $request
  516. * @param KernelInterface $kernel
  517. * @param EventDispatcherInterface $eventDispatcher
  518. * @param CoreCacheHandler $cache
  519. * @param Filesystem $filesystem
  520. * @param CacheClearer $symfonyCacheClearer
  521. *
  522. * @return JsonResponse
  523. */
  524. public function clearCacheAction(
  525. Request $request,
  526. KernelInterface $kernel,
  527. EventDispatcherInterface $eventDispatcher,
  528. CoreCacheHandler $cache,
  529. Filesystem $filesystem,
  530. CacheClearer $symfonyCacheClearer
  531. ) {
  532. $this->checkPermissionsHasOneOf(['clear_cache', 'system_settings']);
  533. $result = [
  534. 'success' => true,
  535. ];
  536. $clearPimcoreCache = !(bool)$request->get('only_symfony_cache');
  537. $clearSymfonyCache = !(bool)$request->get('only_pimcore_cache');
  538. if ($clearPimcoreCache) {
  539. // empty document cache
  540. $cache->clearAll();
  541. if ($filesystem->exists(PIMCORE_CACHE_DIRECTORY)) {
  542. $filesystem->remove(PIMCORE_CACHE_DIRECTORY);
  543. }
  544. // PIMCORE-1854 - recreate .dummy file => should remain
  545. File::put(PIMCORE_CACHE_DIRECTORY . '/.gitkeep', '');
  546. $eventDispatcher->dispatch(new GenericEvent(), SystemEvents::CACHE_CLEAR);
  547. }
  548. if ($clearSymfonyCache) {
  549. // pass one or move env parameters to clear multiple envs
  550. // if no env is passed it will use the current one
  551. $environments = $request->get('env', $kernel->getEnvironment());
  552. if (!is_array($environments)) {
  553. $environments = trim((string)$environments);
  554. if (empty($environments)) {
  555. $environments = [];
  556. } else {
  557. $environments = [$environments];
  558. }
  559. }
  560. if (empty($environments)) {
  561. $environments = [$kernel->getEnvironment()];
  562. }
  563. $result['environments'] = $environments;
  564. if (in_array($kernel->getEnvironment(), $environments)) {
  565. // remove terminate and exception event listeners for the current env as they break with a
  566. // cleared container - see #2434
  567. foreach ($eventDispatcher->getListeners(KernelEvents::TERMINATE) as $listener) {
  568. $eventDispatcher->removeListener(KernelEvents::TERMINATE, $listener);
  569. }
  570. foreach ($eventDispatcher->getListeners(KernelEvents::EXCEPTION) as $listener) {
  571. $eventDispatcher->removeListener(KernelEvents::EXCEPTION, $listener);
  572. }
  573. }
  574. foreach ($environments as $environment) {
  575. try {
  576. $symfonyCacheClearer->clear($environment);
  577. } catch (\Throwable $e) {
  578. $errors = $result['errors'] ?? [];
  579. $errors[] = $e->getMessage();
  580. $result = array_merge($result, [
  581. 'success' => false,
  582. 'errors' => $errors,
  583. ]);
  584. }
  585. }
  586. }
  587. $response = new JsonResponse($result);
  588. if ($clearSymfonyCache) {
  589. // we send the response directly here and exit to make sure no code depending on the stale container
  590. // is running after this
  591. $response->sendHeaders();
  592. $response->sendContent();
  593. exit;
  594. }
  595. return $response;
  596. }
  597. /**
  598. * @Route("/clear-output-cache", name="pimcore_admin_settings_clearoutputcache", methods={"DELETE"})
  599. *
  600. * @param EventDispatcherInterface $eventDispatcher
  601. *
  602. * @return JsonResponse
  603. */
  604. public function clearOutputCacheAction(EventDispatcherInterface $eventDispatcher)
  605. {
  606. $this->checkPermission('clear_fullpage_cache');
  607. // remove "output" out of the ignored tags, if a cache lifetime is specified
  608. Cache::removeIgnoredTagOnClear('output');
  609. // empty document cache
  610. Cache::clearTags(['output', 'output_lifetime']);
  611. $eventDispatcher->dispatch(new GenericEvent(), SystemEvents::CACHE_CLEAR_FULLPAGE_CACHE);
  612. return $this->adminJson(['success' => true]);
  613. }
  614. /**
  615. * @Route("/clear-temporary-files", name="pimcore_admin_settings_cleartemporaryfiles", methods={"DELETE"})
  616. *
  617. * @param EventDispatcherInterface $eventDispatcher
  618. *
  619. * @return JsonResponse
  620. */
  621. public function clearTemporaryFilesAction(EventDispatcherInterface $eventDispatcher)
  622. {
  623. $this->checkPermission('clear_temp_files');
  624. // public files
  625. Tool\Storage::get('thumbnail')->deleteDirectory('/');
  626. Tool\Storage::get('asset_cache')->deleteDirectory('/');
  627. // system files
  628. recursiveDelete(PIMCORE_SYSTEM_TEMP_DIRECTORY, false);
  629. $eventDispatcher->dispatch(new GenericEvent(), SystemEvents::CACHE_CLEAR_TEMPORARY_FILES);
  630. return $this->adminJson(['success' => true]);
  631. }
  632. /**
  633. * @Route("/staticroutes", name="pimcore_admin_settings_staticroutes", methods={"POST"})
  634. *
  635. * @param Request $request
  636. *
  637. * @return JsonResponse
  638. */
  639. public function staticroutesAction(Request $request)
  640. {
  641. if ($request->get('data')) {
  642. $this->checkPermission('routes');
  643. $data = $this->decodeJson($request->get('data'));
  644. if (is_array($data)) {
  645. foreach ($data as &$value) {
  646. if (is_string($value)) {
  647. $value = trim($value);
  648. }
  649. }
  650. }
  651. if ($request->get('xaction') == 'destroy') {
  652. $data = $this->decodeJson($request->get('data'));
  653. $id = $data['id'];
  654. $route = Staticroute::getById($id);
  655. $route->delete();
  656. return $this->adminJson(['success' => true, 'data' => []]);
  657. } elseif ($request->get('xaction') == 'update') {
  658. // save routes
  659. $route = Staticroute::getById($data['id']);
  660. $route->setValues($data);
  661. $route->save();
  662. return $this->adminJson(['data' => $route->getObjectVars(), 'success' => true]);
  663. } elseif ($request->get('xaction') == 'create') {
  664. unset($data['id']);
  665. // save route
  666. $route = new Staticroute();
  667. $route->setValues($data);
  668. $route->save();
  669. return $this->adminJson(['data' => $route->getObjectVars(), 'success' => true]);
  670. }
  671. } else {
  672. // get list of routes
  673. $list = new Staticroute\Listing();
  674. if ($request->get('filter')) {
  675. $filter = $request->get('filter');
  676. $list->setFilter(function ($row) use ($filter) {
  677. foreach ($row as $value) {
  678. if (! is_scalar($value)) {
  679. continue;
  680. }
  681. if (strpos((string)$value, $filter) !== false) {
  682. return true;
  683. }
  684. }
  685. return false;
  686. });
  687. }
  688. $list->load();
  689. $routes = [];
  690. /** @var Staticroute $route */
  691. foreach ($list->getRoutes() as $route) {
  692. if (is_array($route->getSiteId())) {
  693. $route = $route->getObjectVars();
  694. $route['siteId'] = implode(',', $route['siteId']);
  695. }
  696. $routes[] = $route;
  697. }
  698. return $this->adminJson(['data' => $routes, 'success' => true, 'total' => $list->getTotalCount()]);
  699. }
  700. return $this->adminJson(['success' => false]);
  701. }
  702. /**
  703. * @Route("/get-available-admin-languages", name="pimcore_admin_settings_getavailableadminlanguages", methods={"GET"})
  704. *
  705. * @param Request $request
  706. *
  707. * @return JsonResponse
  708. */
  709. public function getAvailableAdminLanguagesAction(Request $request)
  710. {
  711. $langs = [];
  712. $availableLanguages = Tool\Admin::getLanguages();
  713. $locales = Tool::getSupportedLocales();
  714. foreach ($availableLanguages as $lang) {
  715. if (array_key_exists($lang, $locales)) {
  716. $langs[] = [
  717. 'language' => $lang,
  718. 'display' => $locales[$lang],
  719. ];
  720. }
  721. }
  722. usort($langs, function ($a, $b) {
  723. return strcmp($a['display'], $b['display']);
  724. });
  725. return $this->adminJson($langs);
  726. }
  727. /**
  728. * @Route("/glossary", name="pimcore_admin_settings_glossary", methods={"POST"})
  729. *
  730. * @param Request $request
  731. *
  732. * @return JsonResponse
  733. */
  734. public function glossaryAction(Request $request)
  735. {
  736. if ($request->get('data')) {
  737. $this->checkPermission('glossary');
  738. Cache::clearTag('glossary');
  739. if ($request->get('xaction') == 'destroy') {
  740. $data = $this->decodeJson($request->get('data'));
  741. $id = $data['id'];
  742. $glossary = Glossary::getById($id);
  743. $glossary->delete();
  744. return $this->adminJson(['success' => true, 'data' => []]);
  745. } elseif ($request->get('xaction') == 'update') {
  746. $data = $this->decodeJson($request->get('data'));
  747. // save glossary
  748. $glossary = Glossary::getById($data['id']);
  749. if (!empty($data['link'])) {
  750. if ($doc = Document::getByPath($data['link'])) {
  751. $data['link'] = $doc->getId();
  752. }
  753. }
  754. $glossary->setValues($data);
  755. $glossary->save();
  756. if ($link = $glossary->getLink()) {
  757. if ((int)$link > 0) {
  758. if ($doc = Document::getById((int)$link)) {
  759. $glossary->setLink($doc->getRealFullPath());
  760. }
  761. }
  762. }
  763. return $this->adminJson(['data' => $glossary, 'success' => true]);
  764. } elseif ($request->get('xaction') == 'create') {
  765. $data = $this->decodeJson($request->get('data'));
  766. unset($data['id']);
  767. // save glossary
  768. $glossary = new Glossary();
  769. if (!empty($data['link'])) {
  770. if ($doc = Document::getByPath($data['link'])) {
  771. $data['link'] = $doc->getId();
  772. }
  773. }
  774. $glossary->setValues($data);
  775. $glossary->save();
  776. if ($link = $glossary->getLink()) {
  777. if ((int)$link > 0) {
  778. if ($doc = Document::getById((int)$link)) {
  779. $glossary->setLink($doc->getRealFullPath());
  780. }
  781. }
  782. }
  783. return $this->adminJson(['data' => $glossary->getObjectVars(), 'success' => true]);
  784. }
  785. } else {
  786. // get list of glossaries
  787. $list = new Glossary\Listing();
  788. $list->setLimit($request->get('limit'));
  789. $list->setOffset($request->get('start'));
  790. $sortingSettings = \Pimcore\Bundle\AdminBundle\Helper\QueryParams::extractSortingSettings(array_merge($request->request->all(), $request->query->all()));
  791. if ($sortingSettings['orderKey']) {
  792. $list->setOrderKey($sortingSettings['orderKey']);
  793. $list->setOrder($sortingSettings['order']);
  794. }
  795. if ($request->get('filter')) {
  796. $list->setCondition('`text` LIKE ' . $list->quote('%'.$request->get('filter').'%'));
  797. }
  798. $list->load();
  799. $glossaries = [];
  800. foreach ($list->getGlossary() as $glossary) {
  801. if ($link = $glossary->getLink()) {
  802. if ((int)$link > 0) {
  803. if ($doc = Document::getById((int)$link)) {
  804. $glossary->setLink($doc->getRealFullPath());
  805. }
  806. }
  807. }
  808. $glossaries[] = $glossary->getObjectVars();
  809. }
  810. return $this->adminJson(['data' => $glossaries, 'success' => true, 'total' => $list->getTotalCount()]);
  811. }
  812. return $this->adminJson(['success' => false]);
  813. }
  814. /**
  815. * @Route("/get-available-sites", name="pimcore_admin_settings_getavailablesites", methods={"GET"})
  816. *
  817. * @param Request $request
  818. *
  819. * @return JsonResponse
  820. */
  821. public function getAvailableSitesAction(Request $request)
  822. {
  823. $excludeMainSite = $request->get('excludeMainSite');
  824. $sitesList = new Model\Site\Listing();
  825. $sitesObjects = $sitesList->load();
  826. $sites = [];
  827. if (!$excludeMainSite) {
  828. $sites[] = [
  829. 'id' => 'default',
  830. 'rootId' => 1,
  831. 'domains' => '',
  832. 'rootPath' => '/',
  833. 'domain' => $this->trans('main_site'),
  834. ];
  835. }
  836. foreach ($sitesObjects as $site) {
  837. if ($site->getRootDocument()) {
  838. if ($site->getMainDomain()) {
  839. $sites[] = [
  840. 'id' => $site->getId(),
  841. 'rootId' => $site->getRootId(),
  842. 'domains' => implode(',', $site->getDomains()),
  843. 'rootPath' => $site->getRootPath(),
  844. 'domain' => $site->getMainDomain(),
  845. ];
  846. }
  847. } else {
  848. // site is useless, parent doesn't exist anymore
  849. $site->delete();
  850. }
  851. }
  852. return $this->adminJson($sites);
  853. }
  854. /**
  855. * @Route("/get-available-countries", name="pimcore_admin_settings_getavailablecountries", methods={"GET"})
  856. *
  857. * @param LocaleServiceInterface $localeService
  858. *
  859. * @return JsonResponse
  860. */
  861. public function getAvailableCountriesAction(LocaleServiceInterface $localeService)
  862. {
  863. $countries = $localeService->getDisplayRegions();
  864. asort($countries);
  865. $options = [];
  866. foreach ($countries as $short => $translation) {
  867. if (strlen($short) == 2) {
  868. $options[] = [
  869. 'key' => $translation . ' (' . $short . ')',
  870. 'value' => $short,
  871. ];
  872. }
  873. }
  874. $result = ['data' => $options, 'success' => true, 'total' => count($options)];
  875. return $this->adminJson($result);
  876. }
  877. /**
  878. * @Route("/thumbnail-adapter-check", name="pimcore_admin_settings_thumbnailadaptercheck", methods={"GET"})
  879. *
  880. * @param Request $request
  881. *
  882. * @return Response
  883. */
  884. public function thumbnailAdapterCheckAction(Request $request)
  885. {
  886. $content = '';
  887. $instance = \Pimcore\Image::getInstance();
  888. if ($instance instanceof \Pimcore\Image\Adapter\GD) {
  889. $content = '<span style="color: red; font-weight: bold;padding: 10px;margin:0 0 20px 0;border:1px solid red;display:block;">' .
  890. $this->trans('important_use_imagick_pecl_extensions_for_best_results_gd_is_just_a_fallback_with_less_quality') .
  891. '</span>';
  892. }
  893. return new Response($content);
  894. }
  895. /**
  896. * @Route("/thumbnail-tree", name="pimcore_admin_settings_thumbnailtree", methods={"GET", "POST"})
  897. *
  898. * @param Request $request
  899. *
  900. * @return JsonResponse
  901. */
  902. public function thumbnailTreeAction(Request $request)
  903. {
  904. $this->checkPermission('thumbnails');
  905. $thumbnails = [];
  906. $list = new Asset\Image\Thumbnail\Config\Listing();
  907. $items = $list->getThumbnails();
  908. $groups = [];
  909. /** @var Asset\Image\Thumbnail\Config $item */
  910. foreach ($items as $item) {
  911. if ($item->getGroup()) {
  912. if (empty($groups[$item->getGroup()])) {
  913. $groups[$item->getGroup()] = [
  914. 'id' => 'group_' . $item->getName(),
  915. 'text' => $item->getGroup(),
  916. 'expandable' => true,
  917. 'leaf' => false,
  918. 'allowChildren' => true,
  919. 'iconCls' => 'pimcore_icon_folder',
  920. 'group' => $item->getGroup(),
  921. 'children' => [],
  922. ];
  923. }
  924. $groups[$item->getGroup()]['children'][] =
  925. [
  926. 'id' => $item->getName(),
  927. 'text' => $item->getName(),
  928. 'leaf' => true,
  929. 'iconCls' => 'pimcore_icon_thumbnails',
  930. ];
  931. } else {
  932. $thumbnails[] = [
  933. 'id' => $item->getName(),
  934. 'text' => $item->getName(),
  935. 'leaf' => true,
  936. 'iconCls' => 'pimcore_icon_thumbnails',
  937. ];
  938. }
  939. }
  940. foreach ($groups as $group) {
  941. $thumbnails[] = $group;
  942. }
  943. return $this->adminJson($thumbnails);
  944. }
  945. /**
  946. * @Route("/thumbnail-downloadable", name="pimcore_admin_settings_thumbnaildownloadable", methods={"GET"})
  947. *
  948. * @param Request $request
  949. *
  950. * @return JsonResponse
  951. */
  952. public function thumbnailDownloadableAction(Request $request)
  953. {
  954. $thumbnails = [];
  955. $list = new Asset\Image\Thumbnail\Config\Listing();
  956. $list->setFilter(function (array $config) {
  957. return array_key_exists('downloadable', $config) ? $config['downloadable'] : false;
  958. });
  959. $items = $list->getThumbnails();
  960. /** @var Asset\Image\Thumbnail\Config $item */
  961. foreach ($items as $item) {
  962. $thumbnails[] = [
  963. 'id' => $item->getName(),
  964. 'text' => $item->getName(),
  965. ];
  966. }
  967. return $this->adminJson($thumbnails);
  968. }
  969. /**
  970. * @Route("/thumbnail-add", name="pimcore_admin_settings_thumbnailadd", methods={"POST"})
  971. *
  972. * @param Request $request
  973. *
  974. * @return JsonResponse
  975. */
  976. public function thumbnailAddAction(Request $request)
  977. {
  978. $this->checkPermission('thumbnails');
  979. $success = false;
  980. $pipe = Asset\Image\Thumbnail\Config::getByName($request->get('name'));
  981. if (!$pipe) {
  982. $pipe = new Asset\Image\Thumbnail\Config();
  983. $pipe->setName($request->get('name'));
  984. $pipe->save();
  985. $success = true;
  986. }
  987. return $this->adminJson(['success' => $success, 'id' => $pipe->getName()]);
  988. }
  989. /**
  990. * @Route("/thumbnail-delete", name="pimcore_admin_settings_thumbnaildelete", methods={"DELETE"})
  991. *
  992. * @param Request $request
  993. *
  994. * @return JsonResponse
  995. */
  996. public function thumbnailDeleteAction(Request $request)
  997. {
  998. $this->checkPermission('thumbnails');
  999. $pipe = Asset\Image\Thumbnail\Config::getByName($request->get('name'));
  1000. $pipe->delete();
  1001. return $this->adminJson(['success' => true]);
  1002. }
  1003. /**
  1004. * @Route("/thumbnail-get", name="pimcore_admin_settings_thumbnailget", methods={"GET"})
  1005. *
  1006. * @param Request $request
  1007. *
  1008. * @return JsonResponse
  1009. */
  1010. public function thumbnailGetAction(Request $request)
  1011. {
  1012. $this->checkPermission('thumbnails');
  1013. $pipe = Asset\Image\Thumbnail\Config::getByName($request->get('name'));
  1014. return $this->adminJson($pipe->getObjectVars());
  1015. }
  1016. /**
  1017. * @Route("/thumbnail-update", name="pimcore_admin_settings_thumbnailupdate", methods={"PUT"})
  1018. *
  1019. * @param Request $request
  1020. *
  1021. * @return JsonResponse
  1022. */
  1023. public function thumbnailUpdateAction(Request $request)
  1024. {
  1025. $this->checkPermission('thumbnails');
  1026. $pipe = Asset\Image\Thumbnail\Config::getByName($request->get('name'));
  1027. $settingsData = $this->decodeJson($request->get('settings'));
  1028. $mediaData = $this->decodeJson($request->get('medias'));
  1029. $mediaOrder = $this->decodeJson($request->get('mediaOrder'));
  1030. foreach ($settingsData as $key => $value) {
  1031. $setter = 'set' . ucfirst($key);
  1032. if (method_exists($pipe, $setter)) {
  1033. $pipe->$setter($value);
  1034. }
  1035. }
  1036. $pipe->resetItems();
  1037. uksort($mediaData, function ($a, $b) use ($mediaOrder) {
  1038. if ($a === 'default') {
  1039. return -1;
  1040. }
  1041. return ($mediaOrder[$a] < $mediaOrder[$b]) ? -1 : 1;
  1042. });
  1043. foreach ($mediaData as $mediaName => $items) {
  1044. foreach ($items as $item) {
  1045. $type = $item['type'];
  1046. unset($item['type']);
  1047. $pipe->addItem($type, $item, $mediaName);
  1048. }
  1049. }
  1050. $pipe->save();
  1051. return $this->adminJson(['success' => true]);
  1052. }
  1053. /**
  1054. * @Route("/video-thumbnail-adapter-check", name="pimcore_admin_settings_videothumbnailadaptercheck", methods={"GET"})
  1055. *
  1056. * @param Request $request
  1057. *
  1058. * @return Response
  1059. */
  1060. public function videoThumbnailAdapterCheckAction(Request $request)
  1061. {
  1062. $content = '';
  1063. if (!\Pimcore\Video::isAvailable()) {
  1064. $content = '<span style="color: red; font-weight: bold;padding: 10px;margin:0 0 20px 0;border:1px solid red;display:block;">' .
  1065. $this->trans('php_cli_binary_and_or_ffmpeg_binary_setting_is_missing') .
  1066. '</span>';
  1067. }
  1068. return new Response($content);
  1069. }
  1070. /**
  1071. * @Route("/video-thumbnail-tree", name="pimcore_admin_settings_videothumbnailtree", methods={"GET", "POST"})
  1072. *
  1073. * @param Request $request
  1074. *
  1075. * @return JsonResponse
  1076. */
  1077. public function videoThumbnailTreeAction(Request $request)
  1078. {
  1079. $this->checkPermission('thumbnails');
  1080. $thumbnails = [];
  1081. $list = new Asset\Video\Thumbnail\Config\Listing();
  1082. $items = $list->getThumbnails();
  1083. $groups = [];
  1084. /** @var Asset\Image\Thumbnail\Config $item */
  1085. foreach ($items as $item) {
  1086. if ($item->getGroup()) {
  1087. if (!$groups[$item->getGroup()]) {
  1088. $groups[$item->getGroup()] = [
  1089. 'id' => 'group_' . $item->getName(),
  1090. 'text' => $item->getGroup(),
  1091. 'expandable' => true,
  1092. 'leaf' => false,
  1093. 'allowChildren' => true,
  1094. 'iconCls' => 'pimcore_icon_folder',
  1095. 'group' => $item->getGroup(),
  1096. 'children' => [],
  1097. ];
  1098. }
  1099. $groups[$item->getGroup()]['children'][] =
  1100. [
  1101. 'id' => $item->getName(),
  1102. 'text' => $item->getName(),
  1103. 'leaf' => true,
  1104. 'iconCls' => 'pimcore_icon_videothumbnails',
  1105. ];
  1106. } else {
  1107. $thumbnails[] = [
  1108. 'id' => $item->getName(),
  1109. 'text' => $item->getName(),
  1110. 'leaf' => true,
  1111. 'iconCls' => 'pimcore_icon_videothumbnails',
  1112. ];
  1113. }
  1114. }
  1115. foreach ($groups as $group) {
  1116. $thumbnails[] = $group;
  1117. }
  1118. return $this->adminJson($thumbnails);
  1119. }
  1120. /**
  1121. * @Route("/video-thumbnail-add", name="pimcore_admin_settings_videothumbnailadd", methods={"POST"})
  1122. *
  1123. * @param Request $request
  1124. *
  1125. * @return JsonResponse
  1126. */
  1127. public function videoThumbnailAddAction(Request $request)
  1128. {
  1129. $this->checkPermission('thumbnails');
  1130. $success = false;
  1131. $pipe = Asset\Video\Thumbnail\Config::getByName($request->get('name'));
  1132. if (!$pipe) {
  1133. $pipe = new Asset\Video\Thumbnail\Config();
  1134. $pipe->setName($request->get('name'));
  1135. $pipe->save();
  1136. $success = true;
  1137. }
  1138. return $this->adminJson(['success' => $success, 'id' => $pipe->getName()]);
  1139. }
  1140. /**
  1141. * @Route("/video-thumbnail-delete", name="pimcore_admin_settings_videothumbnaildelete", methods={"DELETE"})
  1142. *
  1143. * @param Request $request
  1144. *
  1145. * @return JsonResponse
  1146. */
  1147. public function videoThumbnailDeleteAction(Request $request)
  1148. {
  1149. $this->checkPermission('thumbnails');
  1150. $pipe = Asset\Video\Thumbnail\Config::getByName($request->get('name'));
  1151. $pipe->delete();
  1152. return $this->adminJson(['success' => true]);
  1153. }
  1154. /**
  1155. * @Route("/video-thumbnail-get", name="pimcore_admin_settings_videothumbnailget", methods={"GET"})
  1156. *
  1157. * @param Request $request
  1158. *
  1159. * @return JsonResponse
  1160. */
  1161. public function videoThumbnailGetAction(Request $request)
  1162. {
  1163. $this->checkPermission('thumbnails');
  1164. $pipe = Asset\Video\Thumbnail\Config::getByName($request->get('name'));
  1165. return $this->adminJson($pipe->getObjectVars());
  1166. }
  1167. /**
  1168. * @Route("/video-thumbnail-update", name="pimcore_admin_settings_videothumbnailupdate", methods={"PUT"})
  1169. *
  1170. * @param Request $request
  1171. *
  1172. * @return JsonResponse
  1173. */
  1174. public function videoThumbnailUpdateAction(Request $request)
  1175. {
  1176. $this->checkPermission('thumbnails');
  1177. $pipe = Asset\Video\Thumbnail\Config::getByName($request->get('name'));
  1178. $settingsData = $this->decodeJson($request->get('settings'));
  1179. $mediaData = $this->decodeJson($request->get('medias'));
  1180. $mediaOrder = $this->decodeJson($request->get('mediaOrder'));
  1181. foreach ($settingsData as $key => $value) {
  1182. $setter = 'set' . ucfirst($key);
  1183. if (method_exists($pipe, $setter)) {
  1184. $pipe->$setter($value);
  1185. }
  1186. }
  1187. $pipe->resetItems();
  1188. uksort($mediaData, function ($a, $b) use ($mediaOrder) {
  1189. if ($a === 'default') {
  1190. return -1;
  1191. }
  1192. return ($mediaOrder[$a] < $mediaOrder[$b]) ? -1 : 1;
  1193. });
  1194. foreach ($mediaData as $mediaName => $items) {
  1195. foreach ($items as $item) {
  1196. $type = $item['type'];
  1197. unset($item['type']);
  1198. $pipe->addItem($type, $item, $mediaName);
  1199. }
  1200. }
  1201. $pipe->save();
  1202. return $this->adminJson(['success' => true]);
  1203. }
  1204. /**
  1205. * @Route("/robots-txt", name="pimcore_admin_settings_robotstxtget", methods={"GET"})
  1206. *
  1207. * @return JsonResponse
  1208. */
  1209. public function robotsTxtGetAction()
  1210. {
  1211. $this->checkPermission('robots.txt');
  1212. $config = Config::getRobotsConfig();
  1213. $config = $config->toArray();
  1214. return $this->adminJson([
  1215. 'success' => true,
  1216. 'data' => $config,
  1217. 'onFileSystem' => file_exists(PIMCORE_WEB_ROOT . '/robots.txt'),
  1218. ]);
  1219. }
  1220. /**
  1221. * @Route("/robots-txt", name="pimcore_admin_settings_robotstxtput", methods={"PUT"})
  1222. *
  1223. * @param Request $request
  1224. *
  1225. * @return JsonResponse
  1226. */
  1227. public function robotsTxtPutAction(Request $request)
  1228. {
  1229. $this->checkPermission('robots.txt');
  1230. $values = $request->get('data');
  1231. if (!is_array($values)) {
  1232. $values = [];
  1233. }
  1234. foreach ($values as $siteId => $robotsContent) {
  1235. SettingsStore::set('robots.txt-' . $siteId, $robotsContent, 'string', 'robots.txt');
  1236. }
  1237. return $this->adminJson([
  1238. 'success' => true,
  1239. ]);
  1240. }
  1241. /**
  1242. * @Route("/website-settings", name="pimcore_admin_settings_websitesettings", methods={"POST"})
  1243. *
  1244. * @param Request $request
  1245. *
  1246. * @return JsonResponse
  1247. *
  1248. * @throws \Exception
  1249. */
  1250. public function websiteSettingsAction(Request $request)
  1251. {
  1252. $this->checkPermission('website_settings');
  1253. if ($request->get('data')) {
  1254. $data = $this->decodeJson($request->get('data'));
  1255. if (is_array($data)) {
  1256. foreach ($data as &$value) {
  1257. $value = trim($value);
  1258. }
  1259. }
  1260. if ($request->get('xaction') == 'destroy') {
  1261. $id = $data['id'];
  1262. $setting = WebsiteSetting::getById($id);
  1263. if ($setting instanceof WebsiteSetting) {
  1264. $setting->delete();
  1265. return $this->adminJson(['success' => true, 'data' => []]);
  1266. }
  1267. } elseif ($request->get('xaction') == 'update') {
  1268. // save routes
  1269. $setting = WebsiteSetting::getById($data['id']);
  1270. if ($setting instanceof WebsiteSetting) {
  1271. switch ($setting->getType()) {
  1272. case 'document':
  1273. case 'asset':
  1274. case 'object':
  1275. if (isset($data['data'])) {
  1276. $element = Element\Service::getElementByPath($setting->getType(), $data['data']);
  1277. $data['data'] = $element;
  1278. }
  1279. break;
  1280. }
  1281. $setting->setValues($data);
  1282. $setting->save();
  1283. $data = $this->getWebsiteSettingForEditMode($setting);
  1284. return $this->adminJson(['data' => $data, 'success' => true]);
  1285. }
  1286. } elseif ($request->get('xaction') == 'create') {
  1287. unset($data['id']);
  1288. // save route
  1289. $setting = new WebsiteSetting();
  1290. $setting->setValues($data);
  1291. $setting->save();
  1292. return $this->adminJson(['data' => $setting->getObjectVars(), 'success' => true]);
  1293. }
  1294. } else {
  1295. $list = new WebsiteSetting\Listing();
  1296. $list->setLimit($request->get('limit'));
  1297. $list->setOffset($request->get('start'));
  1298. $sortingSettings = \Pimcore\Bundle\AdminBundle\Helper\QueryParams::extractSortingSettings(array_merge($request->request->all(), $request->query->all()));
  1299. if ($sortingSettings['orderKey']) {
  1300. $list->setOrderKey($sortingSettings['orderKey']);
  1301. $list->setOrder($sortingSettings['order']);
  1302. } else {
  1303. $list->setOrderKey('name');
  1304. $list->setOrder('asc');
  1305. }
  1306. if ($request->get('filter')) {
  1307. $list->setCondition('`name` LIKE ' . $list->quote('%'.$request->get('filter').'%'));
  1308. }
  1309. $totalCount = $list->getTotalCount();
  1310. $list = $list->load();
  1311. $settings = [];
  1312. foreach ($list as $item) {
  1313. $resultItem = $this->getWebsiteSettingForEditMode($item);
  1314. $settings[] = $resultItem;
  1315. }
  1316. return $this->adminJson(['data' => $settings, 'success' => true, 'total' => $totalCount]);
  1317. }
  1318. return $this->adminJson(['success' => false]);
  1319. }
  1320. /**
  1321. * @param WebsiteSetting $item
  1322. *
  1323. * @return array
  1324. */
  1325. private function getWebsiteSettingForEditMode($item)
  1326. {
  1327. $resultItem = [
  1328. 'id' => $item->getId(),
  1329. 'name' => $item->getName(),
  1330. 'language' => $item->getLanguage(),
  1331. 'type' => $item->getType(),
  1332. 'data' => null,
  1333. 'siteId' => $item->getSiteId(),
  1334. 'creationDate' => $item->getCreationDate(),
  1335. 'modificationDate' => $item->getModificationDate(),
  1336. ];
  1337. switch ($item->getType()) {
  1338. case 'document':
  1339. case 'asset':
  1340. case 'object':
  1341. $element = $item->getData();
  1342. if ($element) {
  1343. $resultItem['data'] = $element->getRealFullPath();
  1344. }
  1345. break;
  1346. default:
  1347. $resultItem['data'] = $item->getData();
  1348. break;
  1349. }
  1350. return $resultItem;
  1351. }
  1352. /**
  1353. * @Route("/get-available-algorithms", name="pimcore_admin_settings_getavailablealgorithms", methods={"GET"})
  1354. *
  1355. * @param Request $request
  1356. *
  1357. * @return JsonResponse
  1358. */
  1359. public function getAvailableAlgorithmsAction(Request $request)
  1360. {
  1361. $options = [
  1362. [
  1363. 'key' => 'password_hash',
  1364. 'value' => 'password_hash',
  1365. ],
  1366. ];
  1367. $algorithms = hash_algos();
  1368. foreach ($algorithms as $algorithm) {
  1369. $options[] = [
  1370. 'key' => $algorithm,
  1371. 'value' => $algorithm,
  1372. ];
  1373. }
  1374. $result = ['data' => $options, 'success' => true, 'total' => count($options)];
  1375. return $this->adminJson($result);
  1376. }
  1377. /**
  1378. * deleteViews
  1379. * delete views for localized fields when languages are removed to
  1380. * prevent mysql errors
  1381. *
  1382. * @param string $language
  1383. * @param string $dbName
  1384. */
  1385. protected function deleteViews($language, $dbName)
  1386. {
  1387. $db = \Pimcore\Db::get();
  1388. $views = $db->fetchAll('SHOW FULL TABLES IN ' . $db->quoteIdentifier($dbName) . " WHERE TABLE_TYPE LIKE 'VIEW'");
  1389. foreach ($views as $view) {
  1390. if (preg_match('/^object_localized_[0-9]+_' . $language . '$/', $view['Tables_in_' . $dbName])) {
  1391. $sql = 'DROP VIEW ' . $db->quoteIdentifier($view['Tables_in_' . $dbName]);
  1392. $db->query($sql);
  1393. }
  1394. }
  1395. }
  1396. /**
  1397. * @Route("/test-web2print", name="pimcore_admin_settings_testweb2print", methods={"GET"})
  1398. *
  1399. * @param Request $request
  1400. *
  1401. * @return Response
  1402. */
  1403. public function testWeb2printAction(Request $request)
  1404. {
  1405. $this->checkPermission('web2print_settings');
  1406. $response = $this->render('@PimcoreAdmin/Admin/Settings/testWeb2print.html.twig');
  1407. $html = $response->getContent();
  1408. $adapter = \Pimcore\Web2Print\Processor::getInstance();
  1409. $params = [];
  1410. if ($adapter instanceof \Pimcore\Web2Print\Processor\WkHtmlToPdf) {
  1411. $params['adapterConfig'] = '-O landscape';
  1412. } elseif ($adapter instanceof \Pimcore\Web2Print\Processor\PdfReactor) {
  1413. $params['adapterConfig'] = [
  1414. 'javaScriptMode' => 0,
  1415. 'addLinks' => true,
  1416. 'appendLog' => true,
  1417. 'enableDebugMode' => true,
  1418. ];
  1419. }
  1420. $responseOptions = [
  1421. 'Content-Type' => 'application/pdf',
  1422. ];
  1423. $pdfData = $adapter->getPdfFromString($html, $params);
  1424. return new \Symfony\Component\HttpFoundation\Response(
  1425. $pdfData,
  1426. 200,
  1427. $responseOptions
  1428. );
  1429. }
  1430. }