added property and entity definition classes

This commit is contained in:
Steffen Vogel 2010-08-24 15:33:55 +02:00
parent 9d3a02147c
commit f90a9a9b8b
22 changed files with 786 additions and 351 deletions

View file

@ -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';

View file

@ -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

View file

@ -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; }
}
?>

View file

@ -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() {
}
}
?>

View file

@ -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
*/

View file

@ -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;
}
}

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()
{

View file

@ -55,7 +55,7 @@ class Token {
* var integer timestamp until token is valid
*
* @Column(type="bigint")
* @todo implement
* @todo to be implemented
*/
protected $valid;

View file

@ -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
View 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);
}
}
?>

View 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);
}
}
}
?>

View file

@ -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"');

View file

@ -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;
}
}
?>

View file

@ -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');
}

View file

@ -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');

View file

@ -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
},
]

View file

@ -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
View 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>';
?>

View 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>';
?>