Passed
Push — master ( 9ba004...24c81f )
by Simon
02:38
created

SeederTask::getFixtureFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Firesphere\Seeder\Tasks;
4
5
use SilverStripe\Control\Director;
6
use SilverStripe\Control\HTTPRequest;
7
use SilverStripe\Core\Config\Config;
8
use SilverStripe\Core\Config\Configurable;
9
use SilverStripe\Core\Injector\Injector;
10
use SilverStripe\Dev\BuildTask;
11
use SilverStripe\Dev\Debug;
12
use SilverStripe\Dev\FixtureFactory;
13
use SilverStripe\Dev\SapphireTest;
14
use SilverStripe\Dev\YamlFixture;
15
use SilverStripe\ORM\DatabaseAdmin;
16
use SilverStripe\ORM\DataList;
17
use SilverStripe\ORM\DataObject;
18
use SilverStripe\Security\DefaultAdminService;
19
use SilverStripe\Security\Security;
20
use SilverStripe\Versioned\Versioned;
21
use Symfony\Component\Yaml\Parser;
22
23
class SeederTask extends BuildTask
24
{
25
    use Configurable;
26
27
    /**
28
     * @var string URLSegment
29
     */
30
    private static $segment = 'seeder';
0 ignored issues
show
introduced by
The private property $segment is not used, and could be removed.
Loading history...
31
32
    /**
33
     * @var string path to fixture
34
     */
35
    protected static $fixtureFile;
36
37
    /**
38
     * @var array
39
     */
40
    protected $config;
41
42
    /**
43
     * @var FixtureFactory
44
     */
45
    protected $factory;
46
47
    /**
48
     * @var YamlFixture
49
     */
50
    protected $fixture;
51
52
    /**
53
     * SeederTask constructor.
54
     * @throws \Psr\Container\NotFoundExceptionInterface
55
     * @throws \Exception
56
     */
57
    public function __construct()
58
    {
59
        $this->config = Config::inst()->get(static::class);
60
61
        $this->factory = Injector::inst()->get(FixtureFactory::class);
62
        $seed = $this->config['Seedfile'];
63
64
        /** @var YamlFixture $fixture */
65
        $this->fixture = Injector::inst()->create(YamlFixture::class, $seed);
66
67
        // Log in as admin so we can publish and unpublish
68
        $adminService = Injector::inst()->get(DefaultAdminService::class);
69
        $admin = $adminService->findOrCreateDefaultAdmin();
70
        Security::setCurrentUser($admin);
71
        parent::__construct();
72
    }
73
74
    /**
75
     * @return string
76
     */
77
    public static function getFixtureFile()
78
    {
79
        return self::$fixtureFile;
80
    }
81
82
    /**
83
     * @param string $fixtureFile
84
     */
85
    public static function setFixtureFile($fixtureFile)
86
    {
87
        self::$fixtureFile = $fixtureFile;
88
    }
89
90
    /**
91
     * @param HTTPRequest $request
92
     * @throws \Psr\Container\NotFoundExceptionInterface
93
     * @throws \Exception
94
     */
95
    public function run($request)
96
    {
97
        if (Director::isLive()) {
98
            throw new \Exception('DO NOT RUN ME ON LIVE ENVIRONMENTS');
99
        }
100
101
        switch ($request->getVar('type')) {
102
            case 'seed':
103
                $this->seed();
104
                break;
105
            case 'unseed':
106
                $this->unSeed();
107
                break;
108
            default:
109
                throw new \Exception('Please tell me what to do? `type=seed` or `type=unseed`');
110
        }
111
    }
112
113
    /**
114
     * @throws \Symfony\Component\Yaml\Exception\ParseException
115
     * @throws \Psr\Container\NotFoundExceptionInterface
116
     */
117
    public function seed()
118
    {
119
        Debug::message('Starting seed');
120
        $this->fixture->writeInto($this->factory);
121
        Debug::message('Publishing Versioned items');
122
        $this->publishEach();
123
        Debug::message('Done seeding');
124
    }
125
126
    /**
127
     *
128
     * @throws \Symfony\Component\Yaml\Exception\ParseException
129
     * @throws \Psr\Container\NotFoundExceptionInterface
130
     */
131
    public function unSeed()
132
    {
133
        Debug::message('Starting unseed');
134
        $fixtureContent = $this->parseFixture();
135
        foreach ($fixtureContent as $class => $items) {
136
            /** @var DataObject $class */
137
            $class = Injector::inst()->get($class);
138
            if ($class->hasExtension(Versioned::class)) {
139
                $this->unpublishEach($class);
140
            }
141
            $class::get()->removeAll();
142
        }
143
        Debug::message('Done Unseeding');
144
    }
145
146
    /**
147
     * @throws \Symfony\Component\Yaml\Exception\ParseException
148
     * @throws \Psr\Container\NotFoundExceptionInterface
149
     */
150
    public function publishEach()
151
    {
152
        $fixtureContent = $this->parseFixture();
153
        foreach ($fixtureContent as $class => $items) {
154
            $class = Injector::inst()->get($class);
155
            if ($class->hasExtension(Versioned::class)) {
156
                /** @var DataList|DataObject[] $items */
157
                $items = $class::get();
158
                foreach ($items as $item) {
159
                    $item->publishRecursive();
160
                    $item->destroy();
161
                }
162
            }
163
        }
164
    }
165
166
167
    /**
168
     * @param DataObject $class
169
     */
170
    public function unpublishEach($class)
171
    {
172
        /** @var DataList|DataObject[] $items */
173
        $items = $class::get();
174
        foreach ($items as $item) {
175
            if ($item->manyMany()) {
176
                Debug::dump($item->manyMany());exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
177
            }
178
            $item->doUnpublish();
179
            $item->destroy();
180
        }
181
    }
182
183
    /**
184
     * @return array|mixed
185
     * @throws \Symfony\Component\Yaml\Exception\ParseException
186
     */
187
    public function parseFixture()
188
    {
189
        $parser = new Parser();
190
        $fixtureContent = [];
191
        if ($this->fixture->getFixtureString() !== null) {
0 ignored issues
show
introduced by
The condition $this->fixture->getFixtureString() !== null can never be false.
Loading history...
192
            $fixtureContent = $parser->parse($this->fixture->getFixtureString());
193
        } else {
194
            if (file_exists($this->fixture->getFixtureFile())) {
195
                $contents = file_get_contents($this->fixture->getFixtureFile());
196
                $fixtureContent = $parser->parse($contents);
197
            }
198
        }
199
200
        return $fixtureContent;
201
    }
202
}
203