Completed
Pull Request — master (#23)
by Alessandro
06:14
created

MongoFixturesLoader::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Facile\MongoDbBundle\Fixtures;
6
7
use Symfony\Component\DependencyInjection\ContainerInterface;
8
9
/**
10
 * Class MongoFixturesLoader.
11
 */
12
class MongoFixturesLoader
13
{
14
    /** @var  array|MongoFixtureInterface[] */
15
    private $loadedClasses;
16
    /** @var ContainerInterface */
17
    private $container;
18
19
    /**
20
     * MongoFixturesLoader constructor.
21
     *
22
     * @param ContainerInterface $container
23
     */
24
    public function __construct(ContainerInterface $container)
25
    {
26
        $this->container = $container;
27
    }
28
29
    /**
30
     * @param string $dir
31
     *
32
     * @return array
33
     */
34
    public function loadFromDirectory(string $dir)
35
    {
36
        if (!is_dir($dir)) {
37
            throw new \InvalidArgumentException(sprintf('"%s" does not exist', $dir));
38
        }
39
40
        $iterator = new \RecursiveIteratorIterator(
41
            new \RecursiveDirectoryIterator($dir),
42
            \RecursiveIteratorIterator::LEAVES_ONLY
43
        );
44
45
        return $this->loadFromIterator($iterator);
46
    }
47
48
    /**
49
     * @param \Iterator $iterator
50
     *
51
     * @return array
52
     */
53
    private function loadFromIterator(\Iterator $iterator)
54
    {
55
        $includedFiles = array();
56
        foreach ($iterator as $file) {
57
            if ($file->getBasename('.php') == $file->getBasename()) {
58
                continue;
59
            }
60
            $sourceFile = realpath($file->getPathName());
61
            require_once $sourceFile;
62
            $includedFiles[] = $sourceFile;
63
        }
64
65
        $declared = get_declared_classes();
66
67
        return array_reduce(
68
            $declared,
69
            function ($classList, string $className) use ($includedFiles) {
70
                $reflClass = new \ReflectionClass($className);
71
                $sourceFile = $reflClass->getFileName();
72
73
                if (
74
                    in_array($sourceFile, $includedFiles) &&
75
                    in_array(MongoFixtureInterface::class, array_keys($reflClass->getInterfaces()))
76
                ) {
77
                    $instance = $this->buildFixture(new $className);
78
                    $this->addInstance($instance);
79
                    $classList[] = $instance;
80
                }
81
82
                return $classList;
83
            },
84
            []
85
        );
86
    }
87
88
    /**
89
     * @param mixed $instance
90
     *
91
     * @return MongoFixtureInterface
92
     */
93
    private function buildFixture($instance): MongoFixtureInterface
94
    {
95
        if ($instance instanceof AbstractContainerAwareFixture) {
96
            $instance->setContainer($this->container);
97
        }
98
99
        return $instance;
100
    }
101
102
    /**
103
     * @param MongoFixtureInterface $list
104
     */
105
    public function addInstance(MongoFixtureInterface $list)
106
    {
107
        $listClass = get_class($list);
108
109
        if (!isset($this->loadedClasses[$listClass])) {
110
            $this->loadedClasses[$listClass] = $list;
111
        }
112
    }
113
114
    /**
115
     * @param string $fileName
116
     *
117
     * @return array
118
     */
119
    public function loadFromFile(string $fileName)
120
    {
121
        if (!is_readable($fileName)) {
122
            throw new \InvalidArgumentException(sprintf('"%s" does not exist or is not readable', $fileName));
123
        }
124
125
        $iterator = new \ArrayIterator(array(new \SplFileInfo($fileName)));
126
127
        return $this->loadFromIterator($iterator);
128
    }
129
130
    /**
131
     * @return array|MongoFixtureInterface[]
132
     */
133
    public function getLoadedClasses()
134
    {
135
        return $this->loadedClasses;
136
    }
137
}
138