Main API Service for interacting with Flux-based FlexForms
Inheritance: implements TYPO3\CMS\Core\SingletonInterface
Esempio n. 1
0
 /**
  * @param string $headerContent
  * @param string $itemContent
  * @param array $row
  * @param boolean $drawItem
  * @return NULL
  */
 public function renderPreview(&$headerContent, &$itemContent, array &$row, &$drawItem)
 {
     $fieldName = NULL;
     // every provider for tt_content will be asked to get a preview
     if ('shortcut' === $row['CType'] && FALSE === strpos($row['records'], ',')) {
         $itemContent = $this->createShortcutIcon($row) . $itemContent;
     } else {
         $itemContent = '<a name="c' . $row['uid'] . '"></a>' . $itemContent;
     }
     $providers = $this->configurationService->resolveConfigurationProviders('tt_content', $fieldName, $row);
     foreach ($providers as $provider) {
         /** @var ProviderInterface $provider */
         list($previewHeader, $previewContent, $continueDrawing) = $provider->getPreview($row);
         if (FALSE === empty($previewHeader)) {
             $headerContent = $previewHeader . (FALSE === empty($headerContent) ? ': ' . $headerContent : '');
             $drawItem = FALSE;
         }
         if (FALSE === empty($previewContent)) {
             $itemContent .= $previewContent;
             $drawItem = FALSE;
         }
         if (FALSE === $continueDrawing) {
             break;
         }
     }
     $this->attachAssets();
     return NULL;
 }
 /**
  * @return string
  */
 public function indexAction()
 {
     $this->view->assign('grid', $this->grid);
     $this->view->assign('row', $this->row);
     $paths = $this->configurationService->getViewConfigurationForExtensionName('flux');
     $templateRootPath = TRUE === isset($paths['templateRootPath']) ? $paths['templateRootPath'] : NULL;
     $templatePathAndFilename = ResolveUtility::resolveWidgetTemplateFileBasedOnTemplateRootPathAndEnvironment($templateRootPath);
     $this->view->setTemplatePathAndFilename($templatePathAndFilename);
 }
 /**
  * Hook for generating dynamic FlexForm source code
  *
  * @param array $dataStructArray
  * @param array $conf
  * @param array $row
  * @param string $table
  * @param string $fieldName
  * @return void
  */
 public function getFlexFormDS_postProcessDS(&$dataStructArray, $conf, &$row, $table, $fieldName)
 {
     if (empty($fieldName) === TRUE) {
         // Cast NULL if an empty but not-NULL field name was passed. This has significance to the Flux internals in
         // respect to which ConfigurationProvider(s) are returned.
         $fieldName = NULL;
     }
     $providers = $this->configurationService->resolveConfigurationProviders($table, $fieldName, $row);
     foreach ($providers as $provider) {
         $provider->postProcessDataStructure($row, $dataStructArray, $conf);
     }
 }
Esempio n. 4
0
 /**
  * @param string $sectionName
  * @param string $formName
  * @return Form|NULL
  */
 public function getForm($sectionName = 'Configuration', $formName = 'form')
 {
     /** @var Form $form */
     $form = $this->getStoredVariable(AbstractFormViewHelper::SCOPE, $formName, $sectionName);
     if (NULL !== $form && TRUE === isset($this->templatePathAndFilename)) {
         $form->setOption(Form::OPTION_TEMPLATEFILE, $this->templatePathAndFilename);
         $signature = ExtensionNamingUtility::getExtensionSignature($this->controllerContext->getRequest()->getControllerExtensionName());
         $overrides = (array) $this->configurationService->getTypoScriptByPath('plugin.tx_' . $signature . '.forms.' . $form->getName());
         $form->modify($overrides);
     }
     return $form;
 }
 /**
  * @param integer $pageUid
  * @param integer $columnPosition
  * @param integer $relativeUid
  * @return array
  */
 protected function getWhiteAndBlackListsFromPageAndContentColumn($pageUid, $columnPosition, $relativeUid)
 {
     $whitelist = array();
     $blacklist = array();
     // if a Provider is registered for the "pages" table, try to get a Grid from it. If the Grid
     // returned contains a Column which matches the desired colPos value, attempt to read a list
     // of allowed/denied content element types from it.
     $pageRecord = (array) $this->recordService->getSingle('pages', '*', $pageUid);
     $pageProviders = $this->configurationService->resolveConfigurationProviders('pages', NULL, $pageRecord);
     $this->appendToWhiteAndBlacklistFromProviders($pageProviders, $pageRecord, $whitelist, $blacklist, $columnPosition);
     // Detect what was clicked in order to create the new content element; decide restrictions
     // based on this. Returned parent UID and area name is either non-zero and string, or zero
     // and NULL when record is NOT inserted as child.
     list($parentRecordUid, $fluxAreaName) = $this->getAreaNameAndParentFromRelativeRecordOrDefaults($relativeUid);
     // if these variables now indicate that we are inserting content elements into a Flux-enabled content
     // area inside another content element, attempt to read allowed/denied content types from the
     // Grid returned by the Provider that applies to the parent element's type and configuration
     // (admitted, that's quite a mouthful - but it's not that different from reading the values from
     // a page template like above; it's the same principle).
     if (0 < $parentRecordUid && FALSE === empty($fluxAreaName)) {
         $parentRecord = (array) $this->recordService->getSingle('tt_content', '*', $parentRecordUid);
         $contentProviders = $this->configurationService->resolveConfigurationProviders('tt_content', NULL, $parentRecord);
         $this->appendToWhiteAndBlacklistFromProviders($contentProviders, $parentRecord, $whitelist, $blacklist, NULL, $fluxAreaName);
     }
     // White/blacklist filtering. If whitelist contains elements, filter the list
     // of possible types by whitelist first. Then apply the blacklist, removing
     // any element types recorded herein.
     $whitelist = array_unique($whitelist);
     $blacklist = array_unique($blacklist);
     return array($whitelist, $blacklist);
 }
Esempio n. 6
0
 /**
  * @param ProviderInterface $provider
  * @param array $row
  * @param Form $form
  * @return string|NULL
  */
 protected function renderPreviewSection(ProviderInterface $provider, array $row, Form $form = NULL)
 {
     $templatePathAndFilename = $provider->getTemplatePathAndFilename($row);
     if (NULL === $templatePathAndFilename) {
         return NULL;
     }
     $extensionKey = $provider->getExtensionKey($row);
     $paths = $provider->getTemplatePaths($row);
     $flexformVariables = $provider->getFlexFormValues($row);
     $templateVariables = $provider->getTemplateVariables($row);
     $variables = RecursiveArrayUtility::merge($templateVariables, $flexformVariables);
     $variables['row'] = $row;
     $variables['record'] = $row;
     if (TRUE === is_object($form)) {
         $formLabel = $form->getLabel();
         $label = LocalizationUtility::translate($formLabel, $extensionKey);
         $variables['label'] = $label;
     }
     $templatePaths = new TemplatePaths($paths);
     $viewContext = new ViewContext($templatePathAndFilename, $extensionKey, self::CONTROLLER_NAME);
     $viewContext->setTemplatePaths($templatePaths);
     $viewContext->setVariables($variables);
     $view = $this->configurationService->getPreparedExposedTemplateView($viewContext);
     $existingContentObject = $this->configurationManager->getContentObject();
     $contentObject = new ContentObjectRenderer();
     $contentObject->start($row, $provider->getTableName($row));
     $this->configurationManager->setContentObject($contentObject);
     $previewContent = $view->renderStandaloneSection(self::PREVIEW_SECTION, $variables, TRUE);
     $this->configurationManager->setContentObject($existingContentObject);
     $previewContent = trim($previewContent);
     return $previewContent;
 }
 /**
  * @param string $pattern Pattern to be resolved
  * @param boolean $bubbleControllerAndSubpackage if TRUE, then we successively split off parts from "@controller" and "@subpackage" until both are empty.
  * @param boolean $formatIsOptional if TRUE, then half of the resulting strings will have ."@format" stripped off, and the other half will have it.
  * @return array unix style path
  */
 protected function expandGenericPathPattern($pattern, $bubbleControllerAndSubpackage, $formatIsOptional)
 {
     $extensionKey = $this->controllerContext->getRequest()->getControllerExtensionKey();
     $configurations = $this->configurationService->getViewConfigurationForExtensionName($extensionKey);
     $pathOverlayConfigurations = $this->buildPathOverlayConfigurations($configurations);
     $paths = parent::expandGenericPathPattern($pattern, $bubbleControllerAndSubpackage, $formatIsOptional);
     foreach ($pathOverlayConfigurations as $overlayPaths) {
         if (FALSE === empty($overlayPaths['templateRootPath'])) {
             $templateRootPath = $overlayPaths['templateRootPath'];
             $this->setTemplateRootPath($templateRootPath);
         }
         if (FALSE === empty($overlayPaths['partialRootPath'])) {
             $partialRootPath = $overlayPaths['partialRootPath'];
             $this->setPartialRootPath($partialRootPath);
         }
         if (FALSE === empty($overlayPaths['layoutRootPath'])) {
             $layoutRootPath = $overlayPaths['layoutRootPath'];
             $this->setLayoutRootPath($layoutRootPath);
         }
         $subset = parent::expandGenericPathPattern($pattern, $bubbleControllerAndSubpackage, $formatIsOptional);
         $paths = array_merge($paths, $subset);
     }
     $paths = array_unique($paths);
     $paths = array_reverse($paths);
     $paths = $this->trimPathStringRecursive($paths);
     return $paths;
 }
