Passed
Push — master ( f96468...e8dc9f )
by M. Mikkel
03:43
created

CacheFlag::getCpNavItem()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 6
rs 10
1
<?php
2
/**
3
 * Cache Flag plugin for Craft CMS 3.x
4
 *
5
 * Flag and clear template caches.
6
 *
7
 * @link      https://vaersaagod.no
8
 * @copyright Copyright (c) 2018 Mats Mikkel Rummelhoff
9
 */
10
11
namespace mmikkel\cacheflag;
12
13
use Craft;
14
use craft\base\Element;
15
use craft\base\ElementInterface;
16
use craft\base\Plugin;
17
use craft\console\Application as ConsoleApplication;
18
use craft\elements\actions\SetStatus;
19
use craft\events\ElementEvent;
20
use craft\events\ElementActionEvent;
21
use craft\events\MergeElementsEvent;
22
use craft\events\MoveElementEvent;
23
use craft\events\PluginEvent;
24
use craft\events\RegisterCacheOptionsEvent;
25
use craft\events\TemplateEvent;
26
use craft\helpers\ElementHelper;
27
use craft\services\Elements;
28
use craft\services\Plugins;
29
use craft\services\ProjectConfig;
30
use craft\services\Structures;
31
use craft\utilities\ClearCaches;
32
use craft\web\UrlManager;
33
use craft\web\twig\variables\CraftVariable;
34
use craft\web\View;
35
36
use yii\base\Event;
37
use yii\base\InvalidConfigException;
38
39
use mmikkel\cacheflag\services\CacheFlagService;
40
use mmikkel\cacheflag\services\ProjectConfig as CacheFlagProjectConfigService;
41
use mmikkel\cacheflag\services\TemplateCachesService;
42
use mmikkel\cacheflag\twigextensions\Extension as CacheFlagTwigExtension;
43
use mmikkel\cacheflag\variables\CpVariable;
44
45
/**
46
 * Class CacheFlag
47
 *
48
 * @author    Mats Mikkel Rummelhoff
49
 * @package   CacheFlag
50
 * @since     1.0.0
51
 *
52
 * @property CacheFlagService $cacheFlag
53
 * @property CacheFlagProjectConfigService $projectConfig
54
 * @property TemplateCachesService $templateCaches
55
 */
