SlugifyDecorator.php 5.04 KB
<?php
    
    namespace artbox\core\helpers;
    
    use yii\bootstrap\Html;
    use yii\db\ActiveRecord;
    use yii\helpers\Url;
    use yii\widgets\ActiveField;

    /**
     * Class SlugifyDecorator
     * Decorator to add slugify button to the ActiveField
     */
    class SlugifyDecorator
    {
        /**
         * ActiveField input template param
         */
        const INPUT_FIELD = '{input}';
    
        /**
         * Decorate ActiveField input.
         *
         * @param \yii\widgets\ActiveField      $field        ActiveField to decorate
         * @param array                         $url          Url to get slug from
         * @param \yii\widgets\ActiveField|null $attribute    ActiveField to get value to slugify from
         * @param bool                          $enableCancel Whether to generate Cancel button
         * @param int|null                      $languageId
         *
         * @return \yii\widgets\ActiveField
         */
        public static function decorate(
            ActiveField $field,
            array $url = [ '/alias/slugify' ],
            ActiveField $attribute = null,
            bool $enableCancel = false,
            int $languageId = null
        ): ActiveField {
            if (!$attribute) {
                $attribute = $field;
            }
            $template = $field->template;
            $input = self::INPUT_FIELD;
            if (( $posBegin = strpos($template, $input) ) !== false) {
                $posEnd = $posBegin + strlen($input);
                $divBegin = Html::beginTag(
                    'div',
                    [
                        'class' => 'input-group',
                    ]
                );
                $divEnd = Html::tag(
                        'span',
                        self::createButton(
                            $field,
                            $url,
                            $attribute,
                            $languageId
                        ) . ( $enableCancel ? self::createCancel(
                            $field
                        ) : '' ),
                        [
                            'class' => 'input-group-btn',
                        ]
                    ) . Html::endTag('div');
                $template = substr_replace($template, $divEnd, $posEnd, 0);
                $template = substr_replace($template, $divBegin, $posBegin, 0);
                $field->template = $template;
            }
            return $field;
        }
    
        /**
         * Create 'Slugify' button
         *
         * @param \yii\widgets\ActiveField $field
         * @param array                    $url
         * @param \yii\widgets\ActiveField $attribute
         * @param int                      $languageId
         *
         * @return string
         */
        private static function createButton(
            ActiveField $field,
            array $url,
            ActiveField $attribute,
            int $languageId
        ): string {
            $options = [
                'data'  => [
                    'id'           => Html::getInputId($field->model, $field->attribute),
                    'attribute-id' => Html::getInputId($attribute->model, $attribute->attribute),
                    'url'          => Url::to($url),
                    'language-id'  => $languageId,
                ],
                'class' => 'btn btn-info slugify_button',
            ];
            if ($field !== $attribute) {
                $options[ 'data' ] = array_merge(
                    $options[ 'data' ],
                    [
                        'toggle'         => 'tooltip',
                        'placement'      => 'top',
                        'original-title' => \Yii::t(
                            'core',
                            'Create slug from {field} field',
                            [
                                'field' => $attribute->model->getAttributeLabel(
                                    Html::getAttributeName($attribute->attribute)
                                ),
                            ]
                        ),
                    ]
                );
            }
            return Html::button(
                \Yii::t('core', 'Slugify'),
                $options
            );
        }
    
        /**
         * Create 'Cancel' button
         *
         * @param \yii\widgets\ActiveField $field
         *
         * @return string
         */
        private static function createCancel(
            ActiveField $field
        ): string {
            /**
             * @var ActiveRecord $model
             */
            $model = $field->model;
            $options = [
                'data'  => [
                    'id'    => Html::getInputId($model, $field->attribute),
                    'value' => $model->getAttribute(Html::getAttributeName($field->attribute)),
                ],
                'class' => 'btn btn-default slugify_cancel_button',
            ];
            return Html::button(
                \Yii::t('core', 'Cancel'),
                $options
            );
        }
    }