2011-05-02 06:33:05 +02:00
|
|
|
<?php
|
2017-04-21 02:27:01 +02:00
|
|
|
namespace SilverStripe\FullTextSearch\Search;
|
2017-02-17 04:27:38 +01:00
|
|
|
use SilverStripe\Core\ClassInfo;
|
|
|
|
use SilverStripe\ORM\DataObject;
|
2011-05-02 06:33:05 +02:00
|
|
|
/**
|
|
|
|
* Some additional introspection tools that are used often by the fulltext search code
|
|
|
|
*/
|
2015-11-21 07:19:20 +01:00
|
|
|
class SearchIntrospection
|
|
|
|
{
|
|
|
|
protected static $ancestry = array();
|
2011-05-02 06:33:05 +02:00
|
|
|
|
2015-11-21 07:19:20 +01:00
|
|
|
/**
|
|
|
|
* Check if class is subclass of (a) the class in $of, or (b) any of the classes in the array $of
|
|
|
|
* @static
|
|
|
|
* @param $class
|
|
|
|
* @param $of
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public static function is_subclass_of($class, $of)
|
|
|
|
{
|
|
|
|
$ancestry = isset(self::$ancestry[$class]) ? self::$ancestry[$class] : (self::$ancestry[$class] = ClassInfo::ancestry($class));
|
|
|
|
return is_array($of) ? (bool)array_intersect($of, $ancestry) : array_key_exists($of, $ancestry);
|
|
|
|
}
|
2011-05-02 06:33:05 +02:00
|
|
|
|
2015-11-21 07:19:20 +01:00
|
|
|
protected static $hierarchy = array();
|
2011-05-02 06:33:05 +02:00
|
|
|
|
2015-11-21 07:19:20 +01:00
|
|
|
/**
|
|
|
|
* Get all the classes involved in a DataObject hierarchy - both super and optionally subclasses
|
|
|
|
*
|
|
|
|
* @static
|
|
|
|
* @param String $class - The class to query
|
|
|
|
* @param bool $includeSubclasses - True to return subclasses as well as super classes
|
|
|
|
* @param bool $dataOnly - True to only return classes that have tables
|
|
|
|
* @return Array - Integer keys, String values as classes sorted by depth (most super first)
|
|
|
|
*/
|
|
|
|
public static function hierarchy($class, $includeSubclasses = true, $dataOnly = false)
|
|
|
|
{
|
|
|
|
$key = "$class!" . ($includeSubclasses ? 'sc' : 'an') . '!' . ($dataOnly ? 'do' : 'al');
|
|
|
|
|
|
|
|
if (!isset(self::$hierarchy[$key])) {
|
|
|
|
$classes = array_values(ClassInfo::ancestry($class));
|
|
|
|
if ($includeSubclasses) {
|
|
|
|
$classes = array_unique(array_merge($classes, array_values(ClassInfo::subclassesFor($class))));
|
|
|
|
}
|
2011-05-02 06:33:05 +02:00
|
|
|
|
2017-04-22 11:30:29 +02:00
|
|
|
$idx = array_search('SilverStripe\ORM\DataObject', $classes);
|
2017-04-21 04:14:30 +02:00
|
|
|
if ($idx !== false) {
|
|
|
|
array_splice($classes, 0, $idx+1);
|
|
|
|
}
|
|
|
|
|
2017-02-17 04:27:38 +01:00
|
|
|
//@todo find another way to determine if a dataobject does not have a table
|
|
|
|
// if ($dataOnly) {
|
|
|
|
// foreach ($classes as $i => $class) {
|
|
|
|
// if (!DataObject::has_own_table($class)) {
|
|
|
|
// unset($classes[$i]);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
2011-05-02 06:33:05 +02:00
|
|
|
|
2015-11-21 07:19:20 +01:00
|
|
|
self::$hierarchy[$key] = $classes;
|
|
|
|
}
|
2011-05-02 06:33:05 +02:00
|
|
|
|
2015-11-21 07:19:20 +01:00
|
|
|
return self::$hierarchy[$key];
|
|
|
|
}
|
2011-05-02 06:33:05 +02:00
|
|
|
|
2015-11-21 07:19:20 +01:00
|
|
|
/**
|
|
|
|
* Add classes to list, keeping only the parent when parent & child are both in list after add
|
|
|
|
*/
|
|
|
|
public static function add_unique_by_ancestor(&$list, $class)
|
|
|
|
{
|
|
|
|
// If class already has parent in list, just ignore
|
|
|
|
if (self::is_subclass_of($class, $list)) {
|
|
|
|
return;
|
|
|
|
}
|
2011-05-02 06:33:05 +02:00
|
|
|
|
2015-11-21 07:19:20 +01:00
|
|
|
// Strip out any subclasses of $class already in the list
|
|
|
|
$children = ClassInfo::subclassesFor($class);
|
|
|
|
$list = array_diff($list, $children);
|
2011-05-02 06:33:05 +02:00
|
|
|
|
2015-11-21 07:19:20 +01:00
|
|
|
// Then add the class in
|
|
|
|
$list[] = $class;
|
|
|
|
}
|
2011-05-02 06:33:05 +02:00
|
|
|
|
2015-11-21 07:19:20 +01:00
|
|
|
/**
|
|
|
|
* Does this class, it's parent (or optionally one of it's children) have the passed extension attached?
|
|
|
|
*/
|
|
|
|
public static function has_extension($class, $extension, $includeSubclasses = true)
|
|
|
|
{
|
|
|
|
foreach (self::hierarchy($class, $includeSubclasses) as $relatedclass) {
|
|
|
|
if ($relatedclass::has_extension($extension)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-03 04:33:03 +02:00
|
|
|
}
|