Esempio n. 8
0
 /**
  * @param string $extensionName
  * @param string $controllerName
  * @param string $actionName
  * @return boolean
  */
 protected function hasSubControllerActionOnForeignController($extensionName, $controllerName, $actionName)
 {
     $potentialControllerClassName = $this->configurationService->getResolver()->resolveFluxControllerClassNameByExtensionKeyAndAction($extensionName, $actionName, $controllerName);
     $isForeign = $extensionName !== $this->extensionName;
     $isValidController = class_exists($potentialControllerClassName);
     return TRUE === $isForeign && TRUE === $isValidController;
 }
 /**
  * Render method
  * @param string $table
  * @param string $field
  * @param integer $uid
  * @param array $record
  * @param string $as
  * @return array
  * @throws Exception
  */
 public function render($table, $field, $uid = NULL, $record = NULL, $as = NULL)
 {
     if (NULL === $uid && NULL !== $record && TRUE === isset($record['uid'])) {
         $uid = $record['uid'];
     }
     if (TRUE === isset(self::$dataCache[$uid . $table . $field])) {
         $dataArray = self::$dataCache[$uid . $table . $field];
     } elseif (TRUE === isset($GLOBALS['TCA'][$table]) && TRUE === isset($GLOBALS['TCA'][$table]['columns'][$field])) {
         if (NULL === $record) {
             $record = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('uid,' . $field, $table, sprintf('uid=%d', $uid));
         }
         if (FALSE === $record) {
             throw new Exception(sprintf('Either table "%s", field "%s" or record with uid %d do not exist and you did not manually ' . 'provide the "row" attribute.', $table, $field, $uid), 1358679983);
         }
         $providers = $this->configurationService->resolveConfigurationProviders($table, $field, $record);
         if (0 === count($providers)) {
             $dataArray = $this->configurationService->convertFlexFormContentToArray($record[$field]);
         } else {
             $dataArray = array();
             foreach ($providers as $provider) {
                 $data = (array) $provider->getFlexFormValues($record);
                 $dataArray = RecursiveArrayUtility::merge($dataArray, $data);
             }
         }
         self::$dataCache[$uid . $table . $field] = $dataArray;
     } else {
         throw new Exception('Invalid table:field "' . $table . ':' . $field . '" - does not exist in TYPO3 TCA.', 1387049117);
     }
     if (NULL !== $as) {
         if ($this->templateVariableContainer->exists($as)) {
             $backupVariable = $this->templateVariableContainer->get($as);
             $this->templateVariableContainer->remove($as);
         }
         $this->templateVariableContainer->add($as, $dataArray);
         $content = $this->renderChildren();
         $this->templateVariableContainer->remove($as);
         if (TRUE === isset($backupVariable)) {
             $this->templateVariableContainer->add($as, $backupVariable);
         }
         return $content;
     }
     return $dataArray;
 }
Esempio n. 10
0
 /**
  * @return string
  */
 public function indexAction()
 {
     $workspaceVersionOfRecord = $this->workspacesAwareRecordService->getSingle('tt_content', '*', $this->row['uid']);
     $this->view->assign('grid', $this->grid);
     $this->view->assign('row', $workspaceVersionOfRecord);
     $this->view->assign('colPosFluxContent', ContentService::COLPOS_FLUXCONTENT);
     $paths = $this->configurationService->getViewConfigurationForExtensionName('flux');
     $templateRootPath = TRUE === isset($paths['templateRootPath']) ? $paths['templateRootPath'] : NULL;
     $templatePathAndFilename = ResolveUtility::resolveWidgetTemplateFileBasedOnTemplateRootPathAndEnvironment($templateRootPath);
     $this->view->setTemplatePathAndFilename($templatePathAndFilename);
 }
