Файл: cobisja/BootHelp/src/Helpers/Html/Html.php
Строк: 327
<?php
/**
* BootHelp - PHP Helpers for Bootstrap
*
* (The MIT License)
*
* Copyright (c) 2015 Jorge Cobis <jcobis@gmail.com / http://twitter.com/cobisja>.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
namespace cobisjaBootHelpHelpersHtml;
use cobisjaBootHelpHelpersHtmlHtmlAttribute;
use cobisjaBootHelpHelpersHtmlHtmlContent;
/**
* Class Html: Handle of logic related to HTML generation base on a BootHelp helper.
*/
class Html
{
const SPACE = ' ';
/**
* @var string Type of html tag.
*/
private $type;
/**
* @var array Attributes associated to html tag.
*/
private $attributes = [];
/**
* @var mixed Inner content of html tag.
*/
private $content;
/**
* Build an Html instance.
*
* @param string $type type of html tag.
* @param mixed $attributes attributes of html tag (ussualy an array).
* @param mixed $content inner content of html tag
*/
public function __construct($type, $attributes, $content = '')
{
$this->setType($type);
$this->setAttributes($attributes);
$this->setContent($content);
}
/**
* Returns type of html tag.
*
* @return string type of html.
*/
public function getType()
{
return $this->type;
}
/**
* Returns Attributes of html tag.
*
* @return mixed whole set of attributes.
*/
public function getAttributes()
{
return (0 === count($this->attributes)) ? '' : $this->attributes;
}
/**
* Return a string representing the html attributes.
*
* @return string string representation of the whole set of attributes.
*/
public function getAttributesToString()
{
$attributes = $this->getAttributes();
if (is_array($attributes)) {
$attributes_string = join(
self::SPACE,
array_map(
function ($attribute) {
return (string) $attribute;
},
$attributes
)
);
} else {
$attributes_string = $attributes;
}
return $attributes_string;
}
/**
* Returns an array containing the html attributes.
*
* @return array array of attributes.
*/
public function getAttributesToArray()
{
$attrs = [];
array_map(
function ($attribute) use (&$attrs) {
$attrs[$attribute->getName()] = $attribute->getValue();
},
$this->getAttributes()
);
return $attrs;
}
/**
* Returns the indicated attribute's value
*
* @param string $name attribute's name.
* @param array $options options to specify format of the value to return.
*
* @return mixed value of specific attribute.
*/
public function getAttribute($name, array $options = [])
{
$attribute_value = str_replace('"', '', $this->getAttributeWithValue($name));
return isset($options['as']) &&
'array' === $options['as'] ? explode(self::SPACE, $attribute_value) : $attribute_value;
}
/**
* Indicates if an given attribute with a especific value exists.
*
* @param string $name name of html attribute.
* @param mixed $with_value values associated with the html attribute asked for.
*
* @return boolean true if exists, false otherwise.
*/
public function hasAttribute($name, $with_value)
{
return !is_null($this->getAttributeWithValue($name, $with_value));
}
/**
* Return inner html tag content.
*
* @return mixed whole content of html object.
*/
public function getContent()
{
return $this->content;
}
/**
* Sets html tag type.
*
* @param string $type type of html tag.
*/
public function setType($type)
{
$this->type = $type;
}
/**
* Sets html attributes.
*
* @param array $attributes html tag attributes.
*/
public function setAttributes($attributes)
{
!is_array($attributes) ? $attributes = [] : null;
foreach ($attributes as $name => $value) {
$this->attributes[] = new HtmlAttribute($name, $value);
}
}
/**
* Sets inner html tag content.
*
* @param mixed $content inner html tag content.
*/
public function setContent($content)
{
$this->content = new HtmlContent($content);
}
/**
* Test if an html instance "is a" specific html tag with specific attributes.
*
* @param string $type type of html tag is searching for.
* @param mixed $attributes specific attributes for html tag that is searching for.
*
* @return boolean true on success, false otherwise.
*/
public function isA($type, $attributes = [])
{
return $type === $this->type && $this->hasAttributesOfType($this, $attributes);
}
/**
* Tells if there is any child of specific type with specific attributes.
*
* @param string $type type of html tag.
* @param mixed $attributes attributes associated to html tag.
*
* @return boolean true if exists, otherwise false.
*/
public function hasAChildOfType($type, $attributes = [])
{
$result = false;
$children = $this->getChildren();
foreach ($children as $child) {
if ($child instanceof Html) {
$result = $type === $child->getType() && $this->hasAttributesOfType($child, $attributes);
if (true === $result) {
break;
}
}
}
return $result;
}
/**
* Tells the number of children that belongs to especific html tag.
*
* @return int number of children.
*/
public function numberOfChildren()
{
return $this->content->length();
}
/**
* Returns html tag children.
*
* @return mixed whole set of children.
*/
public function getChildren()
{
return $this->content->getContent();
}
/**
* Returns the html tag child specified.
*
* @param int $id number of child.
*
* @return mixed html object that represents a html's child.
*/
public function getChild($id)
{
$children = $this->content->getContent();
return isset($children[$id]) ? $children[$id] : null;
}
/**
* Helper to get the string form of Html object.
*
* @return string string representation of html object.
*/
public function toString()
{
return trim((string) $this);
}
/**
* Magic method to get the string for Html object.
*
* @return string string representation of html object.
*/
public function __toString()
{
$html_string = '<' . trim(
$this->type . self::SPACE . $this->getAttributesToString()
) . '>' . $this->content . '</' . $this->type . ">n";
return $html_string;
}
/**
* Test if a html objects have a specific set of attributes
*
* @param mixed $html_object html object.
* @param mixed $attributes attributes is searching for.
*
* @return boolean true on success, false otherwise.
*/
private function hasAttributesOfType($html_object, $attributes)
{
if (0 === count($attributes)) {
return true;
}
$html = $html_object->getAttributesToArray();
$mock_html = (new Html('undefined', $attributes))->getAttributesToArray();
array_walk(
$mock_html,
function (&$value, $attribute) use ($html) {
$value = isset($html[$attribute]) &&
count($value) === count($html[$attribute]) &&
(0 === count(array_diff($html[$attribute], $value)));
}
);
return 1 === count(array_unique(array_values($mock_html))) && array_values($mock_html)[0];
}
/**
* Returns string value of a specific html object attribute.
*
* @param string $name attribute name.
* @param mixed $with_value value associated to attribute.
*
* @return mixed null if there is not match, otherwise string attributes values.
*/
private function getAttributeWithValue($name, $with_value = null)
{
$attribute = array_filter(
$this->getAttributes(),
function ($attribute) use ($name, $with_value) {
return ($name === $attribute->getName()) &&
(is_null($with_value) || $attribute->hasValue($with_value));
}
);
return 0 === count($attribute) ? null : str_replace($name . '=', '', (string) end($attribute));
}
}