Issues (48)

src/Tasks/PublishAllFiles.php (3 issues)

1
<?php
2
3
namespace Sunnysideup\MigrateData\Tasks;
4
5
use SilverStripe\AssetAdmin\Controller\AssetAdmin;
0 ignored issues
show
The type SilverStripe\AssetAdmin\Controller\AssetAdmin was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use SilverStripe\Assets\File;
7
use SilverStripe\Assets\Folder;
8
use SilverStripe\Core\Injector\Injector;
9
use SilverStripe\ORM\DB;
10
use SilverStripe\ORM\Queries\SQLSelect;
11
use SilverStripe\Versioned\Versioned;
0 ignored issues
show
The type SilverStripe\Versioned\Versioned was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Sunnysideup\Flush\FlushNow;
13
use Sunnysideup\Flush\FlushNowImplementor;
14
15
class PublishAllFiles extends MigrateDataTaskBase
16
{
17
    /**
18
     * @var mixed
19
     */
20
    public $admin;
21
22
    protected $title = 'Publish All Files';
23
24
    protected $description = 'Get all files ready to go - useful in SS3 to SS4 conversion.';
25
26
    protected $updateLocation = false;
27
28
    protected $generateThumbnails = false;
29
30
    protected $oneFolderOnlyID = 0;
31
32
    protected $oneFileOnlyID = 0;
33
34
    protected $enabled = true;
35
36
    /**
37
     * @return PublishAllFiles
38
     */
39
    public function setUpdateLocation(bool $b)
40
    {
41
        $this->updateLocation = $b;
42
43
        return $this;
44
    }
45
46
    /**
47
     * @return PublishAllFiles
48
     */
49
    public function setGenerateThumbnails(bool $b)
50
    {
51
        $this->generateThumbnails = $b;
52
53
        return $this;
54
    }
55
56
    protected function performMigration()
57
    {
58
        $this->admin = Injector::inst()->get(AssetAdmin::class);
59
        $this->runForFolder(0);
60
        $this->compareCount();
61
    }
62
63
    protected function runForFolder($parentID)
64
    {
65
        if ($this->oneFolderOnlyID && $this->oneFolderOnlyID !== $parentID) {
66
            return;
67
        }
68
        if ($parentID) {
69
            $folder = Folder::get_by_id($parentID);
70
            FlushNowImplementor::do_flush('<h3>Processing Folder: ' . $folder->getFilename() . '</h3>');
71
        } else {
72
            FlushNowImplementor::do_flush('<h3>Processing Root Folder</h3>');
73
        }
74
        $sqlQuery = new SQLSelect();
75
        $sqlQuery->setFrom('File');
76
        $sqlQuery->selectField('ID');
77
        $sqlQuery->addWhere(['ParentID' => $parentID]);
78
        $sqlQuery->setOrderBy('Name');
79
80
        // Execute and return a Query object
81
        $result = $sqlQuery->execute();
82
        foreach ($result as $row) {
83
            $file = File::get_by_id($row['ID']);
84
            if (null !== $file) {
85
                $name = $file->getFilename();
86
                if (!$name) {
87
                    $file->write();
88
                    $name = $file->getFilename();
89
                }
90
                if ($this->oneFileOnlyID && $this->oneFileOnlyID !== $file->ID) {
91
                    continue;
92
                }
93
                if ($name) {
94
                    if ($this->updateLocation) {
95
                        $this->updateLocationForOneFile($file, $name);
96
                        $file = File::get_by_id($row['ID']);
97
                    }
98
99
                    try {
100
                        if ($file->exists()) {
101
102
                            $this->publishFile($file, $name);
103
                        } else {
104
                            FlushNowImplementor::do_flush('... Error in publishing V2 ...' . print_r($file->toMap(), 1), 'deleted');
0 ignored issues
show
Are you sure print_r($file->toMap(), 1) of type string|true can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

104
                            FlushNowImplementor::do_flush('... Error in publishing V2 ...' . /** @scrutinizer ignore-type */ print_r($file->toMap(), 1), 'deleted');
Loading history...
105
                        }
106
                    } catch (\Exception $exception) {
107
                        FlushNowImplementor::do_flush('... Error in publishing V1 ...' . print_r($file->toMap(), 1), 'deleted');
108
                    }
109
                } else {
110
                    $fix = false;
111
                    foreach ([''] as $suffix) {
112
                        $fileNameOld = DB::query('SELECT "Filename" FROM "File' . $suffix . '" WHERE ID = ' . $file->ID)->value();
113
                        $fileNameNewTest = DB::query('SELECT "FileFilename" FROM "File' . $suffix . '" WHERE ID = ' . $file->ID)->value();
114
                        if ($fileNameOld && !$fileNameNewTest) {
115
                            $newFileName = str_replace(
116
                                'assets/',
117
                                '',
118
                                $fileNameOld
119
                            );
120
                            DB::query(
121
                                'UPDATE "File' . $suffix . '" SET "FileFilename" = \'' . $newFileName . '\' WHERE "ID" = \'' . $file->ID . '\' LIMIT 1;'
122
                            );
123
                            $fix = true;
124
                        }
125
                    }
126
                    if ($fix) {
127
                        FlushNowImplementor::do_flush(
128
                            '... Fixed file name for ' . $file->ID . ' - run this task again to complete.',
129
                            'created'
130
                        );
131
                    } else {
132
                        FlushNowImplementor::do_flush('... Error in finding name for ' . print_r($file->toMap(), 1), 'deleted');
133
                    }
134
                }
135
136
                $file->destroy();
137
            }
138
139
            if ($file instanceof Folder) {
140
                $this->runForFolder($file->ID);
141
            }
142
        }
143
    }
144
145
    protected function updateLocationForOneFile($file, $name)
146
    {
147
        $originalDir = ASSETS_PATH . '/';
148
        if (file_exists($originalDir . $name) && !is_dir($originalDir . $name)) {
149
            if (!$file->getField('FileHash')) {
150
                $hash = sha1_file($originalDir . $name);
151
                $this->runUpdateQuery('UPDATE "File" SET "FileHash" = \'' . $hash . '\' WHERE "ID" = \'' . $file->ID . "' LIMIT 1;");
152
            } else {
153
                $hash = $file->FileHash;
154
            }
155
156
            $targetDir = str_replace(
157
                './',
158
                '',
159
                ASSETS_PATH . '/.protected/' . dirname($name)
160
                    . '/' . substr((string) $hash, 0, 10) . '/'
161
            );
162
163
            if (!file_exists($targetDir)) {
164
                mkdir($targetDir, 0755, true);
165
            }
166
167
            FlushNowImplementor::do_flush($originalDir . $name . ' > ' . $targetDir . basename($name), 'obsolete');
168
169
            rename(
170
                $originalDir . $name,
171
                $targetDir . basename($name)
172
            );
173
        }
174
    }
175
176
    /**
177
     * @param null|int $parentID
178
     */
179
    protected function compareCount($parentID = null)
180
    {
181
        $where = '';
182
        if (null === $parentID) {
183
        } else {
184
            $where = ' WHERE ParentID = ' . $parentID;
185
        }
186
        $count1 = DB::query('SELECT COUNT("ID") FROM "File" ' . $where)->value();
187
        $count2 = DB::query('SELECT COUNT("ID") FROM "File_Live" ' . $where)->value();
188
        if ($count1 === $count2) {
189
            FlushNowImplementor::do_flush('<h1>Draft and Live have the same amount of items ' . $where . '</h1>', 'created');
190
        } else {
191
            FlushNowImplementor::do_flush(
192
                '
193
                Draft and Live DO NOT have the same amount of items ' . $where . ', ' . $count1 . ' not equal ' . $count2 . '',
194
                'deleted'
195
            );
196
            if (null === $parentID) {
197
                $parentIDs = File::get()->column('ParentID');
198
                $parentIDs = array_unique($parentIDs);
199
                foreach ($parentIDs as $parentID) {
200
                    $this->compareCount($parentID);
201
                }
202
            }
203
        }
204
    }
205
206
    protected function publishFile($file, $name)
207
    {
208
        FlushNowImplementor::do_flush('... Publishing: ' . $name . ', ID = ' . $file->ID);
209
        if ($this->generateThumbnails) {
210
            $this->admin->generateThumbnails($file);
211
        }
212
        $file->forceChange();
213
        $file->write();
214
        $file->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
215
        $test = DB::query('SELECT COUNT(ID) FROM File_Live WHERE ID = ' . $file->ID)->value();
216
        if (0 === (int) $test) {
217
            FlushNowImplementor::do_flush('... error finding: ' . $name, 'deleted');
218
        }
219
    }
220
}
221