Issues (354)

src/Twigpack.php (1 issue)

1
<?php
2
/**
3
 * Twigpack plugin for Craft CMS 3.x
4
 *
5
 * Twigpack is the conduit between Twig and webpack, with manifest.json &
6
 * webpack-dev-server HMR support
7
 *
8
 * @link      https://nystudio107.com/
9
 * @copyright Copyright (c) 2018 nystudio107
10
 */
11
12
namespace nystudio107\twigpack;
13
14
use Craft;
15
use craft\base\Model;
16
use craft\base\Plugin;
17
use craft\cloud\cli\controllers\UpController;
18
use craft\events\CancelableEvent;
19
use craft\events\PluginEvent;
20
use craft\events\RegisterCacheOptionsEvent;
21
use craft\events\TemplateEvent;
22
use craft\services\Plugins;
23
use craft\utilities\ClearCaches;
24
use craft\web\Application;
25
use craft\web\twig\variables\CraftVariable;
26
use craft\web\View;
27
use nystudio107\twigpack\models\Settings;
28
use nystudio107\twigpack\services\Manifest as ManifestService;
29
use nystudio107\twigpack\variables\ManifestVariable;
30
use yii\base\Event;
31
use yii\web\NotFoundHttpException;
32
33
/**
34
 * Class Twigpack
35
 *
36
 * @author    nystudio107
37
 * @package   Twigpack
38
 * @since     1.0.0
39
 *
40
 * @property  ManifestService $manifest
41
 */
