SeederTask   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 199
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 199
rs 10
c 0
b 0
f 0
wmc 27

10 Methods

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