예제 #1
0
 /**
  * Retrieve possible suggestions for a field name
  *
  * @param string $fieldNameAndPath
  * @return array
  */
 public function getSuggestions($fieldNameAndPath)
 {
     $values = array();
     $dataType = $this->getFieldPathResolver()->getDataType($fieldNameAndPath);
     $fieldName = $this->getFieldPathResolver()->stripFieldPath($fieldNameAndPath);
     if (Tca::grid()->facet($fieldNameAndPath)->hasSuggestions()) {
         $values = Tca::grid()->facet($fieldNameAndPath)->getSuggestions();
     } else {
         if (Tca::table($dataType)->hasField($fieldName)) {
             if (Tca::table($dataType)->field($fieldName)->hasRelation()) {
                 // Fetch the adequate repository
                 $foreignTable = Tca::table($dataType)->field($fieldName)->getForeignTable();
                 $contentRepository = ContentRepositoryFactory::getInstance($foreignTable);
                 $table = Tca::table($foreignTable);
                 // Initialize the matcher object.
                 $matcher = MatcherObjectFactory::getInstance()->getMatcher(array(), $foreignTable);
                 $numberOfValues = $contentRepository->countBy($matcher);
                 if ($numberOfValues <= $this->getLimit()) {
                     $contents = $contentRepository->findBy($matcher);
                     foreach ($contents as $content) {
                         $values[] = array($content->getUid() => $content[$table->getLabelField()]);
                     }
                 }
             } elseif (!Tca::table($dataType)->field($fieldName)->isTextArea()) {
                 // We don't want suggestion if field is text area.
                 // Fetch the adequate repository
                 /** @var \Fab\Vidi\Domain\Repository\ContentRepository $contentRepository */
                 $contentRepository = ContentRepositoryFactory::getInstance($dataType);
                 // Initialize some objects related to the query
                 $matcher = MatcherObjectFactory::getInstance()->getMatcher(array(), $dataType);
                 // Count the number of objects.
                 $numberOfValues = $contentRepository->countDistinctValues($fieldName, $matcher);
                 // Only returns suggestion if there are not too many for the browser.
                 if ($numberOfValues <= $this->getLimit()) {
                     // Query the repository.
                     $contents = $contentRepository->findDistinctValues($fieldName, $matcher);
                     foreach ($contents as $content) {
                         $value = $content[$fieldName];
                         $label = $content[$fieldName];
                         if (Tca::table($dataType)->field($fieldName)->isSelect()) {
                             $label = Tca::table($dataType)->field($fieldName)->getLabelForItem($value);
                         }
                         $values[] = $label;
                     }
                 }
             }
         }
     }
     return $values;
 }
예제 #2
0
 /**
  * Fetch the files given an object assuming
  *
  * @param Matcher $matcher
  * @param Order $order The order
  * @param int $limit
  * @param int $offset
  * @return $this
  */
 public function findBy(Matcher $matcher, Order $order = NULL, $limit = NULL, $offset = NULL)
 {
     // Query the repository.
     $objects = ContentRepositoryFactory::getInstance($this->dataType)->findBy($matcher, $order, $limit, $offset);
     $signalResult = $this->emitAfterFindContentObjectsSignal($objects, $matcher, $order, $limit, $offset);
     // Reset objects variable after possible signal / slot processing.
     $this->objects = $signalResult->getContentObjects();
     // Count number of content objects.
     if ($signalResult->getHasBeenProcessed()) {
         $this->numberOfObjects = $signalResult->getNumberOfObjects();
     } else {
         $this->numberOfObjects = ContentRepositoryFactory::getInstance($this->dataType)->countBy($matcher);
     }
     return $this;
 }
예제 #3
0
 /**
  * Count a result set.
  *
  * @return int
  */
 public function render()
 {
     if (!empty($this->arguments['dataType'])) {
         print 'Sorry to be so rude! There is something to change in the View Helper "v:find". Please replace attribute "dataType" by "type". This is a shorter syntax...';
         exit;
     }
     $dataType = $this->arguments['type'];
     $matches = $this->replacesAliases($this->arguments['matches']);
     $ignoreEnableFields = $this->arguments['ignoreEnableFields'];
     $matcher = $this->getMatcher($dataType, $matches);
     $contentRepository = ContentRepositoryFactory::getInstance($dataType);
     $contentRepository->setDefaultQuerySettings($this->getDefaultQuerySettings($ignoreEnableFields));
     $numberOfObjects = ContentRepositoryFactory::getInstance($dataType)->countBy($matcher);
     return $numberOfObjects;
 }
