Created
August 6, 2015 21:47
-
-
Save phptek/c98f82b67ba242bbdd7d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* Determines if the current page has any translations. | |
* | |
* "Translation" means: | |
* | |
* >=1 of a page's translated fields e.g. `Title_ar_EG` is populated, And/Or | |
* >=1 of a page's `has|many_xxx` related classes, itself has >=1 translated + populated field(s), And/Or | |
* >=1 of a page's arbitrary ORM calls to a DataObject sub-class, itself has >=1 translated & populated field(s) | |
* | |
* The logic will exclude the default_locale, unless $includeDefault is set to `true` | |
* | |
* @param string $locale The locale to use for determining whether the current | |
* page is translated. | |
* @param string $class The class to analyse. If not passed, it is "guessed". | |
* @param boolean $incDef Whether or not to include the `default_locale` | |
* in the returned array. | |
* @param int $type A Bitwise value to determine which fields to consider | |
* @return array $result An array of the locales that the current page is | |
* translated into. | |
* @todo Write tests. | |
*/ | |
public function isTranslatedInto($locale = null, $class = null, $incDef = false, $type = 2) { | |
if(!$class) { | |
if($this->owner) { | |
$class = $this->owner->class; | |
} else { | |
$class = $this->class; | |
} | |
} | |
$baseClass = ClassInfo::baseDataClass($class); | |
// "1" Get translations on direct class-fields (Fields defined via $db static) | |
$dbFields = $this->getDBTranslations($baseClass, ($type & 2)); | |
// "2" Get translations on related class-fields (Fields defined on classes via $has_xx|$many_xx statics) | |
$relFields = $this->getRelationTranslations(($type & 4)); | |
// "3" Get translations on "called" class-fields (Fields defined on classes via arbitrary ORM calls) | |
$ormFields = $this->getORMTranslations($baseClass, ($type & 8)); | |
$defaultLocale = Fluent::default_locale(); | |
$fields = array_merge($dbFields, $relFields, $ormFields); | |
$result = array(); | |
foreach($fields as $field) { | |
// Include / exclude the default_locale in the result | |
if(!$incDef && preg_match("#$defaultLocale$#", $field)) { | |
continue; | |
} | |
$result[] = self::db_locale_from_field($field); | |
} | |
$translatedIntoLocales = array_unique($result); | |
// If a $locale is passed as an argument, check if it exists in array of | |
// translated locales, and return a single value array, comprising that locale. | |
// otherwise return an array of all translated locales. | |
if($locale) { | |
return in_array($locale, $translatedIntoLocales) ? array($locale) : array(); | |
} | |
return array_unique($result); | |
} | |
/** | |
* | |
* Determine if translations exist on native fields, defined via the current object's | |
* $db static. | |
* | |
* @param string $class | |
* @param boolean $return | |
* @return array | |
*/ | |
private function getDBTranslations($class, $return = true) { | |
if(!$return) { | |
return array(); | |
} | |
echo '#1'; | |
$fluentFields = array_keys(FluentExtension::translated_fields_for($class)); | |
$populated = array(); | |
foreach($fluentFields as $field) { | |
foreach(Fluent::locales() as $locale) { | |
$fluentField = Fluent::db_field_for_locale($field, $locale); | |
if(!empty($this->owner->getField($fluentField))) { | |
$populated[] = self::db_locale_from_field($fluentField); | |
} | |
} | |
} | |
return $populated; | |
} | |
/** | |
* | |
* Determine if translations exist on native-relation fields, defined via the | |
* current object's $has_xxx or $many_xxx statics. | |
* | |
* @param boolean $return | |
* @return array $populated | |
*/ | |
private function getRelationTranslations($return = true) { | |
if(!$return) { | |
return array(); | |
} | |
echo '#2'; | |
$hasOneClasses = $this->owner->has_one(); | |
$hasManyClasses = $this->owner->has_many(null, true); | |
$manyManyClasses = $this->owner->many_many(null, true); | |
$relationClasses = array_merge( | |
$hasOneClasses, | |
$hasManyClasses, | |
$manyManyClasses | |
); | |
$populated = array(); | |
foreach($relationClasses as $caller => $class) { | |
if(!DataObject::has_own_table($class)) { | |
continue; | |
} | |
$fluentFields = array_keys(FluentExtension::translated_fields_for($class)); | |
foreach($fluentFields as $field) { | |
foreach(Fluent::locales() as $locale) { | |
$fluentField = Fluent::db_field_for_locale($field, $locale); | |
if(!empty($this->owner->$caller()->getField($fluentField))) { | |
$populated[] = self::db_locale_from_field($fluentField); | |
} | |
} | |
} | |
} | |
return $populated; | |
} | |
/** | |
* | |
* Determine if translations exist on the fields of classes called in arbitrary | |
* ORM queries made in the current object. | |
* | |
* Example: If $class is a pagetype with some method containing a single ORM | |
* call thus: `DataObject::get('Foo')` and `Foo` has translated fields via Fluent | |
* then return those fields. | |
* | |
* Warning: This method makes heavy use of Reflection and as such there will be | |
* a performance hit in its use. | |
* | |
* @param string $class | |
* @param string $pattern e.g. "DataObject::get(" | |
* @param boolean $return | |
* @return array $populated | |
*/ | |
private function getORMTranslations($class, $pattern = '', $return = true) { | |
if(!$return) { | |
return array(); | |
} | |
echo '#3'; | |
$class = ClassInfo::baseDataClass($class); | |
$signitures = self::get_orm_queries_for_class($class, $pattern); | |
$populated = array(); | |
return $populated; | |
} | |
/** | |
* | |
* Using Reflection, parses the given $class file for function def's. | |
* For each definition found, we parse it for the passed $signiture (e.g. "DataObject::get('Foo')") | |
* and extract 'Foo'. This gives us the ORM queries made on the current object. | |
* | |
* Note, this is obviosuly file-specifric and won't take into account parent classes. | |
* This could be achieved with an optional $all = true param.. | |
* | |
* @param string $class | |
* @param string $signiture | |
* @return array $signituresFound | |
* @todo issue PR on modified ClassInfo class. | |
*/ | |
public static function get_orm_queries_for_class($class, $signiture) { | |
$signituresFound = array(); | |
// This gives us some metainformation as to which lines | |
$classDef = ReflectionClass::export($class, true); | |
return $signituresFound; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment