Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,205 @@
<?php
namespace Gedmo\Translatable\Mapping\Event\Adapter;
use Gedmo\Mapping\Event\Adapter\ODM as BaseAdapterODM;
use Gedmo\Tool\Wrapper\AbstractWrapper;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
use Doctrine\ODM\MongoDB\Cursor;
use Gedmo\Translatable\Mapping\Event\TranslatableAdapter;
/**
* Doctrine event adapter for ODM adapted
* for Translatable behavior
*
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
final class ODM extends BaseAdapterODM implements TranslatableAdapter
{
/**
* {@inheritDoc}
*/
public function usesPersonalTranslation($translationClassName)
{
return $this
->getObjectManager()
->getClassMetadata($translationClassName)
->getReflectionClass()
->isSubclassOf('Gedmo\Translatable\Document\MappedSuperclass\AbstractPersonalTranslation')
;
}
/**
* {@inheritDoc}
*/
public function getDefaultTranslationClass()
{
return 'Gedmo\\Translatable\\Document\\Translation';
}
/**
* {@inheritDoc}
*/
public function loadTranslations($object, $translationClass, $locale, $objectClass)
{
$dm = $this->getObjectManager();
$wrapped = AbstractWrapper::wrap($object, $dm);
$result = array();
if ($this->usesPersonalTranslation($translationClass)) {
// first try to load it using collection
foreach ($wrapped->getMetadata()->fieldMappings as $mapping) {
$isRightCollection = isset($mapping['association'])
&& $mapping['association'] === ClassMetadataInfo::REFERENCE_MANY
&& $mapping['targetDocument'] === $translationClass
&& $mapping['mappedBy'] === 'object'
;
if ($isRightCollection) {
$collection = $wrapped->getPropertyValue($mapping['fieldName']);
foreach ($collection as $trans) {
if ($trans->getLocale() === $locale) {
$result[] = array(
'field' => $trans->getField(),
'content' => $trans->getContent(),
);
}
}
return $result;
}
}
$q = $dm
->createQueryBuilder($translationClass)
->field('object.$id')->equals($wrapped->getIdentifier())
->field('locale')->equals($locale)
->getQuery()
;
} else {
// load translated content for all translatable fields
// construct query
$q = $dm
->createQueryBuilder($translationClass)
->field('foreignKey')->equals($wrapped->getIdentifier())
->field('locale')->equals($locale)
->field('objectClass')->equals($objectClass)
->getQuery()
;
}
$q->setHydrate(false);
$result = $q->execute();
if ($result instanceof Cursor) {
$result = $result->toArray();
}
return $result;
}
/**
* {@inheritDoc}
*/
public function findTranslation(AbstractWrapper $wrapped, $locale, $field, $translationClass, $objectClass)
{
$dm = $this->getObjectManager();
$qb = $dm
->createQueryBuilder($translationClass)
->field('locale')->equals($locale)
->field('field')->equals($field)
->limit(1)
;
if ($this->usesPersonalTranslation($translationClass)) {
$qb->field('object.$id')->equals($wrapped->getIdentifier());
} else {
$qb->field('foreignKey')->equals($wrapped->getIdentifier());
$qb->field('objectClass')->equals($objectClass);
}
$q = $qb->getQuery();
$result = $q->execute();
if ($result instanceof Cursor) {
$result = current($result->toArray());
}
return $result;
}
/**
* {@inheritDoc}
*/
public function removeAssociatedTranslations(AbstractWrapper $wrapped, $transClass, $objectClass)
{
$dm = $this->getObjectManager();
$qb = $dm
->createQueryBuilder($transClass)
->remove()
;
if ($this->usesPersonalTranslation($transClass)) {
$qb->field('object.$id')->equals($wrapped->getIdentifier());
} else {
$qb->field('foreignKey')->equals($wrapped->getIdentifier());
$qb->field('objectClass')->equals($objectClass);
}
$q = $qb->getQuery();
return $q->execute();
}
/**
* {@inheritDoc}
*/
public function insertTranslationRecord($translation)
{
$dm = $this->getObjectManager();
$meta = $dm->getClassMetadata(get_class($translation));
$collection = $dm->getDocumentCollection($meta->name);
$data = array();
foreach ($meta->getReflectionProperties() as $fieldName => $reflProp) {
if (!$meta->isIdentifier($fieldName)) {
$data[$meta->fieldMappings[$fieldName]['name']] = $reflProp->getValue($translation);
}
}
if (!$collection->insert($data)) {
throw new \Gedmo\Exception\RuntimeException('Failed to insert new Translation record');
}
}
/**
* {@inheritDoc}
*/
public function getTranslationValue($object, $field, $value = false)
{
$dm = $this->getObjectManager();
$wrapped = AbstractWrapper::wrap($object, $dm);
$meta = $wrapped->getMetadata();
$mapping = $meta->getFieldMapping($field);
$type = $this->getType($mapping['type']);
if ($value === false) {
$value = $wrapped->getPropertyValue($field);
}
return $type->convertToDatabaseValue($value);
}
/**
* {@inheritDoc}
*/
public function setTranslationValue($object, $field, $value)
{
$dm = $this->getObjectManager();
$wrapped = AbstractWrapper::wrap($object, $dm);
$meta = $wrapped->getMetadata();
$mapping = $meta->getFieldMapping($field);
$type = $this->getType($mapping['type']);
$value = $type->convertToPHPValue($value);
$wrapped->setPropertyValue($field, $value);
}
private function getType($type)
{
// due to change in ODM beta 9
return class_exists('Doctrine\ODM\MongoDB\Types\Type') ? \Doctrine\ODM\MongoDB\Types\Type::getType($type)
: \Doctrine\ODM\MongoDB\Mapping\Types\Type::getType($type);
}
}

View File

@@ -0,0 +1,260 @@
<?php
namespace Gedmo\Translatable\Mapping\Event\Adapter;
use Doctrine\Common\Proxy\Proxy;
use Doctrine\DBAL\Types\Type;
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>
* @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 = $this->foreignKey($wrapped->getIdentifier(), $translationClass);
// 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;
}
/**
* Transforms foreigh key of translation to appropriate PHP value
* to prevent database level cast
*
* @param $key - foreign key value
* @param $className - translation class name
* @return transformed foreign key
*/
private function foreignKey($key, $className)
{
$em = $this->getObjectManager();
$meta = $em->getClassMetadata($className);
$type = Type::getType($meta->getTypeOfField('foreignKey'));
switch ($type->getName()) {
case Type::BIGINT:
case Type::INTEGER:
case Type::SMALLINT:
return intval($key);
default:
return (string)$key;
}
}
/**
* {@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 {
$objectId = $this->foreignKey($wrapped->getIdentifier(), $translationClass);
$isRequestedTranslation = $trans->getForeignKey() === $objectId
&& $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');
if ($wrapped->getIdentifier()) {
$qb->setParameter('object', $wrapped->getObject());
} else {
$qb->setParameter('object', null);
}
} else {
$qb->andWhere('trans.foreignKey = :objectId');
$qb->andWhere('trans.objectClass = :objectClass');
$qb->setParameter('objectId', $this->foreignKey($wrapped->getIdentifier(), $translationClass));
$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', $this->foreignKey($wrapped->getIdentifier(), $transClass));
$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);
}
}

View File

@@ -0,0 +1,96 @@
<?php
namespace Gedmo\Translatable\Mapping\Event;
use Gedmo\Mapping\Event\AdapterInterface;
use Gedmo\Tool\Wrapper\AbstractWrapper;
/**
* Doctrine event adapter interface
* for Translatable behavior
*
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
interface TranslatableAdapter extends AdapterInterface
{
/**
* Checks if $translationClassName is a subclass
* of personal translation
*
* @param string $translationClassName
*
* @return boolean
*/
public function usesPersonalTranslation($translationClassName);
/**
* Get default LogEntry class used to store the logs
*
* @return string
*/
public function getDefaultTranslationClass();
/**
* Load the translations for a given object
*
* @param object $object
* @param string $translationClass
* @param string $locale
* @param string $objectClass
*
* @return array
*/
public function loadTranslations($object, $translationClass, $locale, $objectClass);
/**
* Search for existing translation record
*
* @param AbstractWrapper $wrapped
* @param string $locale
* @param string $field
* @param string $translationClass
* @param string $objectClass
*
* @return mixed - null if nothing is found, Translation otherwise
*/
public function findTranslation(AbstractWrapper $wrapped, $locale, $field, $translationClass, $objectClass);
/**
* Removes all associated translations for given object
*
* @param AbstractWrapper $wrapped
* @param string $transClass
* @param string $objectClass
*/
public function removeAssociatedTranslations(AbstractWrapper $wrapped, $transClass, $objectClass);
/**
* Inserts the translation record
*
* @param object $translation
*/
public function insertTranslationRecord($translation);
/**
* Get the transformed value for translation
* storage
*
* @param object $object
* @param string $field
* @param mixed $value
*
* @return mixed
*/
public function getTranslationValue($object, $field, $value = false);
/**
* Transform the value from database
* for translation
*
* @param object $object
* @param string $field
* @param mixed $value
*/
public function setTranslationValue($object, $field, $value);
}