Seditio Source
Root |
./othercms/croogo-4.0.7/vendor/croogo/croogo/Core/src/View/Helper/FormHelper.php
<?php

namespace Croogo\Core\View\Helper;

use
BootstrapUI\View\Helper\FormHelper as BaseFormHelper;
use
Cake\Utility\Hash;
use
Cake\Utility\Inflector;
use
Cake\View\View;
use
Croogo\Extensions\CroogoTheme;

/**
 * Croogo Form Helper
 *
 * @package Croogo.Croogo.View.Helper
 */
class FormHelper extends BaseFormHelper
{

    public
$helpers = [
       
'Html',
       
'Url',
       
'Croogo/Core.Theme',
       
'Croogo/Core.Croogo',
       
'Croogo/Core.Html',
    ];

   
/**
     * Constructor
     */
   
public function __construct(View $View, $settings = [])
    {
       
$settings = Hash::merge([
           
'widgets' => [
               
'stringlist' => [
                   
'Croogo/Core.StringList',
                   
'textarea',
                   
'label',
                ],
               
'datetime' => ['Croogo/Core.DateTime', 'select'],
               
'button' => ['Croogo/Core.Button']
            ],
        ],
$settings);

        if (
$View->getTheme()) {
           
$themeConfig = CroogoTheme::config($View->getTheme());
           
$themeSettings = $themeConfig['settings'];
           
$settings = Hash::merge($themeSettings, $settings);
        }

       
parent::__construct($View, $settings);
    }

    protected function
_tooltip($options)
    {
        if (
$options['tooltip'] === false) {
            unset(
$options['title']);

            return
$options;
        }
       
$tooltipOptions = [
           
'data-placement' => 'right',
           
'data-trigger' => 'focus',
        ];
        if (
is_string($options['tooltip'])) {
           
$options['tooltip'] = ['data-title' => $options['tooltip']];
        }
        if (isset(
$options['title']) && empty($options['tooltip']['data-title'])) {
           
$tooltipOptions['data-title'] = $options['title'];
        }

       
$tooltipOptions = Hash::merge($tooltipOptions, $options['tooltip']);
        unset(
$options['title']);
        unset(
$options['tooltip']);

        if (isset(
$options['type']) && in_array($options['type'], ['checkbox', 'radio', 'select'])) {
            if (isset(
$options['div'])) {
                if (
is_string($options['div'])) {
                   
$options['div'] = ['div' => $options['div']] + $tooltipOptions;
                } else {
                   
$options['div'] += $tooltipOptions;
                }
            } else {
               
$options['div'] = $tooltipOptions;
            }
        } else {
           
$options += $tooltipOptions;
        }

        return
$options;
    }

   
/**
     * placeholderOptions
     */
   
protected function _placeholderOptions($fieldName, $options = [])
    {
       
$autoPlaceholder = empty($options['placeholder']) &&
            isset(
$this->_inputDefaults['placeholder']) &&
           
$this->_inputDefaults['placeholder'] === true;
       
$autoPlaceholder = $autoPlaceholder ||
            (isset(
$options['placeholder']) && $options['placeholder'] === true);
        if (
$autoPlaceholder) {
            if (!empty(
$options['title'])) {
               
$options['placeholder'] = $options['title'];
            } else {
                if (
strpos($fieldName, '.') !== false) {
                   
$fieldNameE = explode('.', $fieldName);
                   
$placeholder = end($fieldNameE);
                    if (
substr($placeholder, -3) == '_id') {
                       
$placeholder = substr($placeholder, 0, -3);
                    }
                } else {
                   
$placeholder = $fieldName;
                }
               
$options['placeholder'] = Inflector::humanize($placeholder);
            }
        }

        return
$options;
    }

   
/**
     * Generate input options array
     *
     * @param array $fieldName Options list
     * @return array
     */
   
protected function _parseOptions($fieldName, $options)
    {
       
$options = parent::_parseOptions($fieldName, $options);

       
$formInput = $this->Theme->getCssClass('formInput');
       
$isMultipleCheckbox = isset($options['multiple']) &&
           
$options['multiple'] === 'checkbox';
       
$isRadioOrCheckbox = isset($options['type']) &&
           
in_array($options['type'], ['checkbox', 'radio']);

        if (
$isMultipleCheckbox || $isRadioOrCheckbox) {
            if (
$options['type'] == 'radio') {
               
$class = $this->Theme->getCssClass('radioClass');
            } elseif (
$options['type'] == 'checkbox') {
               
$class = $this->Theme->getCssClass('checkboxClass');
            }
            if (empty(
$class) && isset($options['class'])) {
               
$class = str_replace($formInput, '', $options['class']);
            }
            if (empty(
$class)) {
                unset(
$options['class']);
            } else {
               
$options['class'] = $class;
            }
        }

        if ((
array_key_exists('linkChooser', $options)) && ($options['linkChooser'])) {
           
$target = '#' . $options['id'];
           
$options['append'] = $this->Croogo->linkChooser($target);
        }

        return
$options;
    }

   
/**
     * Normalize field name
     *
     * @return array Map of normalized field names and corresponding list of roleIds
     */
   
protected function _setupFieldAccess($fieldAccess)
    {
       
$map = [];
        foreach (
$fieldAccess as $field => $config) {
            if (
strpos($field, '.') === false) {
               
$field = $this->defaultModel . '.' . $field;
            }
           
$map[$field] = (array)$config;
        }

        return
$map;
    }

   
/**
     * Checks if field is editable by current user's role
     *
     * @return bool True if field is editable
     */
   
protected function _isEditable($field)
    {
        if (
strpos($field, '.') === false) {
           
$field = $this->defaultModel . '.' . $field;
        }
        if (isset(
$this->_fieldAccess[$field])) {
            return
in_array($this->_currentRoleId, $this->_fieldAccess[$field]);
        }

        return
true;
    }

   
/**
     * Returns an HTML FORM element.
     *
     * @return string A formatted opening FORM tag
     * @see FormHelper::create()
     */
   
public function create($model = null, array $options = [])
    {
        if (!empty(
$options['fieldAccess'])) {
           
$this->_fieldAccess = $this->_setupFieldAccess($options['fieldAccess']);
           
$this->_currentRoleId = $this->_View->Layout->getRoleId();
            unset(
$options['fieldAccess']);
        }

        return
parent::create($model, $options);
    }

