This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
<?php
namespace Gedmo\Translatable\Mapping\Driver;
use Gedmo\Mapping\Driver\AbstractAnnotationDriver;
use Gedmo\Exception\InvalidMappingException;
/**
* This is an annotation mapping driver for Translatable
* behavioral extension. Used for extraction of extended
* metadata from Annotations specifically for Translatable
* extension.
*
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class Annotation extends AbstractAnnotationDriver
{
/**
* Annotation to identity translation entity to be used for translation storage
*/
const ENTITY_CLASS = 'Gedmo\\Mapping\\Annotation\\TranslationEntity';
/**
* Annotation to identify field as translatable
*/
const TRANSLATABLE = 'Gedmo\\Mapping\\Annotation\\Translatable';
/**
* Annotation to identify field which can store used locale or language
* alias is LANGUAGE
*/
const LOCALE = 'Gedmo\\Mapping\\Annotation\\Locale';
/**
* Annotation to identify field which can store used locale or language
* alias is LOCALE
*/
const LANGUAGE = 'Gedmo\\Mapping\\Annotation\\Language';
/**
* {@inheritDoc}
*/
public function readExtendedMetadata($meta, array &$config)
{
$class = $this->getMetaReflectionClass($meta);
// class annotations
if ($annot = $this->reader->getClassAnnotation($class, self::ENTITY_CLASS)) {
if (!$cl = $this->getRelatedClassName($meta, $annot->class)) {
throw new InvalidMappingException("Translation class: {$annot->class} does not exist.");
}
$config['translationClass'] = $cl;
}
// property annotations
foreach ($class->getProperties() as $property) {
if ($meta->isMappedSuperclass && !$property->isPrivate() ||
$meta->isInheritedField($property->name) ||
isset($meta->associationMappings[$property->name]['inherited'])
) {
continue;
}
// translatable property
if ($translatable = $this->reader->getPropertyAnnotation($property, self::TRANSLATABLE)) {
$field = $property->getName();
if (!$meta->hasField($field)) {
throw new InvalidMappingException("Unable to find translatable [{$field}] as mapped property in entity - {$meta->name}");
}
// fields cannot be overrided and throws mapping exception
$config['fields'][] = $field;
if (isset($translatable->fallback)) {
$config['fallback'][$field] = $translatable->fallback;
}
}
// locale property
if ($this->reader->getPropertyAnnotation($property, self::LOCALE)) {
$field = $property->getName();
if ($meta->hasField($field)) {
throw new InvalidMappingException("Locale field [{$field}] should not be mapped as column property in entity - {$meta->name}, since it makes no sense");
}
$config['locale'] = $field;
} elseif ($this->reader->getPropertyAnnotation($property, self::LANGUAGE)) {
$field = $property->getName();
if ($meta->hasField($field)) {
throw new InvalidMappingException("Language field [{$field}] should not be mapped as column property in entity - {$meta->name}, since it makes no sense");
}
$config['locale'] = $field;
}
}
// Embedded entity
if (property_exists($meta, 'embeddedClasses') && $meta->embeddedClasses) {
foreach ($meta->embeddedClasses as $propertyName => $embeddedClassInfo) {
if ($meta->isInheritedEmbeddedClass($propertyName)) {
continue;
}
$embeddedClass = new \ReflectionClass($embeddedClassInfo['class']);
foreach ($embeddedClass->getProperties() as $embeddedProperty) {
if ($translatable = $this->reader->getPropertyAnnotation($embeddedProperty, self::TRANSLATABLE)) {
$field = $propertyName . '.' . $embeddedProperty->getName();
$config['fields'][] = $field;
if (isset($translatable->fallback)) {
$config['fallback'][$field] = $translatable->fallback;
}
}
}
}
}
if (!$meta->isMappedSuperclass && $config) {
if (is_array($meta->identifier) && count($meta->identifier) > 1) {
throw new InvalidMappingException("Translatable does not support composite identifiers in class - {$meta->name}");
}
}
}
}

View File