42
class Twigpack extends Plugin
43
{
44
    // Static Properties
45
    // =========================================================================
46
47
    /**
48
     * @var ?Twigpack
49
     */
50
    public static ?Twigpack $plugin = null;
51
52
    /**
53
     * @var string
54
     */
55
    public static string $templateName = '';
56
57
    // Static Methods
58
    // =========================================================================
59
    /**
60
     * @var string
61
     */
62
    public string $schemaVersion = '1.0.0';
63
64
    // Public Properties
65
    // =========================================================================
66
    /**
67
     * @var bool
68
     */
69
    public bool $hasCpSection = false;
70
    /**
71
     * @var bool
72
     */
73
    public bool $hasCpSettings = false;
74
75
    /**
76
     * @inheritdoc
77
     */
78
    public function __construct($id, $parent = null, array $config = [])
79
    {
80
        $config['components'] = [
81
            'manifest' => ManifestService::class,
82
        ];
83
84
        parent::__construct($id, $parent, $config);
85
    }
86
87
    // Public Methods
88
    // =========================================================================
89
90
    /**
91
     * @inheritdoc
92
     */
93
    public function init(): void
94
    {
95
        parent::init();
96
        self::$plugin = $this;
97
        // Install our event listeners
98
        $this->installEventListeners();
99
        // Log that we've loaded
100
        Craft::info(
101
            Craft::t(
102
                'twigpack',
103
                '{name} plugin loaded',
104
                ['name' => $this->name]
105
            ),
106
            __METHOD__
107
        );
108
    }
109
110
    /**
111
     * Clear all the caches!
112
     */
113
    public function clearAllCaches(): void
114
    {
115
        // Clear all of Twigpack's caches
116
        self::$plugin->manifest->invalidateCaches();
117
    }
118
119
    /**
120
     * Inject the error entry point JavaScript for auto-reloading of Twig error
121
     * pages
122
     */
123
    public function injectErrorEntry(): void
124
    {
125
        if (Craft::$app->getResponse()->isServerError || Craft::$app->getResponse()->isClientError) {
126
            /** @var ?Settings $settings */
127
            $settings = self::$plugin->getSettings();
128
            if ($settings && !empty($settings->errorEntry) && $settings->useDevServer) {
129
                try {
130
                    $errorEntry = $settings->errorEntry;
131
                    if (is_string($errorEntry)) {
132
                        $errorEntry = [$errorEntry];
133
                    }
134
                    foreach ($errorEntry as $entry) {
135
                        $tag = self::$plugin->manifest->getJsModuleTags($entry, false);
136
                        if ($tag !== null) {
137
                            echo $tag;
138
                        }
139
                    }
140
                } catch (NotFoundHttpException $e) {
141
                    // That's okay, Twigpack will have already logged the error
142
                }
143
            }
144
        }
145
    }
146
147
    // Protected Methods
148
    // =========================================================================
149
150
    /**
151
     * Install our event listeners.
152
     */
153
    protected function installEventListeners(): void
154
    {
155
        // Remember the name of the currently rendering template
156
        // Handler: View::EVENT_BEFORE_RENDER_PAGE_TEMPLATE
157
        Event::on(
158
            View::class,
159
            View::EVENT_BEFORE_RENDER_PAGE_TEMPLATE,
160
            static function(TemplateEvent $event) {
161
                self::$templateName = $event->template;
162
            }
163
        );
164
        // Handler: CraftVariable::EVENT_INIT
165
        Event::on(
166
            CraftVariable::class,
167
            CraftVariable::EVENT_INIT,
168
            static function(Event $event) {
169
                /** @var CraftVariable $variable */
170
                $variable = $event->sender;
171
                $variable->set('twigpack', ManifestVariable::class);
172
            }
173
        );
174
        // Handler: Plugins::EVENT_AFTER_INSTALL_PLUGIN
175
        Event::on(
176
            Plugins::class,
177
            Plugins::EVENT_AFTER_INSTALL_PLUGIN,
178
            function(PluginEvent $event) {
179
                if ($event->plugin === $this) {
180
                    // Invalidate our caches after we've been installed
181
                    $this->clearAllCaches();
182
                }
183
            }
184
        );
185
        // Handler: ClearCaches::EVENT_REGISTER_CACHE_OPTIONS
186
        Event::on(
187
            ClearCaches::class,
188
            ClearCaches::EVENT_REGISTER_CACHE_OPTIONS,
189
            function(RegisterCacheOptionsEvent $event) {
190
                Craft::debug(
191
                    'ClearCaches::EVENT_REGISTER_CACHE_OPTIONS',
192
                    __METHOD__
193
                );
194
                // Register our caches for the Clear Cache Utility
195
                $event->options = array_merge(
196
                    $event->options,
197
                    $this->customAdminCpCacheOptions()
198
                );
199
            }
200
        );
201
        // Clears cache after craft cloud/up is run, which Craft Cloud runs on deploy
202
        // Handler: UpController::EVENT_AFTER_UP
203
        if (class_exists(UpController::class)) {
204
            Event::on(
205
                UpController::class,
206
                UpController::EVENT_AFTER_UP,
207
                function (CancelableEvent $event) {
0 ignored issues
show
The parameter $event is not used and could be removed. ( Ignorable by Annotation )

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

207
                function (/** @scrutinizer ignore-unused */ CancelableEvent $event) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
208
                    $this->clearAllCaches();
209
                }
210
            );
211
        }
212
213
        // delay attaching event handler to the view component after it is fully configured
214
        $app = Craft::$app;
215
        if ($app->getConfig()->getGeneral()->devMode) {
216
            $app->on(Application::EVENT_BEFORE_REQUEST, function() use ($app) {
217
                $app->getView()->on(View::EVENT_END_BODY, [$this, 'injectErrorEntry']);
218
            });
219
        }
220
    }
221
222
    /**
223
     * Returns the custom Control Panel cache options.
224
     *
225
     * @return array
226
     */
227
    protected function customAdminCpCacheOptions(): array
228
    {
229
        return [
230
            // Manifest cache
231
            [
232
                'key' => 'twigpack-manifest-cache',
233
                'label' => Craft::t('twigpack', 'Twigpack Manifest Cache'),
234
                'action' => [$this, 'clearAllCaches'],
235
            ],
236
        ];
237
    }
238
239
    /**
240
     * @inheritdoc
241
     */
242
    protected function createSettingsModel(): ?Model
243
    {
244
        return new Settings();
245
    }
246
}
247