56
class CacheFlag extends Plugin
57
{
58
    // Static Properties
59
    // =========================================================================
60
61
    /**
62
     * @var CacheFlag
63
     */
64
    public static $plugin;
65
66
    // Public Properties
67
    // =========================================================================
68
69
    /**
70
     * @var string
71
     */
72
    public $schemaVersion = '1.0.1';
73
74
    // Public Methods
75
    // =========================================================================
76
77
    /**
78
     * @inheritdoc
79
     */
80
    public function init()
81
    {
82
        parent::init();
83
        self::$plugin = $this;
84
85
        // Register services
86
        $this->setComponents([
87
            'cacheFlag' => CacheFlagService::class,
88
            'projectConfig' => CacheFlagProjectConfigService::class,
89
            'templateCaches' => TemplateCachesService::class,
90
        ]);
91
92
        $this->initProjectConfig();
93
94
        $this->addElementEventListeners();
95
96
        // Register custom Twig extension
97
        Craft::$app->getView()->registerTwigExtension(new CacheFlagTwigExtension());
98
99
        // Add option to the Clear Caches utility to invalidate all flagged caches
100
        Event::on(ClearCaches::class, ClearCaches::EVENT_REGISTER_CACHE_OPTIONS,
101
            static function (RegisterCacheOptionsEvent $event) {
102
                $event->options[] = [
103
                    'key' => 'cacheflag-flagged-caches',
104
                    'label' => Craft::t('cache-flag', 'Flagged template caches'),
105
                    'action' => [CacheFlag::getInstance()->cacheFlag, 'invalidateAllFlaggedCaches'],
106
                    'info' => Craft::t('cache-flag', 'All template caches flagged using Cache Flag'),
107
                ];
108
            }
109
        );
110
111
        // Register CP variable
112
        Event::on(
113
            CraftVariable::class,
114
            CraftVariable::EVENT_INIT,
115
            function (Event $event) {
116
                /** @var CraftVariable $variable */
117
                $variable = $event->sender;
118
                $variable->set('cacheFlagCp', CpVariable::class);
119
            }
120
        );
121
122
        Craft::info(
123
            Craft::t(
124
                'cache-flag',
125
                '{name} plugin loaded',
126
                ['name' => $this->name]
127
            ),
128
            __METHOD__
129
        );
130
    }
131
132
    /** @inheritDoc */
133
    public function getCpNavItem()
134
    {
135
        if (!Craft::$app->getConfig()->getGeneral()->allowAdminChanges) {
136
            return null;
137
        }
138
        return parent::getCpNavItem();
139
    }
140
141
    /**
142
     *
143
     */
144
    protected function initProjectConfig()
145
    {
146
        Event::on(
147
            ProjectConfig::class,
148
            ProjectConfig::EVENT_REBUILD,
149
            [$this->projectConfig, 'onProjectConfigRebuild']
150
        );
151
152
        Craft::$app->projectConfig
153
            ->onAdd('cacheFlags.{uid}', [$this->projectConfig, 'onProjectConfigChange'])
154
            ->onUpdate('cacheFlags.{uid}', [$this->projectConfig, 'onProjectConfigChange'])
155
            ->onRemove('cacheFlags.{uid}', [$this->projectConfig, 'onProjectConfigDelete']);
156
157
        // Flush the project config when the plugin is uninstalled
158
        Event::on(
159
            Plugins::class,
160
            Plugins::EVENT_AFTER_UNINSTALL_PLUGIN,
161
            function (PluginEvent $event) {
162
                if ($event->plugin === $this) {
163
                    Craft::$app->getProjectConfig()->remove('cacheFlags');
164
                }
165
            }
166
        );
167
    }
168
169
    /**
170
     *
171
     */
172
    protected function addElementEventListeners()
173
    {
174
        // Invalidate flagged caches when elements are saved
175
        Event::on(
176
            Elements::class,
177
            Elements::EVENT_AFTER_SAVE_ELEMENT,
178
            function (ElementEvent $event) {
179
                $this->_maybeInvalidateFlaggedCachesByElement($event->element);
180
            }
181
        );
182
183
        // Invalidate flagged caches when elements are deleted
184
        Event::on(
185
            Elements::class,
186
            Elements::EVENT_BEFORE_DELETE_ELEMENT,
187
            function (ElementEvent $event) {
188
                $this->_maybeInvalidateFlaggedCachesByElement($event->element);
189
            }
190
        );
191
192
        // Invalidate flagged caches when structure entries are moved
193
        Event::on(
194
            Structures::class,
195
            Structures::EVENT_AFTER_MOVE_ELEMENT,
196
            function (MoveElementEvent $event) {
197
                $this->_maybeInvalidateFlaggedCachesByElement($event->element);
198
            }
199
        );
200
201
        // Invalidate flagged caches when elements change status
202
        Event::on(
203
            Elements::class,
204
            Elements::EVENT_AFTER_PERFORM_ACTION,
205
            function (ElementActionEvent $event) {
206
207
                /* @var ElementActionInterface|null $action */
208
                $action = $event->action;
209
                if ($action === null || \get_class($action) !== SetStatus::class) {
210
                    return;
211
                }
212
213
                /* @var ElementQueryInterface|null $criteria */
214
                $criteria = $event->criteria;
215
                if ($criteria === null) {
216
                    return;
217
                }
218
219
                /** @var ElementInterface[] $elements */
220
                $elements = $criteria->all();
221
                foreach ($elements as $element) {
222
                    $this->_maybeInvalidateFlaggedCachesByElement($element);
223
                }
224
            }
225
        );
226
    }
227
228
    /**
229
     * @param ElementInterface|Element|null $element
230
     */
231
    private function _maybeInvalidateFlaggedCachesByElement($element)
232
    {
233
        /** @var Element $element */
234
        if ($element === null || ElementHelper::isDraftOrRevision($element)) {
235
            return;
236
        }
237
        CacheFlag::$plugin->cacheFlag->invalidateFlaggedCachesByElement($element);
238
    }
239
240
}
241