resolveConfigurationProviders() public method

Resolves a ConfigurationProvider which can provide a working FlexForm configuration based on the given parameters.
public resolveConfigurationProviders ( string $table, string $fieldName, array $row = NULL, string $extensionKey = NULL ) : FluidTYPO3\Flux\Provider\ProviderInterface[]
$table string
$fieldName string
$row array
$extensionKey string
return FluidTYPO3\Flux\Provider\ProviderInterface[]
示例#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;
 }
示例#2
0
 /**
  * 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 === $record && NULL === $as) {
         $record = $this->renderChildren();
     }
     if (NULL === $uid && NULL !== $record && TRUE === isset($record['uid'])) {
         $uid = $record['uid'];
     }
     if (TRUE === isset($GLOBALS['TCA'][$table]) && TRUE === isset($GLOBALS['TCA'][$table]['columns'][$field])) {
         if (NULL === $record) {
             $record = $this->recordService->getSingle($table, 'uid,' . $field, $uid);
         }
         if (NULL === $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 "record" attribute.', $table, $field, $uid), 1358679983);
         }
         $providers = $this->configurationService->resolveConfigurationProviders($table, $field, $record);
         $dataArray = $this->readDataArrayFromProvidersOrUsingDefaultMethod($providers, $record, $field);
     } 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;
 }
 /**
  * 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);
     }
 }
 /**
  * @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);
 }
 /**
  * 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;
 }
示例#6
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;
 }
示例#7
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);
 }
示例#9
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;
 }
示例#10
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 $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]);
         }
     }
 }