Issues (1834)

src/fields/ShortLink.php (56 issues)

1
<?php
2
/**
3
 * Retour plugin for Craft CMS
4
 *
5
 * @link      https://nystudio107.com/
0 ignored issues
show
The tag in position 1 should be the @copyright tag
Loading history...
6
 * @copyright Copyright (c) 2022 nystudio107
0 ignored issues
show
@copyright tag must contain a year and the name of the copyright holder
Loading history...
7
 * @license   https://nystudio107.com/license
0 ignored issues
show
@license tag must contain a URL and a license name
Loading history...
8
 */
0 ignored issues
show
PHP version not specified
Loading history...
Missing @category tag in file comment
Loading history...
Missing @package tag in file comment
Loading history...
Missing @author tag in file comment
Loading history...
9
10
namespace nystudio107\retour\fields;
11
12
use Craft;
13
use craft\base\ElementInterface;
14
use craft\base\Field;
15
use craft\base\PreviewableFieldInterface;
16
use craft\helpers\ElementHelper;
17
use craft\helpers\Html;
18
use craft\helpers\Json;
19
use craft\helpers\UrlHelper;
20
use nystudio107\retour\Retour as RetourPlugin;
21
use yii\helpers\StringHelper;
22
23
/**
0 ignored issues
show
Missing short description in doc comment
Loading history...
24
 * @author    nystudio107
0 ignored issues
show
The tag in position 1 should be the @package tag
Loading history...
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
Tag value for @author tag indented incorrectly; expected 2 spaces but found 4
Loading history...
25
 * @package   Retour
0 ignored issues
show
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
26
 * @since     3.2.0
0 ignored issues
show
The tag in position 3 should be the @author tag
Loading history...
Tag value for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
27
 *
28
 * @property-read string $contentColumnType
29
 */