예제 #4
0
 /**
  * Fetch and returns a list of content objects.
  *
  * @return array
  */
 public function render()
 {
     $selection = (int) $this->arguments['selection'];
     if ($selection > 0) {
         /** @var \Fab\Vidi\Domain\Repository\SelectionRepository $selectionRepository */
         $selectionRepository = $this->objectManager->get('Fab\\Vidi\\Domain\\Repository\\SelectionRepository');
         /** @var Selection $selection */
         $selection = $selectionRepository->findByUid($selection);
         $matches = json_decode($selection->getMatches(), TRUE);
         $dataType = $selection->getDataType();
     } else {
         $dataType = $this->arguments['type'];
         if (!empty($this->arguments['dataType'])) {
             print 'Sorry to be so rude! There is something to change in the View Helper "v:find". Please replace attribute "dataType" by "type". This is a shorter syntax...';
             exit;
         }
         $matches = $this->replacesAliases($this->arguments['matches']);
     }
     $orderings = $this->replacesAliases($this->arguments['orderings']);
     $limit = $this->arguments['limit'];
     $offset = $this->arguments['offset'];
     $ignoreEnableFields = $this->arguments['ignoreEnableFields'];
     $querySignature = $this->getQuerySignature($dataType, $matches, $orderings, $limit, $offset);
     $resultSet = $this->getResultSetStorage()->get($querySignature);
     if (!$resultSet) {
         $matcher = $this->getMatcher($dataType, $matches);
         $orderings = $this->getOrder($dataType, $orderings);
         $this->emitPostProcessLimitSignal($dataType, $limit);
         $this->emitPostProcessOffsetSignal($dataType, $offset);
         $contentRepository = ContentRepositoryFactory::getInstance($dataType);
         $contentRepository->setDefaultQuerySettings($this->getDefaultQuerySettings($ignoreEnableFields));
         $resultSet = $contentRepository->findBy($matcher, $orderings, $limit, $offset);
         $this->getResultSetStorage()->set($querySignature, $resultSet);
         // store the result set for performance sake.
     }
     return $resultSet;
 }
예제 #5
0
 /**
  * Retrieve Content objects first according to matching criteria and then "localize" them.
  *
  * Possible values for $matches, refer to method "updateAction".
  *
  * @param string $fieldNameAndPath
  * @param array $matches
  * @param int $language
  * @return string
  * @throws \Exception
  */
 public function localizeAction($fieldNameAndPath, array $matches = array(), $language = 0)
 {
     $matcher = MatcherObjectFactory::getInstance()->getMatcher($matches);
     // Fetch objects via the Content Service.
     $contentService = $this->getContentService()->findBy($matcher);
     // Get result object for storing data along the processing.
     $result = $this->getJsonResult();
     $result->setNumberOfObjects($contentService->getNumberOfObjects());
     foreach ($contentService->getObjects() as $object) {
         $identifier = $this->getContentObjectResolver()->getValue($object, $fieldNameAndPath, 'uid');
         $dataType = $this->getContentObjectResolver()->getDataType($object, $fieldNameAndPath);
         // Fetch the source object to be localized.
         /** @var Content $content */
         $content = ContentRepositoryFactory::getInstance($dataType)->findByIdentifier($identifier);
         // Makes sure the object was retrieved. Security!
         if (!$content) {
             $message = sprintf('Something went wrong when retrieving content "%s" with identifier "%s".', $dataType, $identifier);
             throw new \Exception($message, 1412343097);
         }
         // Handover the localization to the Repository.
         ContentRepositoryFactory::getInstance($dataType)->localize($content, $language);
         // Get the possible error messages and store them.
         $errorMessages = ContentRepositoryFactory::getInstance()->getErrorMessages();
         // Redirect to TCEForm so that the BE User can do its job!
         if ($contentService->getNumberOfObjects() === 1) {
             if (!empty($errorMessages)) {
                 $message = sprintf('Something went wrong when localizing content "%s" with identifier "%s". <br/>%s', $dataType, $identifier, implode('<br/>', $errorMessages));
                 throw new \Exception($message, 1412343098);
             }
             $localizedContent = $this->getLanguageService()->getLocalizedContent($content, $language);
             if (empty($localizedContent)) {
                 $message = sprintf('Oups! I could not retrieve localized content of type "%s" with identifier "%s"', $content->getDataType(), $content->getUid());
                 throw new \Exception($message, 1412343099);
             }
             /** @var \Fab\Vidi\View\Uri\EditUri $uri */
             $uriRenderer = GeneralUtility::makeInstance('Fab\\Vidi\\View\\Uri\\EditUri');
             $uri = $uriRenderer->render($localizedContent);
             HttpUtility::redirect($uri);
             break;
             // no need to further continue
         }
         $result->addErrorMessages($errorMessages);
     }
     // Set the result and render the JSON view.
     $this->getJsonView()->setResult($result);
     return $this->getJsonView()->render();
 }
