Passed
Push — develop-v3 ( 122a20...dc1389 )
by Andrew
03:18
created

Code   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 207
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 88
c 3
b 0
f 0
dl 0
loc 207
rs 10
wmc 15

6 Methods

Rating   Name   Duplication   Size   Complexity  
A displayName() 0 3 1
A getContentColumnType() 0 3 1
A rules() 0 17 1
B normalizeValue() 0 37 7
A getInputHtml() 0 32 4
A getSettingsHtml() 0 9 1
1
<?php
2
/**
3
 * Code Field plugin for Craft CMS
4
 *
5
 * Provides a Code Field that has a full-featured code editor with syntax highlighting & autocomplete
6
 *
7
 * @link      https://nystudio107.com
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @copyright tag
Loading history...
8
 * @copyright Copyright (c) 2022 nystudio107
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
9
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
10
11
namespace nystudio107\codefield\fields;
12
13
use Craft;
14
use craft\base\ElementInterface;
15
use craft\base\Field;
16
use craft\base\PreviewableFieldInterface;
17
use craft\helpers\Json;
18
use craft\validators\ArrayValidator;
19
use nystudio107\codefield\models\CodeData;
20
use nystudio107\codefield\validators\JsonValidator;
21
use yii\db\Schema;
22
23
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
24
 * @author    nystudio107
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @package tag
Loading history...
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
Coding Style introduced by
Tag value for @author tag indented incorrectly; expected 2 spaces but found 4
Loading history...
25
 * @package   CodeField
0 ignored issues
show
Coding Style introduced by
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
26
 * @since     3.0.0
0 ignored issues
show
Coding Style introduced by
The tag in position 3 should be the @author tag
Loading history...
Coding Style introduced by
Tag value for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
27
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
28
class Code extends Field implements PreviewableFieldInterface
29
{
30
    // Public Properties
31
    // =========================================================================
32
33
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
34
     * @var string The theme to use for the Code Editor field.
35
     */
36
    public $theme = 'vs';
37
38
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
39
     * @var string The language to use for the Code Editor field.
40
     */
41
    public $language = 'javascript';
42
43
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
44
     * @var bool Whether the Code Editor field display as a single line
45
     */
46
    public $singleLineEditor = false;
47
48
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
49
     * @var int The font size to use for the Code Editor field
50
     */
51
    public $fontSize = 14;
52
53
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
54
     * @var bool Whether line numbers should be displayed in the Code Editor field
55
     */
56
    public $lineNumbers = false;
57
58
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
59
     * @var bool Whether code folding should be used in the Code Editor field
60
     */
61
    public $codeFolding = false;
62
63
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
64
     * @var string The text that will be shown if the code field is empty.
65
     */
66
    public $placeholder = '';
67
68
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
69
     * @var bool Whether the language selector dropdown menu should be displayed.
70
     */
71
    public $showLanguageDropdown = true;
72
73
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
74
     * @var array The languages that should be listed in the language selector dropdown menu.
75
     */
76
    public $availableLanguages = [
77
        'css',
78
        'graphql',
79
        'html',
80
        'javascript',
81
        'json',
82
        'markdown',
83
        'mysql',
84
        'php',
85
        'shell',
86
        'twig',
87
        'typescript',
88
        'yaml',
89
    ];
90
91
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
92
     * @var string JSON blob of Monaco [EditorOptions](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.IEditorOptions.html) that will override the default settings
93
     */
94
    public $monacoEditorOptions = '';
95
96
    // Static Methods
97
    // =========================================================================
98
99
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
100
     * @inheritdoc
101
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
102
    public static function displayName(): string
103
    {
104
        return Craft::t('codefield', 'Code');
105
    }
106
107
    // Public Methods
108
    // =========================================================================
109
110
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
Parameter $value should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $element should have a doc-comment as per coding-style.
Loading history...
111
     * @inheritdoc
112
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
113
    public function normalizeValue($value, ElementInterface $element = null)
