/** * {@inheritdoc} */ public function transform($value) { if (!$value) { return ''; } if (is_array($value)) { $result = []; $user = $this->securityFacade->getToken()->getUser(); foreach ($value as $target) { if (ClassUtils::getClass($user) === ClassUtils::getClass($target) && $user->getId() === $target->getId()) { continue; } if ($fields = $this->mapper->getEntityMapParameter(ClassUtils::getClass($target), 'title_fields')) { $text = []; foreach ($fields as $field) { $text[] = $this->mapper->getFieldValue($target, $field); } } else { $text = [(string) $target]; } $text = implode(' ', $text); if ($label = $this->getClassLabel(ClassUtils::getClass($target))) { $text .= ' (' . $label . ')'; } $result[] = json_encode(['text' => $text, 'id' => json_encode(['entityClass' => ClassUtils::getClass($target), 'entityId' => $target->getId()])]); } $value = implode(';', $result); } return $value; }
/** * {@inheritdoc} */ public function visitResult(DatagridConfiguration $config, ResultsObject $result) { $rows = $result->offsetGetByPath('[data]'); if (!is_array($rows)) { throw new UnexpectedTypeException($rows, 'array'); } $mappingConfig = $this->mapper->getMappingConfig(); $rows = array_map(function (ResultRecordInterface $record) use($mappingConfig) { $entityClass = $record->getValue('entityName'); $entityId = $record->getValue('recordId'); $entityConfig = array_key_exists($entityClass, $mappingConfig) ? $entityConfig = $this->mapper->getEntityConfig($entityClass) : []; return new ResultItem($this->em, $entityClass, $entityId, null, null, $entityConfig); }, $rows); $entities = $this->resultFormatter->getResultEntities($rows); $resultRows = []; /** @var ResultItem $item */ foreach ($rows as $item) { $entityClass = $item->getEntityName(); $entityId = $item->getRecordId(); $entity = $entities[$entityClass][$entityId]; $this->dispatcher->dispatch(PrepareResultItemEvent::EVENT_NAME, new PrepareResultItemEvent($item, $entity)); $resultRows[] = new ResultRecord(['entity' => $entity, 'indexer_item' => $item]); } $result->offsetSet('data', $resultRows); }
/** * {@inheritDoc} */ public function visitResult(DatagridConfiguration $config, ResultsObject $result) { $rows = $result->offsetGetByPath('[data]'); $rows = is_array($rows) ? $rows : []; $rows = array_map(function (ResultRecordInterface $record) { if ($rootEntity = $record->getRootEntity()) { return $rootEntity; } $entityName = $record->getValue('entityName'); $recordId = $record->getValue('recordId'); if ($entityName && $recordId) { return new ResultItem($this->em, $entityName, $recordId, null, null, null, $this->mapper->getEntityConfig($entityName)); } return null; }, $rows); $entities = $this->resultFormatter->getResultEntities($rows); $resultRows = []; /** @var ResultItem $item */ foreach ($rows as $item) { $entityName = $item->getEntityName(); $entityId = $item->getRecordId(); if (!isset($entities[$entityName][$entityId])) { continue; } $entity = $entities[$entityName][$entityId]; $this->dispatcher->dispatch(PrepareResultItemEvent::EVENT_NAME, new PrepareResultItemEvent($item, $entity)); $resultRows[] = new ResultRecord(['entity' => $entity, 'indexer_item' => $item]); } // set results $result->offsetSet('data', $resultRows); }
/** * {@inheritdoc} */ public function getResults($tagId) { $originResults = $this->em->createQueryBuilder()->select('t')->from('Oro\\Bundle\\TagBundle\\Entity\\Tagging', 't')->where('t.tag = :tag')->setParameter('tag', $tagId)->addGroupBy('t.entityName')->addGroupBy('t.recordId')->getQuery()->getResult(); $results = array(); /** @var Tagging $item */ foreach ($originResults as $item) { $results[] = new Item($this->em, $item->getEntityName(), $item->getRecordId(), null, null, null, $this->mapper->getEntityConfig($item->getEntityName())); } return new Result(new Query(), $results, count($results)); }
protected function setUp() { $config = (require rtrim(__DIR__, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'searchConfig.php'); $this->eventDispatcher = $this->getMock('Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); $this->registry = $this->getMock('Doctrine\\Common\\Persistence\\ManagerRegistry'); $this->mapper = new ObjectMapper($this->eventDispatcher, $config); $eventDispatcher = $this->getMockBuilder('Symfony\\Component\\EventDispatcher\\EventDispatcher')->disableOriginalConstructor()->getMock(); $mapperProvider = new SearchMappingProvider($eventDispatcher); $mapperProvider->setMappingConfig($config); $this->mapper->setMappingProvider($mapperProvider); $this->doctrineHelper = new DoctrineHelper($this->registry); }
/** * {@inheritdoc} */ public function getResults($tagId) { $queryBuilder = $this->em->createQueryBuilder()->select('t.entityName', 't.recordId')->from('Oro\\Bundle\\TagBundle\\Entity\\Tagging', 't')->where('t.tag = :tag')->setParameter('tag', $tagId)->addGroupBy('t.entityName')->addGroupBy('t.recordId'); $this->securityProvider->applyAcl($queryBuilder, 't'); $originResults = $queryBuilder->getQuery()->getResult(); $results = []; /** @var Tagging $item */ foreach ($originResults as $item) { $entityName = $item['entityName']; $results[] = new Item($this->em, $entityName, $item['recordId'], null, null, $this->mapper->getEntityConfig($entityName)); } return new Result(new Query(), $results, count($results)); }
/** * {@inheritdoc} */ protected function doSearch(Query $query) { $results = []; $searchResults = $this->getIndexRepository()->search($query); if ($query->getCriteria()->getMaxResults() > 0 || $query->getCriteria()->getFirstResult() > 0) { $recordsCount = $this->getIndexRepository()->getRecordsCount($query); } else { $recordsCount = count($searchResults); } if ($searchResults) { foreach ($searchResults as $item) { if (is_array($item)) { $item = $item['item']; } /** * Search result can contains duplicates and we can not use HYDRATE_OBJECT because of performance issue. * @todo: update after fix BAP-7166. Remove check for existing result. */ $id = $item['id']; if (isset($results[$id])) { continue; } $results[$id] = new ResultItem($this->registry->getManagerForClass($item['entity']), $item['entity'], $item['recordId'], $item['title'], null, null, $this->mapper->getEntityConfig($item['entity'])); } } return ['results' => $results, 'records_count' => $recordsCount]; }
public function process(PrepareResultItemEvent $event) { $entity = $event->getEntity(); if (!$entity instanceof Ticket) { return; } $item = $event->getResultItem(); $name = $item->getEntityName(); $routeParameters = $this->mapper->getEntityMapParameter($name, 'route'); $routeData = array(); foreach ($routeParameters['parameters'] as $parameter => $field) { $routeData[$parameter] = $entity->getKey(); break; } $router = $this->container->get('router'); $url = $router->generate($routeParameters['name'], $routeData, true); $item->setRecordUrl($url); $title = $entity->getKey() . static::TITLE_PART_SEPARATOR . $entity->getSubject(); $item->setRecordTitle($title); }
/** * Returns a DQL expression that can be used to get a text representation of the given type of entities. * * @param string $className The FQCN of the entity * @param string $alias The alias in SELECT or JOIN statement * * @return string|false */ protected function getNameDQL($className, $alias) { $fields = $this->mapper->getEntityMapParameter($className, 'title_fields'); if ($fields) { $titleParts = []; foreach ($fields as $field) { $titleParts[] = $alias . '.' . $field; $titleParts[] = '\' \''; } return QueryUtils::buildConcatExpr($titleParts); } return false; }
/** * @param Taggable $resource * @param ArrayCollection $tagsToAdd */ protected function persistTags(Taggable $resource, ArrayCollection $tagsToAdd) { foreach ($tagsToAdd as $tag) { if ($this->getUser() && (!$this->securityFacade->isGranted(self::ACL_RESOURCE_ASSIGN_ID_KEY) || !$this->securityFacade->isGranted(self::ACL_RESOURCE_CREATE_ID_KEY) && !$tag->getId())) { // skip tags that have not ID because user not granted to create tags continue; } $this->em->persist($tag); $alias = $this->mapper->getEntityConfig(ClassUtils::getClass($resource)); $tagging = $this->createTagging($tag, $resource)->setAlias($alias['alias']); $this->em->persist($tagging); } }
/** * {@inheritdoc} */ public function transform($value) { if (!$value) { return ''; } if (is_array($value)) { $result = []; $user = $this->securityTokenStorage->getToken()->getUser(); foreach ($value as $target) { // Exclude current user $targetClass = ClassUtils::getClass($target); if (ClassUtils::getClass($user) === $targetClass && $user->getId() === $target->getId()) { continue; } if ($fields = $this->mapper->getEntityMapParameter($targetClass, 'title_fields')) { $text = []; foreach ($fields as $field) { $text[] = $this->mapper->getFieldValue($target, $field); } } else { $text = [$this->translator->trans('oro.entity.item', ['%id%' => $target->getId()])]; } $text = implode(' ', $text); if ($label = $this->getClassLabel($targetClass)) { $text .= ' (' . $label . ')'; } $item['title'] = $text; $item['targetId'] = $target->getId(); $event = new PrepareContextTitleEvent($item, $targetClass); $this->dispatcher->dispatch(PrepareContextTitleEvent::EVENT_NAME, $event); $item = $event->getItem(); $text = $item['title']; $result[] = json_encode(['text' => $text, 'id' => json_encode(['entityClass' => ClassUtils::getClass($target), 'entityId' => $target->getId()])]); } $value = implode(';', $result); } return $value; }
/** * Get entity string * * @param object $entity * * @return string */ protected function getEntityTitle($entity) { $entityClass = ClassUtils::getClass($entity); $fields = $this->mapper->getEntityMapParameter($entityClass, 'title_fields'); if ($fields) { $title = []; foreach ($fields as $field) { $title[] = $this->mapper->getFieldValue($entity, $field); } } else { $title = [(string) $entity]; } return implode(' ', $title); }
/** * Get entity string * * @param $entity object * @param $item \Oro\Bundle\SearchBundle\Query\Result\Item * * @return string */ protected function getEntityTitle($entity, $item) { $name = $item->getEntityName(); if (!$entity) { $entity = $this->em->getRepository($name)->find($item->getRecordId()); } if ($fields = $this->mapper->getEntityMapParameter($name, 'title_fields')) { $title = array(); foreach ($fields as $field) { $title[] = $this->mapper->getFieldValue($entity, $field); } } else { $title = array((string) $entity); } return implode(' ', $title); }
/** * Returns the context for the given activity class and id * * @param string $class The FQCN of the activity entity * @param $id * * @return array */ public function getActivityContext($class, $id) { $currentUser = $this->securityTokenStorage->getToken()->getUser(); $userClass = ClassUtils::getClass($currentUser); $entity = $this->doctrineHelper->getEntity($class, $id); $result = []; if (!$entity || !$entity instanceof ActivityInterface) { return $result; } $targets = $entity->getActivityTargetEntities(); $entityProvider = $this->configManager->getProvider('entity'); foreach ($targets as $target) { $targetClass = ClassUtils::getClass($target); $targetId = $target->getId(); if ($userClass === $targetClass && $currentUser->getId() === $targetId) { continue; } $item = []; $config = $entityProvider->getConfig($targetClass); $metadata = $this->configManager->getEntityMetadata($targetClass); $safeClassName = $this->entityClassNameHelper->getUrlSafeClassName($targetClass); $link = null; if ($metadata) { $link = $this->router->generate($metadata->getRoute(), ['id' => $targetId]); } elseif ($link === null && ExtendHelper::isCustomEntity($targetClass)) { // Generate view link for the custom entity $link = $this->router->generate('oro_entity_view', ['id' => $targetId, 'entityName' => $safeClassName]); } if ($fields = $this->mapper->getEntityMapParameter($targetClass, 'title_fields')) { $text = []; foreach ($fields as $field) { $text[] = $this->mapper->getFieldValue($target, $field); } $item['title'] = implode(' ', $text); } else { $item['title'] = $this->translator->trans('oro.entity.item', ['%id%' => $targetId]); } $item['activityClassAlias'] = $this->entityAliasResolver->getPluralAlias($class); $item['entityId'] = $id; $item['targetId'] = $targetId; $item['targetClassName'] = $safeClassName; $item['icon'] = $config->get('icon'); $item['link'] = $link; $result[] = $item; } return $result; }
/** * @param $item * @param $targetClass * @param $target * @param $targetId * * @return mixed */ protected function prepareItemTitle($item, $targetClass, $target, $targetId) { if (!array_key_exists('title', $item) || !$item['title']) { if ($fields = $this->mapper->getEntityMapParameter($targetClass, 'title_fields')) { $text = []; foreach ($fields as $field) { $text[] = $this->mapper->getFieldValue($target, $field); } $item['title'] = implode(' ', $text); return $item; } else { $item['title'] = $this->translator->trans('oro.entity.item', ['%id%' => $targetId]); return $item; } } return $item; }
/** * Apply ACL to search Query. * Removes all entities of the request to which the user has no access * * @param Query $query */ protected function applyAclToQuery(Query $query) { $allowedEntities = $this->getAllowedEntitiesListAliases(); $queryFromEntities = $query->getFrom(); $entitiesList = array_values($allowedEntities); // in query, from record !== '*' if (!empty($queryFromEntities) && $queryFromEntities[0] !== '*') { foreach ($queryFromEntities as $key => $fromEntityAlias) { if (!in_array($fromEntityAlias, $entitiesList)) { unset($queryFromEntities[$key]); } } $query->from($queryFromEntities); } elseif ($allowedEntities != $this->mapper->getEntitiesListAliases()) { $query->from($allowedEntities); } }
/** * Returns the context for the given activity class and id * * @param string $class The FQCN of the activity entity * @param $id * * @return array */ public function getActivityContext($class, $id) { $currentUser = $this->securityTokenStorage->getToken()->getUser(); $userClass = ClassUtils::getClass($currentUser); $entity = $this->doctrineHelper->getEntity($class, $id); $result = []; if (!$entity || !$entity instanceof ActivityInterface) { return $result; } $targets = $entity->getActivityTargetEntities(); $entityProvider = $this->configManager->getProvider('entity'); foreach ($targets as $target) { $targetClass = ClassUtils::getClass($target); $targetId = $target->getId(); if ($userClass === $targetClass && $currentUser->getId() === $targetId) { continue; } $item = []; $config = $entityProvider->getConfig($targetClass); $safeClassName = $this->entityClassNameHelper->getUrlSafeClassName($targetClass); if (!array_key_exists('title', $item) || !$item['title']) { if ($fields = $this->mapper->getEntityMapParameter($targetClass, 'title_fields')) { $text = []; foreach ($fields as $field) { $text[] = $this->mapper->getFieldValue($target, $field); } $item['title'] = implode(' ', $text); } else { $item['title'] = $this->translator->trans('oro.entity.item', ['%id%' => $targetId]); } } $item['activityClassAlias'] = $this->entityAliasResolver->getPluralAlias($class); $item['entityId'] = $id; $item['targetId'] = $targetId; $item['targetClassName'] = $safeClassName; $item['icon'] = $config->get('icon'); $item['link'] = $this->getContextLink($targetClass, $targetId); $event = new PrepareContextTitleEvent($item, $targetClass); $this->dispatcher->dispatch(PrepareContextTitleEvent::EVENT_NAME, $event); $item = $event->getItem(); $result[] = $item; } return $result; }
/** * Saves tags for the given taggable resource * * @param Taggable $resource Taggable resource * @param bool $flush Whether to flush the changes (default true) */ public function saveTagging(Taggable $resource, $flush = true) { $oldTags = $this->getTagging($resource, $this->getUser()->getId()); $newTags = $resource->getTags(); if (isset($newTags['all'], $newTags['owner'])) { $newOwnerTags = new ArrayCollection($newTags['owner']); $newAllTags = new ArrayCollection($newTags['all']); $manager = $this; $tagsToAdd = $newOwnerTags->filter(function ($tag) use($oldTags, $manager) { return !$oldTags->exists($manager->compareCallback($tag)); }); $tagsToDelete = $oldTags->filter(function ($tag) use($newOwnerTags, $manager) { return !$newOwnerTags->exists($manager->compareCallback($tag)); }); if (!$tagsToDelete->isEmpty() && $this->securityFacade->isGranted(self::ACL_RESOURCE_ASSIGN_ID_KEY)) { $this->deleteTaggingByParams($tagsToDelete, ClassUtils::getClass($resource), $resource->getTaggableId(), $this->getUser()->getId()); } // process if current user allowed to remove other's tag links if ($this->securityFacade->isGranted(self::ACL_RESOURCE_REMOVE_ID_KEY)) { // get 'not mine' taggings $oldTags = $this->getTagging($resource, $this->getUser()->getId(), true); $tagsToDelete = $oldTags->filter(function ($tag) use($newAllTags, $manager) { return !$newAllTags->exists($manager->compareCallback($tag)); }); if (!$tagsToDelete->isEmpty()) { $this->deleteTaggingByParams($tagsToDelete, ClassUtils::getClass($resource), $resource->getTaggableId()); } } foreach ($tagsToAdd as $tag) { if (!$this->securityFacade->isGranted(self::ACL_RESOURCE_ASSIGN_ID_KEY) || !$this->securityFacade->isGranted(self::ACL_RESOURCE_CREATE_ID_KEY) && !$tag->getId()) { // skip tags that have not ID because user not granted to create tags continue; } $this->em->persist($tag); $alias = $this->mapper->getEntityConfig(ClassUtils::getClass($resource)); $tagging = $this->createTagging($tag, $resource)->setAlias($alias['alias']); $this->em->persist($tagging); } if (!$tagsToAdd->isEmpty() && $flush) { $this->em->flush(); } } }
/** * {@inheritdoc} */ protected function doSearch(Query $query) { $results = array(); $searchResults = $this->getIndexRepository()->search($query); if ($query->getMaxResults() > 0 || $query->getFirstResult() > 0) { $recordsCount = $this->getIndexRepository()->getRecordsCount($query); } else { $recordsCount = count($searchResults); } if ($searchResults) { foreach ($searchResults as $item) { if (is_array($item)) { $item = $item['item']; } /** @var $item Item */ $results[] = new ResultItem($this->registry->getManagerForClass($item->getEntity()), $item->getEntity(), $item->getRecordId(), $item->getTitle(), null, $item->getRecordText(), $this->mapper->getEntityConfig($item->getEntity())); } } return array('results' => $results, 'records_count' => $recordsCount); }
/** * Apply special behavior of class inheritance processing * * @param Query $query */ protected function applyModesBehavior(Query $query) { // process abstract indexes // make hashes increasing performance $fromParts = (array) $query->getFrom(); $fromHash = array_combine($fromParts, $fromParts); $aliases = $this->mapper->getEntitiesListAliases(); $aliasesHash = array_flip($aliases); if (!isset($fromHash['*'])) { foreach ($fromParts as $part) { $entityName = $part; $isAlias = false; if (isset($aliasesHash[$part])) { // find real name by alias $entityName = $aliasesHash[$part]; $isAlias = true; } $mode = $this->mapper->getEntityModeConfig($entityName); $descendants = $this->mapper->getRegisteredDescendants($entityName); if (false !== $descendants) { // add descendants to from clause foreach ($descendants as $fromPart) { if ($isAlias) { $fromPart = $aliases[$fromPart]; } if (!isset($fromHash[$fromPart])) { $fromHash[$fromPart] = $fromPart; } } } if ($mode === Mode::ONLY_DESCENDANTS) { unset($fromHash[$part]); } } } $collectedParts = array_values($fromHash); if ($collectedParts !== $fromParts) { $query->from($collectedParts); } }
/** * Advanced search from API * * @param string $searchString * @return Result */ public function advancedSearch($searchString) { $parser = new Parser($this->mapper->getMappingConfig()); return $this->query($parser->getQueryFromString($searchString)); }
public function testNonExistsConfig() { $this->assertEquals(false, $this->mapper->getEntityConfig('non exists entity')); }