<commit_before><commit_msg>Created HTMLTag class, which is the base class for all other HTML tags<commit_after><?php
/**
 * Created by PhpStorm.
 * User: kije
 * Date: 3/19/14
 * Time: 7:46 PM
 */

/** Idea: create class Attribute, which is simply a class with a key and value, and it can validate itself  */

namespace kije\Formulargenerator\Tags;
require_once '../inc/globals.inc.php';

class HTMLTagException extends \Exception {}

abstract class HTMLTag {
    protected $_tagname;
    protected $_selfclosing;
    protected $_required_attributes = array();
    protected $_allowed_attributes = array(
        // global attributes
        'accesskey',
        'class',
        'contenteditable',
        'contextmenu',
        'dir',
        'draggable',
        'dropzone',
        'hidden',
        'id',
        'itemid',
        'itemprop',
        'itemref',
        'itemscope',
        'itemtype',
        'lang',
        'spellcheck',
        'style',
        'tabindex',
        'title'
    );
    protected $_attrs = array();
    protected $_innerHTML = '';

    /**
     * @param $attrs
     * @internal param $text
     * @internal param $value
     */
    public function __construct(array $attrs = array()) {
        $this->setAttributes($attrs);
    }

    /**
     * @return array
     */
    public function getRequiredAttributes()
    {
        return $this->_required_attributes;
    }

    /**
     * @return array
     */
    public function getAllowedAttributes()
    {
        return $this->_allowed_attributes;
    }

    /**
     * @return mixed
     */
    public function getInnerHTML()
    {
        return $this->_innerHTML;
    }

    protected function setInnerHTML($html) {
        $this->_innerHTML = $html;
    }

    /**
     * @return boolean
     */
    public function isSelfclosing()
    {
        return $this->_selfclosing;
    }

    /**
     * @return string
     */
    public function getTagname()
    {
        return $this->_tagname;
    }

    /**
     * @return array
     */
    public function getAttributes()
    {
        return $this->_attrs;
    }

    /**
     * @param $key
     * @return bool
     */
    public function isAttributeAllowed($key) {
        return in_array($key, $this->_allowed_attributes);
    }

    /**
     * @param $key
     * @param $value
     * @return bool
     */
    public function isValueValidForAttribute($key, $value) {
        // here useless, but child classes can implement their own validation
        return $this->isAttributeAllowed($key);
    }

    /**
     * @param $key
     * @param $value
     * @throws HTMLTagException
     */
    public function setAttribute($key, $value) {
        if ($this->isAttributeAllowed($key)) {
            if ($this->isValueValidForAttribute($key, $value)) {
                $this->_attrs[$key] = $value;
            } else {
                throw new HTMLTagException('Value '.$value.' for attribute '.$key.' is not allowed in this tag.');
            }
        } else {
            throw new HTMLTagException('Attribute '.$key.' not allowed in this tag.');
        }
    }

    /**
     * @param $attrs
     */
    public function setAttributes(array $attrs) {
        foreach($attrs as $key => $value) {
            $this->setAttribute($key, $value);
        }
    }

    public function setDataAttribute($key, $value) {
        if (strpos($key, 'data-') === 0) {
            $this->_attrs[$key] = $value;
        } else {
            throw new HTMLTagException('Data-Attribute ('.$key.') must start with "data-".');
        }
    }

    /**
     * @throws HTMLTagException
     * @return string
     */
    public function toHTML() {
        // check if all required attributes are set
        // FIXME: the following won't work.... it will also throw an error, when more attributes are set than the require ones
        if (count(($diffs = array_diff($this->_required_attributes, array_keys($this->_attrs)))) !== 0) {
            throw new HTMLTagException('Required attributes ['.implode(', ', $diffs).'] not set!');
        }

        $html = '<'.$this->_tagname;

        foreach($this->_attrs as $attr => $value) {
            $html .= sprintf(' %s="%s"', $attr, $value);
        }

        if ($this->_selfclosing) {
            $html .= '/>';
        } else {
            $html .= sprintf('>%s</%s>', $this->_innerHTML, $this->_tagname);
        }

        return $html;
    }


} 
{'fraction_non_alphanumeric': 0.14072735486785634, 'fraction_numerical': 0.00225886604924328, 'mean_word_length': 1.9227722772277227, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3418771', 'n_tokens_mistral': 1271, 'n_tokens_neox': 1256, 'n_words': 322}