114
    {
115
        if ($value instanceof CodeData) {
116
            return $value;
117
        }
118
        // Default config
119
        $config = [
120
            'value' => '',
121
            'language' => $this->language,
122
        ];
123
        // Handle incoming values potentially being JSON or an array
124
        if (!empty($value)) {
125
            // Handle JSON-encoded values coming in
126
            if (\is_string($value)) {
127
                $jsonValue = Json::decodeIfJson($value);
128
                // If this is still a string (meaning it's not valid JSON), treat it as the value
129
                if (\is_string($jsonValue)) {
130
                    $config['value'] = $jsonValue;
131
                } else {
132
                    $value = $jsonValue;
133
                }
134
            }
135
            if (\is_array($value)) {
136
                $config = array_merge($config, array_filter($value));
137
            }
138
        }
139
        // Create and validate the model
140
        $codeData = new CodeData($config);
141
        if (!$codeData->validate()) {
142
            Craft::error(
143
                Craft::t('codefield', 'CodeData failed validation: ')
144
                . print_r($codeData->getErrors(), true),
0 ignored issues
show
Bug introduced by
Are you sure print_r($codeData->getErrors(), true) of type string|true can be used in concatenation? ( Ignorable by Annotation )

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

144
                . /** @scrutinizer ignore-type */ print_r($codeData->getErrors(), true),
Loading history...
145
                __METHOD__
146
            );
147
        }
148
149
        return $codeData;
150
    }
151
152
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
153
     * @inheritdoc
154
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
155
    public function getSettingsHtml()
156
    {
157
        $monacoLanguages = require(__DIR__ . '/MonacoLanguages.php');
0 ignored issues
show
Coding Style introduced by
"require" is a statement not a function; no parentheses are required
Loading history...
Coding Style introduced by
File is being conditionally included; use "include" instead
Loading history...
158
        // Render the settings template
159
        return Craft::$app->getView()->renderTemplate(
160
            'codefield/_components/fields/Code_settings',
161
            [
162
                'field' => $this,
163
                'monacoLanguages' => $monacoLanguages,
164
            ]
165
        );
166
    }
167
168
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
Parameter $value should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $element should have a doc-comment as per coding-style.
Loading history...
169
     * @inheritdoc
170
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
171
    public function getInputHtml($value, ElementInterface $element = null): string
172
    {
173
        // Get our id and namespace
174
        $id = Craft::$app->getView()->formatInputId($this->handle);
175
        $namespacedId = Craft::$app->getView()->namespaceInputId($id);
176
177
        // Extract just the languages that have been selected for display
178
        $displayLanguages = [];
179
        if ($this->showLanguageDropdown) {
180
            $monacoLanguages = require(__DIR__ . '/MonacoLanguages.php');
0 ignored issues
show
Coding Style introduced by
"require" is a statement not a function; no parentheses are required
Loading history...
Coding Style introduced by
File is being conditionally included; use "include" instead
Loading history...
181
            $decomposedLanguages = array_column($monacoLanguages, 'label', 'value');
182
            $displayLanguages = array_intersect_key($decomposedLanguages, array_flip($this->availableLanguages));
183
            $displayLanguages = array_map(function ($k, $v) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
184
                return ['value' => $k, 'label' => $v];
185
            }, array_keys($displayLanguages), array_values($displayLanguages));
0 ignored issues
show
Coding Style introduced by
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...
186
        }
187
        $monacoOptionsOverride = Json::decodeIfJson($this->monacoEditorOptions);
188
        if ($monacoOptionsOverride === null || is_string($monacoOptionsOverride)) {
189
            $monacoOptionsOverride = [];
190
        }
191
        // Render the input template
192
        return Craft::$app->getView()->renderTemplate(
193
            'codefield/_components/fields/Code_input',
194
            [
195
                'name' => $this->handle,
196
                'value' => $value,
197
                'field' => $this,
198
                'orientation' => $this->getOrientation($element),
199
                'id' => $id,
200
                'namespacedId' => $namespacedId,
201
                'displayLanguages' => $displayLanguages,
202
                'monacoOptionsOverride' => $monacoOptionsOverride,
203
            ]
204
        );
205
    }
206
207
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
208
     * @inheritdoc
209
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
210
    public function rules()
211
    {
212
        $rules = parent::rules();
213
        $rules = array_merge($rules, [
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
214
            ['theme', 'in', 'range' => ['vs', 'vs-dark', 'hc-black']],
215
            ['theme', 'default', 'value' => 'vs'],
216
            ['language', 'string'],
217
            ['language', 'default', 'value' => 'javascript'],
218
            [['singleLineEditor', 'showLanguageDropdown', 'lineNumbers', 'codeFolding'], 'boolean'],
219
            ['placeholder', 'string'],
220
            ['placeholder', 'default', 'value' => ''],
221
            ['fontSize', 'integer'],
222
            ['fontSize', 'default', 'value' => 14],
223
            ['availableLanguages', ArrayValidator::class],
224
            ['monacoEditorOptions', JsonValidator::class],
225
        ]);
0 ignored issues
show
Coding Style introduced by
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...
226
        return $rules;
227
    }
228
229
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
230
     * @inheritdoc
231
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
232
    public function getContentColumnType(): string
233
    {
234
        return Schema::TYPE_TEXT;
235
    }
236
}
237