0 ignored issues
show
Missing @category tag in class comment
Loading history...
Missing @license tag in class comment
Loading history...
Missing @link tag in class comment
Loading history...
30
class ShortLink extends Field implements PreviewableFieldInterface
31
{
32
    protected static $allowShortLinkUpdates = true;
33
    public $redirectSrcMatch = 'pathonly';
34
    public $redirectHttpCode = 301;
35
36
    // Static Methods
37
38
    // =========================================================================
39
40
    /**
0 ignored issues
show
Missing short description in doc comment
Loading history...
41
     * @inheritdoc
42
     */
0 ignored issues
show
Missing @return tag in function comment
Loading history...
43
    public static function displayName(): string
44
    {
45
        return Craft::t('retour', 'Short Link');
46
    }
47
48
    /**
49
     * Prevent element updates from updating the short link redirects.
50
     */
0 ignored issues
show
Missing @return tag in function comment
Loading history...
51
    public static function preventShortLinkUpdates()
52
    {
53
        self::$allowShortLinkUpdates = false;
54
    }
55
56
    /**
57
     * Allow element updates to update the short link redirects.
58
     */
0 ignored issues
show
Missing @return tag in function comment
Loading history...
59
    public static function allowShortLinkUpdates()
60
    {
61
        self::$allowShortLinkUpdates = true;
62
    }
63
64
    // Public Methods
65
    // =========================================================================
66
67
    /**
0 ignored issues
show
Missing short description in doc comment
Loading history...
Parameter $value should have a doc-comment as per coding-style.
Loading history...
Parameter $element should have a doc-comment as per coding-style.
Loading history...
68
     * @inheritdoc
69
     */
0 ignored issues
show
Missing @return tag in function comment
Loading history...
70
    public function getInputHtml($value, ElementInterface $element = null): string
71
    {
72
        // Get our id & namespaceId
73
        $craft35 = version_compare(Craft::$app->getVersion(), '3.5', '>=');
74
        if ($craft35) {
75
            $id = Html::id($this->handle);
0 ignored issues
show
It seems like $this->handle can also be of type null; however, parameter $id of craft\helpers\Html::id() 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

75
            $id = Html::id(/** @scrutinizer ignore-type */ $this->handle);
Loading history...
76
        } else {
77
            $id = Craft::$app->getView()->formatInputId($this->handle);
78
        }
79
        $namespacedId = Craft::$app->getView()->namespaceInputId($id);
80
81
        // Render the input template
82
        return Craft::$app->getView()->renderTemplate(
83
            'retour/_components/fields/ShortLink_input',
84
            [
85
                'name' => $this->handle,
86
                'value' => $value,
87
                'field' => $this,
88
                'id' => $id,
89
                'namespacedId' => $namespacedId,
90
            ]
91
        );
92
    }
93
94
    /**
0 ignored issues
show
Missing short description in doc comment
Loading history...
95
     * @inheritdoc
96
     */
0 ignored issues
show
Missing @return tag in function comment
Loading history...
97
    public function getSettingsHtml()
98
    {
99
        return Craft::$app->getView()->renderTemplate('retour/_components/fields/ShortLink_settings',
0 ignored issues
show
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
100
            [
101
                'field' => $this,
102
            ]);
0 ignored issues
show
This line of the multi-line function call does not seem to be indented correctly. Expected 8 spaces, but found 12.
Loading history...
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
103
    }
104
105
    /**
0 ignored issues
show
Missing short description in doc comment
Loading history...
Parameter $element should have a doc-comment as per coding-style.
Loading history...
106
     * @inheritdoc
107
     */
0 ignored issues
show
Missing @return tag in function comment
Loading history...
108
    public function getIsTranslatable(ElementInterface $element = null): bool
109
    {
110
        return false;
111
    }
112
113
    /**
0 ignored issues
show
Missing short description in doc comment
Loading history...
Parameter $element should have a doc-comment as per coding-style.
Loading history...
Parameter $isNew should have a doc-comment as per coding-style.
Loading history...
114
     * @inheritdoc
115
     */
0 ignored issues
show
Missing @return tag in function comment
Loading history...
116
    public function afterElementSave(ElementInterface $element, bool $isNew)
117
    {
118
        if (!self::$allowShortLinkUpdates || $element->getIsDraft() || !$element->getSite()->hasUrls) {
119
            return;
120
        }
121
122
        $value = $element->getFieldValue($this->handle);
0 ignored issues
show
It seems like $this->handle can also be of type null; however, parameter $fieldHandle of craft\base\ElementInterface::getFieldValue() 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

122
        $value = $element->getFieldValue(/** @scrutinizer ignore-type */ $this->handle);
Loading history...
123
124
        // Return for propagating elements
125
        if ($this->redirectSrcMatch === 'pathonly') {
126
            $parentElement = ElementHelper::rootElement($element);
127
            if ($this->translationMethod === Field::TRANSLATION_METHOD_NONE && ($element->propagating || $parentElement->propagating)) {
0 ignored issues
show
Accessing propagating on the interface craft\base\ElementInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
128
                return;
129
            }
130
        } elseif (!empty($value) && !StringHelper::startsWith($value, 'http')) {
131
            $value = UrlHelper::siteUrl($value, null, null, $element->siteId);
0 ignored issues
show
Accessing siteId on the interface craft\base\ElementInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
132
        }
133
134
        $parentElement = ElementHelper::rootElement($element);
135
        RetourPlugin::$plugin->redirects->removeElementRedirect($parentElement, false);
136
137
        if (!empty($value)) {
138
            $redirectSrcMatch = $this->redirectSrcMatch;
139
140
            RetourPlugin::$plugin->redirects->enableElementRedirect($parentElement, $value, $redirectSrcMatch, $this->redirectHttpCode);
141
        }
142
143
        parent::afterElementSave($element, $isNew);
144
    }
145
146
    /**
0 ignored issues
show
Missing short description in doc comment
Loading history...
Parameter $element should have a doc-comment as per coding-style.
Loading history...
147
     * @inheritdoc
148
     */
0 ignored issues
show
Missing @return tag in function comment
Loading history...
149
    public function afterElementDelete(ElementInterface $element)
150
    {
151
        if ($element->getIsDraft() || $element->getIsRevision()) {
152
            return;
153
        }
154
155
        RetourPlugin::$plugin->redirects->removeElementRedirect($element, true, true);
156
        parent::afterElementDelete($element);
157
    }
158
159
    /**
0 ignored issues
show
Missing short description in doc comment
Loading history...
Parameter $value should have a doc-comment as per coding-style.
Loading history...
Parameter $element should have a doc-comment as per coding-style.
Loading history...
160
     * @inheritdoc
161
     */
0 ignored issues
show
Missing @return tag in function comment
Loading history...
162
    public function getTableAttributeHtml($value, ElementInterface $element): string
163
    {
164
        $decoded = Json::decodeIfJson($value);
165
        if (is_array($decoded)) {
166
            $value = $decoded['legacyUrl'] ?? '';
167
        }
168
        // Render the preview template
169
        return Craft::$app->getView()->renderTemplate(
170
            'retour/_components/fields/ShortLink_preview',
171
            [
172
                'name' => $this->handle,
173
                'value' => $value,
174
                'field' => $this,
175
            ]
176
        );
177
    }
178
179
    /**
0 ignored issues
show
Missing short description in doc comment
Loading history...
180
     * @inheritdoc
181
     */
0 ignored issues
show
Missing @return tag in function comment
Loading history...
182
    public function getElementValidationRules(): array
183
    {
184
        return [
185
            [
186
                /** @var ElementInterface $element */
0 ignored issues
show
Missing short description in doc comment
Loading history...
The open comment tag must be the only content on the line
Loading history...
The close comment tag must be the only content on the line
Loading history...
187
                function($element) {
0 ignored issues
show
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
188
                    $value = $element->getFieldValue($this->handle);
0 ignored issues
show
It seems like $this->handle can also be of type null; however, parameter $fieldHandle of craft\base\ElementInterface::getFieldValue() 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

188
                    $value = $element->getFieldValue(/** @scrutinizer ignore-type */ $this->handle);
Loading history...
189
                    $redirect = RetourPlugin::$plugin->getRedirects()->getRedirectByRedirectSrcUrl($value);
190
                    if (method_exists($element, 'getCanonical')) {
191
                        // Handle drafts
192
                        $element = $element->getCanonical();
193
                    }
194
                    if ($redirect && isset($redirect['associatedElementId'])) {
195
                        if ($redirect['associatedElementId'] == 0) {
196
                            $element->addError($this->handle, Craft::t('retour', 'A Retour redirect with this Legacy URL already exists.'));
197
                        } elseif ($redirect['associatedElementId'] !== $element->id) {
0 ignored issues
show
Accessing id on the interface craft\base\ElementInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
198
                            $element->addError($this->handle, Craft::t('retour', 'A Short Link with this URL already exists.'));
199
                        }
200
                    }
201
                },
202
            ],
203
        ];
204
    }
205
}
206