1<?php
2
3namespace ComboStrap;
4
5
6use ReflectionClass;
7
8class ClassUtility
9{
10
11    /**
12     * @param object|string $objectOrClass
13     * @return LocalPath
14     *
15     * Example to get the path of a class, you would call:
16     * ```
17     * getClassPath($this)
18     * ```
19     * @throws \ReflectionException - if this is not possible to return the path
20     */
21    public static function getClassPath($objectOrClass): LocalPath
22    {
23        $reflector = new \ReflectionClass($objectOrClass);
24        $fileName = $reflector->getFileName();
25        if ($fileName === false) {
26            throw new \ReflectionException("The class is defined in php core or in a php extension");
27        }
28        return LocalPath::createFromPathString($fileName);
29    }
30
31    public static function getClassImplementingInterface(string $interface): array
32    {
33        /**
34         * The class created by reflection are not loaded
35         * We need to load them explicitly
36         */
37        self::loadingComboStrapClasses();
38        $class = [];
39        $getDeclaredClasses = get_declared_classes();
40        foreach ($getDeclaredClasses as $className) {
41            if (in_array($interface, class_implements($className))) {
42                $class[] = $className;
43            }
44        }
45        return $class;
46    }
47
48    /**
49     * @throws \ReflectionException
50     */
51    public static function getObjectImplementingInterface(string $interface): array
52    {
53        $classes = self::getClassImplementingInterface($interface);
54        $objects = [];
55        foreach ($classes as $class) {
56            $classReflection = new ReflectionClass($class);
57            if (!$classReflection->isAbstract()) {
58                $objects[] = new $class();
59            }
60        }
61        return $objects;
62    }
63
64    public static function isLoaded(string $class): bool
65    {
66        return class_exists($class, false);
67    }
68
69    private static function loadingComboStrapClasses()
70    {
71        try {
72            $parent = ClassUtility::getClassPath(ClassUtility::class)->getParent();
73        } catch (ExceptionNotFound|\ReflectionException $e) {
74            throw new ExceptionRuntimeInternal("We could load the ClassUtility class. Error: {$e->getMessage()}");
75        }
76        foreach (FileSystems::getChildrenLeaf($parent) as $child) {
77            try {
78                $extension = $child->getExtension();
79            } catch (ExceptionNotFound $e) {
80                continue;
81            }
82            if($extension!=='php'){
83                continue;
84            }
85            include_once $child->toAbsoluteId();
86        }
87    }
88}
89