/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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(); }
/** * 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}; }
/** * @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); }