Passed
Push — master ( 24c81f...6ec46a )
by Simon
01:50
created

SeederTask::removeManyMany()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 1
dl 0
loc 7
rs 9.4285
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\YamlFixture;
14
use SilverStripe\ORM\DataList;
15
use SilverStripe\ORM\DataObject;
16
use SilverStripe\Security\DefaultAdminService;
17
use SilverStripe\Security\Security;
18
use SilverStripe\Versioned\Versioned;
19
use Symfony\Component\Yaml\Parser;
20
21
class SeederTask extends BuildTask
22
{
23
    use Configurable;
24
25
    /**
26
     * @var string URLSegment
27
     */
28
    private static $segment = 'seeder';
0 ignored issues
show
introduced by
The private property $segment is not used, and could be removed.
Loading history...
29
30
    /**
31
     * @var string path to fixture
32
     */
33
    protected static $fixtureFile;
34
35
    /**
36
     * @var array
37
     */
38
    protected $config;
39
40
    /**
41
     * @var FixtureFactory
42
     */
43
    protected $factory;
44
45
    /**
46
     * @var YamlFixture
47
     */
48
    protected $fixture;
49
50
    /**
51
     * SeederTask constructor.
52
     * @throws \Psr\Container\NotFoundExceptionInterface
53
     * @throws \Exception
54
     */
55
    public function __construct()
56
    {
57
        $this->config = Config::inst()->get(static::class);
58
59
        $this->factory = Injector::inst()->get(FixtureFactory::class);
60
        $seed = $this->config['Seedfile'];
61
62
        /** @var YamlFixture $fixture */
63
        $this->fixture = Injector::inst()->create(YamlFixture::class, $seed);
64
65
        // Log in as admin so we can publish and unpublish
66
        $adminService = Injector::inst()->get(DefaultAdminService::class);
67
        $admin = $adminService->findOrCreateDefaultAdmin();
68
        Security::setCurrentUser($admin);
69
        parent::__construct();
70
    }
71
72
    /**
73
     * @return string
74
     */
75
    public static function getFixtureFile()
76
    {
77
        return self::$fixtureFile;
78
    }
79
80
    /**
81
     * @param string $fixtureFile
82
     */
83
    public static function setFixtureFile($fixtureFile)
84
    {
85
        self::$fixtureFile = $fixtureFile;
86
    }
87
88
    /**
89
     * @param HTTPRequest $request
90
     * @throws \Psr\Container\NotFoundExceptionInterface
91
     * @throws \Exception
92
     */
93
    public function run($request)
94
    {
95
        if (Director::isLive()) {
96
            throw new \Exception('DO NOT RUN ME ON LIVE ENVIRONMENTS');
97
        }
98
99
        switch ($request->getVar('type')) {
100
            case 'seed':
101
                $this->seed();
102
                break;
103
            case 'unseed':
104
                $this->unSeed();
105
                break;
106
            default:
107
                throw new \Exception('Please tell me what to do? `type=seed` or `type=unseed`');
108
        }
109
    }
110
111
    /**
112
     * @throws \Symfony\Component\Yaml\Exception\ParseException
113
     * @throws \Psr\Container\NotFoundExceptionInterface
114
     */
115
    public function seed()
116
    {
117
        Debug::message('Starting seed');
118
        $this->fixture->writeInto($this->factory);
119
        Debug::message('Publishing Versioned items');
120
        $this->publishEach();
121
        Debug::message('Done seeding');
122
    }
123
124
    /**
125
     *
126
     * @throws \Symfony\Component\Yaml\Exception\ParseException
127
     * @throws \Psr\Container\NotFoundExceptionInterface
128
     */
129
    public function unSeed()
130
    {
131
        Debug::message('Starting unseed');
132
        $fixtureContent = $this->parseFixture();
133
        foreach ($fixtureContent as $class => $items) {
134
            /** @var DataObject $class */
135
            $class = Injector::inst()->get($class);
136
            if ($class->manyMany()) {
137
                $this->removeManyMany($class);
138
            }
139
            if ($class->hasExtension(Versioned::class)) {
140
                $this->unpublishEach($class);
141
            }
142
            $class::get()->removeAll();
143
        }
144
        Debug::message('Done Unseeding');
145
    }
146
147
    /**
148
     * @throws \Symfony\Component\Yaml\Exception\ParseException
149
     * @throws \Psr\Container\NotFoundExceptionInterface
150
     */
151
    public function publishEach()
152
    {
153
        $fixtureContent = $this->parseFixture();
154
        foreach ($fixtureContent as $class => $items) {
155
            $class = Injector::inst()->get($class);
156
            if ($class->hasExtension(Versioned::class)) {
157
                /** @var DataList|DataObject[] $items */
158
                $items = $class::get();
159
                foreach ($items as $item) {
160
                    $item->publishRecursive();
161
                    $item->destroy();
162
                }
163
            }
164
        }
165
    }
166
167
    public function removeManyMany($class)
168
    {
169
        $items = $class::get();
170
        Debug::dump('Removing relations');
171
        foreach ($items as $obj) {
172
            foreach ($obj->manyMany() as $name => $className) {
173
                $obj->$name()->removeAll();
174
            }
175
        }
176
    }
177
178
    /**
179
     * @param DataObject $class
180
     */
181
    public function unpublishEach($class)
182
    {
183
        /** @var DataList|DataObject[] $items */
184
        $items = $class::get();
185
        foreach ($items as $item) {
186
            $item->doUnpublish();
187
            $item->destroy();
188
        }
189
    }
190
191
    /**
192
     * @return array|mixed
193
     * @throws \Symfony\Component\Yaml\Exception\ParseException
194
     */
195
    public function parseFixture()
196
    {
197
        $parser = new Parser();
198
        $fixtureContent = [];
199
        if ($this->fixture->getFixtureString() !== null) {
0 ignored issues
show
introduced by
The condition $this->fixture->getFixtureString() !== null can never be false.
Loading history...
200
            $fixtureContent = $parser->parse($this->fixture->getFixtureString());
201
        } else {
202
            if (file_exists($this->fixture->getFixtureFile())) {
203
                $contents = file_get_contents($this->fixture->getFixtureFile());
204
                $fixtureContent = $parser->parse($contents);
205
            }
206
        }
207
208
        return $fixtureContent;
209
    }
210
}
211