Passed
Push — master ( b4e3f0...d6a119 )
by Robbie
04:16 queued 02:31
created

src/Search/SearchIntrospection.php (1 issue)

Severity
1
<?php
2
namespace SilverStripe\FullTextSearch\Search;
3
4
use SilverStripe\Core\ClassInfo;
5
use SilverStripe\ORM\DataObject;
6
7
/**
8
 * Some additional introspection tools that are used often by the fulltext search code
9
 */
10
class SearchIntrospection
11
{
12
    protected static $ancestry = array();
13
14
    /**
15
     * Check if class is subclass of (a) the class in $of, or (b) any of the classes in the array $of
16
     * @static
17
     * @param  $class
18
     * @param  $of
19
     * @return bool
20
     */
21
    public static function is_subclass_of($class, $of)
22
    {
23
        $ancestry = isset(self::$ancestry[$class]) ? self::$ancestry[$class] : (self::$ancestry[$class] = ClassInfo::ancestry($class));
24
        return is_array($of) ? (bool)array_intersect($of, $ancestry) : array_key_exists($of, $ancestry);
25
    }
26
27
    protected static $hierarchy = array();
28
29
    /**
30
     * Get all the classes involved in a DataObject hierarchy - both super and optionally subclasses
31
     *
32
     * @static
33
     * @param string $class - The class to query
34
     * @param bool $includeSubclasses - True to return subclasses as well as super classes
35
     * @param bool $dataOnly - True to only return classes that have tables
36
     * @return array - Integer keys, String values as classes sorted by depth (most super first)
37
     */
38
    public static function hierarchy($class, $includeSubclasses = true, $dataOnly = false)
39
    {
40
        $key = "$class!" . ($includeSubclasses ? 'sc' : 'an') . '!' . ($dataOnly ? 'do' : 'al');
41
42
        if (!isset(self::$hierarchy[$key])) {
43
            $classes = array_values(ClassInfo::ancestry($class));
44
            if ($includeSubclasses) {
45
                $classes = array_unique(array_merge($classes, array_values(ClassInfo::subclassesFor($class))));
46
            }
47
48
            $idx = array_search(DataObject::class, $classes);
49
            if ($idx !== false) {
50
                array_splice($classes, 0, $idx+1);
51
            }
52
53
            if ($dataOnly) {
54
                foreach ($classes as $i => $class) {
0 ignored issues
show
$class is overwriting one of the parameters of this function.
Loading history...
55
                    if (!DataObject::getSchema()->classHasTable($class)) {
56
                        unset($classes[$i]);
57
                    }
58
                }
59
            }
60
61
            self::$hierarchy[$key] = $classes;
62
        }
63
64
        return self::$hierarchy[$key];
65
    }
66
67
    /**
68
     * Add classes to list, keeping only the parent when parent & child are both in list after add
69
     */
70
    public static function add_unique_by_ancestor(&$list, $class)
71
    {
72
        // If class already has parent in list, just ignore
73
        if (self::is_subclass_of($class, $list)) {
74
            return;
75
        }
76
77
        // Strip out any subclasses of $class already in the list
78
        $children = ClassInfo::subclassesFor($class);
79
        $list = array_diff($list, $children);
80
81
        // Then add the class in
82
        $list[] = $class;
83
    }
84
85
    /**
86
     * Does this class, it's parent (or optionally one of it's children) have the passed extension attached?
87
     */
88
    public static function has_extension($class, $extension, $includeSubclasses = true)
89
    {
90
        foreach (self::hierarchy($class, $includeSubclasses) as $relatedclass) {
91
            if ($relatedclass::has_extension($extension)) {
92
                return true;
93
            }
94
        }
95
        return false;
96
    }
97
}
98