56 private $_persistenceFacade = null;
57 private $_configuration = null;
59 private $_supportedLanguages = null;
60 private $_defaultLanguage = null;
61 private $_translationType = null;
62 private $_languageType = null;
73 Configuration $configuration, $defaultLanguage, $translationType, $languageType) {
74 $this->_persistenceFacade = $persistenceFacade;
75 $this->_configuration = $configuration;
78 if (!isset($supportedLanguages[$defaultLanguage])) {
79 throw new ConfigurationException(
'No supported language equals the default language \''.$defaultLanguage.
'\'');
81 $this->_defaultLanguage = $defaultLanguage;
83 if (!$this->_persistenceFacade->isKnownType($translationType)) {
86 $this->_translationType = $translationType;
88 if (!$this->_persistenceFacade->isKnownType($languageType)) {
89 throw new IllegalArgumentException('The language type \
''.$languageType.
'\' is unknown.
');
91 $this->_languageType = $languageType;
97 public function getDefaultLanguage() {
98 return $this->_defaultLanguage;
105 public function getSupportedLanguages() {
106 if ($this->_supportedLanguages == null) {
107 // check if the configuration section exists
108 if (($languages = $this->_configuration->getSection('languages
')) !== false) {
109 $this->_supportedLanguages = $languages;
111 // if not, use the languageType
113 $languages = $this->_persistenceFacade->loadObjects($this->_languageType, BuildDepth::SINGLE);
114 for($i=0, $count=sizeof($languages); $i<$count; $i++) {
115 $curLanguage = $languages[$i];
116 $this->_supportedLanguages[$curLanguage->getCode()] = $curLanguage->getName();
120 return $this->_supportedLanguages;
126 public function loadTranslatedObject(ObjectId $oid, $lang, $useDefaults=true) {
127 $object = $this->_persistenceFacade->load($oid, BuildDepth::SINGLE);
129 return $this->loadTranslation($object, $lang, $useDefaults, false);
135 public function loadTranslation(PersistentObject $object, $lang, $useDefaults=true, $recursive=true) {
136 $translatedObject = $this->loadTranslationImpl($object, $lang, $useDefaults);
137 $object->setProperty(__CLASS__.'.loaded
', true);
139 // recurse if requested
141 $relations = $object->getMapper()->getRelations('child
');
142 foreach ($relations as $relation) {
143 if ($relation->getOtherNavigability()) {
144 $role = $relation->getOtherRole();
145 $childValue = $object->getValue($role);
146 if ($childValue != null) {
147 $children = $relation->isMultiValued() ? $childValue : array($childValue);
148 foreach ($children as $child) {
149 // don't resolve proxies
150 if (!($child instanceof
PersistentObjectProxy) && $child->getProperty(__CLASS__.
'.loaded') !==
true) {
151 $translatedChild = $this->
loadTranslation($child, $lang, $useDefaults, $recursive);
152 $translatedObject->addNode($translatedChild, $role);
159 return $translatedObject;
173 if ($object == null) {
177 $translatedObject = $object;
178 $oidStr = $object->
getOID()->__toString();
182 if ($lang != $this->getDefaultLanguage()) {
183 $transaction = $this->_persistenceFacade->getTransaction();
184 $translatedObject = $this->_persistenceFacade->create($object->
getType());
185 $transaction->detach($translatedObject->getOID());
188 $query =
new ObjectQuery($this->_translationType, __CLASS__.
'load_save');
189 $tpl = $query->getObjectTemplate($this->_translationType);
190 $tpl->setValue(
'objectid', Criteria::asValue(
'=', $oidStr));
191 $tpl->setValue(
'language', Criteria::asValue(
'=', $lang));
192 $translations = $query->execute(BuildDepth::SINGLE);
196 for($iter->rewind(); $iter->valid(); $iter->next()) {
197 $this->setTranslatedValue($translatedObject, $iter->key(), $translations, $useDefaults);
200 return $translatedObject;
208 $this->saveTranslationImpl($object, $lang);
213 foreach($iterator as $oidStr => $obj) {
214 if ($obj->getOID() != $object->
getOID()) {
217 $this->saveTranslation($obj, $lang, $recursive);
232 if ($lang == $this->getDefaultLanguage()) {
240 $query =
new ObjectQuery($this->_translationType, __CLASS__.
'load_save');
241 $tpl = $query->getObjectTemplate($this->_translationType);
242 $tpl->setValue(
'objectid', Criteria::asValue(
'=', $object->
getOID()->__toString()));
243 $tpl->setValue(
'language', Criteria::asValue(
'=', $lang));
244 $translations = $query->execute(BuildDepth::SINGLE);
247 $pkNames = $object->
getMapper()->getPkNames();
249 for($iter->rewind(); $iter->valid(); $iter->next()) {
250 $valueName = $iter->key();
251 if (!in_array($valueName, $pkNames)) {
252 $curIterNode = $iter->currentNode();
253 $this->saveTranslatedValue($curIterNode, $valueName, $translations, $lang);
264 if ($lang == $this->getDefaultLanguage()) {
270 $query =
new ObjectQuery($this->_translationType, __CLASS__.
'delete_trans'.($lang != null));
271 $tpl = $query->getObjectTemplate($this->_translationType);
272 $tpl->setValue(
'objectid', Criteria::asValue(
'=', $oid->
__toString()));
274 $tpl->setValue(
'language', Criteria::asValue(
'=', $lang));
276 $translations = $query->execute(BuildDepth::SINGLE);
279 foreach ($translations as $curTranslation) {
280 $curTranslation->delete();
290 if ($lang == $this->getDefaultLanguage()) {
296 $query =
new ObjectQuery($this->_translationType, __CLASS__.
'delete_lang');
297 $tpl = $query->getObjectTemplate($this->_translationType);
298 $tpl->setValue(
'language', Criteria::asValue(
'=', $lang));
299 $translations = $query->execute(BuildDepth::SINGLE);
302 foreach ($translations as $curTranslation) {
303 $curTranslation->delete();
317 private function setTranslatedValue(
PersistentObject $object, $valueName, array $translations, $useDefaults) {
319 $isTranslatable = $mapper != null && $mapper->hasAttribute($valueName) ? $mapper->getAttribute($valueName)->hasTag(
'TRANSLATABLE') :
false;
320 if ($isTranslatable) {
323 $object->
setValue($valueName, null,
true);
326 for ($i=0, $count=
sizeof($translations); $i<$count; $i++) {
327 $curValueName = $translations[$i]->getValue(
'attribute');
328 if ($curValueName == $valueName) {
329 $translation = $translations[$i]->getValue(
'translation');
330 if (!($useDefaults && strlen($translation) == 0)) {
331 $object->
setValue($valueName, $translation,
true);
347 private function saveTranslatedValue(PersistentObject $object, $valueName, array $existingTranslations, $lang) {
348 $mapper = $object->getMapper();
349 $isTranslatable = $mapper != null && $mapper->hasAttribute($valueName) ? $mapper->getAttribute($valueName)->hasTag(
'TRANSLATABLE') :
false;
350 if ($isTranslatable) {
351 $value = $object->getValue($valueName);
355 for ($i=0, $count=
sizeof($existingTranslations); $i<$count; $i++) {
356 $curValueName = $existingTranslations[$i]->getValue(
'attribute');
357 if ($curValueName == $valueName) {
358 $translation = &$existingTranslations[$i];
364 if ($translation == null) {
365 $translation = $this->_persistenceFacade->create($this->_translationType);
369 $translation->setValue(
'objectid', $object->getOID()->__toString());
370 $translation->setValue(
'attribute', $valueName);
371 $translation->setValue(
'translation', $object->getValue($valueName));
372 $translation->setValue(
'language', $lang);
getType()
Get the type of the object.
Localization defines the interface for storing localized entity instances and retrieving them back...
getOID()
Get the object id of the PersistentObject.
saveTranslation(PersistentObject $object, $lang, $recursive=true)
beforeUpdate()
This method is called always before updating the modified object in the store.
IllegalArgumentException signals an exception in method arguments.
loadTranslationImpl(PersistentObject $object, $lang, $useDefaults=true)
Load a translation of a single entity for a specific language.
NodeValueIterator is used to iterate over all persistent values of a Node (not including relations)...
getMapper()
Get the PersistenceMapper of the object.
ObjectQuery implements a template based object query.
NodeIterator is used to iterate over a tree/list built of Nodes using a Depth-First-Algorithm.
ObjectId is the unique identifier of an object.
DefaultLocalization is a Localization implementation that saves translations in the store...
PersistentObjectProxy is proxy for an PersistentObject instance.
Implementations of Configuration give access to the application configuration.
deleteTranslation(ObjectId $oid, $lang=null)
__toString()
Get a string representation of the object id.
loadTranslation(PersistentObject $object, $lang, $useDefaults=true, $recursive=true)
setValue($name, $value, $forceSet=false, $trackChange=true)
Set the value of a named item if it exists.
copyValues(PersistentObject $object, $copyPkValues=true)
Copy all non-empty values to a given instance (ChangeListeners are triggered)
PersistenceFacade defines the interface for PersistenceFacade implementations.
__construct(PersistenceFacade $persistenceFacade, Configuration $configuration, $defaultLanguage, $translationType, $languageType)
Configuration.
saveTranslationImpl(PersistentObject $object, $lang)
Save a translation of a single entity for a specific language.
ConfigurationException signals an exception in the configuration.
PersistentObject defines the interface of all persistent objects.