Esempio n. 11
0
 /**
  * @param array $providers
  * @param array $record
  * @param string $field
  * @return array
  */
 protected function readDataArrayFromProvidersOrUsingDefaultMethod(array $providers, $record, $field)
 {
     if (0 === count($providers)) {
         $dataArray = $this->configurationService->convertFlexFormContentToArray($record[$field]);
     } else {
         $dataArray = array();
         foreach ($providers as $provider) {
             $data = (array) $provider->getFlexFormValues($record);
             $dataArray = RecursiveArrayUtility::merge($dataArray, $data);
         }
     }
     return $dataArray;
 }
 /**
  * @return void
  */
 protected function initializeViewObject()
 {
     $row = $this->getRecord();
     $templatePathAndFilename = $this->provider->getTemplatePathAndFilename($row);
     $extensionKey = $this->provider->getExtensionKey($row);
     $extensionName = ExtensionNamingUtility::getExtensionName($extensionKey);
     $controller = $this->request->getControllerName();
     $this->view = $this->configurationService->getPreparedExposedTemplateView($extensionKey, $controller, $this->setup, $this->data);
     $this->request->setControllerExtensionName($extensionName);
     $this->view->setControllerContext($this->controllerContext);
     if (FALSE === empty($templatePathAndFilename)) {
         $this->view->setTemplatePathAndFilename($templatePathAndFilename);
     }
 }
Esempio n. 13
0
 /**
  * Perform various cleanup operations upon clearing cache
  *
  * @param string $command
  * @return void
  */
 public function clearCacheCommand($command)
 {
     if (TRUE === self::$cachesCleared) {
         return;
     }
     $tables = array_keys($GLOBALS['TCA']);
     foreach ($tables as $table) {
         $providers = $this->configurationService->resolveConfigurationProviders($table, NULL);
         foreach ($providers as $provider) {
             /** @var $provider ProviderInterface */
             $provider->clearCacheCommand($command);
         }
     }
     self::$cachesCleared = TRUE;
 }
Esempio n. 14
0
 /**
  * @param array $providers
  * @param array $record
  * @param string $field
  * @return array
  */
 protected static function readDataArrayFromProvidersOrUsingDefaultMethod(array $providers, $record, $field)
 {
     if (0 === count($providers)) {
         $lang = static::getCurrentLanguageName();
         $pointer = static::getCurrentValuePointerName();
         $dataArray = static::$configurationService->convertFlexFormContentToArray($record[$field], NULL, $lang, $pointer);
     } else {
         $dataArray = array();
         /** @var ProviderInterface $provider */
         foreach ($providers as $provider) {
             $data = (array) $provider->getFlexFormValues($record);
             $dataArray = RecursiveArrayUtility::merge($dataArray, $data);
         }
     }
     return $dataArray;
 }
Esempio n. 15
0
 /**
  * @return ProviderInterface[]
  */
 public function loadTypoScriptConfigurationProviderInstances()
 {
     $providerConfigurations = (array) $this->configurationService->getTypoScriptByPath('plugin.tx_flux.providers');
     $providers = array();
     foreach ($providerConfigurations as $name => $providerSettings) {
         $className = 'FluidTYPO3\\Flux\\Provider\\Provider';
         if (TRUE === isset($providerSettings['className']) && TRUE === class_exists($providerSettings['className'])) {
             $className = $providerSettings['className'];
         }
         /** @var ProviderInterface $provider */
         $provider = $this->objectManager->get($className);
         $provider->setName($name);
         $provider->loadSettings($providerSettings);
         $providers[$name] = $provider;
     }
     return $providers;
 }
