Correzioni al dao (save Tested)
Modifiche ai model Rimossa la constrained interface in quanto inefficace e troppo pesante
This commit is contained in:
@@ -1,137 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
Author: Riccardo Di Dato
|
|
||||||
Creation Date: 07/gen/2016
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ConstrainedObject {
|
|
||||||
const SET_BEHAVIOUR_NORMAL = 1;
|
|
||||||
const SET_BEHAVIOUR_IGNORE = 2;
|
|
||||||
const SET_BEHAVIOUR_THROW = 100;
|
|
||||||
|
|
||||||
const UNSET_BEHAVIOUR_NORMAL = 1;
|
|
||||||
const UNSET_BEHAVIOUR_IGNORE = 2;
|
|
||||||
const UNSET_BEHAVIOUR_THROW = 100;
|
|
||||||
|
|
||||||
const GET_BEHAVIOUR_NORMAL = 1;
|
|
||||||
const GET_BEHAVIOUR_EMPTY = 2;
|
|
||||||
const GET_BEHAVIOUR_THROW = 100;
|
|
||||||
|
|
||||||
private $original;
|
|
||||||
|
|
||||||
private $constraints = array();
|
|
||||||
|
|
||||||
public function __construct($original){
|
|
||||||
$this->original = $original;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __set($key, $value){
|
|
||||||
if (array_key_exists($key, $this->constraints)){
|
|
||||||
$constraint = $this->constraints[$key]->set;
|
|
||||||
switch ($constraint->behaviour){
|
|
||||||
case self::SET_BEHAVIOUR_NORMAL:
|
|
||||||
$this->original->$key = $value;
|
|
||||||
break;
|
|
||||||
case self::SET_BEHAVIOUR_THROW:
|
|
||||||
throw new ConstraintException("Constraint violation: impossible to set field '$key'");
|
|
||||||
break;
|
|
||||||
case self::SET_BEHAVIOUR_IGNORE:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (property_exists($constraint, "callbackClass") && !is_null($constraint->callbackClass)){
|
|
||||||
$this->original = $constraint->callbackClass->executeSetCallback($this->original, $key, $value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->original->$key = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __get($key){
|
|
||||||
$rval = $this->original->$key;
|
|
||||||
if (array_key_exists($key, $this->constraints)){
|
|
||||||
$constraint = $this->constraints[$key]->get;
|
|
||||||
switch ($constraint->behaviour){
|
|
||||||
case self::GET_BEHAVIOUR_EMPTY:
|
|
||||||
$rval = null;
|
|
||||||
break;
|
|
||||||
case self::GET_BEHAVIOUR_THROW:
|
|
||||||
throw new ConstraintException("Constraint violation: impossible to get field '$key'");
|
|
||||||
break;
|
|
||||||
case self::GET_BEHAVIOUR_NORMAL:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (property_exists($constraint, "callbackClass") && !is_null($constraint->callbackClass)){
|
|
||||||
$rval = $constraint->callbackClass->executeGetCallback($this->original, $key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __unset($key){
|
|
||||||
if (array_key_exists($key, $this->constraints)){
|
|
||||||
$constraint = $this->constraints[$key]->unset;
|
|
||||||
switch ($constraint->behaviour){
|
|
||||||
case self::UNSET_BEHAVIOUR_NORMAL:
|
|
||||||
unset($this->original->$key);
|
|
||||||
break;
|
|
||||||
case self::UNSET_BEHAVIOUR_THROW:
|
|
||||||
throw new ConstraintException("Constraint violation: impossible to unset field '$key'");
|
|
||||||
break;
|
|
||||||
case self::UNSET_BEHAVIOUR_IGNORE:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (property_exists($constraint, "callbackClass") && !is_null($constraint->callbackClass)){
|
|
||||||
$this->original = $constraint->callbackClass->executeUnsetCallback($this->original, $key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
unset($this->original->$key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createSetBehaviour($key, $behaviour, ConstraintObjectBehaviourCallable $callbackClass = null){
|
|
||||||
$this->constraints[$key]->set = new stdClass();
|
|
||||||
if ($behaviour < self::SET_BEHAVIOUR_NORMAL){
|
|
||||||
$behaviour = self::SET_BEHAVIOUR_NORMAL;
|
|
||||||
}
|
|
||||||
else if ($behaviour > self::SET_BEHAVIOUR_THROW){
|
|
||||||
$behaviour = self::SET_BEHAVIOUR_THROW;
|
|
||||||
}
|
|
||||||
$this->constraints[$key]->set->behaviour = $behaviour;
|
|
||||||
$this->constraints[$key]->set->callbackClass = $callbackClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createGetBehaviour($key, $behaviour, ConstraintObjectBehaviourCallable $callbackClass = null){
|
|
||||||
$this->constraints[$key]->get = new stdClass();
|
|
||||||
if ($behaviour < self::GET_BEHAVIOUR_NORMAL){
|
|
||||||
$behaviour = self::GET_BEHAVIOUR_NORMAL;
|
|
||||||
}
|
|
||||||
else if ($behaviour > self::GET_BEHAVIOUR_THROW){
|
|
||||||
$behaviour = self::GET_BEHAVIOUR_THROW;
|
|
||||||
}
|
|
||||||
$this->constraints[$key]->get->behaviour = $behaviour;
|
|
||||||
$this->constraints[$key]->get->callbackClass = $callbackClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createUnsetBehaviour($key, $behaviour, ConstraintObjectBehaviourCallable $callbackClass = null){
|
|
||||||
$this->constraints[$key]->unset = new stdClass();
|
|
||||||
if ($behaviour < self::UNSET_BEHAVIOUR_NORMAL){
|
|
||||||
$behaviour = self::UNSET_BEHAVIOUR_NORMAL;
|
|
||||||
}
|
|
||||||
else if ($behaviour > self::UNSET_BEHAVIOUR_THROW){
|
|
||||||
$behaviour = self::UNSET_BEHAVIOUR_THROW;
|
|
||||||
}
|
|
||||||
$this->constraints[$key]->unset->behaviour = $behaviour;
|
|
||||||
$this->constraints[$key]->unset->callbackClass = $callbackClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get(){
|
|
||||||
return $this->original;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
Author: Riccardo Di Dato
|
|
||||||
Creation Date: 07/gen/2016
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ConstraintException extends CoreException{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Author: Riccardo Di Dato
|
||||||
|
Creation Date: 08/gen/2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class Constrained implements ConstrainedInterface{
|
||||||
|
public static $SET_BEHAVIOURS = array(
|
||||||
|
self::SET_BEHAVIOUR_NORMAL => array("label"=>"Normal"),
|
||||||
|
self::SET_BEHAVIOUR_IGNORE => array("label"=>"Ignore"),
|
||||||
|
self::SET_BEHAVIOUR_THROW => array("label"=>"Throw Exception")
|
||||||
|
);
|
||||||
|
|
||||||
|
public static $UNSET_BEHAVIOURS = array(
|
||||||
|
self::UNSET_BEHAVIOUR_NORMAL => array("label"=>"Normal"),
|
||||||
|
self::UNSET_BEHAVIOUR_IGNORE => array("label"=>"Ignore"),
|
||||||
|
self::UNSET_BEHAVIOUR_THROW => array("label"=>"Throw Exception")
|
||||||
|
);
|
||||||
|
|
||||||
|
public static $GET_BEHAVIOURS = array(
|
||||||
|
self::GET_BEHAVIOUR_NORMAL => array("label"=>"Normal"),
|
||||||
|
self::GET_BEHAVIOUR_EMPTY => array("label"=>"Empty"),
|
||||||
|
self::GET_BEHAVIOUR_THROW => array("label"=>"Throw Exception")
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
private $constraints = array();
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
$this->createSetBehaviour("*", self::SET_BEHAVIOUR_NORMAL);
|
||||||
|
$this->createGetBehaviour("*", self::GET_BEHAVIOUR_NORMAL);
|
||||||
|
$this->createUnsetBehaviour("*", self::UNSET_BEHAVIOUR_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createSetBehaviour($key, $behaviour, ConstrainedBehaviour $callbackClass = null){
|
||||||
|
// if (strpos($key, ".")!== false){
|
||||||
|
// $matches = array();
|
||||||
|
// if (!preg_match("/^([^.]+)\.(.+)$/", $key, $matches)){
|
||||||
|
// throw new CoreException("Invalid key format passed to ".get_class($this)."::createSetBehaviour ($key)");
|
||||||
|
// }
|
||||||
|
// $myKey = $matches[1];
|
||||||
|
// $childKey = $matches[2];
|
||||||
|
|
||||||
|
// $child = $this->getInternal($myKey);
|
||||||
|
// if (is_null($child)){
|
||||||
|
// $this->setInternal($myKey, new ConstrainedMemoryObject());
|
||||||
|
// }
|
||||||
|
// if ($child instanceof Constrained){
|
||||||
|
// $child->createSetBehaviour($childKey, $behaviour, $callbackClass);
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// throw new CoreException("Invalid key passed to ".get_class($this)."::createSetBehaviour. Setting a child constraint on a non constrained element.");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
if (!array_key_exists($behaviour, self::$SET_BEHAVIOURS)){
|
||||||
|
throw new CoreException("Invalid behaviour parameter passed to ".get_class($this)."::createSetBehaviour ($behaviour)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!array_key_exists($key,$this->constraints)){
|
||||||
|
$this->constraints[$key] = new stdClass();
|
||||||
|
}
|
||||||
|
$this->constraints[$key]->set = new stdClass();
|
||||||
|
$this->constraints[$key]->set->behaviour = $behaviour;
|
||||||
|
$this->constraints[$key]->set->callbackClass = $callbackClass;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createGetBehaviour($key, $behaviour, ConstrainedBehaviour $callbackClass = null){
|
||||||
|
if (!array_key_exists($behaviour, self::$GET_BEHAVIOURS)){
|
||||||
|
throw new CoreException("Invalid behaviour parameter passed to ".get_class($this)."::createGetBehaviour ($behaviour)");
|
||||||
|
}
|
||||||
|
if (!array_key_exists($key,$this->constraints)){
|
||||||
|
$this->constraints[$key] = new stdClass();
|
||||||
|
}
|
||||||
|
$this->constraints[$key]->get = new stdClass();
|
||||||
|
$this->constraints[$key]->get->behaviour = $behaviour;
|
||||||
|
$this->constraints[$key]->get->callbackClass = $callbackClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createUnsetBehaviour($key, $behaviour, ConstrainedBehaviour $callbackClass = null){
|
||||||
|
if (!array_key_exists($behaviour, self::$UNSET_BEHAVIOURS)){
|
||||||
|
throw new CoreException("Invalid behaviour parameter passed to ".get_class($this)."::createUnsetBehaviour ($behaviour)");
|
||||||
|
}
|
||||||
|
if (!array_key_exists($key,$this->constraints)){
|
||||||
|
$this->constraints[$key] = new stdClass();
|
||||||
|
}
|
||||||
|
$this->constraints[$key]->unset = new stdClass();
|
||||||
|
$this->constraints[$key]->unset->behaviour = $behaviour;
|
||||||
|
$this->constraints[$key]->unset->callbackClass = $callbackClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setConstrained($key, $value){
|
||||||
|
try {
|
||||||
|
$constraint = $this->constraints["*"]->set;
|
||||||
|
if (array_key_exists($key, $this->constraints) && property_exists($this->constraints[$key], "set")){
|
||||||
|
$constraint = $this->constraints[$key]->set;
|
||||||
|
}
|
||||||
|
$constraint = $this->constraints[$key]->set;
|
||||||
|
switch ($constraint->behaviour){
|
||||||
|
case self::SET_BEHAVIOUR_NORMAL:
|
||||||
|
$this->setInternal($key, $value);
|
||||||
|
break;
|
||||||
|
case self::SET_BEHAVIOUR_THROW:
|
||||||
|
throw new ConstraintException("set",$key,$value);
|
||||||
|
break;
|
||||||
|
case self::SET_BEHAVIOUR_IGNORE:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (property_exists($constraint, "callbackClass") && !is_null($constraint->callbackClass)){
|
||||||
|
$this->setBase($constraint->callbackClass->executeSetCallback($this->getBase(), $key, $value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ConstraintException $cex){
|
||||||
|
throw $this->addPathToChildException($cex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConstrained($key){
|
||||||
|
try {
|
||||||
|
$rval = null;
|
||||||
|
if (array_key_exists($key, $this->constraints) && property_exists($this->constraints[$key], "get")){
|
||||||
|
$constraint = $this->constraints[$key]->get;
|
||||||
|
switch ($constraint->behaviour){
|
||||||
|
case self::GET_BEHAVIOUR_THROW:
|
||||||
|
throw new ConstraintException("get",$key);
|
||||||
|
break;
|
||||||
|
case self::GET_BEHAVIOUR_NORMAL:
|
||||||
|
$rval = $this->getInternal($key);
|
||||||
|
break;
|
||||||
|
case self::GET_BEHAVIOUR_EMPTY:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (property_exists($constraint, "callbackClass") && !is_null($constraint->callbackClass)){
|
||||||
|
$rval = $constraint->callbackClass->executeGetCallback($this->getBase(), $key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$rval = $this->getInternal($key);
|
||||||
|
}
|
||||||
|
return $rval;
|
||||||
|
}
|
||||||
|
catch (ConstraintException $cex){
|
||||||
|
throw $this->addPathToChildException($cex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unsetConstrained($key){
|
||||||
|
try {
|
||||||
|
if (array_key_exists($key, $this->constraints) && property_exists($this->constraints[$key], "unset")){
|
||||||
|
$constraint = $this->constraints[$key]->unset;
|
||||||
|
switch ($constraint->behaviour){
|
||||||
|
case self::UNSET_BEHAVIOUR_NORMAL:
|
||||||
|
$this->unsetInternal($key);
|
||||||
|
break;
|
||||||
|
case self::UNSET_BEHAVIOUR_THROW:
|
||||||
|
throw new ConstraintException("unset",$key);
|
||||||
|
break;
|
||||||
|
case self::UNSET_BEHAVIOUR_IGNORE:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (property_exists($constraint, "callbackClass") && !is_null($constraint->callbackClass)){
|
||||||
|
$this->setBase($constraint->callbackClass->executeUnsetCallback($this->getBase(), $key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->unsetInternal($key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ConstraintException $cex){
|
||||||
|
throw $this->addPathToChildException($cex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function replicateConstraints(Constrained $oth){
|
||||||
|
$this->constraints = clone $oth->constraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract function addPathToChildException($myKey, ConstraintException $ex);
|
||||||
|
protected abstract function setInternal($key,$value);
|
||||||
|
protected abstract function getInternal($key);
|
||||||
|
protected abstract function unsetInternal($key);
|
||||||
|
|
||||||
|
protected abstract function setBase($base);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Author: Riccardo Di Dato
|
||||||
|
Creation Date: 08/gen/2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ConstrainedArrayObject extends Constrained implements ArrayAccess {
|
||||||
|
private $base = array();
|
||||||
|
|
||||||
|
public function __construct(array $base){
|
||||||
|
parent::__construct();
|
||||||
|
$this->setBase($base);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setBase($base){
|
||||||
|
foreach ($base as $key=>$value){
|
||||||
|
$this->base[$key] = ConstrainedFactory::build($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBase(){
|
||||||
|
return $this->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addPathToChildException($myKey, ConstraintException $ex){
|
||||||
|
$newKey = $myKey."[".$ex->getRelatedKey()."]";
|
||||||
|
return new ConstraintException($ex->getRelatedOperation(), $newKey, $ex->getRelatedValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setInternal($key,$value){
|
||||||
|
if (is_null($key)) {
|
||||||
|
$this->base[] = $value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->base[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getInternal($key){
|
||||||
|
return $this->offsetExists($key) ? $this->base[$key] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function unsetInternal($key){
|
||||||
|
unset($this->base[$key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ArrayAccess methods
|
||||||
|
public function offsetExists($key) {
|
||||||
|
return array_key_exists($key, $this->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetSet($key, $value) {
|
||||||
|
$this->setConstrained($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetUnset($key) {
|
||||||
|
$this->unsetConstrained($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetGet($key) {
|
||||||
|
$this->getConstrained($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
+1
-1
@@ -4,7 +4,7 @@ Author: Riccardo Di Dato
|
|||||||
Creation Date: 07/gen/2016
|
Creation Date: 07/gen/2016
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface ConstraintObjectBehaviourCallable {
|
interface ConstrainedBehaviour {
|
||||||
/**
|
/**
|
||||||
* Esegue il callback per le funzioni di set, restituisce il valore finale di constrainedOriginal.
|
* Esegue il callback per le funzioni di set, restituisce il valore finale di constrainedOriginal.
|
||||||
* ATTENZIONE!! LA funzione è in grado di modificare anche parametri diversi da
|
* ATTENZIONE!! LA funzione è in grado di modificare anche parametri diversi da
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Author: Riccardo Di Dato
|
||||||
|
Creation Date: 08/gen/2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ConstrainedFactory {
|
||||||
|
|
||||||
|
public static function build($obj){
|
||||||
|
$rval = $obj;
|
||||||
|
if ($obj instanceof ConstrainedInterface){
|
||||||
|
$rval = clone $obj;
|
||||||
|
}
|
||||||
|
else if (is_object($obj)){
|
||||||
|
$rval = new ConstrainedObject($obj);
|
||||||
|
}
|
||||||
|
else if (is_array($obj)){
|
||||||
|
$rval = new ConstrainedArrayObject($obj);
|
||||||
|
}
|
||||||
|
return $rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function debuild($obj){
|
||||||
|
$rval = $obj;
|
||||||
|
if ($obj instanceof ConstrainedInterface){
|
||||||
|
$rval = new stdClass();
|
||||||
|
$tmp = $obj->getBase();
|
||||||
|
foreach ($tmp as $key=>$val){
|
||||||
|
$rval->$key = self::debuild($val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Author: Riccardo Di Dato
|
||||||
|
Creation Date: 08/gen/2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface ConstrainedInterface {
|
||||||
|
const SET_BEHAVIOUR_NORMAL = 1;
|
||||||
|
const SET_BEHAVIOUR_IGNORE = 2;
|
||||||
|
const SET_BEHAVIOUR_THROW = 3;
|
||||||
|
|
||||||
|
const UNSET_BEHAVIOUR_NORMAL = 1;
|
||||||
|
const UNSET_BEHAVIOUR_IGNORE = 2;
|
||||||
|
const UNSET_BEHAVIOUR_THROW = 3;
|
||||||
|
|
||||||
|
const GET_BEHAVIOUR_NORMAL = 1;
|
||||||
|
const GET_BEHAVIOUR_EMPTY = 2;
|
||||||
|
const GET_BEHAVIOUR_THROW = 3;
|
||||||
|
|
||||||
|
public function setConstrained($key, $value);
|
||||||
|
public function getConstrained($key);
|
||||||
|
public function unsetConstrained($key);
|
||||||
|
|
||||||
|
public function createSetBehaviour($key, $behaviour, ConstrainedBehaviour $callbackClass = null);
|
||||||
|
public function createGetBehaviour($key, $behaviour, ConstrainedBehaviour $callbackClass = null);
|
||||||
|
public function createUnsetBehaviour($key, $behaviour, ConstrainedBehaviour $callbackClass = null);
|
||||||
|
|
||||||
|
|
||||||
|
public function getBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Author: Riccardo Di Dato
|
||||||
|
Creation Date: 08/gen/2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ConstrainedMemoryObject extends Constrained{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,220 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Author: Riccardo Di Dato
|
||||||
|
Creation Date: 07/gen/2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ConstrainedObject extends Constrained {
|
||||||
|
private $base;
|
||||||
|
|
||||||
|
public function __construct($base){
|
||||||
|
parent::__construct();
|
||||||
|
$this->setBase($base);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setBase($base){
|
||||||
|
$this->base = new stdClass();
|
||||||
|
foreach ($base as $key=>$value){
|
||||||
|
$this->base->$key = ConstrainedFactory::build($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBase(){
|
||||||
|
return $this->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addPathToChildException($myKey, ConstraintException $ex){
|
||||||
|
$newKey = $myKey."->".$ex->getRelatedKey();
|
||||||
|
return new ConstraintException($ex->getRelatedOperation(), $newKey, $ex->getRelatedValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setInternal($key,$value){
|
||||||
|
return $this->base->$key = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getInternal($key){
|
||||||
|
return $this->base->$key;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function unsetInternal($key){
|
||||||
|
unset($this->base->$key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __set($key,$value){
|
||||||
|
return $this->setConstrained($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __get($key){
|
||||||
|
return $this->getConstrained($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __unset($key){
|
||||||
|
return $this->unsetConstrained($key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// class ConstrainedObject {
|
||||||
|
// const SET_BEHAVIOUR_NORMAL = 1;
|
||||||
|
// const SET_BEHAVIOUR_IGNORE = 2;
|
||||||
|
// const SET_BEHAVIOUR_THROW = 100;
|
||||||
|
|
||||||
|
// const UNSET_BEHAVIOUR_NORMAL = 1;
|
||||||
|
// const UNSET_BEHAVIOUR_IGNORE = 2;
|
||||||
|
// const UNSET_BEHAVIOUR_THROW = 100;
|
||||||
|
|
||||||
|
// const GET_BEHAVIOUR_NORMAL = 1;
|
||||||
|
// const GET_BEHAVIOUR_EMPTY = 2;
|
||||||
|
// const GET_BEHAVIOUR_THROW = 100;
|
||||||
|
|
||||||
|
// private $original;
|
||||||
|
|
||||||
|
// private $constraints = array();
|
||||||
|
|
||||||
|
// public function __construct($original){
|
||||||
|
// $this->original = $original;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public function __set($key, $value){
|
||||||
|
// if ($value instanceof ArrayObject){
|
||||||
|
// $value = $value->getArrayCopy();
|
||||||
|
// }
|
||||||
|
// if (array_key_exists($key, $this->constraints)){
|
||||||
|
// $constraint = $this->constraints[$key]->set;
|
||||||
|
// switch ($constraint->behaviour){
|
||||||
|
// case self::SET_BEHAVIOUR_NORMAL:
|
||||||
|
// $this->original->$key = $value;
|
||||||
|
// break;
|
||||||
|
// case self::SET_BEHAVIOUR_THROW:
|
||||||
|
// throw new ConstraintException("Constraint violation: impossible to set field '$key'");
|
||||||
|
// break;
|
||||||
|
// case self::SET_BEHAVIOUR_IGNORE:
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// if (property_exists($constraint, "callbackClass") && !is_null($constraint->callbackClass)){
|
||||||
|
// $this->original = $constraint->callbackClass->executeSetCallback($this->original, $key, $value);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// $this->original->$key = $value;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public function __get($key){
|
||||||
|
// $rval = null;
|
||||||
|
// if (array_key_exists($key, $this->constraints)){
|
||||||
|
// $constraint = $this->constraints[$key]->get;
|
||||||
|
// switch ($constraint->behaviour){
|
||||||
|
// case self::GET_BEHAVIOUR_THROW:
|
||||||
|
// throw new ConstraintException("Constraint violation: impossible to get field '$key'");
|
||||||
|
// break;
|
||||||
|
// case self::GET_BEHAVIOUR_NORMAL:
|
||||||
|
// $rval = $this->original->$key;
|
||||||
|
// break;
|
||||||
|
// case self::GET_BEHAVIOUR_EMPTY:
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// if (property_exists($constraint, "callbackClass") && !is_null($constraint->callbackClass)){
|
||||||
|
// $rval = $constraint->callbackClass->executeGetCallback($this->original, $key);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// $rval = $this->original->$key;
|
||||||
|
// }
|
||||||
|
// if (is_array($rval)){
|
||||||
|
// $rval = new ArrayObject($rval);
|
||||||
|
// }
|
||||||
|
// return $rval;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public function __unset($key){
|
||||||
|
// if (array_key_exists($key, $this->constraints)){
|
||||||
|
// $constraint = $this->constraints[$key]->unset;
|
||||||
|
// switch ($constraint->behaviour){
|
||||||
|
// case self::UNSET_BEHAVIOUR_NORMAL:
|
||||||
|
// unset($this->original->$key);
|
||||||
|
// break;
|
||||||
|
// case self::UNSET_BEHAVIOUR_THROW:
|
||||||
|
// throw new ConstraintException("Constraint violation: impossible to unset field '$key'");
|
||||||
|
// break;
|
||||||
|
// case self::UNSET_BEHAVIOUR_IGNORE:
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// if (property_exists($constraint, "callbackClass") && !is_null($constraint->callbackClass)){
|
||||||
|
// $this->original = $constraint->callbackClass->executeUnsetCallback($this->original, $key);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// unset($this->original->$key);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public function createSetBehaviour($key, $behaviour, ConstraintObjectBehaviourCallable $callbackClass = null){
|
||||||
|
// if (!array_key_exists($key,$this->constraints)){
|
||||||
|
// $this->constraints[$key] = new stdClass();
|
||||||
|
// }
|
||||||
|
// $this->constraints[$key]->set = new stdClass();
|
||||||
|
// if ($behaviour < self::SET_BEHAVIOUR_NORMAL){
|
||||||
|
// $behaviour = self::SET_BEHAVIOUR_NORMAL;
|
||||||
|
// }
|
||||||
|
// else if ($behaviour > self::SET_BEHAVIOUR_THROW){
|
||||||
|
// $behaviour = self::SET_BEHAVIOUR_THROW;
|
||||||
|
// }
|
||||||
|
// $this->constraints[$key]->set->behaviour = $behaviour;
|
||||||
|
// $this->constraints[$key]->set->callbackClass = $callbackClass;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public function createGetBehaviour($key, $behaviour, ConstraintObjectBehaviourCallable $callbackClass = null){
|
||||||
|
// if (!array_key_exists($key,$this->constraints)){
|
||||||
|
// $this->constraints[$key] = new stdClass();
|
||||||
|
// }
|
||||||
|
// $this->constraints[$key]->get = new stdClass();
|
||||||
|
// if ($behaviour < self::GET_BEHAVIOUR_NORMAL){
|
||||||
|
// $behaviour = self::GET_BEHAVIOUR_NORMAL;
|
||||||
|
// }
|
||||||
|
// else if ($behaviour > self::GET_BEHAVIOUR_THROW){
|
||||||
|
// $behaviour = self::GET_BEHAVIOUR_THROW;
|
||||||
|
// }
|
||||||
|
// $this->constraints[$key]->get->behaviour = $behaviour;
|
||||||
|
// $this->constraints[$key]->get->callbackClass = $callbackClass;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public function createUnsetBehaviour($key, $behaviour, ConstraintObjectBehaviourCallable $callbackClass = null){
|
||||||
|
// if (!array_key_exists($key,$this->constraints)){
|
||||||
|
// $this->constraints[$key] = new stdClass();
|
||||||
|
// }
|
||||||
|
// $this->constraints[$key]->unset = new stdClass();
|
||||||
|
// if ($behaviour < self::UNSET_BEHAVIOUR_NORMAL){
|
||||||
|
// $behaviour = self::UNSET_BEHAVIOUR_NORMAL;
|
||||||
|
// }
|
||||||
|
// else if ($behaviour > self::UNSET_BEHAVIOUR_THROW){
|
||||||
|
// $behaviour = self::UNSET_BEHAVIOUR_THROW;
|
||||||
|
// }
|
||||||
|
// $this->constraints[$key]->unset->behaviour = $behaviour;
|
||||||
|
// $this->constraints[$key]->unset->callbackClass = $callbackClass;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public function get(){
|
||||||
|
// return $this->original;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// public function debugInfo(){
|
||||||
|
// $rval = array();
|
||||||
|
// foreach ($this->original as $key=>$val){
|
||||||
|
// $rval[$key] = $this->$key;
|
||||||
|
// }
|
||||||
|
// foreach ($this->constraints as $key=>$constr){
|
||||||
|
// if (property_exists($constr, "get")){
|
||||||
|
// if ($constr->get->behaviour != self::GET_BEHAVIOUR_THROW){
|
||||||
|
// $rval[$key] = $this->$key;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return $rval;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Author: Riccardo Di Dato
|
||||||
|
Creation Date: 07/gen/2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ConstraintException extends CoreException{
|
||||||
|
private $operation;
|
||||||
|
private $key;
|
||||||
|
private $value;
|
||||||
|
|
||||||
|
public function __construct($operation,$key,$value = null){
|
||||||
|
$this->operation = $operation;
|
||||||
|
$this->key = $key;
|
||||||
|
$this->value = $value;
|
||||||
|
parent::__construct("Impossible to execute operation '$operation' on attribute '$key'".(!is_null($value)?" with value '$value'":""));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRelatedOperation(){
|
||||||
|
return $this->operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRelatedKey(){
|
||||||
|
return $this->key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRelatedValue(){
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Author: Riccardo Di Dato
|
||||||
|
Creation Date: 08/gen/2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once(dirname(__FILE__)."/ConstraintException.php");
|
||||||
|
require_once(dirname(__FILE__)."/ConstrainedInterface.php");
|
||||||
|
require_once(dirname(__FILE__)."/ConstrainedFactory.php");
|
||||||
|
require_once(dirname(__FILE__)."/Constrained.php");
|
||||||
|
|
||||||
|
require_once(dirname(__FILE__)."/ConstrainedBehaviour.php");
|
||||||
|
|
||||||
|
|
||||||
|
require_once(dirname(__FILE__)."/ConstrainedObject.php");
|
||||||
|
require_once(dirname(__FILE__)."/ConstrainedArrayObject.php");
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -6,29 +6,25 @@ Creation Date: 23/dic/2015
|
|||||||
|
|
||||||
class DaoSaveableDefaultImplementation implements DaoSaveable {
|
class DaoSaveableDefaultImplementation implements DaoSaveable {
|
||||||
private $collectionName;
|
private $collectionName;
|
||||||
// private $saveableObject;
|
private $saveableObject;
|
||||||
private $constrainedObject;
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct($collectionName, $saveableObject){
|
public function __construct($collectionName, $saveableObject){
|
||||||
$this->collectionName = $collectionName;
|
$this->collectionName = $collectionName;
|
||||||
// $this->saveableObject = $saveableObject;
|
$this->updateFromSaveableObj($saveableObject);
|
||||||
$this->constrainedObject = new ConstrainedObject($saveableObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __set($attr,$value){
|
public function __set($attr,$value){
|
||||||
// $this->saveableObject->$attr = $value;
|
$this->saveableObject->$attr = $value;
|
||||||
$this->constrainedObject->$attr = $value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __get($attr){
|
public function &__get($attr){
|
||||||
// return $this->saveableObject->$attr;
|
$rval = &$this->saveableObject->$attr;
|
||||||
return $this->constrainedObject->$attr;
|
return $rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __unset($attr){
|
public function __unset($attr){
|
||||||
// unset($this->saveableObject->$attr);
|
unset($this->saveableObject->$attr);
|
||||||
unset($this->constrainedObject->$attr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,10 +32,29 @@ class DaoSaveableDefaultImplementation implements DaoSaveable {
|
|||||||
* @see DaoSaveable::getSaveableObj()
|
* @see DaoSaveable::getSaveableObj()
|
||||||
*/
|
*/
|
||||||
public function getSaveableObj(){
|
public function getSaveableObj(){
|
||||||
// return $this->saveableObject->get();
|
// return $this->saveableObject;
|
||||||
return $this->constrainedObject->get();
|
return $this->toArray($this->saveableObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function toArray($input){
|
||||||
|
$rval = $input;
|
||||||
|
if (is_object($rval) ){
|
||||||
|
if (!($rval instanceof MongoId)){
|
||||||
|
$rval = (array)$input;
|
||||||
|
}
|
||||||
|
// $rval = (array)$input;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($rval)) {
|
||||||
|
foreach ( $rval as $key=>$val){
|
||||||
|
$rval[$key] = $this->toArray($val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPdoc)
|
* (non-PHPdoc)
|
||||||
* @see DaoSaveable::getCollectionName()
|
* @see DaoSaveable::getCollectionName()
|
||||||
@@ -60,15 +75,32 @@ class DaoSaveableDefaultImplementation implements DaoSaveable {
|
|||||||
* (non-PHPdoc)
|
* (non-PHPdoc)
|
||||||
* @see DaoSaveable::updateFromSaveableObj()
|
* @see DaoSaveable::updateFromSaveableObj()
|
||||||
*/
|
*/
|
||||||
public function updateFromSaveableObj($obj){
|
public function updateFromSaveableObj($saveableObject){
|
||||||
// $this->saveableObject = $obj;
|
$this->saveableObject = $this->toObject($saveableObject);
|
||||||
$this->constrainedObject = new ConstrainedObject($saveableObject);
|
// $this->saveableObject = $saveableObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getConstrainedObject(){
|
private function toObject($input){
|
||||||
return $this->constrainedObject;
|
$rval = $input;
|
||||||
|
if (is_array($input) && sizeof(array_diff_key($input,array_keys($input)))>0 ){
|
||||||
|
$rval = (object)$input;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($rval)){
|
||||||
|
foreach ( $rval as $key=>$val){
|
||||||
|
$rval[$key] = $this->toObject($val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (is_object($rval)) {
|
||||||
|
if (!($rval instanceof MongoId)){
|
||||||
|
foreach ( $rval as $key=>$val){
|
||||||
|
$rval->$key = $this->toObject($val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -64,6 +64,7 @@ class GenericDao{
|
|||||||
|
|
||||||
$rval = array();
|
$rval = array();
|
||||||
foreach ($cursor as $element){
|
foreach ($cursor as $element){
|
||||||
|
var_dump($element);
|
||||||
$rval[] = $retClass::buildFromSaveableObj($collectionName, $element);
|
$rval[] = $retClass::buildFromSaveableObj($collectionName, $element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,11 +78,11 @@ class GenericDao{
|
|||||||
|
|
||||||
$saveObj = $model->getSaveableObj();
|
$saveObj = $model->getSaveableObj();
|
||||||
|
|
||||||
if ( !is_null($saveObj->_id) ){
|
if ( !is_null($saveObj["_id"]) ){
|
||||||
$collection->update( array("_id"=>$id), $saveObj );
|
$collection->update( array("_id"=>$saveObj["_id"] ), $saveObj );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$saveObj->_id = new MongoId();
|
$saveObj["_id"] = new MongoId();
|
||||||
$collection->insert($saveObj);
|
$collection->insert($saveObj);
|
||||||
$model->updateFromSaveableObj($saveObj);
|
$model->updateFromSaveableObj($saveObj);
|
||||||
}
|
}
|
||||||
@@ -111,6 +112,7 @@ class GenericDao{
|
|||||||
}
|
}
|
||||||
self::$defaultReturnClass = $retClass;
|
self::$defaultReturnClass = $retClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -4,29 +4,10 @@ Author: Riccardo Di Dato
|
|||||||
Creation Date: 07/gen/2016
|
Creation Date: 07/gen/2016
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class NotiziaModel extends Model implements ConstraintObjectBehaviourCallable{
|
class NotiziaModel extends Model{
|
||||||
public function __construct($saveableObject){
|
public function __construct($saveableObject){
|
||||||
parent::__construct("notizia", $saveableObject);
|
parent::__construct("notizia", $saveableObject);
|
||||||
$this->getConstrainedObject()->createSetBehaviour("numero", ConstrainedObject::SET_BEHAVIOUR_IGNORE, $this);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function executeGetCallback($constrainedOriginal, $key){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function executeSetCallback($constrainedOriginal, $key, $value){
|
|
||||||
if (strcmp("numero", $key)==0){
|
|
||||||
$constrainedOriginal->$key = $value+100;
|
|
||||||
}
|
|
||||||
return $constrainedOriginal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function executeUnsetCallback($constrainedOriginal, $key){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -8,9 +8,6 @@ Creation Date: 14/nov/2013
|
|||||||
require_once(dirname(__FILE__)."/CoreException.php");
|
require_once(dirname(__FILE__)."/CoreException.php");
|
||||||
|
|
||||||
// Constrained Objects
|
// Constrained Objects
|
||||||
require_once(dirname(__FILE__)."/ConstraintException.php");
|
|
||||||
require_once(dirname(__FILE__)."/ConstrainedObjectBehaviourCallable.php");
|
|
||||||
require_once(dirname(__FILE__)."/ConstrainedObject.php");
|
|
||||||
|
|
||||||
// My instances
|
// My instances
|
||||||
require_once(dirname(__FILE__)."/lib.instances.php");
|
require_once(dirname(__FILE__)."/lib.instances.php");
|
||||||
@@ -18,6 +15,8 @@ require_once(dirname(__FILE__)."/lib.instances.php");
|
|||||||
|
|
||||||
// Include other modules
|
// Include other modules
|
||||||
|
|
||||||
|
// require_once(dirname(__FILE__)."/constrained/lib.inclusion.php");
|
||||||
|
|
||||||
require_once(dirname(__FILE__)."/gui/lib.inclusion.php");
|
require_once(dirname(__FILE__)."/gui/lib.inclusion.php");
|
||||||
|
|
||||||
require_once(dirname(__FILE__)."/logger/lib.inclusion.php");
|
require_once(dirname(__FILE__)."/logger/lib.inclusion.php");
|
||||||
|
|||||||
+14
-4
@@ -9,12 +9,22 @@ require_once(dirname(__FILE__)."/load.php");
|
|||||||
try {
|
try {
|
||||||
// var_dump($dao->query("notizia"));
|
// var_dump($dao->query("notizia"));
|
||||||
|
|
||||||
$prova = new stdClass();
|
$models = $dao->query("notizia");
|
||||||
$prova->numero = 0;
|
$model = reset($models);
|
||||||
$model = new NotiziaModel($prova);
|
|
||||||
$model->numero = 7;
|
|
||||||
|
|
||||||
var_dump($model);
|
var_dump($model);
|
||||||
|
echo "<br><br>";
|
||||||
|
|
||||||
|
$model->immagini = array();
|
||||||
|
|
||||||
|
$model->immagini[] = "1.jpg";
|
||||||
|
$model->about->giorno = "boh";
|
||||||
|
|
||||||
|
var_dump($model);
|
||||||
|
echo "<br><br>";
|
||||||
|
|
||||||
|
$dao->save($model);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception $ex){
|
catch (Exception $ex){
|
||||||
echo $ex->getMessage();
|
echo $ex->getMessage();
|
||||||
|
|||||||
Reference in New Issue
Block a user