Issues (245)

src/models/Settings.php (1 issue)

1
<?php
2
/**
3
 * SEOmatic plugin for Craft CMS
4
 *
5
 * A turnkey SEO implementation for Craft CMS that is comprehensive, powerful,
6
 * and flexible
7
 *
8
 * @link      https://nystudio107.com
9
 * @copyright Copyright (c) 2017 nystudio107
10
 */
11
12
namespace nystudio107\seomatic\models;
13
14
use craft\behaviors\EnvAttributeParserBehavior;
15
use craft\validators\ArrayValidator;
16
use nystudio107\seomatic\base\SeoElementInterface;
17
use nystudio107\seomatic\base\VarsModel;
18
19
/**
20
 * Plugin settings object, containing values for configuring the plugin
21
 *
22
 * @author    nystudio107
23
 * @package   Seomatic
24
 * @since     3.0.0
25
 */
26
class Settings extends VarsModel
27
{
28
    // Public Properties
29
    // =========================================================================
30
31
    /**
32
     * @var string The public-facing name of the plugin
33
     */
34
    public string $pluginName = 'SEOmatic';
35
36
    /**
37
     * @var bool Should SEOmatic render metadata?
38
     */
39
    public bool $renderEnabled = true;
40
41
    /**
42
     * @var bool Should SEOmatic render frontend sitemaps?
43
     */
44
    public bool $sitemapsEnabled = true;
45
46
    /**
47
     * @deprecated This setting is no longer relevant with the paginated sitemap generation
48
     * @var bool Should sitemaps be regenerated automatically?
49
     */
50
    public bool $regenerateSitemapsAutomatically = true;
51
52
    /**
53
     * @var bool Should sitemaps be submitted to search engines automatically whenever there are changes?
54
     */
55
    public bool $submitSitemaps = true;
56
57
    /**
58
     * @var bool Should items where the entry URL doesn't match the canonical URL be excluded?
59
     */
60
    public bool $excludeNonCanonicalUrls = false;
61
62
    /**
63
     * @var bool Should the homepage be included in the generated Breadcrumbs JSON-LD?
64
     */
65
    public bool $includeHomepageInBreadcrumbs = true;
66
67
    /**
68
     * @var bool Should SEOmatic add to the http response headers?
69
     */
70
    public bool $headersEnabled = true;
71
72
    /**
73
     * @var bool Whether the environment should be manually set, or automatically determined
74
     */
75
    public bool $manuallySetEnvironment = false;
76
77
    /**
78
     * @var string The server environment, either `live`, `staging`, or `local`
79
     */
80
    public string $environment = 'live';
81
82
    /**
83
     * @var bool Should SEOmatic display the SEO Preview sidebar?
84
     */
85
    public bool $displayPreviewSidebar = true;
86
87
    /**
88
     * @var bool Should SEOmatic add a Social Media Preview Target?
89
     */
90
    public bool $socialMediaPreviewTarget = true;
91
92
    /**
93
     * @var array The social media platforms that should be displayed in the SEO Preview sidebar
94
     */
95
    public array $sidebarDisplayPreviewTypes = [
96
        'google',
97
        'twitter',
98
        'facebook',
99
    ];
100
101
    /**
102
     * @var bool Should SEOmatic display the SEO Analysis sidebar?
103
     */
104
    public bool $displayAnalysisSidebar = true;
105
106
    /**
107
     * @var string If `devMode` is on, prefix the <title> with this string
108
     */
109
    public string $devModeTitlePrefix = '&#x1f6a7; ';
110
111
    /**
112
     * @var string Prefix the Control Panel <title> with this string
113
     */
114
    public string $cpTitlePrefix = '&#x2699; ';
115
116
    /**
117
     * @var string If `devMode` is on, prefix the Control Panel <title> with this string
118
     */
119
    public string $devModeCpTitlePrefix = '&#x1f6a7;&#x2699; ';
120
121
    /**
122
     * @var string The separator character to use for the `<title>` tag
123
     */
124
    public string $separatorChar = '|';
125
126
    /**
127
     * @var int The max number of characters in the `<title>` tag
128
     */
129
    public int $maxTitleLength = 70;
130
131
    /**
132
     * @var int The max number of characters in the `<meta name="description">` tag
133
     */
134
    public int $maxDescriptionLength = 155;
135
136
    /**
137
     * @var bool Should Title tags be truncated at the max length, on word boundaries?
138
     */
139
    public bool $truncateTitleTags = true;
140
141
    /**
142
     * @var bool Should Description tags be truncated at the max length, on word boundaries?
143
     */
144
    public bool $truncateDescriptionTags = true;
145
146
    /**
147
     * @var bool Site Groups define logically separate sites
148
     */
149
    public bool $siteGroupsSeparate = true;
150
151
    /**
152
     * @var bool Whether to dynamically include the hreflang tags
153
     */
154
    public bool $addHrefLang = true;
155
156
    /**
157
     * @var bool Whether to dynamically include the `x-default` hreflang tags
158
     */
159
    public bool $addXDefaultHrefLang = true;
160
161
    /**
162
     * @var int The site to use for the `x-default` hreflang tag (0 defaults to the Primary site)
163
     */
164
    public int $xDefaultSite = 0;
165
166
    /**
167
     * @var bool Whether to dynamically include hreflang tags on paginated pages
168
     */
169
    public bool $addPaginatedHreflang = true;
170
171
    /**
172
     * @var string Whether to include a Content Security Policy "nonce" for inline
173
     *      CSS or JavaScript. Valid values are 'header' or 'tag' for how the CSP
174
     *      should be included. c.f.:
175
     *      https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Unsafe_inline_script
176
     */
177
    public string $cspNonce = '';
178
179
    /**
180
     * @var array Fixed Content Security Policies to be added before any CSP nonces
181
     */
182
    public array $cspScriptSrcPolicies = [
183
        0 => [
184
            'policy' => "'self'",
185
        ],
186
    ];
187
188
    /**
189
     * @var bool
190
     * SEO [best practices](https://www.searchenginejournal.com/google-dont-mix-noindex-relcanonical/262607)
191
     * are to have `canonical` links not appear on pages that are not intended to be indexed. SEOmatic does
192
     * this for you by default, but you can override that behavior with this setting
193
     */
194
    public bool $alwaysIncludeCanonicalUrls = false;
195
196
    /**
197
     * @var bool Should the Canonical URL be automatically lower-cased?
198
     */
199
    public bool $lowercaseCanonicalUrl = true;
200
201
    /**
202
     * @var bool Should the meta generator tag and X-Powered-By header be included?
203
     */
204
    public bool $generatorEnabled = true;
205
206
    /**
207
     * @var string|array
208
     * SEOmatic uses the Craft `siteUrl` to generate the external URLs.  If you
209
     * are using it in a non-standard environment, such as a headless GraphQL or
210
     * ElementAPI server, you can override what it uses for the `siteUrl` below.
211
     * This can be either a simple string, or an array of strings indexed by the site
212
     * handle, for multi-site setups. e.g.:
213
     * 'siteUrlOverride' => [
214
     *     'default' => 'http://example.com/',
215
     *     'spanish' => 'http://example.com/es/',
216
     * ],     */
217
    public string|array $siteUrlOverride = '';
218
219
    /**
220
     * @var int|null
221
     * The duration of the SEOmatic meta cache in seconds.  Null means always cached until explicitly broken
222
     * If devMode is on, caches last 30 seconds.
223
     */
224
    public ?int $metaCacheDuration = 0;
225
226
    /**
227
     * @var bool Determines whether the meta container endpoint should be enabled for anonymous frontend access
228
     */
229
    public bool $enableMetaContainerEndpoint = false;
230
231
    /**
232
     * @var bool Determines whether the JSON-LD endpoint should be enabled for anonymous frontend access
233
     */
234
    public bool $enableJsonLdEndpoint = false;
235
236
    /**
237
     * @var bool Determines whether the SEO File Link endpoint should be enabled for anonymous frontend access
238
     */
239
    public bool $enableSeoFileLinkEndpoint = false;
240
241
    /**
242
     * @var bool Determines whether the SEOmatic debug toolbar panel should be added to the Yii2 debug toolbar
243
     */
244
    public bool $enableDebugToolbarPanel = true;
245
246
    /**
247
     * @var SeoElementInterface[] The default SeoElement type classes
248
     */
249
    public array $defaultSeoElementTypes = [
250
    ];
251
252
    /**
253
     * @var string[] URL params that are allowed to be considered part of the unique URL used for the metadata cache
254
     */
255
    public array $allowedUrlParams = [
256
    ];
257
258
    /**
259
     * @var class-string[] Array of TwigExtension classes to instantiate and add to the SandboxView
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string[] at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string[].
Loading history...
260
     */
261
    public array $twigExtensionClasses = [
262
    ];
263
264
    // Public Methods
265
    // =========================================================================
266
267
    /**
268
     * @inerhitdoc
269
     */
270
    public function __construct($config = [])
271
    {
272
        if (!empty($config)) {
273
            // Normalize the metaCacheDuration to an integer
274
            if (empty($config['metaCacheDuration']) || $config['metaCacheDuration'] === 'null') {
275
                $config['metaCacheDuration'] = 0;
276
            }
277
        }
278
279
        parent::__construct($config);
280
    }
281
282
    /**
283
     * @inheritdoc
284
     */
285
    public function rules(): array
286
    {
287
        return [
288
            ['pluginName', 'string'],
289
            ['pluginName', 'default', 'value' => 'SEOmatic'],
290
            [
291
                [
292
                    'renderEnabled',
293
                    'sitemapsEnabled',
294
                    'regenerateSitemapsAutomatically',
295
                    'submitSitemaps',
296
                    'excludeNonCanonicalUrls',
297
                    'includeHomepageInBreadcrumbs',
298
                    'headersEnabled',
299
                    'generatorEnabled',
300
                    'addHrefLang',
301
                    'addXDefaultHrefLang',
302
                    'addPaginatedHreflang',
303
                    'manuallySetEnvironment',
304
                ],
305
                'boolean',
306
            ],
307
            ['xDefaultSite', 'integer'],
308
            ['xDefaultSite', 'default', 'value' => 0],
309
            ['cspNonce', 'string'],
310
            ['cspNonce', 'in', 'range' => [
311
                '',
312
                'header',
313
                'tag',
314
            ]],
315
            ['environment', 'string'],
316
            ['environment', 'default', 'value' => 'live'],
317
            [
318
                [
319
                    'displayPreviewSidebar',
320
                    'socialMediaPreviewTarget',
321
                    'displayAnalysisSidebar',
322
                    'enableMetaContainerEndpoint',
323
                    'enableJsonLdEndpoint',
324
                    'enableSeoFileLinkEndpoint',
325
                    'alwaysIncludeCanonicalUrls',
326
                    'lowercaseCanonicalUrl',
327
                    'truncateTitleTags',
328
                    'truncateDescriptionTags',
329
                    'enableDebugToolbarPanel',
330
                ],
331
                'boolean',
332
            ],
333
            [['devModeTitlePrefix', 'cpTitlePrefix', 'devModeCpTitlePrefix'], 'string'],
334
            ['separatorChar', 'string'],
335
            ['separatorChar', 'default', 'value' => '|'],
336
            ['maxTitleLength', 'integer', 'min' => 10],
337
            ['maxTitleLength', 'default', 'value' => 70],
338
            ['maxDescriptionLength', 'integer', 'min' => 10],
339
            ['maxDescriptionLength', 'default', 'value' => 155],
340
            ['siteUrlOverride', 'safe'],
341
            ['siteUrlOverride', 'default', 'value' => ''],
342
            [
343
                [
344
                    'sidebarDisplayPreviewTypes',
345
                    'defaultSeoElementTypes',
346
                    'cspScriptSrcPolicies',
347
                    'allowedUrlParams',
348
                    'twigExtensionClasses',
349
                ],
350
                ArrayValidator::class,
351
            ],
352
            ['metaCacheDuration', 'default', 'value' => 0],
353
            ['metaCacheDuration', 'integer'],
354
        ];
355
    }
356
357
    /**
358
     * @inheritdoc
359
     */
360
    public function behaviors(): array
361
    {
362
        // Keep any parent behaviors
363
        $behaviors = parent::behaviors();
364
365
        return array_merge($behaviors, [
366
            'parser' => [
367
                'class' => EnvAttributeParserBehavior::class,
368
                'attributes' => [
369
                    'environment',
370
                ],
371
            ],
372
        ]);
373
    }
374
}
375