@@ -0,0 +1,108 @@
<?php
namespace Gedmo\Translatable\Mapping\Driver;
use Gedmo\Mapping\Driver\Xml as BaseXml;
use Gedmo\Exception\InvalidMappingException;
/**
* This is a xml mapping driver for Translatable
* behavioral extension. Used for extraction of extended
* metadata from xml specifically for Translatable
* extension.
*
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @author Miha Vrhovnik <miha.vrhovnik@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class Xml extends BaseXml
{
/**
* {@inheritDoc}
*/
public function readExtendedMetadata($meta, array &$config)
{
/**
* @var \SimpleXmlElement $xml
*/
$xml = $this->_getMapping($meta->name);
$xmlDoctrine = $xml;
$xml = $xml->children(self::GEDMO_NAMESPACE_URI);
if (($xmlDoctrine->getName() == 'entity' || $xmlDoctrine->getName() == 'mapped-superclass')) {
if ($xml->count() && isset($xml->translation)) {
/**
* @var \SimpleXmlElement $data
*/
$data = $xml->translation;
if ($this->_isAttributeSet($data, 'locale')) {
$config['locale'] = $this->_getAttribute($data, 'locale');
} elseif ($this->_isAttributeSet($data, 'language')) {
$config['locale'] = $this->_getAttribute($data, 'language');
}
if ($this->_isAttributeSet($data, 'entity')) {
$entity = $this->_getAttribute($data, 'entity');
if (!$cl = $this->getRelatedClassName($meta, $entity)) {
throw new InvalidMappingException("Translation entity class: {$entity} does not exist.");
}
$config['translationClass'] = $cl;
}
}
}
if (property_exists($meta, 'embeddedClasses') && $meta->embeddedClasses) {
foreach ($meta->embeddedClasses as $propertyName => $embeddedClassInfo) {
if ($meta->isInheritedEmbeddedClass($propertyName)) {
continue;
}
$xmlEmbeddedClass = $this->_getMapping($embeddedClassInfo['class']);
$this->inspectElementsForTranslatableFields($xmlEmbeddedClass, $config, $propertyName);
}
}
if ($xmlDoctrine->{'attribute-overrides'}->count() > 0) {
foreach ($xmlDoctrine->{'attribute-overrides'}->{'attribute-override'} as $overrideMapping) {
$this->buildFieldConfiguration($this->_getAttribute($overrideMapping, 'name'), $overrideMapping->field, $config);
}
}
$this->inspectElementsForTranslatableFields($xmlDoctrine, $config);
if (!$meta->isMappedSuperclass && $config) {
if (is_array($meta->identifier) && count($meta->identifier) > 1) {
throw new InvalidMappingException("Translatable does not support composite identifiers in class - {$meta->name}");
}
}
}
private function inspectElementsForTranslatableFields(\SimpleXMLElement $xml, array &$config, $prefix = null)
{
if (!isset($xml->field)) {
return;
}
foreach ($xml->field as $mapping) {
$mappingDoctrine = $mapping;
$fieldName = $this->_getAttribute($mappingDoctrine, 'name');
if ($prefix !== null) {
$fieldName = $prefix . '.' . $fieldName;
}
$this->buildFieldConfiguration($fieldName, $mapping, $config);
}
}
private function buildFieldConfiguration($fieldName, \SimpleXMLElement $mapping, array &$config)
{
$mapping = $mapping->children(self::GEDMO_NAMESPACE_URI);
if ($mapping->count() > 0 && isset($mapping->translatable)) {
$config['fields'][] = $fieldName;
/** @var \SimpleXmlElement $data */
$data = $mapping->translatable;
if ($this->_isAttributeSet($data, 'fallback')) {
$config['fallback'][$fieldName] = 'true' == $this->_getAttribute($data, 'fallback') ? true : false;
}
}
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace Gedmo\Translatable\Mapping\Driver;
use Gedmo\Mapping\Driver\File;
use Gedmo\Mapping\Driver;
use Gedmo\Exception\InvalidMappingException;
/**
* This is a yaml mapping driver for Translatable
* behavioral extension. Used for extraction of extended
* metadata from yaml specifically for Translatable
* extension.
*
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class Yaml extends File implements Driver
{
/**
* File extension
* @var string
*/
protected $_extension = '.dcm.yml';
/**
* {@inheritDoc}
*/
public function readExtendedMetadata($meta, array &$config)
{
$mapping = $this->_getMapping($meta->name);
if (isset($mapping['gedmo'])) {
$classMapping = $mapping['gedmo'];
if (isset($classMapping['translation']['entity'])) {
$translationEntity = $classMapping['translation']['entity'];
if (!$cl = $this->getRelatedClassName($meta, $translationEntity)) {
throw new InvalidMappingException("Translation entity class: {$translationEntity} does not exist.");
}
$config['translationClass'] = $cl;
}
if (isset($classMapping['translation']['locale'])) {
$config['locale'] = $classMapping['translation']['locale'];
} elseif (isset($classMapping['translation']['language'])) {
$config['locale'] = $classMapping['translation']['language'];
}
}
if (isset($mapping['fields'])) {
foreach ($mapping['fields'] as $field => $fieldMapping) {
$this->buildFieldConfiguration($field, $fieldMapping, $config);
}
}
if (isset($mapping['attributeOverride'])) {
foreach ($mapping['attributeOverride'] as $field => $overrideMapping) {
$this->buildFieldConfiguration($field, $overrideMapping, $config);
}
}
if (!$meta->isMappedSuperclass && $config) {
if (is_array($meta->identifier) && count($meta->identifier) > 1) {
throw new InvalidMappingException("Translatable does not support composite identifiers in class - {$meta->name}");
}
}
}
/**
* {@inheritDoc}
*/
protected function _loadMappingFile($file)
{
return \Symfony\Component\Yaml\Yaml::parse(file_get_contents($file));
}
private function buildFieldConfiguration($field, $fieldMapping, array &$config)
{
if (is_array($fieldMapping) && isset($fieldMapping['gedmo'])) {
if (in_array('translatable', $fieldMapping['gedmo']) || isset($fieldMapping['gedmo']['translatable'])) {
// fields cannot be overrided and throws mapping exception
$config['fields'][] = $field;
if (isset($fieldMapping['gedmo']['translatable']['fallback'])) {
$config['fallback'][$field] = $fieldMapping['gedmo']['translatable']['fallback'];
}
}
}
}
}

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);
}