    public function
input($fieldName, array $options = [])
    {
        return
$this->control($fieldName, $options);
    }

    public function
control($fieldName, array $options = [])
    {
        if (!
$this->_isEditable($fieldName)) {
            return
null;
        }
       
$options = $this->_placeholderOptions($fieldName, $options);

        if (
array_key_exists('tooltip', $options)) {
           
$options = $this->_tooltip($options);
        }

        return
parent::control($fieldName, $options);
    }

   
/**
     * Try to guess autocomplete default values
     *
     * @param string $field field name
     * @param array $config setting passed to CroogoFormHelper::autocomplete()
     * @return array Array of id and display value
     */
   
protected function _acDefaults($field, $config)
    {
       
$displayKey = $displayValue = null;
       
$request = $this->getView()->getRequest();
        list(,
$table) = pluginSplit($this->context()->entity()->getSource());
        if (isset(
$request->getData($table)[$field])) {
           
$displayKey = $request->getData($table)[$field];
        }

        if (
substr($field, -3) === '_id') {
           
$varName = Inflector::variable(Inflector::pluralize(substr($field, 0, -3)));
            if (isset(
$this->_View->viewVars[$varName])) {
               
$lookupData = $this->_View->viewVars[$varName];
                if (isset(
$lookupData[$displayKey])) {
                   
$displayValue = $lookupData[$displayKey];
                }
            }
        }

       
$defaults = [$displayKey => $displayValue];

        return
array_filter($defaults);
    }

   
/**
     * Generates an autocomplete text input that works with bootstrap's typeahead
     *
     * Besides the standard Form::input() $options, this method accepts:
     *
     *   'autocomplete' array with the following keys to configure fields to use
     *   from the AJAX result:
     *      `data-displayField`: field to display in the autocomplete dropdown
     *      `data-primaryKey`: field to use as the primary identifier
     *      `data-queryField`: field to use as the AJAX querystring
     *      `data-relatedElement`: selector to the input storing the actual value
     *      `data-url`: url to retrieve autocomplete data
     *
     * @see FormHelper::input()
     */
   
public function autocomplete($fieldName, $options = [])
    {
       
$options = Hash::merge([
           
'type' => 'text',
           
'default' => null,
           
'value' => null,
           
'class' => null,
           
'autocomplete' => [
               
'default' => null,
               
'data-displayField' => null,
               
'data-primaryKey' => null,
               
'data-queryField' => null,
               
'data-relatedElement' => null,
               
'data-url' => null,
            ],
        ],
$options);

       
$field = $fieldName;
       
$defaults = $this->_acDefaults($field, $options['autocomplete']);

       
$default = isset($options['default']) ? $options['default'] : key($defaults);
       
$hiddenOptions = array_filter([
           
'type' => 'hidden',
           
'default' => $default,
        ]);
       
$out = $this->input($fieldName, $hiddenOptions);

       
$this->unlockField($fieldName);

       
$autocomplete = $options['autocomplete'];
       
$label = isset($options['label']) ? $options['label'] : Inflector::humanize($field);

       
$default = isset($autocomplete['default']) ? $autocomplete['default'] : array_shift($defaults);
       
$inputDefaults = $this->_View->Form->getTemplates();
       
$class = null;
        if (!empty(
$inputDefaults['class'])) {
           
$class = $inputDefaults['class'];
        }
       
$class = $options['class'] ? $options['class'] : $class;
       
$autocomplete = Hash::merge($autocomplete, [
           
'type' => $options['type'],
           
'label' => $label,
           
'class' => trim($class . ' typeahead-autocomplete'),
           
'default' => $default,
           
'autocomplete' => 'off',
        ]);
       
$out .= $this->input("autocomplete_${field}", $autocomplete);

        return
$out;
    }
}