예제 #6
0
 /**
  * Try to "resolve" the property whether it has a relation.
  * If the property has not relation it simply returns the same value.
  *
  * @throws \RuntimeException
  * @param string $propertyName
  * @return mixed
  */
 protected function resolveRelation($propertyName)
 {
     // Convert property name to field name and get the foreign data type.
     $fieldName = Property::name($propertyName)->of($this)->toFieldName();
     $foreignDataType = Tca::table($this->dataType)->field($fieldName)->relationDataType();
     // Get the foreign repository instance form the factory
     /** @var \Fab\Vidi\Domain\Repository\ContentRepository $foreignContentRepository */
     $foreignContentRepository = ContentRepositoryFactory::getInstance($foreignDataType, $fieldName);
     if (Tca::table($this->dataType)->field($fieldName)->hasRelationWithCommaSeparatedValues()) {
         // Fetch values from repository
         $values = GeneralUtility::trimExplode(',', $this->{$propertyName});
         $this->{$propertyName} = $foreignContentRepository->findIn('uid', $values);
     } elseif (Tca::table($this->dataType)->field($fieldName)->hasMany()) {
         // Include relation many-to-many and one-to-many
         // Tca::table($this->dataType)->field($fieldName)->hasRelationOneToMany()
         // Tca::table($this->dataType)->field($fieldName)->hasRelationManyToMany()
         $foreignFieldName = Tca::table($this->dataType)->field($fieldName)->getForeignField();
         if (empty($foreignFieldName)) {
             $message = sprintf('Missing "foreign_field" key for field "%s" in table "%s".', $fieldName, $this->dataType);
             throw new \RuntimeException($message, 1376149186);
         }
         // Fetch values from repository.
         $foreignPropertyName = Field::name($foreignFieldName)->of($this)->toPropertyName();
         $findByProperty = 'findBy' . ucfirst($foreignPropertyName);
         // Date picker (type == group) are special fields because property path must contain the table name
         // to determine the relation type. Example for sys_category, property path will look like "items.sys_file"
         $propertyValue = $this->uid;
         if (Tca::table($foreignDataType)->field($foreignFieldName)->isGroup()) {
             $propertyValue = $this->dataType . '.' . $this->uid;
         }
         $this->{$propertyName} = $foreignContentRepository->{$findByProperty}($propertyValue);
     } elseif (Tca::table($this->dataType)->field($fieldName)->hasOne()) {
         $fieldConfiguration = Tca::table($this->dataType)->field($fieldName)->getConfiguration();
         // First case, we are on the "good side" of the relation, just query the repository
         if (empty($fieldConfiguration['foreign_field'])) {
             $this->{$propertyName} = $foreignContentRepository->findByUid($this->{$propertyName});
         } else {
             // Second case, we are the "bad side" of the relation, query the foreign repository
             // e.g. in case of one-to-one relation.
             // We must query the opposite side to get the identifier of the foreign object.
             $foreignDataType = Tca::table($this->dataType)->field($fieldName)->getForeignTable();
             $foreignField = Tca::table($this->dataType)->field($fieldName)->getForeignField();
             $foreignContentRepository = ContentRepositoryFactory::getInstance($foreignDataType);
             $find = 'findOneBy' . GeneralUtility::underscoredToUpperCamelCase($foreignField);
             /** @var Content $foreignObject */
             $this->{$propertyName} = $foreignContentRepository->{$find}($this->getUid());
         }
     }
     return $this->{$propertyName};
 }
예제 #7
0
 /**
  * @param AfterFindContentObjectsSignalArguments $signalArguments
  * @return array
  */
 public function modifyResultSet(AfterFindContentObjectsSignalArguments $signalArguments)
 {
     if ($signalArguments->getDataType() === 'sys_file') {
         $queryParts = $this->getQueryParts();
         if (!empty($queryParts)) {
             $permission = $this->getPermissionValue($queryParts);
             if ($permission) {
                 // We are force to query the content repository again here without limit
                 $matcher = $signalArguments->getMatcher();
                 $order = $signalArguments->getOrder();
                 $objects = ContentRepositoryFactory::getInstance($this->dataType)->findBy($matcher, $order);
                 $filteredObjects = array();
                 foreach ($objects as $object) {
                     $file = $this->getFileConverter()->convert($object->getUid());
                     if ($permission === 'read' && !$file->checkActionPermission('write')) {
                         $filteredObjects[] = $object;
                     } elseif ($permission === 'write' && $file->checkActionPermission('write')) {
                         $filteredObjects[] = $object;
                     }
                 }
                 // Only take part of the array according to offset and limit.
                 $offset = $signalArguments->getOffset();
                 $limit = $signalArguments->getLimit();
                 $signalArguments->setContentObjects(array_slice($filteredObjects, $offset, $limit));
                 // Count number of records
                 $signalArguments->setNumberOfObjects(count($filteredObjects));
                 $signalArguments->setHasBeenProcessed(TRUE);
             }
         }
     }
     return array($signalArguments);
 }