Passed
Push — develop-v4 ( 09ded3...c00934 )
by Andrew
04:31
created

InstantAnalytics::addComponents()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 11
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 18
rs 9.9
1
<?php
2
/**
3
 * Instant Analytics plugin for Craft CMS
4
 *
5
 * Instant Analytics brings full Google Analytics support to your Twig templates
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) 2017 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\instantanalyticsGa4;
12
13
use Craft;
14
use craft\base\Model;
15
use craft\base\Plugin;
16
use craft\commerce\elements\Order;
0 ignored issues
show
Bug introduced by
The type craft\commerce\elements\Order was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use craft\commerce\events\LineItemEvent;
0 ignored issues
show
Bug introduced by
The type craft\commerce\events\LineItemEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use craft\commerce\Plugin as Commerce;
0 ignored issues
show
Bug introduced by
The type craft\commerce\Plugin was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use craft\events\PluginEvent;
20
use craft\events\RegisterUrlRulesEvent;
21
use craft\events\TemplateEvent;
22
use craft\helpers\UrlHelper;
23
use craft\services\Plugins;
24
use craft\web\twig\variables\CraftVariable;
25
use craft\web\UrlManager;
26
use craft\web\View;
27
use Exception;
28
use nystudio107\instantanalyticsGa4\helpers\Field as FieldHelper;
29
use nystudio107\instantanalyticsGa4\models\Settings;
30
use nystudio107\instantanalyticsGa4\services\ServicesTrait;
31
use nystudio107\instantanalyticsGa4\twigextensions\InstantAnalyticsTwigExtension;
32
use nystudio107\instantanalyticsGa4\variables\InstantAnalyticsVariable;
33
use nystudio107\seomatic\Seomatic;
0 ignored issues
show
Bug introduced by
The type nystudio107\seomatic\Seomatic was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
34
use yii\base\Event;
35
use yii\web\Response;
36
use function array_merge;
37
38
/** @noinspection MissingPropertyAnnotationsInspection */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
39
40
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
41
 * @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...
42
 * @package   InstantAnalytics
0 ignored issues
show
Coding Style introduced by
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
43
 * @since     1.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...
44
 */
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...
45
class InstantAnalytics extends Plugin
46
{
47
    // Traits
48
    // =========================================================================
49
50
    use ServicesTrait;
51
52
    // Constants
53
    // =========================================================================
54
55
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
56
     * @var string
57
     */
58
    protected const COMMERCE_PLUGIN_HANDLE = 'commerce';
59
60
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
61
     * @var string
62
     */
63
    protected const SEOMATIC_PLUGIN_HANDLE = 'seomatic';
64
65
    // Static Properties
66
    // =========================================================================
67
68
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
69
     * @var null|InstantAnalytics
70
     */
71
    public static ?InstantAnalytics $plugin = null;
72
73
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
74
     * @var null|Settings
75
     */
76
    public static ?Settings $settings = null;
77
78
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
79
     * @var null|Commerce
80
     */
81
    public static ?Commerce $commercePlugin = null;
82
83
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
84
     * @var null|Seomatic
85
     */
86
    public static ?Seomatic $seomaticPlugin = null;
87
88
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
89
     * @var string
90
     */
91
    public static string $currentTemplate = '';
92
93
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
94
     * @var bool
95
     */
96
    public static bool $pageViewSent = false;
97
98
    // Public Properties
99
    // =========================================================================
100
101
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
102
     * @var string
103
     */
104
    public string $schemaVersion = '1.0.0';
105
106
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
107
     * @var bool
108
     */
109
    public bool $hasCpSection = false;
110
111
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
112
     * @var bool
113
     */
114
    public bool $hasCpSettings = true;
115
116
    // Public Methods
117
    // =========================================================================
118
119
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
120
     * @inheritdoc
121
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
122
    public function init(): void
123
    {
124
        parent::init();
125
        self::$plugin = $this;
126
        self::$settings = $this->getSettings();
127
128
        // Add in our Craft components
129
        $this->addComponents();
130
        // Install our global event handlers
131
        $this->installEventListeners();
132
133
        Craft::info(
134
            Craft::t(
135
                'instant-analytics-ga4',
136
                '{name} plugin loaded',
137
                ['name' => $this->name]
138
            ),
139
            __METHOD__
140
        );
141
    }
142
143
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
144
     * @inheritdoc
145
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
146
    protected function settingsHtml(): ?string
147
    {
148
        $commerceFields = [];
149
150
        if (self::$commercePlugin !== null) {
151
            $productTypes = self::$commercePlugin->getProductTypes()->getAllProductTypes();
152
153
            foreach ($productTypes as $productType) {
154
                $productFields = $this->getPullFieldsFromLayoutId($productType->fieldLayoutId);
155
                /** @noinspection SlowArrayOperationsInLoopInspection */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
156
                $commerceFields = array_merge($commerceFields, $productFields);
157
                if ($productType->hasVariants) {
158
                    $variantFields = $this->getPullFieldsFromLayoutId($productType->variantFieldLayoutId);
159
                    /** @noinspection SlowArrayOperationsInLoopInspection */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
160
                    $commerceFields = array_merge($commerceFields, $variantFields);
161
                }
162
            }
163
        }
164
165
        // Rend the settings template
166
        try {
167
            return Craft::$app->getView()->renderTemplate(
168
                'instant-analytics-ga4/settings',
169
                [
170
                    'settings' => $this->getSettings(),
171
                    'commerceFields' => $commerceFields,
172
                ]
173
            );
174
        } catch (Exception $exception) {
175
            Craft::error($exception->getMessage(), __METHOD__);
176
        }
177
178
        return '';
179
    }
180
181
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $context should have a doc-comment as per coding-style.
Loading history...
182
     * Handle the `{% hook iaSendPageView %}`
183
     *
184
     *
185
     */
0 ignored issues
show
Coding Style introduced by
Additional blank lines found at end of doc comment
Loading history...
Coding Style introduced by
Missing @return tag in function comment
Loading history...
186
    public function iaSendPageView(/** @noinspection PhpUnusedParameterInspection */ array &$context): string
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
187
    {
188
        $this->ga4->addPageViewEvent();
189
        return '';
190
    }
191
192
    public function logAnalyticsEvent(string $message, array $variables = [], string $category = ''): void
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function logAnalyticsEvent()
Loading history...
193
    {
194
        Craft::info(
195
            Craft::t('instant-analytics-ga4', $message, $variables),
196
            $category
197
        );
198
    }
199
    // Protected Methods
200
    // =========================================================================
201
202
    /**
203
     * Add in our Craft components
204
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
205
    protected function addComponents(): void
206
    {
207
        $view = Craft::$app->getView();
208
        // Add in our Twig extensions
209
        $view->registerTwigExtension(new InstantAnalyticsTwigExtension());
210
        // Install our template hook
211
        $view->hook('iaSendPageView', fn(array $context): string => (string)$this->ga4->addPageViewEvent());
0 ignored issues
show
Unused Code introduced by
The parameter $context 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

211
        $view->hook('iaSendPageView', fn(/** @scrutinizer ignore-unused */ array $context): string => (string)$this->ga4->addPageViewEvent());

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...
Bug introduced by
Are you sure the usage of $this->ga4->addPageViewEvent() targeting nystudio107\instantanaly...Ga4::addPageViewEvent() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
212
213
        // Register our variables
