GrafiteInc/FormMaker

View on GitHub
src/Builders/AttributeBuilder.php

Summary

Maintainability
C
1 day
Test Coverage
<?php

namespace Grafite\Forms\Builders;

use Illuminate\Support\Str;

class AttributeBuilder
{
    /**
     * Build an HTML attribute string from an array.
     *
     * @param array $attributes
     *
     * @return string
     */
    public function render($attributes, $name = null, $livewireEnabled = false, $livewireOnKeydown = false, $livewireOnChange = false)
    {
        $html = [];
        $livewireAttributes = [];

        if ($livewireEnabled) {
            $livewireAttributes['wire:model'] = "data.{$name}";
        }

        if ($livewireOnKeydown) {
            $livewireAttributes['wire:keydown.debounce.1000ms'] = 'submit';
        }

        if ($livewireOnChange) {
            $livewireAttributes['wire:change.debounce.600ms'] = 'submit';
        }

        $attributes = array_merge($attributes, $livewireAttributes);

        foreach ((array) $attributes as $key => $value) {
            if (
                in_array(strtolower($key), $this->validHtmlAttributes())
                || Str::of($key)->startsWith('data-')
                || Str::of($key)->startsWith('wire:')
            ) {
                $element = $this->attributeElement($key, $value);

                if (! is_null($element)) {
                    $html[] = $element;
                }
            }
        }

        return collect($html)->unique()->implode(' ');
    }

    /**
     * Build a single attribute element.
     *
     * @param string $key
     * @param string $value
     *
     * @return string
     */
    public function attributeElement($key, $value)
    {
        if (is_numeric($key)) {
            return $value;
        }

        if (is_bool($value) && $key !== 'value') {
            return $value ? $key : '';
        }

        if (is_array($value) && $key === 'class') {
            return 'class="' . implode(' ', $value) . '"';
        }

        if (! is_null($value)) {
            return $key . '="' . e($value, false) . '"';
        }
    }

    public function validHtmlAttributes()
    {
        return [
            'accept',
            'accept-charset',
            'accesskey',
            'action',
            'align',
            'alt',
            'async',
            'autocomplete',
            'autofocus',
            'autoplay',
            'bgcolor',
            'border',
            'charset',
            'checked',
            'cite',
            'class',
            'color',
            'cols',
            'colspan',
            'content',
            'contenteditable',
            'controls',
            'coords',
            'data',
            'datetime',
            'default',
            'defer',
            'dir',
            'dirname',
            'disabled',
            'download',
            'draggable',
            'enctype',
            'for',
            'form',
            'formaction',
            'headers',
            'height',
            'hidden',
            'high',
            'href',
            'hreflang',
            'http-equiv',
            'id',
            'ismap',
            'kind',
            'label',
            'lang',
            'list',
            'loop',
            'low',
            'max',
            'maxlength',
            'media',
            'method',
            'min',
            'multiple',
            'muted',
            'name',
            'novalidate',
            'onabort',
            'onafterprint',
            'onbeforeprint',
            'onbeforeunload',
            'onblur',
            'oncanplay',
            'oncanplaythrough',
            'onchange',
            'onclick',
            'oncontextmenu',
            'oncopy',
            'oncuechange',
            'oncut',
            'ondblclick',
            'ondrag',
            'ondragend',
            'ondragenter',
            'ondragleave',
            'ondragover',
            'ondragstart',
            'ondrop',
            'ondurationchange',
            'onemptied',
            'onended',
            'onerror',
            'onfocus',
            'onhashchange',
            'oninput',
            'oninvalid',
            'onkeydown',
            'onkeypress',
            'onkeyup',
            'onload',
            'onloadeddata',
            'onloadedmetadata',
            'onloadstart',
            'onmousedown',
            'onmousemove',
            'onmouseout',
            'onmouseover',
            'onmouseup',
            'onmousewheel',
            'onoffline',
            'ononline',
            'onpagehide',
            'onpageshow',
            'onpaste',
            'onpause',
            'onplay',
            'onplaying',
            'onpopstate',
            'onprogress',
            'onratechange',
            'onreset',
            'onresize',
            'onscroll',
            'onsearch',
            'onseeked',
            'onseeking',
            'onselect',
            'onstalled',
            'onstorage',
            'onsubmit',
            'onsuspend',
            'ontimeupdate',
            'ontoggle',
            'onunload',
            'onvolumechange',
            'onwaiting',
            'onwheel',
            'open',
            'optimum',
            'pattern',
            'placeholder',
            'poster',
            'preload',
            'readonly',
            'rel',
            'required',
            'reversed',
            'rows',
            'rowspan',
            'sandbox',
            'scope',
            'selected',
            'shape',
            'size',
            'sizes',
            'span',
            'spellcheck',
            'src',
            'srcdoc',
            'srclang',
            'srcset',
            'start',
            'step',
            'style',
            'tabindex',
            'target',
            'title',
            'translate',
            'type',
            'usemap',
            'value',
            'width',
            'wrap',
        ];
    }
}