Seditio Source
Root |
./othercms/dotclear-2.22/inc/libs/clearbricks/html.form/class.form.component.php
<?php

declare(strict_types=1);

/**
 * @class formComponent
 * @brief HTML Forms creation helpers
 *
 * @package Clearbricks
 * @subpackage html.form
 *
 * @since 1.2 First time this was introduced.
 *
 * @copyright Olivier Meunier & Association Dotclear
 * @copyright GPL-2.0-only
 */
abstract class formComponent
{
    private
$_type;     // Component type
   
private $_element;  // HTML element
   
private $_data;     // Custom component properties (see __get() and __set())

   
public function __construct(?string $type = null, ?string $_element = null)
    {
       
$this->_type    = $type ?? __CLASS__;
       
$this->_element = $_element;
       
$this->_data    = [];
    }

   
/**
     * Call statically new instance
     *
     * @return object New formXxx instance
     */
   
public static function init()
    {
       
$c = get_called_class();

       
/* @phpstan-ignore-next-line */
       
return new $c(...func_get_args());
    }

   
/**
     * Magic getter method
     *
     * @param      string  $property  The property
     *
     * @return     mixed   property value if property exists or null
     */
   
public function __get(string $property)
    {
        if (
array_key_exists($property, $this->_data)) {
            return
$this->_data[$property];
        }

        return
null;
    }

   
/**
     * Magic setter method
     *
     * @param      string  $property  The property
     * @param      mixed   $value     The value
     *
     * @return     self
     */
   
public function __set(string $property, $value)
    {
       
$this->_data[$property] = $value;

        return
$this;
    }

   
/**
     * Magic isset method
     *
     * @param      string  $property  The property
     *
     * @return     bool
     */
   
public function __isset(string $property): bool
   
{
        return isset(
$this->_data[$property]);
    }

   
/**
     * Magic unset method
     *
     * @param      string  $property  The property
     */
   
public function __unset(string $property)
    {
        unset(
$this->_data[$property]);
    }

   
/**
     * Magic call method
     *
     * If the method exists, call it and return it's return value
     * If not, if there is no argument ($argument empty array), assume that it's a get
     * If not, assume that's is a set (value = $argument[0])
     *
     * @param      string  $method     The property
     * @param      array   $arguments  The arguments
     *
     * @return     mixed   method called, property value (or null), self
     */
   
public function __call(string $method, $arguments)
    {
       
// Cope with known methods
       
if (method_exists($this, $method)) {
            return
call_user_func_array([$this, $method], $arguments);
        }

       
// Unknown method
       
if (!count($arguments)) {
           
// No argument, assume its a get
           
if (array_key_exists($method, $this->_data)) {
                return
$this->_data[$method];
            }

            return
null;    // @phpstan-ignore-line
       
}
       
// Argument here, assume its a set
       
$this->_data[$method] = $arguments[0];

        return
$this;   // @phpstan-ignore-line
   
}

   
/**
     * Magic invoke method
     *
     * Return rendering of component
     *
     * @return     string
     */
   
public function __invoke(): string
   
{
        return
$this->render();
    }

   
/**
     * Gets the type of component
     *
     * @return     string  The type.
     */
   
public function getType(): string
   
{
        return
$this->_type;
    }

   
/**
     * Sets the type of component
     *
     * @param      string  $type   The type
     *
     * @return     self
     */
   
public function setType(string $type)
    {
       
$this->_type = $type;

        return
$this;
    }

   
/**
     * Gets the HTML element
     *
     * @return     null|string  The element.
     */
   
public function getElement(): ?string
   
{
        return
$this->_element;
    }

   
/**
     * Sets the HTML element
     *
     * @param      string  $element  The element
     *
     * @return     self
     */
   
public function setElement(string $element)
    {
       
$this->_element = $element;

        return
$this;
    }

   
/**
     * Attaches the label.
     *
     * @param      formLabel|null  $label     The label
     * @param      int|null        $position  The position
     *
     * @return     self
     */
   
public function attachLabel(?formLabel $label = null, ?int $position = null)
    {
        if (
$label) {
           
$this->label($label);
           
$label->for($this->id);
            if (
$position !== null) {
               
$label->setPosition($position);
            }
        } elseif (isset(
$this->label)) {
            unset(
$this->label);
        }

        return
$this;
    }

   
/**
     * Detaches the label from this component
     *
     * @return     self
     */
   
public function detachLabel()
    {
        if (isset(
$this->label)) {
            unset(
$this->label);
        }

        return
$this;
    }

   
/**
     * Check mandatory attributes in properties, at least name or id must be present
     *
     * @return     bool
     */
   
public function checkMandatoryAttributes(): bool
   
{
       
// Check for mandatory info
       
return (isset($this->name) || isset($this->id));
    }

   
/**
     * Render common attributes
     *
     *      $this->
     *
     *          type            => string type (may be used for input component).
     *
     *          name            => string name (required if id is not provided).
     *          id              => string id (required if name is not provided).
     *
     *          value           => string value.
     *          default         => string default value (will be used if value is not provided).
     *          checked         => boolean checked.
     *
     *          accesskey       => string accesskey (character(s) space separated).
     *          autocomplete    => string autocomplete type.
     *          autofocus       => boolean autofocus.
     *          class           => string (or array of string) class(es).
     *          contenteditable => boolean content editable.
     *          dir             => string direction.
     *          disabled        => boolean disabled.
     *          form            => string form id.
     *          lang            => string lang.
     *          list            => string list id.
     *          max             => int max value.
     *          maxlength       => int max length.
     *          min             => int min value.
     *          readonly        => boolean readonly.
     *          required        => boolean required.
     *          pattern         => string pattern.
     *          placeholder     => string placeholder.
     *          size            => int size.
     *          spellcheck      => boolean spellcheck.
     *          tabindex        => int tabindex.
     *          title           => string title.
     *
     *          data            => array data.
     *              [
     *                  key   => string data id (rendered as data-<id>).
     *                  value => string data value.
     *              ]
     *
     *          extra           => string (or array of string) extra HTML attributes.
     *
     * @param      bool    $includeValue    Includes $this->value if exist (default = true)
     *                                      should be set to false to textarea and may be some others
     *
     * @return     string
     */
   
public function renderCommonAttributes(bool $includeValue = true): string
   
{
       
$render = '' .

           
// Type (used for input component)
           
(isset($this->type) ?
               
' type="' . $this->type . '"' : '') .

           
// Identifier
            // - use $this->name for name attribute else $this->id if exists
            // - use $this->id for id attribute else $this->name if exists
           
(isset($this->name) ?
               
' name="' . $this->name . '"' :
                (isset(
$this->id) ? ' name="' . $this->id . '"' : '')) .
            (isset(
$this->id) ?
               
' id="' . $this->id . '"' :
                (isset(
$this->name) ? ' id="' . $this->name . '"' : '')) .

           
// Value
            // - $this->default will be used as value if exists and $this->value does not
           
($includeValue && array_key_exists('value', $this->_data) ?
               
' value="' . $this->value . '"' : '') .
            (
$includeValue && !array_key_exists('value', $this->_data) && array_key_exists('default', $this->_data) ?
               
' value="' . $this->default . '"' : '') .
            (isset(
$this->checked) && $this->checked ?
               
' checked' : '') .

           
// Common attributes
           
(isset($this->accesskey) ?
               
' accesskey="' . $this->accesskey . '"' : '') .
            (isset(
$this->autocomplete) ?
               
' autocomplete="' . $this->autocomplete . '"' : '') .
            (isset(
$this->autofocus) && $this->autofocus ?
               
' autofocus' : '') .
            (isset(
$this->class) ?
               
' class="' . (is_array($this->class) ? implode(' ', $this->class) : $this->class) . '"' : '') .
            (isset(
$this->contenteditable) && $this->contenteditable ?
               
' contenteditable' : '') .
            (isset(
$this->dir) ?
               
' dir="' . $this->dir . '"' : '') .
            (isset(
$this->disabled) && $this->disabled ?
               
' disabled' : '') .
            (isset(
$this->form) ?
               
' form="' . $this->form . '"' : '') .
            (isset(
$this->lang) ?
               
' lang="' . $this->lang . '"' : '') .
            (isset(
$this->list) ?
               
' list="' . $this->list . '"' : '') .
            (isset(
$this->max) ?
               
' max="' . strval((int) $this->max) . '"' : '') .
            (isset(
$this->maxlength) ?
               
' maxlength="' . strval((int) $this->maxlength) . '"' : '') .
            (isset(
$this->min) ?
               
' min="' . strval((int) $this->min) . '"' : '') .
            (isset(
$this->pattern) ?
               
' pattern="' . $this->pattern . '"' : '') .
            (isset(
$this->placeholder) ?
               
' placeholder="' . $this->placeholder . '"' : '') .
            (isset(
$this->readonly) && $this->readonly ?
               
' readonly' : '') .
            (isset(
$this->required) && $this->required ?
               
' required' : '') .
            (isset(
$this->size) ?
               
' size="' . strval((int) $this->size) . '"' : '') .
            (isset(
$this->spellcheck) ?
               
' spellcheck="' . ($this->spellcheck ? 'true' : 'false') . '"' : '') .
            (isset(
$this->tabindex) ?
               
' tabindex="' . strval((int) $this->tabindex) . '"' : '') .
            (isset(
$this->title) ?
               
' title="' . $this->title . '"' : '') .

       
'';

        if (isset(
$this->data) && is_array($this->data)) {
           
// Data attributes
           
foreach ($this->data as $key => $value) {
               
$render .= ' data-' . $key . '="' . $value . '"';
            }
        }

        if (isset(
$this->extra)) {
           
// Extra HTML
           
$render .= ' ' . (is_array($this->extra) ? implode(' ', $this->extra) : $this->extra);
        }

        return
$render;
    }

   
// Abstract methods

    /**
     * Renders the object.
     *
     * Must be provided by classes which extends this class
     */
   
abstract protected function render(): string;

   
/**
     * Gets the default element.
     *
     * @return     string  The default HTML element.
     */
   
abstract protected function getDefaultElement(): string;
}