PHP Classes
elePHPant
Icontem

File: docs/files/src/SVGCreator/Element.php.txt

Recommend this page to a friend!
  Classes of Tio  >  PHP SVG Creator  >  docs/files/src/SVGCreator/Element.php.txt  >  Download  
File: docs/files/src/SVGCreator/Element.php.txt
Role: Documentation
Content type: text/plain
Description: Documentation
Class: PHP SVG Creator
Generate SVG chart documents
Author: By
Last change:
Date: 2 years ago
Size: 7,068 bytes
 

Contents

Class file image Download
<?php
/**
 * Main Element Class
 *
 * @package    SVGCreator
 * @subpackage my-subpackage
 * @author     Sérgio Diniz
 * @version    1.0
 */

namespace SVGCreator;

/**
 * Main element class
 * 
 * @abstract
 */
abstract class Element {

	const CIRCLE = 'circle';
	const DEFS = 'defs';
	const GROUP = 'g';
	const LINE = 'line';
	const MARKER = 'marker';
	const PATH = 'path';
	const RECT = 'rect';
	const SVG = 'svg';
	const TEXT = 'text';

	/**
	 * The array that holds all attributes
	 * @var array
	 */
	protected $attributes;

	/**
	 * The string that has all the element as a string
	 * @var string
	 */
	protected $elementString;

	/**
	 * Array with the child elements
	 * @var \SVGCreator\Element[]
	 */
	protected $childElements;

	/**
	 * Definitons array
	 * @var array
	 */
	private $defs;

	/**
	 * The text to put inside the element
	 * @var string
	 */
	private $text = null;

	public function __construct($attributes = array()) {

		// Setup the private variables
		$this->attributes = $attributes;
		$this->elementString = '';
		$this->childElements = array();
		$this->defs = array();
	}

	/**
	 * Returns the defs array for this element
	 * @return array
	 */
	protected function getDefs() {
		return $this->defs;
	}

	/**
	 * Set's the definition array
	 * @param array 
	 * @return \SVGCreator\Element
	 */
	protected function setDefs($defs = array()) {
		$this->defs = $defs;
		return $this;
	}

	/**
	 * Adds an def element to the element
	 * @param \SVGCreator\Element $def
	 * @return \SVGCreator\Element
	 */
	public function addDef(\SVGCreator\Element $def) {
		$this->defs[] = $def;
		return $def;
	}

	abstract protected function validateElementValues();

	private function validateElement() {
		$this->validateMandatoryAttribs();
		$this->validateElementValues();
	}

	protected function validateMandatoryAttribs() {
		// Iterate over all fields
    	foreach ( static::$mandatoryFields as $field ) {
    		// If the field does not exist then exit with exception
    		if ( !array_key_exists($field, $this->attributes) ) {
    			throw new \SVGCreator\SVGException("The field ".$field." does not exist for ".static::TYPE.".", 1);
    		}
    	}
	}

	/**
	 * Set's an attribute for the current element
	 * @param  mixed 	 $attrKey		The name of the attribute
	 * @param  string    $attrValue		The value of the attribute
	 * @return mixed 					Could be an \SVGCreator\Element or could be the value of the attribute, 
	 * this means that the second parameter wasn't passed
	 */
	public function attr($attrKey, $attrValue = null) {
		if ( $attrValue != null ) {
			if ( !is_array($this->attributes) ) {
				$this->attributes = array();
			}
			$this->attributes[$attrKey] = $attrValue;
			return $this;
		} else {
			if ( array_key_exists($attrKey, $this->attributes) ) {
				return $this->attributes[$attrKey];
			} else {
				return null;
			}
		}
		
	}

