Skip to content

Instantly share code, notes, and snippets.

@Petah
Created September 6, 2012 01:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Petah/3649339 to your computer and use it in GitHub Desktop.
Save Petah/3649339 to your computer and use it in GitHub Desktop.
Abstract Tags
<?php
/**
* XMod\HTML\Tag
*
* @author David Neilsen <david@panmedia.co.nz>
*/
namespace XMod\HTML;
use XMod\Common\Args;
/**
*
*/
class Tag {
public $name = null;
public $contents = array();
public $attributes = array();
public $data = array();
public $classes = array();
/**
*
* @param string $name
*/
public function __construct($name = null) {
$this->name = $name;
}
/**
* Sets, or gets the contents of the tag. The content can either be a
* string/number, an object that implements __toString, or a callable.
* When passed no parameters, the HTML content is returned as a string.
*
* @param mixed $content (Optional) The HTML content to set
* @param bool $conditional
* @return Tag|string
*/
public function html($content = false, $conditional = true) {
if (func_num_args() === 0) {
return implode('', $this->contents);
} elseif ($conditional) {
if ($content === false) {
$this->contents = array();
} else {
$this->contents = array($content);
}
}
return $this;
}
/**
* Sets, or gets the contents of the tag converting all special HTML
* characters.
*
* @param mixed $content The text content to set
* @param bool $conditional
* @return Tag
*/
public function text($content, $conditional = true) {
return $this->html(htmlspecialchars($content), $conditional);
}
/**
* Appends content to the inner contents of the tag. The content can either
* be a string/number, an object that implements __toString, or a callable.
* @param mixed $content...
*/
public function append($content) {
$content = array();
foreach (func_get_args() as $arg) {
if (is_bool($arg) === true) {
// Conditional append
if ($arg === false) {
return $this;
}
} else {
$content[] = $arg;
}
}
$this->contents = array_merge($this->contents, $content);
return $this;
}
/**
* @param string... $class
* @param bool $conditional
* @return Tag
*/
public function addClass($class, $conditional = true) {
$classes = array();
foreach (func_get_args() as $class) {
if (is_bool($class) === true) {
// Conditional set
if ($class === false) {
return $this;
}
} else {
$classes[] = $class;
}
}
$this->classes = array_merge($this->classes, $classes);
$this->classes = array_unique($this->classes);
return $this;
}
/**
*
* @param string|array $name
* @param mixed $value
* @param bool $conditional
* @return Tag
*/
public function attr($name, $value = null, $conditional = true) {
if (is_array($name)) {
foreach ($name as $name => $value) {
$this->__call($name, array($value));
}
} elseif (func_num_args() === 1) {
return $this->__call($name, array());
} else {
$this->__call($name, array($value, $conditional));
}
return $this;
}
public function removeAttr($name) {
unset($this->attributes[$name]);
return $this;
}
/**
*
* @return string
*/
public function render() {
// Set class
if (empty($this->classes) === false) {
$this->class = implode(' ', $this->classes);
}
$attributes = '';
// Add normal attributes
foreach ($this->attributes as $key => $value) {
if (is_array($value)) {
$value = implode(',', $value);
}
$attributes .= " $key=\"$value\"";
}
// Add data attributes
foreach ($this->data as $key => $value) {
$attributes .= " data-$key='{$this->dataEncode($value)}'";
}
// Get the HTML content
$html = implode('', $this->contents);
if ($this->name === null) {
// If there is no tag name, return the HTML
return $html;
} elseif (empty($this->contents)) {
// If there is no content, return a self closing tag
return "<{$this->name}{$attributes}/>";
}
// Return a normal tag
return "<{$this->name}{$attributes}>{$html}</{$this->name}>";
}
/**
*
* @param mixed $data
* @return string
*/
function dataEncode($data) {
$data = json_encode($data);
$data = str_replace('\'', '&#39;', $data);
return $data;
}
/**
*
* @param string $name
* @param mixed $data
* @param bool $conditional
* @return Tag
*/
public function data($name = null, $data = null, $conditional = true) {
if (func_num_args() == 0) {
return $this->data;
} elseif (func_num_args() == 1) {
return $this->data[$name];
} elseif ($conditional) {
$this->data[$name] = $data;
}
return $this;
}
/**
*
* @param string $name
* @param mixed $data
* @param bool $conditional
* @return Tag
*/
public function extendData($name = null, $data = null, $conditional = true) {
if (func_num_args() == 0) {
return $this->data;
} elseif (func_num_args() == 1) {
return $this->data[$name];
} elseif ($conditional) {
if (isset($this->data[$name]) && is_array($this->data[$name])) {
$this->data[$name] = $this->extendArray($this->data[$name], $data);
} else {
$this->data[$name] = $data;
}
}
return $this;
}
/**
* jQuery style array extend function
* @param array $first_array
* @param array $second_array
* @return type
*/
public function extendArray(array $first_array, array $second_array) {
$args = func_get_args();
$extended = array();
if (is_array($args) && sizeof($args) > 0) {
foreach ($args as $array) {
if (is_array($array)) {
$extended = array_merge($extended, $array);
}
}
}
return $extended;
}
/**
*
* @param string $name
* @param array $arguments
* @return Tag
*/
public function __call($name, $arguments) {
$substr = substr($name, 0, 3);
if ($substr === 'get' && sizeof($arguments) == 0) {
// Attribute getter
$name = strtolower(substr($name, 3));
return $this->__get($name);
} elseif (sizeof($arguments) == 0) {
// Attribute getter
return $this->__get($name);
} elseif ($substr === 'set' &&
sizeof($arguments) >= 1 &&
(!isset($arguments[1]) || $arguments[1])) {
// Standard set
$name = strtolower(substr($name, 3));
$this->__set($name, $arguments[0]);
} elseif (sizeof($arguments) === 1) {
if ($arguments[0] === true) {
// Boolean attribute setter
$this->$name = $name;
} elseif (!is_bool($arguments[0])) {
// Normal attribute setter
$this->__set($name, $arguments[0]);
}
} elseif (sizeof($arguments) === 2) {
// Conditional set
if ($arguments[1]) {
$this->__set($name, $arguments[0]);
}
}
return $this;
}
/**
*
* @param string $name
* @param mixed $value
*/
public function __set($name, $value) {
$this->attributes[$name] = $value;
}
/**
*
* @param string $name
*/
public function __get($name) {
if (!isset($this->attributes[$name])) {
return null;
}
return $this->attributes[$name];
}
/**
*
* @return string
*/
public function __toString() {
return $this->render();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment