| Current Path : /home/ereika83/public_html/wp-content/plugins/squirrly-seo/models/abstract/ |
| Current File : /home/ereika83/public_html/wp-content/plugins/squirrly-seo/models/abstract/Domain.php |
<?php
defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
/**
* ObjectAbstract
*
* Abstract base class for domain objects.
* Magic setters and getters and get<Property>/set<Property> based on protected properties defined.
*/
abstract class SQ_Models_Abstract_Domain implements ArrayAccess {
public function __construct( $properties = null ) {
if ( isset( $properties ) ) {
if ( ! is_array( $properties ) ) {
$properties = (array) $properties;
}
if ( ! empty( $properties ) ) {
foreach ( $properties as $key => $value ) {
// assign value to key
$this->$key = $value;
}
}
}
}
// -----------------------------------------------------------------------
/**
* Magic methods
*/
/**
* Magic isset
*/
public function __isset( $name ) {
// map name to key; prepend _
$key = '_' . $name;
// if there is no such property
if ( ! property_exists( $this, $key ) ) {
return false;
}
return isset( $this->$key );
}
/**
* Magic getter
*
* @param string $name the name of the property
*
* @return mixed the value of the property
*/
public function __get( $name ) {
// map name to getter method; prepend 'get'
$method = 'get' . ucfirst( $name );
return $this->$method();
}
/**
* Magic setter
* $object->innerAttribute = $value; will call setInnerAttribute($value)
*
* @param string $name the name of the property
* @param mixed $value the value to assign
*/
public function __set( $name, $value ) {
// map name to setter method; prepend 'set'
$method = 'set' . ucfirst( $name );
$this->$method( $value );
}
/**
* Magic unset
*/
public function __unset( $name ) {
$this->$name = null;
}
/**
* Return the string representation of this model.
*
* @return string
*/
public function __toString() {
return get_class( $this );
}
/**
* Magic call to implement default setters and getters.
*
* get<MyProperty>
* set<MyProperty>
* maps to $_myProperty if property exists
*
* @param string $name
* @param array $arguments
*
* @return mixed
*/
public function __call( $method, array $arguments ) {
$matches = array();
// generate default getters
if ( preg_match( '/^get(\w+?)?$/', $method, $matches ) ) {
// matches[0] = method
// matches[1] = property
// map name to property; prepend _
if ( function_exists( 'lcfirst' ) ) {
$property = lcfirst( $matches[1] );
} else {
$property = strtolower( substr( $matches[1], 0, 1 ) ) . substr( $matches[1], 1 );
}
$_property = "_" . $property;
if ( ! property_exists( $this, $_property ) ) {
return null;
}
// if no property then throw exception
// throw new Exception('Object does not have property [' . $property . ']');
return $this->$_property;
}
if ( preg_match( '/^set(\w+?)?$/', $method, $matches ) ) {
// matches[0] = method
// matches[1] = property
// map name to property; prepend _
if ( $matches[1] == 'ID' ) {
$property = $matches[1];
} elseif ( function_exists( 'lcfirst' ) ) {
$property = lcfirst( $matches[1] );
} else {
$property = strtolower( substr( $matches[1], 0, 1 ) ) . substr( $matches[1], 1 );
}
$value = $arguments[0];
$_property = "_" . $property;
if ( property_exists( $this, $_property ) ) {
// no property, throw exception
// throw new Exception('Object does not have property [' . $property . ']');
// property exists, assign the value
$this->$_property = $value;
}
// return $this to provide fluid interface
return $this;
}
return false;
}
// -----------------------------------------------------------------------
/**
* Utility methods
*/
/**
* Return this model as an array.
* Any properties of type object will be converted to string.
*
* @return array
*/
public function toArray() {
$args = func_get_args();
$data = array();
if ( empty( $args ) ) {
// iterate over each property in this object
foreach ( $this->_getProperties() as $property => $value ) {
// if the property is ignored, just skip it
if ( in_array( $property, $this->_getIgnoredProperties() ) ) {
continue;
}
// if the property value is traversable
if ( $value instanceof Traversable ) {
// if value is an array or an object traversable using foreach
$tmp = array();
foreach ( $value as $k => $v ) {
if ( is_object( $v ) && method_exists( $v, 'toArray' ) ) {
$tmp[ $k ] = $v->toArray();
} else {
$tmp[ $k ] = $v . '';
}
}
// if value is an iterator (or subclass), rewind it
if ( $value instanceof Iterator ) {
$value->rewind();
}
$data[ $property ] = $tmp;
} elseif ( is_object( $value ) ) {
if ( method_exists( $value, 'toArray' ) ) {
$data[ $property ] = $value->toArray();
} elseif ( method_exists( $value, 'toString' ) ) {
$data[ $property ] = $value->toString();
} else {
$data[ $property ] = $value;
}
} elseif ( is_array( $value ) ) {
$data[ $property ] = current( $value );
} else {
$data[ $property ] = $value . '';
}
}
} else {
foreach ( $args as $arg ) {
if ( isset( $this->$arg ) ) {
$data[ $arg ] = $this->$arg;
}
}
}
return $data;
}
/**
* Return this model as an array.
* Any properties of type object will be converted to string.
*
* @return array
*/
public function prepareDB() {
$args = func_get_args();
$data = array();
if ( empty( $args ) ) {
// iterate over each property in this object
foreach ( $this->_getProperties() as $property => $value ) {
// if the property is ignored, just skip it
if ( in_array( $property, $this->_getIgnoredProperties() ) ) {
continue;
}
// if the property value is traversable
if ( $value instanceof Traversable ) {
// if value is an array or an object traversable using foreach
$tmp = array();
foreach ( $value as $k => $v ) {
if ( is_object( $v ) && method_exists( $v, 'toArray' ) ) {
$tmp[ $k ] = $v->prepareDB();
} else {
$tmp[ $k ] = $v . '';
}
}
// if value is an iterator (or subclass), rewind it
if ( $value instanceof Iterator ) {
$value->rewind();
}
$data[ $property ] = $tmp;
} else if ( is_object( $value ) ) {
if ( method_exists( $value, 'toArray' ) ) {
$data[ $property ] = $value->prepareDB();
} elseif ( method_exists( $value, 'toString' ) ) {
$data[ $property ] = $value->toString();
} else {
$data[ $property ] = $value;
}
} // otherwise
else {
if ( isset( $value ) ) {
$data[ $property ] = $value . '';
}
}
}
} else {
foreach ( $args as $arg ) {
if ( isset( $this->$arg ) ) {
$data[ $arg ] = $this->$arg;
}
}
}
return $data;
}
/**
* Return this model as json.
* Any properties of type object will be converted to string.
*
* @return string
*/
public function toJson() {
return wp_json_encode( $this->toArray() );
}
/**
* Return this model as xml.
* Any properties of type object will be converted to string.
*
* @return string
*/
public function toXml() {
$schema = $this->_xmlSchema();
// the dom document
$dom = new DOMDocument;
$dom->formatOutput = true;
// the node
$nodeKey = key( $schema );
$node = $dom->createElement( $nodeKey );
// attributes
$attributes = $schema[ $nodeKey ]['attributes'];
if ( isset( $attributes ) && is_array( $attributes ) ) {
foreach ( $attributes as $key => $value ) {
$attribute = $dom->createAttribute( $key );
$attribute->value = htmlentities( $value );
$node->appendChild( $attribute );
}
}
// elements
$elements = $schema[ $nodeKey ]['elements'];
if ( isset( $elements ) && is_array( $elements ) ) {
foreach ( $elements as $key => $element ) {
if ( is_array( $element ) || ( $element instanceof Traversable ) ) {
if ( is_int( $key ) ) {
foreach ( $element as $e ) {
$tmpDom = new DOMDocument;
$tmpDom->loadXML( $e->toXml() );
$iNode = $tmpDom->getElementsByTagName( '*' )->item( 0 );
$node->appendChild( $dom->importNode( $iNode, true ) );
}
} elseif ( is_string( $key ) ) {
$tmp = $dom->createElement( $key );
foreach ( $element as $e ) {
$tmpDom = new DOMDocument;
$tmpDom->loadXML( $e->toXml() );
$iNode = $tmpDom->getElementsByTagName( '*' )->item( 0 );
$tmp->appendChild( $dom->importNode( $iNode, true ) );
}
$node->appendChild( $tmp );
}
} else {
$tmpDom = new DOMDocument;
$tmpDom->loadXML( $element->toXml() );
$iNode = $tmpDom->getElementsByTagName( '*' )->item( 0 );
$node->appendChild( $dom->importNode( $iNode, true ) );
}
}
}
// add node to the dom
$dom->appendChild( $node );
// only get node xml
return $dom->saveXML( $node );
}
/**
* The xml schema is an array that defines how the xml is build from the current object.
* This method may be override in child classes which may add/modify attributes/elements.
*
* @return array
*/
protected function _xmlSchema() {
$className = get_class( $this );
$classParts = explode( '_', $className );
$node = array_pop( $classParts );
// build a xml schema automatically based on data members' name and value
$attributes = array();
$elements = array();
// traverse all data members, getting the key (name of the variable) and value
foreach ( $this->_getProperties() as $property => $value ) {
if ( is_scalar( $value ) || ! isset( $value ) )
// if the value is scalar or null
// treat is as an attribute
{
$attributes[ ucfirst( $property ) ] = $value;
} else if ( is_array( $value ) ) {
$elements[ ucfirst( $property ) ] = $value;
}
}
return array(
// node name => node content
$node => array(
'attributes' => $attributes,
'elements' => $elements,
)
);
}
// -----------------------------------------------------------------------
/**
* Methods required by the ArrayAccess interface.
* Allows to access object properties using the array notation, with [].
*
* @param $offset
*
* @return bool
*/
#[ReturnTypeWillChange]
public function offsetExists( $offset ) {
return (bool) array_key_exists( $offset, $this->$offset );
}
#[ReturnTypeWillChange]
public function offsetGet( $offset ) {
return $this->offsetExists( $offset ) ? $this->$offset : null;
}
#[ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
$this->$offset = $value;
}
#[ReturnTypeWillChange]
public function offsetUnset( $offset ) {
$this->$offset = null;
}
// -----------------------------------------------------------------------
/**
* Get ignored properties
*
* Allows to define a list of property names that will be ignored
* when converting the object to array, json, xml.
*
* There may be multiple reasons to ignore properties:
* - we don't want to export the value for the property
* - to resolve circular reference
* (e.g. an object contains one or more children objects, which will each
* contain a reference back to the parent; we may set the 'parent' property
* as ignored in the child object to eliminate circular toArray() calls
* which result in 'out of memory' error)
*
* @return array
*/
protected function _getIgnoredProperties() {
return array();
}
/**
* Get an array with the object's properties.
*
* The valid object's properties are
* - protected
* - start with one underscore
*
* Private properties will be ignored.
*
* @return array
* @throws Exception
*/
protected function _getProperties() {
$properties = array();
// get object vars
$vars = get_object_vars( $this );
foreach ( $vars as $key => $value ) {
$properties[ substr( $key, 1 ) ] = $value;
}
// if no properties are found
if ( empty( $properties ) ) {
throw new Exception( 'no properties found' );
}
return $properties;
}
}