	/**
	 * Factory for building the several elements available
	 * @param  string  			 $type 			The type of element to build
	 * @return \SVGCreator\Element
	 */
	private function factoryElement($type) {
		switch ( $type ) {
			case \SVGCreator\Element::CIRCLE:
				return new \SVGCreator\Elements\Circle();
				break;
			case \SVGCreator\Element::DEFS:
				return new \SVGCreator\Elements\Defs();
				break;
			case \SVGCreator\Element::GROUP:
				return new \SVGCreator\Elements\Group();
				break;
			case \SVGCreator\Element::LINE:
				return new \SVGCreator\Elements\Line();
				break;
			case \SVGCreator\Element::MARKER:
				return new \SVGCreator\Elements\Marker();
				break;
			case \SVGCreator\Element::PATH:
				return new \SVGCreator\Elements\Path();
				break;
			case \SVGCreator\Element::RECT:
				return new \SVGCreator\Elements\Rect();
				break;
			case \SVGCreator\Element::SVG:
				return new \SVGCreator\Elements\Svg();
				break;
			case \SVGCreator\Element::TEXT:
				return new \SVGCreator\Elements\Text();
				break;
			default:
				throw new \SVGCreator\SVGException("The tag ".$type." is not implemented yet", 1);
				break;
		}
	}

	/**
	 * Appends an element to the current element
	 * @param  mixed            	$element 	The element to append to this element could be an object \SVGCreator\Element or a string of the type to create
	 * @return \SVGCreator\Element 				The element append
	 */
	public function append($element) {
		if ( true === $element instanceof \SVGCreator\Element ) {
			$this->childElements[] = $element;
			return $element;
		} else {
			$elementCreated = $this->factoryElement($element);
			$this->childElements[] = $elementCreated;
			return $elementCreated;
		}
	}

	/**
	 * Returns the element string
	 * @return string  				Returns the element string
	 */
	public function getString() {
		// Validate the element first of all!
		$this->validateElement();

		// Start writing the tag
		$elementStringData = '';
		$elementStringData = '<' . static::TYPE;
		foreach ( $this->attributes as $key => $data ) {
			$elementStringData .= ' ' . $key.'="'.$data.'"';
		}
		// Close the initiating tag
		$elementStringData .= '>';

		if ( $this->text !== null ) {
			$elementStringData .= $this->text;
		}

		// If it has child elements we have to write them!
		if ( count($this->childElements) > 0 ) {

			// See if there are definitions to put if the type is svg this is run here
			// because the definition area should be the first to appear!
			if  ( static::TYPE == 'svg' ) {
				foreach ( $this->childElements as $childElement ) {
					// Let's get the definitions array from the child element and propagate them to the top!
					$this->defs = array_merge($this->defs, $childElement->getDefs());
				}

				// If there are definitions to add then add them
				if ( count($this->defs) > 0 ) {
					// Create the defs area
					$defArea = new \SVGCreator\Elements\Defs();
					foreach ( $this->defs as $def ) {
						// Append all elements to def area
						$defArea->append($def);
					}
					// Get the defarea xml
					$elementStringData .= $defArea->getString();
				}
			}

			// Iterate trough each element and write it's child element
			foreach ( $this->childElements as $childElement ) {
				$elementStringData .= $childElement->getString();
			}
		}
		// Always close the tag with no self closing, simplifys things a bit
		// and it's not a couple of bytes that has us worried
		$elementStringData .= '</' . static::TYPE . '>';

		$this->elementString = $elementStringData;

		return $this->elementString;
	}

	/**
	 * Saves the element as a file
	 * @param  string 	$fileName 	The filename with path to save
	 * @return string 				Returns the filename or false on failure
	 */
	public function saveElementAsFile($fileName) {
		// Get the element string
		$this->getString();
		if ( false === file_put_contents($fileName, $this->elementString) ) {
			return false;
		} else {
			return $fileName;
		}
	}

	/**
	 * Set's or returns the text of the element
	 * @param  string 	 $text 	 The text to add to the element
	 * @return \SVGCreator\Element
	 */
	public function text($text) {
		$this->text = $text;
		return $this;
	}
}