@ 2015-12-15T03:35:39Z <?php
/**
* @package at.app
* @version 0.3[20151212]
* @author Adrian <adrian@enspi.red>
* @copyright 2014 - 2015
* @license GNU GPL V2 <http://gnu.org/licenses/gpl-2.0.txt>
*/
declare( strict_types = 1 );
namespace at\simple\app;
use at\simple\app\api\modelable as modelableAPI;
/**
* base implementation of modelableAPI.
*
* concrete classes may define getter methods for any string <offset>,
* with the following signature:
* get<offset>( void ) : mixed
*
* concrete classes may define setter methods for any string <offset>,
* with the following signature:
* set<offset>( mixed $value ) : void
*
* concrete classes may define unsetter methods for any string <offset>,
* with the following signature:
* unset<offset>( void ) : void
*
* concrete classes may define validator methods for any string <offset>,
* with the following signature:
* validate<offset>( mixed $value, bool $throw ) : bool
* any <offset> with a validator method must either be a literal offset,
* or have a corresponding set<offset> method (@see self::offsetSet()).
* if the $throw argument is TRUE, and validation fails,
* the validator method must throw a DomainException.
*/
abstract class DomainModel extends \SPLFixedArray implements modelableAPI {
/**
* @const array literal property name => default value map.
* if no default is specified for a property, null will be used.
*/
const DATA = [];
/**
* @const array|null list of enumerable offsets.
* if null, defaults to PROP.
*/
const ENUM = null;
/**
* @const array|null list of json-serializable offsets.
* if null, defaults to ENUM.
*/
const JSON = null;
/**
* @const array list of identifiable literal properties. */
const KEYS = [];
/**
* @const array literal property name => index map. */
const PROP = [];
/**
* @const array literal property name => type (data type|classname) map. */
const TYPE = [];
/**
* @type array runtime list of enumerable properties. */
private $_enum = [];
/**
* @see <http://php.net/SPLFixedArray.fromArray> */
public static function fromArray( array $array ) {
return static::from_array( $array );
}
/**
* @see modelableAPI::from_array() */
public static function from_array( array $data ) : modelableAPI {
$dataObject = new static;
foreach( $array as $prop => $value ) {
$dataObject->offsetSet( $prop, $value );
}
return $dataObject;
}
public function __construct() {
parent::__construct( count( self::PROP ) );
foreach( static::DATA as $prop => $default ) {
$this->offsetSet( $prop, $default );
}
$this->_enum = static::ENUM ??
array_keys( static::PROP );
}
/**
* @see <http://php.net/Iterator.current> */
public function current() {
return $this->offsetGet( current( $this->_enum ) );
}
/**
* @see modelableAPI::getDefaults() */
public function getDefaults() : array {
return static::DATA;
}
/**
* @see modelableAPI::getKeys() */
public function getKeys() : array {
$keys = [];
foreach( static::KEYS as $key ) {
$keys[$key] = $this->offsetGet( $key );
}
return $keys;
}
/**
* @see modelableAPI::getProperties() */
public function getProperties() : array {
return $this->_enum;
}
/**
* @see modealableAPI::getTypes() */
public function getTypes() : array {
return static::TYPE;
}
/**
* @see <http://php.net/jsonSerializable.jsonSerialize> */
public function jsonSerialize() {
$props = static::JSON ??
$this->_enum;
$jsonable = [];
foreach( $props as $prop ) {
$jsonable[$prop] = $this->offsetGet( $prop );
}
return $jsonable;
}
/**
* @see <http://php.net/Iterator.key> */
public function key() {
return current( $this->_enum );
}
/**
* @see <http://php.net/Iterator.next> */
public function next() {
next( $this->_enum );
}
/**
* @see <http://php.net/ArrayAccess.offsetExists> */
public function offsetExists( $offset ) {
return (
method_exists( [$this, "get{$offset}"] ) ||
method_exists( [$this, "set{$offset}"] ) ||
isset( self::PROP[$offset] )
);
}
/**
* @see <http://php.net/ArrayAccess.offsetGet>
*
* @throws UnderflowException if offset does not exist or is not readable
*/
public function offsetGet( $offset ) {
if( ! is_string( $offset ) ) {
$t = gettype( $offset );
$m = "\$offset must be a string, [{$t}] provided";
throw new \InvalidArgumentException( $m, E_USER_WARNING );
}
if( method_exists( [$this, "get{$offset}"] ) ) {
return $this->{"get{$offset}"}();
}
if( isset( self::PROP[$offset] ) ) {
return parent::offsetGet( self::PROP[$offset] );
}
$m = "no readable property [{$offset}]";
throw new \UnderflowException( $m, E_USER_WARNING );
}
/**
* @see <http://php.net/ArrayAccess.offsetSet>
*
* @throws DomainException if validation fails
* @throws OverflowException if offset does not exist or is not settable
*/
public function offsetSet( $offset, $value ) {
$this->offsetValid( $offset, $value, true );
if( method_exists( [$this, "set{$offset}"] ) ) {
return $this->{"set{$offset}"}( $value );
}
if( isset( self::PROP[$offset] ) ) {
return parent::offsetSet( self::PROP[$offset], $value );
}
$m = "no setable property [{$offset}]";
throw new \OverflowException( $m, E_USER_WARNING );
}
/**
* @see <http://php.net/ArrayAccess.offsetUnset>
*
* @throws UnderflowException if offset does not exist or is not unsettable
*/
public function offsetUnset( $offset ) {
if( ! is_string( $offset ) ) {
$t = gettype( $offset );
$m = "\$offset must be a string, [{$t}] provided";
throw new \InvalidArgumentException( $m, E_USER_WARNING );
}
if( method_exists( [$this, "unset{$offset}"] ) ) {
$this->{"unset{$offset}"}( $value );
}
// props with non-null default values are required (cannot be unset)
if( isset( static::PROP[$offset] ) && ! isset( static::DATA[$offset] ) ) {
parent::offsetUnset( self::PROP[$offset], $value );
}
$m = "no unsetable property [{$offset}]";
throw new \UnderflowException( $m, E_USER_WARNING );
}
/**
* @see modelableAPI::offsetValid() */
public function offsetValid( string $offset, $value, bool $throw=false ) : bool {
if( ! $this->offsetExists( $offset ) ) {
$m = "no offset [{$offset}] exists";
throw new \OverflowException( $m, E_USER_WARNING );
}
$class = static::TYPE[$offset];
if(
(! isset( static::TYPE[$offset] )) ||
($value instanceof $class ||
gettype( $value ) === static::TYPE[$offset])
) {
if(
(! method_exists( [$this, "validate{$offset}"] )) ||
$this->{"validate{$offset}"}( $value ))
) {
return true;
}
}
if( $throw ){
$m = "invalid value for property [{$offset}]";
throw new \DomainException( $m, E_USER_NOTICE );
}
return false;
}
/**
* @see <http://php.net/Iterator.rewind> */
public function rewind() {
reset( $this->_enum );
}
/**
* @see <http://php.net/serializable.serialize> */
public function serialize() {
return serialize( parent::toArray() );
}
/** nope. */
public function setSize( $size ) {}
/**
* @see modelableAPI::toArray() */
public function toArray() : array {
$enumerable = [];
foreach( $this->_enum as $prop ) {
$enumerable[$prop] = $this->offsetGet( $prop );
}
return $enumerable;
}
/**
* @see <http://php.net/serializable.unserialize> */
public function unserialize( $serialized ) {
$props = unserialize( $serialized );
if( ! (is_array( $props ) && (count( $props ) === count( static::PROP ))) ) {
$m = '$serialized is not valid property data';
throw new \InvalidArgumentException( $m, E_USER_ERROR );
}
$this->__construct();
foreach( (array) unserialize( $serialized ) as $index => $value ) {
$offset = array_search( $index, static::PROP );
$this->offsetSet( $offset, $value );
}
}
/**
* @see <http://php.net/Iterator.valid> */
public function valid() {
return $this->offsetExists( current( $this->_enum ) );
}
}
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).
Version System time (s) User time (s) Memory (MiB) 7.0.0 0.007 0.063 20.07 5.6.16 0.010 0.087 20.50 5.6.15 0.003 0.040 18.16 5.6.14 0.010 0.033 18.14 5.6.13 0.003 0.043 18.28 5.6.12 0.003 0.047 21.16 5.6.11 0.000 0.080 20.95 5.6.10 0.010 0.083 20.96 5.6.9 0.007 0.077 20.99 5.6.8 0.007 0.053 20.39 5.5.30 0.007 0.067 17.94 5.5.29 0.007 0.083 17.97 5.5.28 0.017 0.063 20.73 5.5.27 0.010 0.080 20.87 5.5.26 0.017 0.073 20.79 5.5.25 0.010 0.080 20.79 5.5.24 0.000 0.073 20.14
preferences:dark mode live preview
137.51 ms | 1394 KiB | 7 Q