Esempio n. 16
0
 /**
  * Hook for generating dynamic FlexForm source code.
  *
  * NOTE: patches data structure resolving in a way that solves
  * a regression in the TYPO3 core when dealing with IRRE AJAX
  * requests (in which the database record is no longer fetched
  * by the controller). This patches not only data structure
  * resolving for Flux data structures but indeed any data
  * structure built using hooks or involving user functions which
  * require the entire record (but when using hooks, supports
  * only extensions which are loaded AFTER or depend on Flux).
  *
  * @param array $dataStructArray
  * @param array $conf
  * @param array $row
  * @param string $table
  * @param string $fieldName
  * @return void
  */
 public function getFlexFormDS_postProcessDS(&$dataStructArray, $conf, &$row, $table, $fieldName)
 {
     if (empty($fieldName) === TRUE) {
         // Cast NULL if an empty but not-NULL field name was passed. This has significance to the Flux internals in
         // respect to which ConfigurationProvider(s) are returned.
         $fieldName = NULL;
     }
     if (!empty($fieldName) && !isset($row[$fieldName])) {
         // Patch required (possibly temporary). Due to changes in TYPO3 in the new FormEngine we must fetch the
         // database record at this point when the record is incomplete, which happens when attempting to render
         // IRRE records. The reason is that the controller that creates the HTML does not fetch the record any
         // more - and that the AJAX request contains only the UID. So, we fetch the record here to ensure it
         // contains the necessary fields. DOES NOT WORK FOR NEW RECORDS - SEE COMMENTS BELOW.
         $row = $this->recordService->getSingle($table, '*', $row['uid']);
     }
     $defaultDataSourceCacheIdentifier = $table . '_' . $fieldName . '_' . sha1(serialize($conf));
     if (!$row) {
         // In the case that the database record cannot be fetched we are dealing with a new or otherwise deleted
         // or unidentifiable record. This happens primarily when AJAX requests are made to render IRRE records
         // without the parent record having been saved first. To accommodate this case we have to be slightly
         // creative and store a "default" data source definition which is identified based on a checksum of the
         // configuration provided. Whenever we are then unable to fetch a record, we can at least attempt to
         // locate a default data source in previously cached content. NB: we enforce a VERY high cache lifetime
         // and continually refresh it every time it is possible to render a new DS that can serve as default.
         $dataStructArray = (array) $this->cache->get($defaultDataSourceCacheIdentifier);
     } else {
         if (FALSE === is_array($dataStructArray)) {
             $dataStructArray = array();
         }
         $providers = $this->configurationService->resolveConfigurationProviders($table, $fieldName, $row);
         foreach ($providers as $provider) {
             $provider->postProcessDataStructure($row, $dataStructArray, $conf);
         }
         if (empty($dataStructArray)) {
             $dataStructArray = array('ROOT' => array('el' => array()));
         }
         $evaluationParameters = array();
         $this->cache->set($defaultDataSourceCacheIdentifier, $this->recursivelyEvaluateClosures($dataStructArray, $evaluationParameters), array(), time() + 31536000);
     }
     // Trigger TCEforms dimension patching only if required by TYPO3 version according to CompatibilityRegistry.
     if (CompatibilityRegistry::get('FluidTYPO3\\Flux\\Backend\\DynamicFlexForm::NEEDS_TCEFORMS_WRAPPER')) {
         $dataStructArray = $this->patchTceformsWrapper($dataStructArray);
     }
 }
 /**
  * @param integer $relativeRecordUid
  * @param string $fluxAreaName
  * @param array $whitelist
  * @param array $blacklist
  * @return array
  */
 protected function readWhitelistAndBlacklistFromColumn($relativeRecordUid, $fluxAreaName, $whitelist, $blacklist)
 {
     $relativeRecord = $this->recordService->getSingle('tt_content', '*', (int) $relativeRecordUid);
     $contentProviders = $this->configurationService->resolveConfigurationProviders('tt_content', NULL, $relativeRecord);
     foreach ($contentProviders as $contentProvider) {
         $grid = $contentProvider->getGrid($relativeRecord);
         if (NULL === $grid) {
             continue;
         }
         foreach ($grid->getRows() as $row) {
             foreach ($row->getColumns() as $column) {
                 if ($column->getName() === $fluxAreaName) {
                     list($whitelist, $blacklist) = $this->appendToWhiteAndBlacklistFromComponent($column, $whitelist, $blacklist);
                 }
             }
         }
     }
     return array($whitelist, $blacklist);
 }