214
        Event::on(
215
            CraftVariable::class,
216
            CraftVariable::EVENT_INIT,
217
            function (Event $event): void {
218
                /** @var CraftVariable $variable */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
219
                $variable = $event->sender;
220
                $variable->set('instantAnalytics', [
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...
221
                    'class' => InstantAnalyticsVariable::class,
222
                    'viteService' => $this->vite,
223
                ]);
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...
224
            }
225
        );
226
    }
227
228
    /**
229
     * Install our event listeners
230
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
231
    protected function installEventListeners(): void
232
    {
233
        // Handler: Plugins::EVENT_AFTER_INSTALL_PLUGIN
234
        Event::on(
235
            Plugins::class,
236
            Plugins::EVENT_AFTER_INSTALL_PLUGIN,
237
            function (PluginEvent $event): void {
238
                if ($event->plugin === $this) {
0 ignored issues
show
introduced by
The condition $event->plugin === $this is always false.
Loading history...
239
                    $request = Craft::$app->getRequest();
240
                    if ($request->isCpRequest) {
241
                        Craft::$app->getResponse()->redirect(UrlHelper::cpUrl('instant-analytics-ga4/welcome'))->send();
242
                    }
243
                }
244
            }
245
        );
246
        // Handler: Plugins::EVENT_AFTER_LOAD_PLUGINS
247
        Event::on(
248
            Plugins::class,
249
            Plugins::EVENT_AFTER_LOAD_PLUGINS,
250
            static function () {
251
                // Determine if Craft Commerce is installed & enabled
252
                self::$commercePlugin = Craft::$app->getPlugins()->getPlugin(self::COMMERCE_PLUGIN_HANDLE);
253
                // Determine if SEOmatic is installed & enabled
254
                self::$seomaticPlugin = Craft::$app->getPlugins()->getPlugin(self::SEOMATIC_PLUGIN_HANDLE);
255
            }
256
        );
257
        $request = Craft::$app->getRequest();
258
        // Install only for non-console site requests
259
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
260
            $this->installSiteEventListeners();
261
        }
262
263
        // Install only for non-console Control Panel requests
264
        if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
265
            $this->installCpEventListeners();
266
        }
267
    }
268
269
    /**
270
     * Install site event listeners for site requests only
271
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
272
    protected function installSiteEventListeners(): void
273
    {
274
        // Handler: UrlManager::EVENT_REGISTER_SITE_URL_RULES
275
        Event::on(
276
            UrlManager::class,
277
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
278
            function (RegisterUrlRulesEvent $event): void {
279
                Craft::debug(
280
                    'UrlManager::EVENT_REGISTER_SITE_URL_RULES',
281
                    __METHOD__
282
                );
283
                // Register our Control Panel routes
284
                $event->rules = array_merge(
285
                    $event->rules,
286
                    $this->customFrontendRoutes()
287
                );
288
            }
289
        );
290
        // Remember the name of the currently rendering template
291
        Event::on(
292
            View::class,
293
            View::EVENT_BEFORE_RENDER_PAGE_TEMPLATE,
294
            static function (TemplateEvent $event): void {
295
                self::$currentTemplate = $event->template;
296
            }
297
        );
298
        // Send the page-view event.
299
        Event::on(
300
            View::class,
301
            View::EVENT_AFTER_RENDER_PAGE_TEMPLATE,
302
            function (TemplateEvent $event): void {
0 ignored issues
show
Unused Code introduced by
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

302
            function (/** @scrutinizer ignore-unused */ TemplateEvent $event): void {

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...
303
                if (self::$settings->autoSendPageView) {
304
                    $request = Craft::$app->getRequest();
305
                    if (!$request->getIsAjax()) {
306
                        $this->ga4->addPageViewEvent();
307
                    }
308
                }
309
            }
