/**
  * @todo: rewrite function doc
  * @param string $cacheToken The token of the cache file to get the current state of the duplication.
  * @param string $index      The index of the process which will be executed (e.g. "pagesDuplication" or "treeUidAssociation").
  * @param bool   $checkAjax  If true, will call the function "checkAjaxCall" of the current process class.
  * @return    array The result of the function, may contain these keys :
  *                           - "success":      "False" if error(s) occurred, "true" otherwise.
  *                           - "result":       The result of the execution function. Contains useful data for further duplication process steps.
  *                           - "errorMessage": If error(s) occurred, will contain an error message. If the current user is admin, it will get a detailed message.
  */
 private function processDuplication($cacheToken, $index, $checkAjax = false)
 {
     // Getting configuration in cache file.
     $cache = CacheManager::getCacheInstance(CacheManager::CACHE_PROCESSED);
     $cacheData = $cache->get($cacheToken);
     $cacheData = json_decode($cacheData, true);
     /** @var Result $result */
     $result = $this->objectManager->get(Result::class);
     try {
         if (isset($cacheData['duplicationData']['modelPageUid']) && MathUtility::canBeInterpretedAsInteger($cacheData['duplicationData']['modelPageUid']) && $cacheData['duplicationData']['modelPageUid'] > 0) {
             $duplicationConfiguration = AbstractDuplicationProcess::getCleanedDuplicationConfiguration($cacheData['duplicationData']['modelPageUid']);
             if (isset($duplicationConfiguration[$index])) {
                 if (isset($duplicationConfiguration[$index]['class'])) {
                     $class = $duplicationConfiguration[$index]['class'];
                     $settings = array_key_exists('settings', $duplicationConfiguration[$index]) ? is_array($duplicationConfiguration[$index]['settings']) ? $duplicationConfiguration[$index]['settings'] : [] : [];
                     // Calling the function of the current process step.
                     /** @var AbstractDuplicationProcess $class */
                     $class = GeneralUtility::makeInstance($class, $cacheData['duplicationData'], $settings, $cacheData['fieldsValues']);
                     if ($class instanceof AbstractDuplicationProcess) {
                         // @todo : else
                         //                            if (!$checkAjax || ($checkAjax && $class->checkAjaxCall())) {
                         $class->run();
                         $fieldsValues = $class->getFieldsValues();
                         $result->merge($class->getResult());
                         // Saving modified data in cache.
                         $configuration = ['duplicationData' => $class->getDuplicationData(), 'fieldsValues' => $fieldsValues];
                         $cache->set($cacheToken, json_encode($configuration));
                         //                            }
                     } else {
                         throw new \Exception('The class "' . $class . '" must extend "' . AbstractDuplicationProcess::class . '".', 1422887215);
                     }
                 } else {
                     throw new \Exception('The class is not set for the duplication configuration named "' . $index . '".', 1422885526);
                 }
             } else {
                 throw new \Exception('Trying to get the duplication configuration named "' . $index . '" but it does not exist.', 1422885438);
             }
         } else {
             throw new \Exception('The duplication data must contain a valid index for "modelPageUid".', 1422885697);
         }
     } catch (\Exception $exception) {
         /** @var BackendUserAuthentication $backendUser */
         $backendUser = $GLOBALS['BE_USER'];
         // Setting up error message. If the user is admin, it gets a detailed message.
         if ($backendUser->isAdmin()) {
             $errorMessage = Core::translate('duplication_process.process_error_detailed') . ' ' . $exception->getMessage();
         } else {
             $errorMessage = Core::translate('duplication_process.process_error_single');
         }
         $result->addError(new Error($errorMessage, 1431985617));
     }
     return Core::convertValidationResultToArray($result);
 }
 /**
  * Returns the TypoScript configuration value at a the given path.
  * Example: config.tx_myext.some_conf
  *
  * @param    string        $path      The path to the configuration value.
  * @param    int|null|bool $pageUid   The uid of the page you want the TypoScript configuration from. If "null" is given, only the static configuration is returned.
  * @param    string        $delimiter The delimiter for the path. Default is ".".
  * @return    mixed|null
  */
 public static function getConfigurationFromPath($path, $pageUid = null, $delimiter = '.')
 {
     $result = null;
     $cacheIdentifier = md5($path . (string) $pageUid);
     $cacheInstance = CacheManager::getCacheInstance(CacheManager::CACHE_MAIN);
     if ($cacheInstance) {
         if ($cacheInstance->has($cacheIdentifier)) {
             $result = $cacheInstance->get($cacheIdentifier);
         } elseif (ArrayUtility::isValidPath(self::getTypoScriptConfiguration($pageUid), $path, $delimiter)) {
             $result = ArrayUtility::getValueByPath(self::getTypoScriptConfiguration($pageUid), $path, $delimiter);
             $cacheInstance->set($cacheIdentifier, $result);
         }
     }
     return $result;
 }
 /**
  * This action is called when a form has been submitted to create a new
  * site.
  *
  * It will get all the information needed to duplicate the model site, and
  * further: management of uploaded files, constants management, etc.
  */
 public function processCopyAction()
 {
     $cacheToken = $this->request->getArgument('duplicationToken');
     $cache = CacheManager::getCacheInstance(CacheManager::CACHE_PROCESSED);
     $cacheData = $cache->get($cacheToken);
     // @todo: manage wrong token or wrong cacheData
     $cacheData = json_decode($cacheData, true);
     // Check if the process is a modification of an already duplicated site.
     $modifySite = null;
     if ($this->request->hasArgument('modifySite') && Core::checkUidIsSavedSite($this->request->getArgument('modifySite'))) {
         $modifySite = $this->request->getArgument('modifySite');
         $cacheData['duplicationData']['modelPageUid'] = $cacheData['fieldsValues']['modelSite'];
         $cacheData['duplicationData']['modifySite'] = $modifySite;
         $cacheData['duplicationData']['duplicatedPageUid'] = $modifySite;
         /** @var Save $savedSite */
         $savedSite = $this->saveRepository->findLastByRootPageUid($modifySite);
         $cacheData['savedSite'] = $savedSite->getConfiguration();
     } else {
         $cacheData['duplicationData']['modelPageUid'] = $cacheData['fieldsValues']['modelSite'];
         $cacheData['duplicationData']['copyDestination'] = Core::getExtensionConfiguration('copyDestination');
     }
     // Saving modified data in cache.
     $cache->set($cacheToken, json_encode($cacheData));
     $this->view->assign('duplicationToken', $cacheToken);
     $siteModificationToken = $modifySite ? true : false;
     $duplicationConfiguration = AbstractDuplicationProcess::getCleanedDuplicationConfiguration($cacheData['duplicationData']['modelPageUid'], $siteModificationToken);
     $this->view->assign('duplicationConfiguration', $duplicationConfiguration);
     $this->view->assign('duplicationConfigurationJSON', addslashes(json_encode(array_keys($duplicationConfiguration))));
 }