Passed
Push — master ( 88dde3...10fdf9 )
by Nicolaas
10:12
created

updateCMSFields()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 27
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 20
c 6
b 0
f 0
dl 0
loc 27
rs 9.6
cc 3
nc 4
nop 1
1
<?php
2
3
namespace Sunnysideup\SimpleTemplateCaching\Extensions;
4
5
use SilverStripe\Core\Injector\Injector;
6
use SilverStripe\Forms\CheckboxField;
7
use SilverStripe\Forms\FieldList;
8
use SilverStripe\Forms\GridField\GridField;
9
use SilverStripe\Forms\GridField\GridFieldConfig_RecordViewer;
10
use SilverStripe\Forms\ReadonlyField;
11
use SilverStripe\ORM\DataExtension;
12
use SilverStripe\ORM\DB;
13
use SilverStripe\ORM\FieldType\DBDatetime;
14
use SilverStripe\SiteConfig\SiteConfig;
15
use Sunnysideup\SimpleTemplateCaching\Model\ObjectsUpdated;
16
17
/**
18
 * Class \Sunnysideup\SimpleTemplateCaching\Extensions\SimpleTemplateCachingSiteConfigExtension.
19
 *
20
 * @property SiteConfig|SimpleTemplateCachingSiteConfigExtension $owner
21
 * @property bool $HasCaching
22
 * @property bool $RecordCacheUpdates
23
 * @property string $CacheKeyLastEdited
24
 * @property string $ClassNameLastEdited
25
 */
26
class SimpleTemplateCachingSiteConfigExtension extends DataExtension
27
{
28
    private const MAX_OBJECTS_UPDATED = 1000;
29
30
    private static $db = [
31
        'HasCaching' => 'Boolean(1)',
32
        'RecordCacheUpdates' => 'Boolean(0)',
33
        'CacheKeyLastEdited' => 'DBDatetime',
34
        'ClassNameLastEdited' => 'Varchar(200)',
35
    ];
36
37
    public function updateCMSFields(FieldList $fields)
38
    {
39
        $name = '';
40
        if (class_exists($this->getOwner()->ClassNameLastEdited)) {
41
            $name = Injector::inst()->get($this->getOwner()->ClassNameLastEdited)->i18n_singular_name();
42
        }
43
        $fields->addFieldsToTab(
44
            'Root.Caching',
45
            [
46
                CheckboxField::create('HasCaching', 'Use caching'),
47
                CheckboxField::create('RecordCacheUpdates', 'Record every change?')
48
                    ->setDescription('To work out when the cache is being updated, you can track every change. This will slow down all your edits, so it is recommend only to turn this on temporarily - for tuning purposes.'),
49
                ReadonlyField::create('CacheKeyLastEdited', 'Content Last Edited')
50
                    ->setRightTitle('The frontend template cache will be invalidated every time this value changes. It changes every time anything is changed in the database.'),
51
                ReadonlyField::create('ClassNameLastEdited', 'Last class updated')
52
                    ->setRightTitle('Last object updated. The name of this object is: ' . $name),
53
            ]
54
        );
55
        if ($this->getOwner()->RecordCacheUpdates) {
56
            $fields->addFieldsToTab(
57
                'Root.Caching',
58
                [
59
                    GridField::create(
60
                        'ObjectsUpdated',
61
                        'Last ' . self::MAX_OBJECTS_UPDATED . ' objects updated',
62
                        ObjectsUpdated::get()->limit(self::MAX_OBJECTS_UPDATED),
63
                        GridFieldConfig_RecordViewer::create()
64
                    ),
65
                ]
66
            );
67
        }
68
    }
69
70
    public static function site_cache_key(): string
71
    {
72
        $obj = SiteConfig::current_site_config();
73
        if ($obj->HasCaching) {
74
            return (string) 'ts_' . strtotime($obj->CacheKeyLastEdited);
0 ignored issues
show
Bug introduced by
It seems like $obj->CacheKeyLastEdited can also be of type null; however, parameter $datetime of strtotime() 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

74
            return (string) 'ts_' . strtotime(/** @scrutinizer ignore-type */ $obj->CacheKeyLastEdited);
Loading history...
75
        }
76
77
        return  (string) 'ts_' . time();
78
    }
79
80
    public static function update_cache_key(?string $className = '')
81
    {
82
        // important - avoid endless loop!
83
        if(SiteConfig::get()->exists()) {
84
            $howOldIsIt = DB::query('SELECT Created FROM SiteConfig LIMIT 1')->value();
85
            if ($howOldIsIt && strtotime((string) $howOldIsIt) > strtotime('-5 minutes')) {
86
                return;
87
            }
88
        } else {
89
            return;
90
        }
91
92
        $obj = SiteConfig::current_site_config();
93
        if ($obj->HasCaching) {
94
            DB::query('
95
                UPDATE "SiteConfig"
96
                SET
97
                    "CacheKeyLastEdited" = \'' . DBDatetime::now()->Rfc2822() . '\',
98
                    "ClassNameLastEdited" = \'' . addslashes((string) $className) . '\'
99
                WHERE ID = ' . $obj->ID . '
100
                LIMIT 1
101
            ;');
102
        }
103
        if ($obj->RecordCacheUpdates) {
104
            $recordId = Injector::inst()
105
                ->create(ObjectsUpdated::class, ['ClassNameLastEdited' => $className])
106
                ->write()
107
            ;
108
            DB::query('DELETE FROM ObjectsUpdated WHERE ID < ' . (int) ($recordId - self::MAX_OBJECTS_UPDATED));
109
        }
110
    }
111
112
    public function requireDefaultRecords()
113
    {
114
        if((int) SiteConfig::get()->count() > 100) {
115
            $currentSiteConfig = SiteConfig::current_site_config();
116
            if($currentSiteConfig) {
0 ignored issues
show
introduced by
$currentSiteConfig is of type SilverStripe\SiteConfig\SiteConfig, thus it always evaluated to true.
Loading history...
117
                DB::alteration_message('Deleting all SiteConfig records except for the current one.', 'deleted');
118
                DB::query('DELETE FROM "SiteConfig" WHERE ID <> ' . $currentSiteConfig->ID);
119
            }
120
        }
121
    }
122
}
123