<?php
namespace Library\View;
class HtmlDiv
{
private $text;
private $id;
private $class;
public function __construct($text, $id = null, $class = null) {
$this->setText($text);
if ($id !== null) {
$this->setId($id);
}
if ($class !== null) {
$this->setClass($class);
}
}
public function setText($text) {
if (!is_string($text) || empty($text)) {
throw new \InvalidArgumentException(
"The text of the element is invalid.");
}
$this->text = $text;
return $this;
}
public function setId($id) {
if (!preg_match('/^[a-z0-9_-]+$/', $id)) {
throw new \InvalidArgumentException(
"The attribute value is invalid.");
}
$this->id = $id;
return $this;
}
public function setClass($class) {
if (!preg_match('/^[a-z0-9_-]+$/', $id)) {
throw new \InvalidArgumentException(
"The attribute value is invalid.");
}
$this->class = $class;
return $this;
}
public function renderDiv() {
return '<div' .
($this->id ? ' id="' . $this->id . '"' : '') .
($this->class ? ' class="' . $this->class . '"' : '') .
'>' . $this->text . '</div>';
}
}
/////////////////////////////////////////////////////////////////////
<?php
namespace Library\View;
class HtmlParagraph
{
private $text;
private $id;
private $class;
public function __construct($text, $id = null, $class = null) {
$this->setText($text);
if ($id !== null) {
$this->setId($id);
}
if ($class !== null) {
$this->setClass($class);
}
}
public function setText($text) {
if (!is_string($text) || empty($text)) {
throw new \InvalidArgumentException(
"The text of the element is invalid.");
}
$this->text = $text;
return $this;
}
public function setId($id) {
if (!preg_match('/^[a-z0-9_-]+$/', $id)) {
throw new \InvalidArgumentException(
"The attribute value is invalid.");
}
$this->id = $id;
return $this;
}
public function setClass($class) {
if (!preg_match('/^[a-z0-9_-]+$/', $id)) {
throw new \InvalidArgumentException(
"The attribute value is invalid.");
}
$this->class = $class;
return $this;
}
public function renderParagraph() {
return '<p' .
($this->id ? ' id="' . $this->id . '"' : '') .
($this->class ? ' class="' . $this->class . '"' : '') .
'>' . $this->text . '</p>';
}
}
/////////////////////////////////////////////////////////////////////
<?php
namespace Library\View;
class HtmlRenderer
{
private $elements = array();
public function __construct(array $elements = array()) {
if (!empty($elements)) {
$this->addElements($elements);
}
}
public function addElement($element) {
$this->elements[] = $element;
return $this;
}
public function addElements(array $elements) {
foreach ($elements as $element) {
$this->addElement($element);
}
return $this;
}
public function render() {
$html = "";
// IF WE FORCE OURSELVES TO NOT TOUCH THIS FILE AGAIN (CLOSED FOR MODIFICATION)
// THEN HOW DO WE MAKE IT "OPEN FOR EXTENSION" (SO WE DON'T HAVE TO ADD MORE 'if' CONDITIONALS)?
foreach ($this->elements as $element) {
if ($element instanceof HtmlDiv) {
$html .= $element->renderDiv();
}
else if ($element instanceof HtmlParagraph) {
$html .= $element->renderParagraph();
}
}
return $html;
}
}
2. Better Example.php
<?php
// THE SOLUTION IS TO USE POLYMORPHISM AND INTERFACES TO BUILD A CONTRACT
// FOR OUR CLASSES TO ABIDE TO AND THEN THE 'HtmlRender' CLASS CAN TRUST LOOPING
// THROUGH ALL ADDED ELEMENTS AS THEY HAVE TO ABIDE BY THE INTERFACE CONTRACT
namespace Library\View;
interface HtmlElementInterface
{
public function render();
}
/////////////////////////////////////////////////////////////////////
<?php
namespace Library\View;
abstract class AbstractHtmlElement implements HtmlElementInterface
{
protected $text;
protected $id;
protected $class;
public function __construct($text, $id = null, $class = null) {
$this->setText($text);
if ($id !== null) {
$this->setId($id);
}
if ($class !== null) {
$this->setClass($class);
}
}
public function setText($text) {
if (!is_string($text) || empty($text)) {
throw new \InvalidArgumentException(
"The text of the element is invalid.");
}
$this->text = $text;
return $this;
}
public function setId($id) {
$this->checkAttribute($id);
$this->id = $id;
return $this;
}
public function setClass($class) {
$this->checkAttribute($class);
$this->class = $class;
return $this;
}
protected function checkAttribute($value) {
if (!preg_match('/^[a-z0-9_-]+$/', $value)) {
throw new \InvalidArgumentException(
"The attribute value is invalid.");
}
}
}
/////////////////////////////////////////////////////////////////////
<?php
namespace Library\View;
class HtmlDiv extends AbstractHtmlElement
{
public function render() {
return '<div' .
($this->id ? ' id="' . $this->id . '"' : '') .
($this->class ? ' class="' . $this->class . '"' : '') .
'>' . $this->text . '</div>';
}
}
/////////////////////////////////////////////////////////////////////
<?php
namespace Library\View;
class HtmlParagraph extends AbstractHtmlElement
{
public function render() {
return '<p' .
($this->id ? ' id="' . $this->id . '"' : '') .
($this->class ? ' class="' . $this->class . '"' : '') .
'>' . $this->text . '</p>';
}
}
/////////////////////////////////////////////////////////////////////
<?php
namespace Library\View;
class HtmlRenderer
{
private $elements = array();
public function __construct(array $elements = array()) {
if (!empty($elements)) {
$this->addElements($elements);
}
}
public function addElement(HtmlElementInterface $element) {
$this->elements[] = $element;
return $this;
}
public function addElements(array $elements) {
foreach ($elements as $element) {
$this->addElement($element);
}
return $this;
}
public function render() {
$html = "";
// NOW THIS IS CLOSED FOR MODIFICATION
// BUT DEFINITELY OPEN FOR EXTENSION BY ANY CLASS THAT IMPLEMENTS THE 'render' METHOD
foreach ($this->elements as $element) {
$html .= $element->render();
}
return $html;
}
}
/////////////////////////////////////////////////////////////////////
<?php
use Library\Loader\Autoloader,
Library\View\HtmlDiv,
Library\View\HtmlParagraph,
Library\View\HtmlRenderer;
require_once __DIR__ . "/Library/Loader/Autoloader.php";
$autoloader = new Autoloader();
$autoloader->register();
$div = new HtmlDiv("This is the text of the div.", "dID", "dClass");
$p = new HtmlParagraph("This is the text of the paragraph.", "pID", "pClass");
$renderer = new HtmlRenderer(array($div, $p));
echo $renderer->render();