added property and entity definition classes
This commit is contained in:
parent
9d3a02147c
commit
f90a9a9b8b
22 changed files with 786 additions and 351 deletions
|
@ -30,9 +30,10 @@ use Volkszaehler\Util;
|
|||
use Volkszaehler\Controller;
|
||||
|
||||
// TODO replace by state class
|
||||
const VERSION = 1.1;
|
||||
const BACKEND_DIR = '/home/steffen/workspace/volkszaehler.org/backend'; // TODO realpath(__DIR__)
|
||||
const DEV_ENV = TRUE;
|
||||
define('VZ_VERSION', 0.2);
|
||||
define('VZ_DIR', '/home/steffen/workspace/volkszaehler.org'); // TODO realpath(__DIR__)
|
||||
define('BACKEND_DIR', VZ_DIR . '/backend');
|
||||
define('DEV_ENV', TRUE);
|
||||
|
||||
// class autoloading
|
||||
require BACKEND_DIR . '/lib/Util/ClassLoader.php';
|
||||
|
|
|
@ -40,7 +40,7 @@ class ChannelController extends Controller {
|
|||
* @todo implement filters
|
||||
*/
|
||||
public function get() {
|
||||
$dql = 'SELECT c FROM Volkszaehler\Model\Channel c';
|
||||
$dql = 'SELECT c, p FROM Volkszaehler\Model\Channel c LEFT JOIN c.properties p';
|
||||
|
||||
if ($uuid = $this->view->request->getParameter('uuid')) {
|
||||
// TODO add conditions
|
||||
|
|
|
@ -44,30 +44,11 @@ class Channel extends Entity {
|
|||
protected $groups;
|
||||
|
||||
/**
|
||||
* indicator => interpreter, unit mapping
|
||||
*
|
||||
* @todo replace by properties?
|
||||
* Constructor
|
||||
*/
|
||||
protected static $indicators = array(
|
||||
'power' => array('meter', 'W'),
|
||||
'gas' => array('meter', 'm³'),
|
||||
'water' => array('meter', 'm³'),
|
||||
'temperature' => array('sensor', '°C'),
|
||||
'pressure' => array('sensor', 'hPa'),
|
||||
'humidity' => array('sensor', '%')
|
||||
);
|
||||
public function __construct($properties = array()) {
|
||||
parent::__construct($properties);
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
public function __construct($indicator) {
|
||||
parent::__construct();
|
||||
|
||||
if (!in_array($indicator, array_keys(self::$indicators))) {
|
||||
throw new \Exception($indicator . ' is no known indicator');
|
||||
}
|
||||
|
||||
$this->indicator = $indicator;
|
||||
$this->data = new ArrayCollection();
|
||||
$this->groups = new ArrayCollection();
|
||||
}
|
||||
|
@ -118,10 +99,6 @@ class Channel extends Entity {
|
|||
public function setResolution($resolution) { $this->resolution = $resolution; }
|
||||
public function getCost() { return $this->cost; }
|
||||
public function setCost($cost) { $this->cost = $cost; }
|
||||
|
||||
public function getType() { return self::$indicators[$this->indicator][0]; }
|
||||
public function getUnit() { return self::$indicators[$this->indicator][1]; }
|
||||
public function getIndicator() { return $this->indicator; }
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -46,7 +46,7 @@ abstract class Entity {
|
|||
*/
|
||||
protected $id;
|
||||
|
||||
/** @Column(type="string", length=36, nullable=false) */
|
||||
/** @Column(type="string", length=36, nullable=false, unique=true) */
|
||||
protected $uuid;
|
||||
|
||||
/**
|
||||
|
@ -56,41 +56,99 @@ abstract class Entity {
|
|||
|
||||
/**
|
||||
* @OneToMany(targetEntity="Property", mappedBy="entity")
|
||||
* @OrderBy({"key" = "ASC"})
|
||||
* @OrderBy({"name" = "ASC"})
|
||||
*/
|
||||
protected $properties = NULL;
|
||||
|
||||
public function __construct() {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $properties of Model\Property
|
||||
*/
|
||||
public function __construct($properties = array()) {
|
||||
$this->uuid = Util\UUID::mint();
|
||||
$this->tokens = new Collections\ArrayCollection();
|
||||
$this->properties = new Collections\ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param unknown_type $token
|
||||
* Getter & setter
|
||||
*/
|
||||
public function validateToken($token) {
|
||||
|
||||
}
|
||||
|
||||
public function getToken() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $name
|
||||
* @return Model\Property
|
||||
*/
|
||||
public function getProperty($name) {
|
||||
|
||||
}
|
||||
|
||||
public function setProperty($name) {
|
||||
public function getProperties() {
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
public function setProperty($name, $value) {
|
||||
|
||||
}
|
||||
|
||||
public function unsetProperty($name) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter & setter
|
||||
*/
|
||||
public function getId() { return $this->id; } // read only
|
||||
public function getUuid() { return $this->uuid; } // read only
|
||||
}
|
||||
|
||||
class EntityDefiniton extends Util\JSONDefinition {
|
||||
/**
|
||||
* File containing the JSON definitons
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILE = '/share/entities.json';
|
||||
|
||||
/**
|
||||
* List of required properties
|
||||
* Allowed properties = optional + required
|
||||
* @var array
|
||||
*/
|
||||
protected $required = array();
|
||||
|
||||
/**
|
||||
* List of optional properties
|
||||
* Allowed properties = optional + required
|
||||
* @var array
|
||||
*/
|
||||
protected $optional = array();
|
||||
|
||||
/**
|
||||
* Classname of intepreter (see backend/lib/Interpreter/)
|
||||
* @var string
|
||||
*/
|
||||
protected $interpreter;
|
||||
|
||||
/**
|
||||
* Not required for group entity
|
||||
* @var string
|
||||
*/
|
||||
protected $unit;
|
||||
|
||||
/**
|
||||
* @todo url relative or absolute?
|
||||
* @var string
|
||||
*/
|
||||
protected $icon;
|
||||
|
||||
/**
|
||||
* Check for required and optional properties
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function checkProperties() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -61,10 +61,10 @@ class Group extends Entity {
|
|||
protected $parents = NULL;
|
||||
|
||||
/**
|
||||
* construct
|
||||
* Construct
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
public function __construct($properties = array()) {
|
||||
parent::__construct($properties);
|
||||
|
||||
$this->channels = new ArrayCollection();
|
||||
$this->children = new ArrayCollection();
|
||||
|
@ -72,7 +72,7 @@ class Group extends Entity {
|
|||
}
|
||||
|
||||
/**
|
||||
* adds group as new child
|
||||
* Adds group as new child
|
||||
*
|
||||
* @param Group $child
|
||||
* @todo check against endless recursion
|
||||
|
@ -88,7 +88,7 @@ class Group extends Entity {
|
|||
}
|
||||
|
||||
/**
|
||||
* adds channel as new child
|
||||
* Adds channel as new child
|
||||
*
|
||||
* @param Channel $child
|
||||
* @todo check if the channel is already member of the group
|
||||
|
@ -103,7 +103,7 @@ class Group extends Entity {
|
|||
}
|
||||
|
||||
/**
|
||||
* getter & setter
|
||||
* Getter & setter
|
||||
*
|
||||
* @todo change to new property model
|
||||
*/
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
namespace Volkszaehler\Model;
|
||||
|
||||
use Volkszaehler\Util;
|
||||
use Volkszaehler\Model;
|
||||
|
||||
/**
|
||||
|
@ -53,6 +54,15 @@ class Property {
|
|||
/** @ManyToOne(targetEntity="Entity", inversedBy="properties") */
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* Property definition
|
||||
*
|
||||
* Used to validate
|
||||
*
|
||||
* @var Model\PropertyDefinition
|
||||
*/
|
||||
protected $definition;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
@ -60,8 +70,106 @@ class Property {
|
|||
* @param string $value
|
||||
*/
|
||||
public function __construct($name, $value) {
|
||||
$this->name = (string) $name;
|
||||
$this->value = (string) $value;
|
||||
$this->definition = Model\PropertyDefinition::get($name);
|
||||
|
||||
$this->setName($name);
|
||||
$this->setValue($value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setter & Getter
|
||||
*/
|
||||
|
||||
public function getName() { return $this->name; }
|
||||
public function getValue() { return $this->value; }
|
||||
|
||||
public function setValue($value) {
|
||||
if (!$this->definition->validate($value)) {
|
||||
throw new \Exception('invalid property value'); $this->value = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $name
|
||||
* @todo validation
|
||||
*/
|
||||
protected function setName($name) { $this->name = $name; }
|
||||
}
|
||||
|
||||
class PropertyDefinition extends Util\JSONDefinition {
|
||||
/** One of: string, numeric, multiple */
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* Regex pattern to match if type == string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $pattern;
|
||||
|
||||
/**
|
||||
* Minimal value if type == numeric
|
||||
* Required string length if type == string
|
||||
*
|
||||
* @var integer|float
|
||||
*/
|
||||
protected $min;
|
||||
|
||||
/**
|
||||
* Maximal value if type == numeric
|
||||
* Allowed string length if type == string
|
||||
*
|
||||
* @var integer|float
|
||||
*/
|
||||
protected $max;
|
||||
|
||||
/**
|
||||
* List of possible choices if type == multiple
|
||||
* (type as in javascript: 1.2 => numeric, "test" => string)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $choices = array();
|
||||
|
||||
|
||||
/**
|
||||
* File containing the JSON definitons
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILE = '/share/properties.json';
|
||||
|
||||
/**
|
||||
* Validate value according to $this->type
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate($value) {
|
||||
switch ($this->type) {
|
||||
case 'string':
|
||||
$invalid = !is_string($value);
|
||||
$invalid |= isset($this->pattern) && !preg_match($this->pattern, $value);
|
||||
$invalid |= isset($this->min) && strlen($value) < $this->min;
|
||||
$invalid |= isset($this->max) && strlen($value) > $this->max;
|
||||
break;
|
||||
|
||||
case 'numeric':
|
||||
$invalid = !is_numeric($value);
|
||||
$invalid |= isset($this->min) && $value < $this->min;
|
||||
$invalid |= isset($this->max) && $value > $this->max;
|
||||
break;
|
||||
|
||||
case 'multiple':
|
||||
$invalid = !in_array($value, $this->choices, TRUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \Exception('unknown property type');
|
||||
}
|
||||
|
||||
return !$invalid;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,46 +87,28 @@ class VolkszaehlerModelChannelProxy extends \Volkszaehler\Model\Channel implemen
|
|||
return parent::setCost($cost);
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
$this->_load();
|
||||
return parent::getType();
|
||||
}
|
||||
|
||||
public function getUnit()
|
||||
{
|
||||
$this->_load();
|
||||
return parent::getUnit();
|
||||
}
|
||||
|
||||
public function getIndicator()
|
||||
{
|
||||
$this->_load();
|
||||
return parent::getIndicator();
|
||||
}
|
||||
|
||||
public function validateToken($token)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::validateToken($token);
|
||||
}
|
||||
|
||||
public function getToken()
|
||||
{
|
||||
$this->_load();
|
||||
return parent::getToken();
|
||||
}
|
||||
|
||||
public function getProperty($name)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::getProperty($name);
|
||||
}
|
||||
|
||||
public function setProperty($name)
|
||||
public function getProperties()
|
||||
{
|
||||
$this->_load();
|
||||
return parent::setProperty($name);
|
||||
return parent::getProperties();
|
||||
}
|
||||
|
||||
public function setProperty($name, $value)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::setProperty($name, $value);
|
||||
}
|
||||
|
||||
public function unsetProperty($name)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::unsetProperty($name);
|
||||
}
|
||||
|
||||
public function getId()
|
||||
|
|
|
@ -27,28 +27,28 @@ class VolkszaehlerModelEntityProxy extends \Volkszaehler\Model\Entity implements
|
|||
}
|
||||
|
||||
|
||||
public function validateToken($token)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::validateToken($token);
|
||||
}
|
||||
|
||||
public function getToken()
|
||||
{
|
||||
$this->_load();
|
||||
return parent::getToken();
|
||||
}
|
||||
|
||||
public function getProperty($name)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::getProperty($name);
|
||||
}
|
||||
|
||||
public function setProperty($name)
|
||||
public function getProperties()
|
||||
{
|
||||
$this->_load();
|
||||
return parent::setProperty($name);
|
||||
return parent::getProperties();
|
||||
}
|
||||
|
||||
public function setProperty($name, $value)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::setProperty($name, $value);
|
||||
}
|
||||
|
||||
public function unsetProperty($name)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::unsetProperty($name);
|
||||
}
|
||||
|
||||
public function getId()
|
||||
|
|
|
@ -99,28 +99,28 @@ class VolkszaehlerModelGroupProxy extends \Volkszaehler\Model\Group implements \
|
|||
return parent::getInterpreter($em);
|
||||
}
|
||||
|
||||
public function validateToken($token)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::validateToken($token);
|
||||
}
|
||||
|
||||
public function getToken()
|
||||
{
|
||||
$this->_load();
|
||||
return parent::getToken();
|
||||
}
|
||||
|
||||
public function getProperty($name)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::getProperty($name);
|
||||
}
|
||||
|
||||
public function setProperty($name)
|
||||
public function getProperties()
|
||||
{
|
||||
$this->_load();
|
||||
return parent::setProperty($name);
|
||||
return parent::getProperties();
|
||||
}
|
||||
|
||||
public function setProperty($name, $value)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::setProperty($name, $value);
|
||||
}
|
||||
|
||||
public function unsetProperty($name)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::unsetProperty($name);
|
||||
}
|
||||
|
||||
public function getId()
|
||||
|
|
|
@ -27,6 +27,24 @@ class VolkszaehlerModelPropertyProxy extends \Volkszaehler\Model\Property implem
|
|||
}
|
||||
|
||||
|
||||
public function getName()
|
||||
{
|
||||
$this->_load();
|
||||
return parent::getName();
|
||||
}
|
||||
|
||||
public function getValue()
|
||||
{
|
||||
$this->_load();
|
||||
return parent::getValue();
|
||||
}
|
||||
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->_load();
|
||||
return parent::setValue($value);
|
||||
}
|
||||
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
|
|
|
@ -55,7 +55,7 @@ class Token {
|
|||
* var integer timestamp until token is valid
|
||||
*
|
||||
* @Column(type="bigint")
|
||||
* @todo implement
|
||||
* @todo to be implemented
|
||||
*/
|
||||
protected $valid;
|
||||
|
||||
|
|
|
@ -78,8 +78,8 @@ class Debug implements Logging\SQLLogger {
|
|||
* @param string $sql the sql query
|
||||
* @param array $parameters optional parameters for prepared queries
|
||||
*/
|
||||
function logSQL($sql, array $parameters = NULL) {
|
||||
$this->queries[] = array('sql' => $sql, 'parameters' => $parameters);
|
||||
function logSQL($sql, array $parameters = NULL, $executionMS = null) {
|
||||
$this->queries[] = array('sql' => $sql, 'parameters' => $parameters, 'execution' => round($executionMS, 5));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
161
backend/lib/Util/JSON.php
Normal file
161
backend/lib/Util/JSON.php
Normal file
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Steffen Vogel <info@steffenvogel.de>
|
||||
* @copyright Copyright (c) 2010, The volkszaehler.org project
|
||||
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
|
||||
*/
|
||||
/*
|
||||
* This file is part of volkzaehler.org
|
||||
*
|
||||
* volkzaehler.org is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* volkzaehler.org is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Volkszaehler\Util;
|
||||
|
||||
/**
|
||||
* Custom option constant for JSON::encode()
|
||||
*/
|
||||
define('JSON_PRETTY', 32);
|
||||
|
||||
/**
|
||||
* Static JSON utility class
|
||||
*
|
||||
* @package util
|
||||
* @author Steffen Vogel <info@steffenvogel.de>
|
||||
*/
|
||||
class JSON extends \ArrayObject {
|
||||
/**
|
||||
* OOP wrapper and factory
|
||||
* @param string $json
|
||||
* @return Util\JSON
|
||||
*/
|
||||
static public function decode($json, $assoc = false, $depth = 512) {
|
||||
$data = json_decode(self::strip($json), $assoc, $depth);
|
||||
|
||||
if (is_null($data)) {
|
||||
throw new JSONException();
|
||||
}
|
||||
|
||||
return new self($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* OOP wrapper
|
||||
* @param integer $options use JSON_* constants
|
||||
* @return string the JSON encoded string
|
||||
*/
|
||||
public function encode($options = 0) {
|
||||
$json = json_encode($this->getArrayCopy(), $options);
|
||||
|
||||
if ($options & JSON_PRETTY) {
|
||||
$json = self::format($json);
|
||||
}
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->encode();
|
||||
}
|
||||
|
||||
protected static function format($json, $indent = "\t", $newLine = "\n") {
|
||||
$formatted = '';
|
||||
$indentLevel = 0;
|
||||
$inString = FALSE;
|
||||
|
||||
$len = strlen($json);
|
||||
for($c = 0; $c < $len; $c++) {
|
||||
$char = $json[$c];
|
||||
switch($char) {
|
||||
case '{':
|
||||
case '[':
|
||||
$formatted .= $char;
|
||||
if (!$inString && (ord($json[$c+1]) != ord($char)+2)) {
|
||||
$indentLevel++;
|
||||
$formatted .= $newLine . str_repeat($indent, $indentLevel);
|
||||
}
|
||||
break;
|
||||
case '}':
|
||||
case ']':
|
||||
if (!$inString && (ord($json[$c-1]) != ord($char)-2)) {
|
||||
$indentLevel--;
|
||||
$formatted .= $newLine . str_repeat($indent, $indentLevel);
|
||||
}
|
||||
$formatted .= $char;
|
||||
break;
|
||||
case ',':
|
||||
$formatted .= $char;
|
||||
if (!$inString) {
|
||||
$formatted .= $newLine . str_repeat($indent, $indentLevel);
|
||||
}
|
||||
break;
|
||||
case ':':
|
||||
$formatted .= $char;
|
||||
if (!$inString) {
|
||||
$formatted .= ' ';
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
if ($c > 0 && $json[$c-1] != '\\') {
|
||||
$inString = !$inString;
|
||||
}
|
||||
default:
|
||||
$formatted .= $char;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip whitespaces and comments from JSON string
|
||||
*
|
||||
* Nessecary for parsing a JSON string with json_decode()
|
||||
*
|
||||
* @param string $json
|
||||
*/
|
||||
protected static function strip($json) {
|
||||
$json = preg_replace(array(
|
||||
// eliminate single line comments in '// ...' form
|
||||
'#//(.+)$#m',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form
|
||||
'#/\*.*?\*/#s'
|
||||
), '', $json);
|
||||
|
||||
// eliminate extraneous space
|
||||
return trim($json);
|
||||
}
|
||||
}
|
||||
|
||||
class JSONException extends \Exception {
|
||||
/**
|
||||
* @var array errorcodes defined by json_last_error()
|
||||
*/
|
||||
protected static $errors = array(
|
||||
JSON_ERROR_NONE => 'No error has occurred',
|
||||
JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
|
||||
JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
|
||||
JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON',
|
||||
JSON_ERROR_SYNTAX => 'Syntax error',
|
||||
JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
|
||||
);
|
||||
|
||||
public function __construct($message = NULL, $code = 0) {
|
||||
parent::__construct((is_null($message)) ? self::$errors[json_last_error()] : $message, $code);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
96
backend/lib/Util/JSONDefinition.php
Normal file
96
backend/lib/Util/JSONDefinition.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2010, The volkszaehler.org project
|
||||
* @package util
|
||||
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
|
||||
*/
|
||||
/*
|
||||
* This file is part of volkzaehler.org
|
||||
*
|
||||
* volkzaehler.org is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* volkzaehler.org is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Volkszaehler\Util;
|
||||
|
||||
/**
|
||||
* @author Steffen Vogel <info@steffenvogel.de>
|
||||
* @package util
|
||||
*/
|
||||
abstract class JSONDefinition {
|
||||
/**
|
||||
* Cached json definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $definitions = NULL;
|
||||
|
||||
/** Discriminator for database column */
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Hide default constructor
|
||||
*
|
||||
* @param array $name
|
||||
*/
|
||||
protected function __construct($object) {
|
||||
foreach (get_object_vars($object) as $name => $value) {
|
||||
if (property_exists(get_class($this), $name)) {
|
||||
$this->$name = $value;
|
||||
}
|
||||
else {
|
||||
throw new \Exception('unknown definition: ' . $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Factory method for creating new instances
|
||||
*
|
||||
* @param string $name
|
||||
* @return Model\PropertyDefinition
|
||||
*/
|
||||
public static function get($name) {
|
||||
if (is_null(self::$definitions)) {
|
||||
self::load();
|
||||
}
|
||||
|
||||
if (!isset(self::$definitions[$name])) {
|
||||
throw new \Exception('unknown definition');
|
||||
}
|
||||
|
||||
return self::$definitions[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load JSON definitions from file (via lazy loading from get())
|
||||
*/
|
||||
protected static function load() {
|
||||
$json = file_get_contents(VZ_DIR . static::FILE);
|
||||
$json = JSON::strip($json);
|
||||
$json = json_decode($json); // TODO move to Util\JSON class
|
||||
|
||||
if (!is_array($json) || count($json) == 0) {
|
||||
throw new \Exception('syntax error in definition');
|
||||
}
|
||||
|
||||
self::$definitions = array();
|
||||
|
||||
foreach ($json as $property) {
|
||||
self::$definitions[$property->name] = new static($property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -46,7 +46,7 @@ class CSV extends View {
|
|||
parent::__construct($request, $response);
|
||||
|
||||
echo 'source: volkszaehler.org' . PHP_EOL;
|
||||
echo 'version: ' . \Volkszaehler\VERSION . PHP_EOL;
|
||||
echo 'version: ' . VZ_VERSION . PHP_EOL;
|
||||
|
||||
$this->response->setHeader('Content-type', 'text/csv');
|
||||
$this->response->setHeader('Content-Disposition', 'attachment; filename="data.csv"');
|
||||
|
|
|
@ -34,7 +34,7 @@ use Volkszaehler\Model;
|
|||
* @author Steffen Vogel <info@steffenvogel.de>
|
||||
*/
|
||||
class JSON extends View {
|
||||
protected $json = array();
|
||||
protected $json;
|
||||
|
||||
protected $padding = FALSE;
|
||||
|
||||
|
@ -44,8 +44,10 @@ class JSON extends View {
|
|||
public function __construct(HTTP\Request $request, HTTP\Response $response) {
|
||||
parent::__construct($request, $response);
|
||||
|
||||
$this->json = new Util\JSON();
|
||||
|
||||
$this->json['source'] = 'volkszaehler.org';
|
||||
$this->json['version'] = \Volkszaehler\VERSION;
|
||||
$this->json['version'] = VZ_VERSION;
|
||||
|
||||
$this->response->setHeader('Content-type', 'application/json');
|
||||
|
||||
|
@ -56,15 +58,10 @@ class JSON extends View {
|
|||
|
||||
public function addChannel(Model\Channel $channel, array $data = NULL) {
|
||||
$jsonChannel['uuid'] = (string) $channel->getUuid();
|
||||
$jsonChannel['type'] = $channel->getType();
|
||||
$jsonChannel['indicator'] = $channel->getIndicator();
|
||||
$jsonChannel['unit'] = $channel->getUnit();
|
||||
$jsonChannel['name'] = $channel->getName();
|
||||
$jsonChannel['description'] = $channel->getDescription();
|
||||
|
||||
if ($channel->getType() == 'meter') {
|
||||
$jsonChannel['resolution'] = (int) $channel->getResolution();
|
||||
$jsonChannel['cost'] = (float) $channel->getCost();
|
||||
|
||||
foreach ($channel->getProperties() as $property) {
|
||||
$jsonChannel[$property->getName()] = $property->getValue();
|
||||
}
|
||||
|
||||
if (isset($data)) {
|
||||
|
@ -138,11 +135,7 @@ class JSON extends View {
|
|||
}
|
||||
|
||||
public function renderResponse() {
|
||||
$json = json_encode($this->json);
|
||||
|
||||
if (Util\Debug::isActivated()) {
|
||||
$json = self::format($json);
|
||||
}
|
||||
$json = $this->json->encode((Util\Debug::isActivated()) ? JSON_PRETTY : 0);
|
||||
|
||||
if ($this->padding) {
|
||||
$json = 'if (self.' . $this->padding . ') { ' . $this->padding . '(' . $json . '); }';
|
||||
|
@ -150,56 +143,6 @@ class JSON extends View {
|
|||
|
||||
echo $json;
|
||||
}
|
||||
|
||||
protected static function format($json) {
|
||||
$formatted = '';
|
||||
$indentLevel = 0;
|
||||
$inString = FALSE;
|
||||
|
||||
$len = strlen($json);
|
||||
for($c = 0; $c < $len; $c++) {
|
||||
$char = $json[$c];
|
||||
switch($char) {
|
||||
case '{':
|
||||
case '[':
|
||||
$formatted .= $char;
|
||||
if (!$inString && (ord($json[$c+1]) != ord($char)+2)) {
|
||||
$indentLevel++;
|
||||
$formatted .= "\n" . str_repeat("\t", $indentLevel);
|
||||
}
|
||||
break;
|
||||
case '}':
|
||||
case ']':
|
||||
if (!$inString && (ord($json[$c-1]) != ord($char)-2)) {
|
||||
$indentLevel--;
|
||||
$formatted .= "\n" . str_repeat("\t", $indentLevel);
|
||||
}
|
||||
$formatted .= $char;
|
||||
break;
|
||||
case ',':
|
||||
$formatted .= $char;
|
||||
if (!$inString) {
|
||||
$formatted .= "\n" . str_repeat("\t", $indentLevel);
|
||||
}
|
||||
break;
|
||||
case ':':
|
||||
$formatted .= $char;
|
||||
if (!$inString) {
|
||||
$formatted .= ' ';
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
if ($c > 0 && $json[$c-1] != '\\') {
|
||||
$inString = !$inString;
|
||||
}
|
||||
default:
|
||||
$formatted .= $char;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $formatted;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -41,7 +41,7 @@ class PlainText extends View {
|
|||
parent::__construct($request, $response);
|
||||
|
||||
echo 'source: volkszaehler.org' . PHP_EOL;
|
||||
echo 'version: ' . \Volkszaehler\VERSION . PHP_EOL;
|
||||
echo 'version: ' . VZ_VERSION . PHP_EOL;
|
||||
|
||||
$this->response->setHeader('Content-type', 'text/plain');
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ class XML extends View {
|
|||
$this->xmlRoot = $this->xmlDoc->createElement('volkszaehler');
|
||||
$this->xmlDoc->appendChild($this->xmlRoot);
|
||||
|
||||
$this->xmlRoot->setAttribute('version', \Volkszaehler\VERSION);
|
||||
$this->xmlRoot->setAttribute('version', VZ_VERSION);
|
||||
$this->xmlRoot->setAttribute('source', 'volkszaehler.org');
|
||||
|
||||
$this->response->setHeader('Content-type', 'application/xml; charset=UTF-8');
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/**
|
||||
* Definition of entities
|
||||
|
||||
* Format is specified in EntityDefinition class
|
||||
*
|
||||
* @author Steffen Vogel <info@steffenvogel.de>
|
||||
* @copyright Copyright (c) 2010, The volkszaehler.org project
|
||||
|
@ -22,87 +24,83 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
{
|
||||
"entities" : [
|
||||
/*{
|
||||
"name" : "", // discriminator for database column
|
||||
"required" : [], // list of required properties
|
||||
"optional" : [], // list of optional properties
|
||||
// allowed properties = optional + required
|
||||
"interpreter" : "", // classname of intepreter (see backend/lib/Interpreter/)
|
||||
"unit" : "", // not required for group
|
||||
"icon" : "" // TODO url relative or absolute?
|
||||
}*/
|
||||
{
|
||||
"name" : "group",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "tolerance"],
|
||||
"interpreter" : "GroupInterpreter",
|
||||
"icon" : "" // TODO look for an group icon
|
||||
},
|
||||
{
|
||||
"name" : "power",
|
||||
"required" : ["name", "resolution"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "MeterInterpreter",
|
||||
"icon" : "" // TODO look for an power icon
|
||||
},
|
||||
{
|
||||
"name" : "gas",
|
||||
"required" : ["name", "resolution"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "MeterInterpreter",
|
||||
"icon" : "" // TODO look for an water icon
|
||||
},
|
||||
{
|
||||
"name" : "rainfall",
|
||||
"required" : ["name", "resolution"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "MeterInterpreter",
|
||||
"icon" : "" // TODO look for an water icon
|
||||
},
|
||||
{
|
||||
"name" : "temperature",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "SensorInterpreter",
|
||||
"icon" : "" // TODO look for an water icon
|
||||
},
|
||||
{
|
||||
"name" : "pressure",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "SensorInterpreter",
|
||||
"icon" : "" // TODO look for an water icon
|
||||
},
|
||||
{
|
||||
"name" : "humidity",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "SensorInterpreter",
|
||||
"icon" : "" // TODO look for an water icon
|
||||
},
|
||||
{
|
||||
"name" : "windspeed",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "SensorInterpreter",
|
||||
"icon" : "" // TODO look for an water icon
|
||||
},
|
||||
{
|
||||
"name" : "radition",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "SensorInterpreter",
|
||||
"icon" : "" // TODO look for an water icon
|
||||
},
|
||||
{
|
||||
"name" : "luminosity",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "SensorInterpreter",
|
||||
"icon" : "" // TODO look for an water icon
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
[
|
||||
{
|
||||
"name" : "group",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "tolerance"],
|
||||
"interpreter" : "GroupInterpreter",
|
||||
"icon" : "" // TODO look for an icon
|
||||
},
|
||||
{
|
||||
"name" : "power",
|
||||
"required" : ["name", "resolution"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "MeterInterpreter",
|
||||
"unit" : "kW/h",
|
||||
"icon" : "" // TODO look for an icon
|
||||
},
|
||||
{
|
||||
"name" : "gas",
|
||||
"required" : ["name", "resolution"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "MeterInterpreter",
|
||||
"unit" : "m³/h",
|
||||
"icon" : "" // TODO look for an icon
|
||||
},
|
||||
{
|
||||
"name" : "water",
|
||||
"required" : ["name", "resolution"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "MeterInterpreter",
|
||||
"unit" : "m³/h",
|
||||
"icon" : "" // TODO look for an icon
|
||||
},
|
||||
{
|
||||
"name" : "temperature",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "SensorInterpreter",
|
||||
"unit" : "°C",
|
||||
"icon" : "" // TODO look for an icon
|
||||
},
|
||||
{
|
||||
"name" : "pressure",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "SensorInterpreter",
|
||||
"unit" : "hPa",
|
||||
"icon" : "" // TODO look for an icon
|
||||
},
|
||||
{
|
||||
"name" : "humidity",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "SensorInterpreter",
|
||||
"unit" : "%",
|
||||
"icon" : "" // TODO look for an icon
|
||||
},
|
||||
{
|
||||
"name" : "windspeed",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "SensorInterpreter",
|
||||
"unit" : "km/h",
|
||||
"icon" : "" // TODO look for an icon
|
||||
},
|
||||
{
|
||||
"name" : "radition",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "SensorInterpreter",
|
||||
"icon" : "" // TODO look for an icon
|
||||
},
|
||||
{
|
||||
"name" : "luminosity",
|
||||
"required" : ["name"],
|
||||
"optional" : ["description", "details:", "owner:", "address:", "tolerance"],
|
||||
"interpreter" : "SensorInterpreter",
|
||||
"icon" : "" // TODO look for an icon
|
||||
},
|
||||
]
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/**
|
||||
* Definition of properties for entities
|
||||
* Definition of properties for entities
|
||||
*
|
||||
* Format is specified in PropertyDefinition class
|
||||
*
|
||||
* @author Steffen Vogel <info@steffenvogel.de>
|
||||
* @copyright Copyright (c) 2010, The volkszaehler.org project
|
||||
|
@ -23,84 +25,72 @@
|
|||
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
{
|
||||
"properties" : [
|
||||
/*{
|
||||
"name" : "", // discriminator for database column
|
||||
"type" : "", // one of: string, numeric, multiple
|
||||
"pattern" : "", // regex pattern to match if type == string
|
||||
"min" : 0, // minimal value if type == numeric
|
||||
// required string length if type == string
|
||||
"max" : 100, // maximal value if type == numeric
|
||||
// allowed string length if type == string
|
||||
"choices" : ["", "", ""] // list of possible choices if type == multiple
|
||||
// (type as in javascript: 1.2 => numeric, "test" => string)
|
||||
},*/
|
||||
{
|
||||
"name" : "name",
|
||||
"type" : "string",
|
||||
"pattern" : "/[a-z0-9 ]/",
|
||||
"max" : 255,
|
||||
},
|
||||
{
|
||||
"name" : "description",
|
||||
"type" : "string",
|
||||
"pattern" : "/[a-z0-9 ]/", // TODO add whitespaces as \t \n \r
|
||||
"max" : 255, // TODO allowed column size in database?
|
||||
},
|
||||
{
|
||||
"name" : "cost",
|
||||
"type" : "numeric",
|
||||
"min" : 0,
|
||||
},
|
||||
{
|
||||
"name" : "resolution",
|
||||
"type" : "numeric",
|
||||
"min" : 1,
|
||||
},
|
||||
{
|
||||
"name" : "tolerance",
|
||||
"type" : "numeric",
|
||||
"min" : 0,
|
||||
"max" : 1
|
||||
},
|
||||
{
|
||||
"name" : "address:lat",
|
||||
"type" : "numeric",
|
||||
"min" : -90,
|
||||
"max" : 90
|
||||
},
|
||||
{
|
||||
"name" : "address:lon",
|
||||
"type" : "numeric",
|
||||
"min" : -90,
|
||||
"max" : 90
|
||||
},
|
||||
{
|
||||
"name" : "address:city",
|
||||
"type" : "string",
|
||||
"pattern" : "" // TODO add pattern
|
||||
},
|
||||
{
|
||||
"name" : "address:houseno",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"name" : "address:postal",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"name" : "address:state",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"name" : "address:country",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"name" : "photo:url",
|
||||
"type" : "string",
|
||||
"pattern" : "" // TODO add pattern
|
||||
},
|
||||
]
|
||||
}
|
||||
[
|
||||
{
|
||||
"name" : "name",
|
||||
"type" : "string",
|
||||
"pattern" : "/[a-z0-9 ]/",
|
||||
"min": 3,
|
||||
"max" : 255
|
||||
},
|
||||
{
|
||||
"name" : "description",
|
||||
"type" : "string",
|
||||
"pattern" : "/[a-z0-9 ]/", // TODO add whitespaces as \t \n \r
|
||||
"max" : 255 // TODO allowed column size in database?
|
||||
},
|
||||
{
|
||||
"name" : "cost",
|
||||
"type" : "numeric",
|
||||
"min" : 0
|
||||
},
|
||||
{
|
||||
"name" : "resolution",
|
||||
"type" : "numeric",
|
||||
"min" : 1
|
||||
},
|
||||
{
|
||||
"name" : "tolerance",
|
||||
"type" : "numeric",
|
||||
"min" : 0,
|
||||
"max" : 1
|
||||
},
|
||||
{
|
||||
"name" : "address:lat",
|
||||
"type" : "numeric",
|
||||
"min" : -90,
|
||||
"max" : 90
|
||||
},
|
||||
{
|
||||
"name" : "address:lon",
|
||||
"type" : "numeric",
|
||||
"min" : -90,
|
||||
"max" : 90
|
||||
},
|
||||
{
|
||||
"name" : "address:city",
|
||||
"type" : "string",
|
||||
"pattern" : "" // TODO add pattern
|
||||
},
|
||||
{
|
||||
"name" : "address:houseno",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"name" : "address:postal",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"name" : "address:state",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"name" : "address:country",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"name" : "photo:url",
|
||||
"type" : "string",
|
||||
"pattern" : "" // TODO add pattern
|
||||
}
|
||||
]
|
||||
|
|
62
share/tests/json.php
Normal file
62
share/tests/json.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
/**
|
||||
* A test for our JSON utility class
|
||||
*
|
||||
* @package tests
|
||||
* @copyright Copyright (c) 2010, The volkszaehler.org project
|
||||
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
|
||||
* @author Steffen Vogel <info@steffenvogel.de>
|
||||
*/
|
||||
/*
|
||||
* This file is part of volkzaehler.org
|
||||
*
|
||||
* volkzaehler.org is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* volkzaehler.org is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use Volkszaehler\Util;
|
||||
include '../../backend/lib/Util/JSON.php';
|
||||
echo '<pre>';
|
||||
|
||||
$data = '{
|
||||
"glossary": {
|
||||
"title": "example glossary",
|
||||
"GlossDiv": {
|
||||
"title": "S",
|
||||
"GlossList": {
|
||||
"GlossEntry": {
|
||||
"ID": "SGML",
|
||||
"SortAs": "SGML",
|
||||
"GlossTerm": "Standard Generalized Markup Language",
|
||||
"Acronym": "SGML",
|
||||
"Abbrev": "ISO 8879:1986",
|
||||
"GlossDef": {
|
||||
"para": "A meta-markup language, used to create markup languages such as DocBook.",
|
||||
"GlossSeeAlso": ["GML", "XML"]
|
||||
},
|
||||
"GlossSee": "markup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
$json = Util\JSON::decode($data);
|
||||
|
||||
$json['test'] = 2;
|
||||
|
||||
echo $json->encode(JSON_PRETTY);
|
||||
|
||||
|
||||
echo '</pre>';
|
||||
?>
|
41
share/tests/properties.php
Normal file
41
share/tests/properties.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
/**
|
||||
* A test for our Property class
|
||||
*
|
||||
* @package tests
|
||||
* @copyright Copyright (c) 2010, The volkszaehler.org project
|
||||
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
|
||||
* @author Steffen Vogel <info@steffenvogel.de>
|
||||
*/
|
||||
/*
|
||||
* This file is part of volkzaehler.org
|
||||
*
|
||||
* volkzaehler.org is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* volkzaehler.org is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use Volkszaehler\Util;
|
||||
use Volkszaehler\Model;
|
||||
|
||||
define('VZ_DIR', '/home/steffen/workspace/volkszaehler.org'); // TODO realpath(__DIR__)
|
||||
|
||||
include '../../backend/lib/Util/JSONDefinition.php';
|
||||
include '../../backend/lib/Model/Property.php';
|
||||
include '../../backend/lib/Util/JSON.php';
|
||||
|
||||
echo '<pre>';
|
||||
|
||||
new Model\Property('name', '1as2');
|
||||
|
||||
echo '</pre>';
|
||||
?>
|
Loading…
Add table
Reference in a new issue