Issues (9)

src/Control/FlushReceiver.php (7 issues)

1
<?php
2
3
namespace Sunnysideup\FlushFrontEnd\Control;
4
5
use Exception;
6
use SilverStripe\Control\Controller;
7
use SilverStripe\Control\Director;
8
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
9
use SilverStripe\Core\ClassInfo;
10
use SilverStripe\Core\Convert;
11
use SilverStripe\Core\Flushable;
12
use SilverStripe\Core\Manifest\ClassLoader;
13
use SilverStripe\Core\Resettable;
14
use SilverStripe\Security\Permission;
15
use Sunnysideup\FlushFrontEnd\Model\FlushRecord;
16
17
/**
18
 * Class \Sunnysideup\FlushFrontEnd\Control\FlushReceiver
19
 *
20
 */
21
class FlushReceiver extends Controller
22
{
23
    private static $allowed_actions = [
24
        'index' => 'ADMIN',
25
        'do' => true,
26
        'completed' => true,
27
        'available' => true,
28
    ];
29
30
    public static function my_url_segment(): string
31
    {
32
        return 'flush-front-end';
33
    }
34
35
    public function Link($action = '')
36
    {
37
        return '/' . self::join_links(self::my_url_segment(), $action);
38
    }
39
40
    public function completed()
41
    {
42
        if (Director::is_cli() || Permission::check('ADMIN')) {
43
            $objects = FlushRecord::get()->filter(['Done' => false]);
44
            foreach ($objects as $obj) {
45
                echo $obj->dbObject('LastEdited')->ago() . ' - ' . $obj->Code;
46
                if (! Director::is_cli()) {
47
                    echo PHP_EOL;
48
                } else {
49
                    echo '<br />';
50
                }
51
            }
52
        } else {
53
            die('This needs to be run from the command line or you need to be logged in as ADMIN.');
0 ignored issues
show
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...
54
        }
55
    }
56
57
    public function available()
58
    {
59
        if (Director::is_cli() || Permission::check('ADMIN')) {
60
            $objects = FlushRecord::get()->filter(['Done' => false]);
61
            foreach ($objects as $obj) {
62
                if (Director::is_cli()) {
63
                    echo $this->Link('do/' . $obj->Code) . PHP_EOL;
64
                } else {
65
                    echo '<a href="' . $this->Link('do/' . $obj->Code) . '">' . $obj->Code . '</a><br />';
66
                }
67
            }
68
        } else {
69
            die('This needs to be run from the command line or you need to be logged in as ADMIN.');
0 ignored issues
show
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...
70
        }
71
    }
72
73
    public function do($request)
74
    {
75
        if (Director::is_cli()) {
76
            die(
0 ignored issues
show
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...
77
                '
78
This needs to be run from the front-end.
79
80
'
81
            );
82
        }
83
        $code = Convert::raw2sql($request->param('ID'));
84
        if ($code) {
85
            $obj = $this->getFlushRecord($code);
0 ignored issues
show
It seems like $code can also be of type array and array; however, parameter $code of Sunnysideup\FlushFrontEn...eiver::getFlushRecord() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

85
            $obj = $this->getFlushRecord(/** @scrutinizer ignore-type */ $code);
Loading history...
86
            if ($obj instanceof \Sunnysideup\FlushFrontEnd\Model\FlushRecord) {
0 ignored issues
show
$obj is always a sub-type of Sunnysideup\FlushFrontEnd\Model\FlushRecord.
Loading history...
87
                // mark as done first
88
                $obj->Done = true;
89
                $obj->write();
90
91
                $this->doFlush();
92
                $olds = FlushRecord::get()->filter(['Created:LessThan' => date('Y-m-d h:i:s', strtotime('-3 months'))]);
93
                foreach ($olds as $old) {
94
                    $old->delete();
95
                }
96
97
                return '
98
-----------------------------------------
99
SUCCESS: FRONT-END FLUSHED
100
-----------------------------------------
101
102
';
103
            }
104
        }
105
        return '
106
-----------------------------------------
107
ERROR: FRONT-END NOT FLUSHED
108
-----------------------------------------
109
110
        ';
111
    }
112
113
    protected function doFlush()
114
    {
115
        if (file_exists(TEMP_PATH)) {
116
            $this->deleteFolderContents(TEMP_PATH);
117
        }
118
119
        HTTPCacheControlMiddleware::singleton()->disableCache(true);
120
        ClassLoader::inst()->getManifest()->regenerate(false);
121
        // Reset all resettables
122
        /** @var Resettable $resettable */
123
        foreach (ClassInfo::implementorsOf(Resettable::class) as $resettable) {
124
            $resettable::reset();
125
        }
126
127
        /** @var Flushable $class */
128
        foreach (ClassInfo::implementorsOf(Flushable::class) as $class) {
129
            $class::flush();
130
        }
131
    }
132
133
    protected function getFlushRecord(string $code): ?FlushRecord
134
    {
135
        /** @var FlushRecord $obj */
136
        $obj = FlushRecord::get()->filter(['Done' => false, 'Code' => $code])->first();
137
        if ($obj) {
0 ignored issues
show
$obj is of type Sunnysideup\FlushFrontEnd\Model\FlushRecord, thus it always evaluated to true.
Loading history...
138
            return $obj;
139
        }
140
141
        echo 'object not found';
142
143
        return null;
144
    }
145
146
    // Function to delete files and folders recursively
147
    private function deleteFolderContents(string $folderPath)
148
    {
149
        if (! is_dir($folderPath)) {
150
            return;
151
        }
152
153
        $files = array_diff(scandir($folderPath), ['.', '..']);
154
155
        foreach ($files as $file) {
156
            $filePath = $folderPath . '/' . $file;
157
158
            if (is_dir($filePath)) {
159
                $this->deleteFolderContents($filePath); // Recursively delete sub-folders
160
            } else {
161
                try {
162
                    unlink($filePath); // Delete files
163
                } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
164
                }
165
            }
166
        }
167
    }
168
}
169