123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- <?php
- namespace Gedmo\Translatable\Mapping\Event\Adapter;
- use Doctrine\DBAL\Types\Type;
- use Doctrine\ORM\Query;
- use Doctrine\ORM\Mapping\ClassMetadataInfo;
- use Gedmo\Mapping\Event\Adapter\ORM as BaseAdapterORM;
- use Gedmo\Translatable\Mapping\Event\TranslatableAdapter;
- use Gedmo\Tool\Wrapper\AbstractWrapper;
- /**
- * Doctrine event adapter for ORM adapted
- * for Translatable behavior
- *
- * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
- * @package Gedmo\Translatable\Mapping\Event\Adapter
- * @subpackage ORM
- * @link http://www.gediminasm.org
- * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
- */
- final class ORM extends BaseAdapterORM implements TranslatableAdapter
- {
- /**
- * {@inheritDoc}
- */
- public function usesPersonalTranslation($translationClassName)
- {
- return $this
- ->getObjectManager()
- ->getClassMetadata($translationClassName)
- ->getReflectionClass()
- ->isSubclassOf('Gedmo\Translatable\Entity\MappedSuperclass\AbstractPersonalTranslation')
- ;
- }
- /**
- * {@inheritDoc}
- */
- public function getDefaultTranslationClass()
- {
- return 'Gedmo\\Translatable\\Entity\\Translation';
- }
- /**
- * {@inheritDoc}
- */
- public function loadTranslations($object, $translationClass, $locale, $objectClass)
- {
- $em = $this->getObjectManager();
- $wrapped = AbstractWrapper::wrap($object, $em);
- $result = array();
- if ($this->usesPersonalTranslation($translationClass)) {
- // first try to load it using collection
- $found = false;
- foreach ($wrapped->getMetadata()->associationMappings as $assoc) {
- $isRightCollection = $assoc['targetEntity'] === $translationClass
- && $assoc['mappedBy'] === 'object'
- && $assoc['type'] === ClassMetadataInfo::ONE_TO_MANY
- ;
- if ($isRightCollection) {
- $collection = $wrapped->getPropertyValue($assoc['fieldName']);
- foreach ($collection as $trans) {
- if ($trans->getLocale() === $locale) {
- $result[] = array(
- 'field' => $trans->getField(),
- 'content' => $trans->getContent()
- );
- }
- }
- $found = true;
- break;
- }
- }
- // if collection is not set, fetch it through relation
- if (!$found) {
- $dql = 'SELECT t.content, t.field FROM ' . $translationClass . ' t';
- $dql .= ' WHERE t.locale = :locale';
- $dql .= ' AND t.object = :object';
- $q = $em->createQuery($dql);
- $q->setParameters(compact('object', 'locale'));
- $result = $q->getArrayResult();
- }
- } else {
- // load translated content for all translatable fields
- $objectId = $wrapped->getIdentifier();
- // construct query
- $dql = 'SELECT t.content, t.field FROM ' . $translationClass . ' t';
- $dql .= ' WHERE t.foreignKey = :objectId';
- $dql .= ' AND t.locale = :locale';
- $dql .= ' AND t.objectClass = :objectClass';
- // fetch results
- $q = $em->createQuery($dql);
- $q->setParameters(compact('objectId', 'locale', 'objectClass'));
- $result = $q->getArrayResult();
- }
- return $result;
- }
- /**
- * {@inheritDoc}
- */
- public function findTranslation(AbstractWrapper $wrapped, $locale, $field, $translationClass, $objectClass)
- {
- $em = $this->getObjectManager();
- // first look in identityMap, will save one SELECT query
- foreach ($em->getUnitOfWork()->getIdentityMap() as $className => $objects) {
- if ($className === $translationClass) {
- foreach ($objects as $trans) {
- $isRequestedTranslation = !$trans instanceof Proxy
- && $trans->getLocale() === $locale
- && $trans->getField() === $field
- ;
- if ($isRequestedTranslation) {
- if ($this->usesPersonalTranslation($translationClass)) {
- $isRequestedTranslation = $trans->getObject() === $wrapped->getObject();
- } else {
- $isRequestedTranslation = $trans->getForeignKey() === $wrapped->getIdentifier()
- && $trans->getObjectClass() === $wrapped->getMetadata()->name
- ;
- }
- }
- if ($isRequestedTranslation) {
- return $trans;
- }
- }
- }
- }
- $qb = $em->createQueryBuilder();
- $qb->select('trans')
- ->from($translationClass, 'trans')
- ->where(
- 'trans.locale = :locale',
- 'trans.field = :field'
- )
- ;
- $qb->setParameters(compact('locale', 'field'));
- if ($this->usesPersonalTranslation($translationClass)) {
- $qb->andWhere('trans.object = :object');
- $qb->setParameter('object', $wrapped->getObject());
- } else {
- $qb->andWhere('trans.foreignKey = :objectId');
- $qb->andWhere('trans.objectClass = :objectClass');
- $qb->setParameter('objectId', $wrapped->getIdentifier());
- $qb->setParameter('objectClass', $objectClass);
- }
- $q = $qb->getQuery();
- $q->setMaxResults(1);
- $result = $q->getResult();
- if ($result) {
- return array_shift($result);
- }
- return null;
- }
- /**
- * {@inheritDoc}
- */
- public function removeAssociatedTranslations(AbstractWrapper $wrapped, $transClass, $objectClass)
- {
- $qb = $this
- ->getObjectManager()
- ->createQueryBuilder()
- ->delete($transClass, 'trans')
- ;
- if ($this->usesPersonalTranslation($transClass)) {
- $qb->where('trans.object = :object');
- $qb->setParameter('object', $wrapped->getObject());
- } else {
- $qb->where(
- 'trans.foreignKey = :objectId',
- 'trans.objectClass = :class'
- );
- $qb->setParameter('objectId', $wrapped->getIdentifier());
- $qb->setParameter('class', $objectClass);
- }
- return $qb->getQuery()->getSingleScalarResult();
- }
- /**
- * {@inheritDoc}
- */
- public function insertTranslationRecord($translation)
- {
- $em = $this->getObjectManager();
- $meta = $em->getClassMetadata(get_class($translation));
- $data = array();
- foreach ($meta->getReflectionProperties() as $fieldName => $reflProp) {
- if (!$meta->isIdentifier($fieldName)) {
- $data[$meta->getColumnName($fieldName)] = $reflProp->getValue($translation);
- }
- }
- $table = $meta->getTableName();
- if (!$em->getConnection()->insert($table, $data)) {
- throw new \Gedmo\Exception\RuntimeException('Failed to insert new Translation record');
- }
- }
- /**
- * {@inheritDoc}
- */
- public function getTranslationValue($object, $field, $value = false)
- {
- $em = $this->getObjectManager();
- $wrapped = AbstractWrapper::wrap($object, $em);
- $meta = $wrapped->getMetadata();
- $type = Type::getType($meta->getTypeOfField($field));
- if ($value === false) {
- $value = $wrapped->getPropertyValue($field);
- }
- return $type->convertToDatabaseValue($value, $em->getConnection()->getDatabasePlatform());
- }
- /**
- * {@inheritDoc}
- */
- public function setTranslationValue($object, $field, $value)
- {
- $em = $this->getObjectManager();
- $wrapped = AbstractWrapper::wrap($object, $em);
- $meta = $wrapped->getMetadata();
- $type = Type::getType($meta->getTypeOfField($field));
- $value = $type->convertToPHPValue($value, $em->getConnection()->getDatabasePlatform());
- $wrapped->setPropertyValue($field, $value);
- }
- }
|