Esempio n. 18
0
 /**
  * @param string $headerContent
  * @param string $itemContent
  * @param array $row
  * @param boolean $drawItem
  * @return NULL
  */
 public function renderPreview(&$headerContent, &$itemContent, array &$row, &$drawItem)
 {
     $children = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,tx_flux_column', 'tt_content', "tx_flux_parent = '" . $row['uid'] . "'");
     $checksum = sha1(json_encode($row)) . '-' . sha1(json_encode($children));
     $cacheFilePathAndfilenameHeader = GeneralUtility::getFileAbsFileName('typo3temp/flux-preview-' . $checksum . '-header.tmp');
     $cacheFilePathAndfilenameContent = GeneralUtility::getFileAbsFileName('typo3temp/flux-preview-' . $checksum . '-content.tmp');
     $drawItem = TRUE;
     if (TRUE === file_exists($cacheFilePathAndfilenameHeader) && TRUE === file_exists($cacheFilePathAndfilenameContent)) {
         $itemContent = file_get_contents($cacheFilePathAndfilenameContent);
         $headerContent = file_get_contents($cacheFilePathAndfilenameHeader);
         $drawItem = FALSE;
         $this->attachStyle();
         return NULL;
     }
     $fieldName = NULL;
     // every provider for tt_content will be asked to get a preview
     if ('shortcut' === $row['CType'] && FALSE === strpos($row['records'], ',')) {
         $itemContent = $this->createShortcutIcon($row) . $itemContent;
     } else {
         $itemContent = '<a name="c' . $row['uid'] . '"></a>' . $itemContent;
     }
     $providers = $this->configurationService->resolveConfigurationProviders('tt_content', $fieldName, $row);
     foreach ($providers as $provider) {
         /** @var ProviderInterface $provider */
         list($previewHeader, $previewContent, $continueDrawing) = $provider->getPreview($row);
         if (FALSE === empty($previewHeader)) {
             $headerContent = $previewHeader . (FALSE === empty($headerContent) ? ': ' . $headerContent : '');
             $drawItem = FALSE;
             GeneralUtility::writeFile($cacheFilePathAndfilenameHeader, $headerContent);
         }
         if (FALSE === empty($previewContent)) {
             $itemContent .= $previewContent;
             $drawItem = FALSE;
             GeneralUtility::writeFile($cacheFilePathAndfilenameContent, $itemContent);
         }
         if (FALSE === $continueDrawing) {
             break;
         }
     }
     $this->attachStyle();
     return NULL;
 }