310
        );
311
312
        // Send the collected events
313
        Event::on(
314
            Response::class,
315
            Response::EVENT_BEFORE_SEND,
316
            function (Event $event): void {
0 ignored issues
show
Unused Code introduced by
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

316
            function (/** @scrutinizer ignore-unused */ Event $event): void {

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...
317
                // Initialize this sooner rather than later, since it's possible this will want to tinker with cookies
318
                $this->ga4->getAnalytics();
319
            }
320
        );
321
322
        // Send the collected events
323
        Event::on(
324
            Response::class,
325
            Response::EVENT_AFTER_SEND,
326
            function (Event $event): void {
0 ignored issues
show
Unused Code introduced by
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

326
            function (/** @scrutinizer ignore-unused */ Event $event): void {

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...
327
                $this->ga4->getAnalytics()->sendCollectedEvents();
328
            }
329
        );
330
331
        // Commerce-specific hooks
332
        if (self::$commercePlugin !== null) {
333
            Event::on(Order::class, Order::EVENT_AFTER_COMPLETE_ORDER, function (Event $e): void {
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...
334
                $order = $e->sender;
335
                if (self::$settings->autoSendPurchaseComplete) {
336
                    $this->commerce->triggerOrderCompleteEvent($order);
337
                }
338
            });
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...
339
340
            Event::on(Order::class, Order::EVENT_AFTER_ADD_LINE_ITEM, function (LineItemEvent $e): void {
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...
341
                $lineItem = $e->lineItem;
342
                if (self::$settings->autoSendAddToCart) {
343
                    $this->commerce->triggerAddToCartEvent($lineItem);
344
                }
345
            });
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...
346
347
            // Check to make sure Order::EVENT_AFTER_REMOVE_LINE_ITEM is defined
348
            if (defined(Order::class . '::EVENT_AFTER_REMOVE_LINE_ITEM')) {
349
                Event::on(Order::class, Order::EVENT_AFTER_REMOVE_LINE_ITEM, function (LineItemEvent $e): void {
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...
350
                    $lineItem = $e->lineItem;
351
                    if (self::$settings->autoSendRemoveFromCart) {
352
                        $this->commerce->triggerRemoveFromCartEvent($lineItem);
353
                    }
354
                });
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...
355
            }
356
        }
357
    }
358
359
    /**
360
     * Install site event listeners for Control Panel requests only
361
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
362
    protected function installCpEventListeners(): void
363
    {
364
    }
365
366
    /**
367
     * Return the custom frontend routes
368
     *
369
     * @return array<string, string>
370
     */
371
    protected function customFrontendRoutes(): array
372
    {
373
        return [
374
            'instantanalytics/pageViewTrack' =>
375
                'instant-analytics-ga4/track/track-page-view-url',
376
            'instantanalytics/eventTrack/<filename:[-\w\.*]+>?' =>
377
                'instant-analytics-ga4/track/track-event-url',
378
        ];
379
    }
380
381
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
382
     * @inheritdoc
383
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
384
    protected function createSettingsModel(): ?Model
385
    {
386
        return new Settings();
387
    }
388
389
    // Private Methods
390
    // =========================================================================
391
392
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
393
     * @param $layoutId
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
394
     *
395
     * @return mixed[]|array<string, string>
396
     */
397
    private function getPullFieldsFromLayoutId($layoutId): array
0 ignored issues
show
Coding Style introduced by
Private method name "InstantAnalytics::getPullFieldsFromLayoutId" must be prefixed with an underscore
Loading history...
398
    {
399
        $result = ['' => 'none'];
400
        if ($layoutId === null) {
401
            return $result;
402
        }
403
404
        $fieldLayout = Craft::$app->getFields()->getLayoutById($layoutId);
405
        if ($fieldLayout) {
406
            $result = FieldHelper::fieldsOfTypeFromLayout(FieldHelper::TEXT_FIELD_CLASS_KEY, $fieldLayout, false);
407
        }
408
409
        return $result;
410
    }
411
}
412