Skip to content

Instantly share code, notes, and snippets.

@phptek
Created August 6, 2015 21:47
Show Gist options
  • Save phptek/c98f82b67ba242bbdd7d to your computer and use it in GitHub Desktop.
Save phptek/c98f82b67ba242bbdd7d to your computer and use it in GitHub Desktop.
/**
*
* 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