Esempio n. 19
0
 /**
  * @param integer $uid
  * @return array
  */
 public function getContentAreasDefinedInContentElement($uid)
 {
     $uid = (int) $uid;
     $record = $this->recordService->getSingle('tt_content', '*', $uid);
     /** @var $providers ProviderInterface[] */
     $providers = $this->fluxService->resolveConfigurationProviders('tt_content', NULL, $record);
     $columns = array();
     foreach ($providers as $provider) {
         $grid = $provider->getGrid($record);
         if (TRUE === empty($grid)) {
             continue;
         }
         $gridConfiguration = $grid->build();
         foreach ($gridConfiguration['rows'] as $row) {
             foreach ($row['columns'] as $column) {
                 array_push($columns, array($column['label'] . ' (' . $column['name'] . ')', $column['name']));
             }
         }
     }
     return array_unique($columns, SORT_REGULAR);
 }
 /**
  * @param integer $uid
  * @return array
  */
 public function getContentAreasDefinedInContentElement($uid)
 {
     $uid = (int) $uid;
     $record = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('*', 'tt_content', "uid = '" . $uid . "'");
     /** @var $providers ProviderInterface[] */
     $providers = $this->fluxService->resolveConfigurationProviders('tt_content', NULL, $record);
     $columns = array();
     foreach ($providers as $provider) {
         $grid = $provider->getGrid($record);
         if (TRUE === empty($grid)) {
             continue;
         }
         $gridConfiguration = $grid->build();
         foreach ($gridConfiguration['rows'] as $row) {
             foreach ($row['columns'] as $column) {
                 foreach ($column['areas'] as $area) {
                     array_push($columns, array($area['label'] . ' (' . $area['name'] . ')', $area['name']));
                 }
             }
         }
     }
     return array_unique($columns);
 }
    /**
     * @param array $parameters
     * @param PageLayoutView|DatabaseRecordList $caller
     * @return string
     */
    public function addSubIcon(array $parameters, $caller = NULL)
    {
        $this->attachAssets();
        list($table, $uid, $record) = $parameters;
        $icon = NULL;
        if (NULL !== $caller) {
            $record = NULL === $record && 0 < $uid ? BackendUtility::getRecord($table, $uid) : $record;
            $cacheIdentity = $table . $uid . sha1(serialize($record));
            // filter 1: icon must not already be cached and both record and caller must be provided.
            if (TRUE === $this->cache->has($cacheIdentity)) {
                $icon = $this->cache->get($cacheIdentity);
            } elseif (NULL !== $record) {
                $field = $this->detectFirstFlexTypeFieldInTableFromPossibilities($table, array_keys($record));
                // filter 2: table must have one field defined as "flex" and record must include it.
                if (NULL !== $field && TRUE === isset($record[$field])) {
                    // we check the cache here because at this point, the cache key is decidedly
                    // unique and we have not yet consulted the (potentially costly) Provider.
                    $provider = $this->fluxService->resolvePrimaryConfigurationProvider($table, $field, $record);
                    // filter 3: a Provider must be resolved for the record.
                    if (NULL !== $provider) {
                        $form = $provider->getForm((array) $record);
                        if (NULL !== $form) {
                            $icon = MiscellaneousUtility::getIconForTemplate($form);
                            if (NULL !== $icon) {
                                $label = trim($form->getLabel());
                                $icon = '<img width="16" height="16" src="' . $icon . '" alt="' . $label . '"
									title="' . $label . '" class="" />';
                                $icon = sprintf($this->templates['iconWrapper'], $icon);
                            }
                        }
                    }
                }
                $this->cache->set($cacheIdentity, $icon);
            }
        }
        return $icon;
    }
 /**
  * @param array $items
  * @param \TYPO3\CMS\Backend\Controller\ContentElement\NewContentElementController
  * @return void
  */
 public function manipulateWizardItems(&$items, &$parentObject)
 {
     $whitelist = array();
     $blacklist = array();
     // if a Provider is registered for the "pages" table, try to get a Grid from it. If the Grid
     // returned contains a Column which matches the desired colPos value, attempt to read a list
     // of allowed/denied content element types from it.
     $pageRecord = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('*', 'pages', "uid = '" . $parentObject->id . "'");
     $pageProviders = $this->configurationService->resolveConfigurationProviders('pages', NULL, $pageRecord);
     foreach ($pageProviders as $pageProvider) {
         $grid = $pageProvider->getGrid($pageRecord);
         if (NULL === $grid) {
             continue;
         }
         foreach ($grid->getRows() as $row) {
             foreach ($row->getColumns() as $column) {
                 if ($column->getColumnPosition() === $parentObject->colPos) {
                     list($whitelist, $blacklist) = $this->appendToWhiteAndBlacklistFromComponent($column, $whitelist, $blacklist);
                 }
             }
         }
     }
     // Detect what was clicked in order to create the new content element; decide restrictions
     // based on this.
     $defaultValues = GeneralUtility::_GET('defVals');
     if (0 > $parentObject->uid_pid) {
         // pasting after another element means we should try to resolve the Flux content relation
         // from that element instead of GET parameters (clicked: "create new" icon after other element)
         $relativeRecordUid = abs($parentObject->uid_pid);
         $relativeRecord = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('*', 'tt_content', "uid = '" . $relativeRecordUid . "'");
         $fluxAreaName = $relativeRecord['tx_flux_column'];
     } elseif (TRUE === isset($defaultValues['tt_content']['tx_flux_column'])) {
         // attempt to read the target Flux content area from GET parameters (clicked: "create new" icon
         // in top of nested Flux content area
         $fluxAreaName = $defaultValues['tt_content']['tx_flux_column'];
         $relativeRecordUid = $defaultValues['tt_content']['tx_flux_parent'];
     }
     // if these variables now indicate that we are inserting content elements into a Flux-enabled content
     // area inside another content element, attempt to read allowed/denied content types from the
     // Grid returned by the Provider that applies to the parent element's type and configuration
     // (admitted, that's quite a mouthful - but it's not that different from reading the values from
     // a page template like above; it's the same principle).
     if (0 < $relativeRecordUid && FALSE === empty($fluxAreaName)) {
         $relativeRecord = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('*', 'tt_content', "uid = '" . $relativeRecordUid . "'");
         $contentProviders = $this->configurationService->resolveConfigurationProviders('tt_content', NULL, $relativeRecord);
         foreach ($contentProviders as $contentProvider) {
             $grid = $contentProvider->getGrid($relativeRecord);
             if (NULL === $grid) {
                 continue;
             }
             foreach ($grid->getRows() as $row) {
                 foreach ($row->getColumns() as $column) {
                     foreach ($column->getAreas() as $area) {
                         if ($area->getName() === $fluxAreaName) {
                             list($whitelist, $blacklist) = $this->appendToWhiteAndBlacklistFromComponent($area, $whitelist, $blacklist);
                         }
                     }
                 }
             }
         }
     }
     // White/blacklist filtering. If whitelist contains elements, filter the list
     // of possible types by whitelist first. Then apply the blacklist, removing
     // any element types recorded herein.
     $whitelist = array_unique($whitelist);
     $blacklist = array_unique($blacklist);
     if (0 < count($whitelist)) {
         foreach ($items as $name => $item) {
             if (FALSE !== strpos($name, '_') && FALSE === in_array($item['tt_content_defValues']['CType'], $whitelist)) {
                 unset($items[$name]);
             }
         }
     }
     if (0 < count($blacklist)) {
         foreach ($blacklist as $contentElementType) {
             foreach ($items as $name => $item) {
                 if ($item['tt_content_defValues']['CType'] === $contentElementType) {
                     unset($items[$name]);
                 }
             }
         }
     }
     // Finally, loop through the items list and clean up any tabs with zero element types inside.
     $preserveHeaders = array();
     foreach ($items as $name => $item) {
         if (FALSE !== strpos($name, '_')) {
             array_push($preserveHeaders, reset(explode('_', $name)));
         }
     }
     foreach ($items as $name => $item) {
         if (FALSE === strpos($name, '_') && FALSE === in_array($name, $preserveHeaders)) {
             unset($items[$name]);
         }
     }
 }
Esempio n. 23
0
 /**
  * @test
  * @dataProvider getSortObjectsTestValues
  * @param array $input
  * @param string $sortBy
  * @param string $direction
  * @param array $expectedOutput
  */
 public function testSortObjectsByProperty($input, $sortBy, $direction, $expectedOutput)
 {
     $service = new FluxService();
     $sorted = $service->sortObjectsByProperty($input, $sortBy, $direction);
     $this->assertEquals($expectedOutput, $sorted);
 }
Esempio n. 24
0
 /**
  * Get preview chunks - header and content - as
  * array(string $headerContent, string $previewContent, boolean $continueRendering)
  *
  * Default implementation renders the Preview section from the template
  * file that the actual Provider returns for $row, using paths also
  * determined by $row. Example: fluidcontent's Provider returns files
  * and paths based on selected "Fluid Content type" and inherits and
  * uses this method to render a Preview from the template file in the
  * specific path. This default implementation expects the TYPO3 core
  * to render the default header, so it returns NULL as $headerContent.
  *
  * @param array $row The record data to be analysed for variables to use in a rendered preview
  * @return array
  */
 public function getPreview(array $row)
 {
     $templateSource = $this->getTemplateSource($row);
     if (TRUE === empty($templateSource)) {
         return array(NULL, NULL, TRUE);
     }
     $extensionKey = $this->getExtensionKey($row);
     $flexformVariables = $this->getFlexFormValues($row);
     $templateVariables = $this->getTemplateVariables($row);
     $variables = RecursiveArrayUtility::merge($templateVariables, $flexformVariables);
     $paths = $this->getTemplatePaths($row);
     $form = $this->getForm($row);
     $formLabel = $form->getLabel();
     $label = LocalizationUtility::translate($formLabel, $extensionKey);
     $variables['label'] = $label;
     $variables['row'] = $row;
     $variables['record'] = $row;
     $view = $this->configurationService->getPreparedExposedTemplateView($extensionKey, 'Content', $paths, $variables);
     $view->setTemplateSource($templateSource);
     $existingContentObject = $this->configurationManager->getContentObject();
     $contentObject = new ContentObjectRenderer();
     $contentObject->start($row, $this->getTableName($row));
     $this->configurationManager->setContentObject($contentObject);
     $previewContent = $view->renderStandaloneSection('Preview', $variables);
     $this->configurationManager->setContentObject($existingContentObject);
     $previewContent = trim($previewContent);
     $headerContent = NULL;
     return array($headerContent, $previewContent, empty($previewContent));
 }
Esempio n. 25
0
 /**
  * @param string $extension
  * @param string $contentType
  * @param string $version
  * @return string
  */
 public function getIconFromVersion($extension, $contentType, $version = NULL)
 {
     $extensionKey = ExtensionNamingUtility::getExtensionKey($extension);
     $templatePathAndFilename = $this->resolveTemplateFileForVariant($extensionKey, $contentType, $extension, $version);
     $paths = $this->getViewConfigurationForExtensionName($extensionKey);
     $templatePaths = new TemplatePaths($paths);
     $viewContext = new ViewContext($templatePathAndFilename, $extensionKey);
     $viewContext->setTemplatePaths($templatePaths);
     $viewContext->setSectionName('Configuration');
     $form = FluxService::getFormFromTemplateFile($viewContext);
     if (FALSE === $form instanceof Form) {
         return '';
     } else {
         return MiscellaneousUtility::getIconForTemplate($form);
     }
 }
Esempio n. 26
0
 /**
  * @param array $row
  * @return array
  */
 public function getTemplatePaths(array $row)
 {
     $paths = $this->templatePaths;
     if (FALSE === is_array($paths)) {
         $extensionKey = $this->getExtensionKey($row);
         $extensionKey = ExtensionNamingUtility::getExtensionKey($extensionKey);
         if (FALSE === empty($extensionKey)) {
             $paths = $this->configurationService->getViewConfigurationForExtensionName($extensionKey);
         }
     }
     if (TRUE === is_array($paths)) {
         $paths = PathUtility::translatePath($paths);
     }
     return $paths;
 }