@ 2015-12-15T03:36:12Z <?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.
Output for 8.0.0 - 8.0.30 , 8.1.0 - 8.1.28 , 8.2.0 - 8.2.18 , 8.3.0 - 8.3.4 , 8.3.6 Fatal error: Uncaught Error: Interface "at\simple\app\api\modelable" not found in /in/CCc5v:38
Stack trace:
#0 {main}
thrown in /in/CCc5v on line 38
Process exited with code 255 . Output for 8.3.5 Warning: PHP Startup: Unable to load dynamic library 'sodium.so' (tried: /usr/lib/php/8.3.5/modules/sodium.so (libsodium.so.23: cannot open shared object file: No such file or directory), /usr/lib/php/8.3.5/modules/sodium.so.so (/usr/lib/php/8.3.5/modules/sodium.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
Fatal error: Uncaught Error: Interface "at\simple\app\api\modelable" not found in /in/CCc5v:38
Stack trace:
#0 {main}
thrown in /in/CCc5v on line 38
Process exited with code 255 . Output for 7.4.0 - 7.4.33 Fatal error: Uncaught Error: Interface 'at\simple\app\api\modelable' not found in /in/CCc5v:38
Stack trace:
#0 {main}
thrown in /in/CCc5v on line 38
Process exited with code 255 . Output for 7.0.0 - 7.0.20 , 7.1.0 - 7.1.33 , 7.2.0 - 7.2.33 , 7.3.0 - 7.3.33 Warning: Declaration of at\simple\app\DomainModel::fromArray(array $array) should be compatible with SplFixedArray::fromArray($data, $save_indexes = NULL) in /in/CCc5v on line 38
Fatal error: Interface 'at\simple\app\api\modelable' not found in /in/CCc5v on line 38
Process exited with code 255 . Output for 5.6.0 - 5.6.28 Warning: Unsupported declare 'strict_types' in /in/CCc5v on line 9
Parse error: syntax error, unexpected ':', expecting ';' or '{' in /in/CCc5v on line 82
Process exited with code 255 . Output for 5.5.0 - 5.5.38 Warning: Unsupported declare 'strict_types' in /in/CCc5v on line 9
Fatal error: Arrays are not allowed in class constants in /in/CCc5v on line 44
Process exited with code 255 . preferences:dark mode live preview
250.47 ms | 401 KiB | 255 Q