/** * Gets owner of the given entity * * @param object $object * @return object * @throws \RuntimeException */ public function getOwner($object) { if (!is_object($object)) { throw new InvalidEntityException('$object must be an object.'); } $result = null; $metadata = $this->metadataProvider->getMetadata($this->entityClassAccessor->getClass($object)); if ($metadata->hasOwner()) { // at first try to use getOwner method to get the owner if (method_exists($object, 'getOwner')) { $result = $object->getOwner(); } else { // if getOwner method does not exist try to get owner directly from field try { $cls = new \ReflectionClass($object); $ownerProp = $cls->getProperty($metadata->getOwnerFieldName()); if (!$ownerProp->isPublic()) { $ownerProp->setAccessible(true); } $result = $ownerProp->getValue($object); } catch (\ReflectionException $ex) { throw new InvalidEntityException(sprintf('$object must have either "getOwner" method or "%s" property.', $metadata->getOwnerFieldName()), 0, $ex); } } } return $result; }
/** * Add organization field to the search mapping * * @param PrepareEntityMapEvent $event */ public function prepareEntityMapEvent(PrepareEntityMapEvent $event) { $data = $event->getData(); $className = $event->getClassName(); $entity = $event->getEntity(); $organizationId = self::EMPTY_ORGANIZATION_ID; $metadata = $this->metadataProvider->getMetadata($className); if ($metadata) { $organizationField = null; if ($metadata->getGlobalOwnerFieldName()) { $organizationField = $metadata->getGlobalOwnerFieldName(); } if ($metadata->isGlobalLevelOwned()) { $organizationField = $metadata->getOwnerFieldName(); } if ($organizationField) { $propertyAccessor = PropertyAccess::createPropertyAccessor(); /** @var Organization $organization */ $organization = $propertyAccessor->getValue($entity, $organizationField); if ($organization && null !== $organization->getId()) { $organizationId = $organization->getId(); } } } $data['integer']['organization'] = $organizationId; $event->setData($data); }
/** * {@inheritdoc} */ public function validate($entity, Constraint $constraint) { $className = $this->doctrineHelper->getEntityClass($entity); $organizationField = $this->metadataProvider->getMetadata($className)->getGlobalOwnerFieldName(); if ($organizationField) { $constraint->fields = array_merge((array) $constraint->fields, [$organizationField]); } parent::validate($entity, $constraint); }
/** * Gets organization of the given entity * * @param $object * @return object|null * @throws InvalidEntityException */ public function getOrganization($object) { if (!is_object($object)) { throw new InvalidEntityException('$object must be an object.'); } $result = null; $metadata = $this->metadataProvider->getMetadata(ClassUtils::getClass($object)); if ($metadata->getOrganizationFieldName()) { $accessor = PropertyAccess::createPropertyAccessor(); $result = $accessor->getValue($object, $metadata->getOrganizationFieldName()); } return $result; }
/** * Get data for query acl access level check * Return null if entity has full access, empty array if user does't have access to the entity * and array with entity field and field values witch user have access. * * @param $entityClassName * @param $permissions * @return null|array */ public function getAclConditionData($entityClassName, $permissions = 'VIEW') { if ($this->aclVoter === null || !$this->getUserId() || !$this->entityMetadataProvider->isProtectedEntity($entityClassName)) { return []; } $condition = null; $observer = new OneShotIsGrantedObserver(); $this->aclVoter->addOneShotIsGrantedObserver($observer); $isGranted = $this->getSecurityContext()->isGranted($permissions, 'entity:' . $entityClassName); if ($isGranted) { $condition = $this->buildConstraintIfAccessIsGranted($entityClassName, $observer->getAccessLevel(), $this->metadataProvider->getMetadata($entityClassName)); } return $condition; }
/** * @param object $entity * @return object|null */ public function discoverSimilar($entity) { if (!$this->configuration) { return null; } $idName = $this->doctrineHelper->getSingleEntityIdentifierFieldName($this->discoveryEntityClass); $idFieldName = self::ROOT_ALIAS . '.' . $idName; /** @var EntityRepository $repository */ $repository = $this->doctrineHelper->getEntityRepository($this->discoveryEntityClass); $qb = $repository->createQueryBuilder(self::ROOT_ALIAS)->select(self::ROOT_ALIAS); // Apply search strategies $this->applyStrategies($qb, $entity); // Apply matcher strategy if ($this->configuration[Configuration::DISCOVERY_OPTIONS_KEY][Configuration::DISCOVERY_MATCH_KEY] === Configuration::DISCOVERY_MATCH_LATEST) { $qb->orderBy($idFieldName, Criteria::DESC); } // Skip current entity $id = $this->doctrineHelper->getSingleEntityIdentifier($entity); if (!empty($id)) { $idParameter = ':' . $idName; $qb->andWhere($qb->expr()->neq($idFieldName, $idParameter))->setParameter($idParameter, $id); } // Add organization limits $organizationField = $this->ownershipMetadata->getMetadata(ClassUtils::getClass($entity))->getOrganizationFieldName(); if ($organizationField) { $propertyAccessor = PropertyAccess::createPropertyAccessor(); $organization = $propertyAccessor->getValue($entity, $organizationField); $qb->andWhere(sprintf('%s.%s = :organization', self::ROOT_ALIAS, $organizationField))->setParameter('organization', $organization); } // Get only 1 match $qb->setMaxResults(1); return $qb->getQuery()->getOneOrNullResult(); }
/** * Add organization field to the search mapping * * @param PrepareEntityMapEvent $event */ public function prepareEntityMapEvent(PrepareEntityMapEvent $event) { $data = $event->getData(); $className = $event->getClassName(); $organizationId = self::EMPTY_ORGANIZATION_ID; $ownerId = self::EMPTY_OWNER_ID; $metadata = $this->metadataProvider->getMetadata($className); if ($metadata) { $entity = $event->getEntity(); $ownerId = $this->getOwnerId($metadata, $entity); $organizationId = $this->getOrganizationId($metadata, $entity); } $data['integer'][sprintf('%s_owner', $event->getEntityMapping()['alias'])] = $ownerId; $data['integer']['organization'] = $organizationId; $event->setData($data); }
/** * Limit segment data by segment's organization * * @param Segment $segment * @param QueryBuilder $qb */ protected function applyOrganizationLimit(Segment $segment, QueryBuilder $qb) { $organizationField = $this->ownershipMetadataProvider->getMetadata($segment->getEntity())->getGlobalOwnerFieldName(); if ($organizationField) { $qb->andWhere(sprintf('%s.%s = %s', $qb->getRootAliases()[0], $organizationField, $segment->getOrganization()->getId())); } }
/** * @param string $entityName * @param Organization $organization */ public function setSourceEntityName($entityName, Organization $organization = null) { /** @var QueryBuilder $qb */ $queryBuilder = $this->registry->getRepository($entityName)->createQueryBuilder('o'); $metadata = $queryBuilder->getEntityManager()->getClassMetadata($entityName); foreach (array_keys($metadata->getAssociationMappings()) as $fieldName) { // can't join with *-to-many relations because they affects query pagination if ($metadata->isAssociationWithSingleJoinColumn($fieldName)) { $alias = '_' . $fieldName; $queryBuilder->addSelect($alias); $queryBuilder->leftJoin('o.' . $fieldName, $alias); } } foreach ($metadata->getIdentifierFieldNames() as $fieldName) { $queryBuilder->orderBy('o.' . $fieldName, 'ASC'); } // Limit data with current organization if ($organization) { $organizationField = $this->ownershipMetadata->getMetadata($entityName)->getOrganizationFieldName(); if ($organizationField) { $queryBuilder->andWhere('o.' . $organizationField . ' = :organization')->setParameter('organization', $organization); } } $this->setSourceQueryBuilder($queryBuilder); }
/** * @param $entity - object | class name entity * * @return bool|OwnershipMetadataInterface */ protected function getMetadataConfig($entity) { if (is_object($entity)) { $entity = ClassUtils::getClass($entity); } $metadata = $this->ownershipMetadataProvider->getMetadata($entity); return $metadata->hasOwner() ? $metadata : false; }
/** * Limit data with current organization * * @param QueryBuilder $queryBuilder * @param string $entityName * @param Organization $organization */ protected function addOrganizationLimits(QueryBuilder $queryBuilder, $entityName, Organization $organization = null) { if ($organization) { $organizationField = $this->ownershipMetadata->getMetadata($entityName)->getGlobalOwnerFieldName(); if ($organizationField) { $queryBuilder->andWhere('o.' . $organizationField . ' = :organization')->setParameter('organization', $organization); } } }
/** * Get metadata for entity * * @param object|string $entity * * @return bool|OwnershipMetadataInterface * @throws \LogicException */ protected function getMetadata($entity) { if (is_object($entity)) { $entity = ClassUtils::getClass($entity); } if (!$this->doctrineHelper->isManageableEntity($entity)) { return false; } $metadata = $this->ownershipMetadataProvider->getMetadata($entity); return $metadata->hasOwner() ? $metadata : false; }
/** * @param StaticSegment $staticSegment * @param QueryBuilder $qb * @return void */ public function prepareMarketingListEntities(StaticSegment $staticSegment, QueryBuilder $qb) { if (!$this->memberClassName) { throw new \InvalidArgumentException('Member class name must be provided'); } $marketingList = $staticSegment->getMarketingList(); $contactInformationFields = $this->contactInformationFieldsProvider->getMarketingListTypedFields($marketingList, ContactInformationFieldsProvider::CONTACT_INFORMATION_SCOPE_EMAIL); $expr = $qb->expr()->orX(); foreach ($contactInformationFields as $contactInformationField) { $contactInformationFieldExpr = $this->fieldHelper->getFieldExpr($marketingList->getEntity(), $qb, $contactInformationField); $qb->addSelect($contactInformationFieldExpr . ' AS ' . $contactInformationField); $expr->add($qb->expr()->eq($contactInformationFieldExpr, sprintf('%s.%s', self::MEMBER_ALIAS, self::MEMBER_EMAIL_FIELD))); } $organization = $staticSegment->getChannel()->getOrganization(); $metadata = $this->ownershipMetadataProvider->getMetadata($marketingList->getEntity()); if ($organization && ($fieldName = $metadata->getOrganizationFieldName())) { $aliases = $qb->getRootAliases(); $qb->andWhere($qb->expr()->eq(sprintf('%s.%s', reset($aliases), $fieldName), ':organization')); $qb->setParameter('organization', $organization); } $qb->leftJoin($this->memberClassName, self::MEMBER_ALIAS, Join::WITH, $qb->expr()->andX($expr, $qb->expr()->eq(sprintf('%s.subscribersList', self::MEMBER_ALIAS), ':subscribersList')))->setParameter('subscribersList', $staticSegment->getSubscribersList()->getId()); }
/** * Get metadata for entity * * @param object|string $entity * @return bool|OwnershipMetadata * @throws \LogicException */ protected function getMetadata($entity) { if (is_object($entity)) { $dataClassName = ClassUtils::getClass($entity); } else { $dataClassName = $entity; } $metadata = $this->ownershipMetadataProvider->getMetadata($dataClassName); if ($metadata->hasOwner()) { return $metadata; } else { return false; } }
/** * Checks if the given owner owns at least one entity * * @param object $owner * @return bool */ public function hasAssignments($owner) { $result = false; $ownerType = $this->getOwnerType($owner); if ($ownerType !== OwnershipType::OWNER_TYPE_NONE) { foreach ($this->ownershipProvider->getConfigs(null, true) as $config) { if ($config->get('owner_type') === $ownerType) { $entityClassName = $config->getId()->getClassName(); $result = $this->getAssignmentChecker($entityClassName)->hasAssignments($this->objectIdAccessor->getId($owner), $entityClassName, $this->ownershipMetadata->getMetadata($entityClassName)->getOwnerFieldName(), $this->em); if ($result) { break; } } } } return $result; }
public function testGetMetadataUndefinedClassWithCache() { $this->configProvider->expects($this->once())->method('hasConfig')->with($this->equalTo('UndefinedClass'))->will($this->returnValue(false)); $this->configProvider->expects($this->never())->method('getConfig'); $this->cache->expects($this->at(0))->method('fetch')->with($this->equalTo('UndefinedClass'))->will($this->returnValue(false)); $this->cache->expects($this->at(2))->method('fetch')->with($this->equalTo('UndefinedClass'))->will($this->returnValue(true)); $this->cache->expects($this->once())->method('save')->with($this->equalTo('UndefinedClass'), $this->equalTo(true)); $this->entityClassResolver = null; $providerWithCleanLocalCache = clone $this->provider; $metadata = new OwnershipMetadata(); // no cache $this->assertEquals($metadata, $this->provider->getMetadata('UndefinedClass')); // local cache $this->assertEquals($metadata, $this->provider->getMetadata('UndefinedClass')); // cache $this->assertEquals($metadata, $providerWithCleanLocalCache->getMetadata('UndefinedClass')); }
public function testGetMetadataUndefinedClassWithCache() { $configProvider = $this->getMockBuilder('Oro\\Bundle\\EntityConfigBundle\\Provider\\ConfigProvider')->disableOriginalConstructor()->getMock(); $cache = $this->getMockForAbstractClass('Doctrine\\Common\\Cache\\CacheProvider', array(), '', false, true, true, array('fetch', 'save')); $provider = new OwnershipMetadataProvider(array('organization' => 'AcmeBundle\\Entity\\Organization', 'business_unit' => 'AcmeBundle\\Entity\\BusinessUnit', 'user' => 'AcmeBundle\\Entity\\User'), $configProvider, null, $cache); $metadata = new OwnershipMetadata(); $configProvider->expects($this->once())->method('hasConfig')->with($this->equalTo('UndefinedClass'))->will($this->returnValue(false)); $configProvider->expects($this->never())->method('getConfig'); $cache->expects($this->at(0))->method('fetch')->with($this->equalTo('UndefinedClass'))->will($this->returnValue(false)); $cache->expects($this->at(2))->method('fetch')->with($this->equalTo('UndefinedClass'))->will($this->returnValue(true)); $cache->expects($this->once())->method('save')->with($this->equalTo('UndefinedClass'), $this->equalTo(true)); // no cache $this->assertEquals($metadata, $provider->getMetadata('UndefinedClass')); // local cache $this->assertEquals($metadata, $provider->getMetadata('UndefinedClass')); // cache $provider = new OwnershipMetadataProvider(array('organization' => 'AcmeBundle\\Entity\\Organization', 'business_unit' => 'AcmeBundle\\Entity\\BusinessUnit', 'user' => 'AcmeBundle\\Entity\\User'), $configProvider, null, $cache); $this->assertEquals($metadata, $provider->getMetadata('UndefinedClass')); }
/** * @param FormBuilderInterface $builder * @param array $options * @throws \LogicException when getOwner method isn't implemented for entity with ownership type */ public function buildForm(FormBuilderInterface $builder, array $options) { $dataClassName = $builder->getFormConfig()->getDataClass(); if (!$dataClassName) { return; } $user = $this->getCurrentUser(); if (!$user) { return; } $metadata = $this->ownershipMetadataProvider->getMetadata($dataClassName); if (!$metadata->hasOwner()) { return; } if (!method_exists($dataClassName, 'getOwner')) { throw new \LogicException(sprintf('Method getOwner must be implemented for %s entity.', $dataClassName)); } /** * TODO: Implement object-based assign check after access levels are supported */ $this->isAssignGranted = $this->securityFacade->isGranted('ASSIGN', 'entity:' . $dataClassName); $defaultOwner = null; if ($metadata->isUserOwned() && $this->isAssignGranted) { $this->addUserOwnerField($builder); $defaultOwner = $user; } elseif ($metadata->isBusinessUnitOwned()) { $this->addBusinessUnitOwnerField($builder, $user, $dataClassName); $defaultOwner = $this->getCurrentBusinessUnit(); } elseif ($metadata->isOrganizationOwned()) { $this->addOrganizationOwnerField($builder, $user); $defaultOwner = $this->getCurrentOrganization(); } /** * Adding subscriber to hide owner field for update pages if assign permission is not granted * and set default owner value */ $builder->addEventSubscriber(new OwnerFormSubscriber($this->managerRegistry, $this->fieldName, $this->fieldLabel, $this->isAssignGranted, $defaultOwner)); }
/** * Get metadata for entity * * @param string $entityFQCN * * @return OwnershipMetadataInterface */ protected function getMetadata($entityFQCN) { return $this->ownershipMetadataProvider->getMetadata($entityFQCN); }
/** * Gets metadata for the given object * * @param mixed $object * * @return OwnershipMetadata */ protected function getMetadata($object) { return $this->metadataProvider->getMetadata($this->getObjectClassName($object)); }
/** * {@inheritdoc} */ public function getMetadata($className) { return isset($this->metadata[$className]) ? $this->metadata[$className] : parent::getMetadata($className); }
/** * Gets metadata for the given domain object * * @param object $domainObject * @return OwnershipMetadata */ protected function getObjectMetadata($domainObject) { return $this->metadataProvider->getMetadata($this->getObjectClass($domainObject)); }