Kontakt - Datenschutz

Subversion

<?php
// Restrict access to specific properties with an accessor.

class Accessor implements Iterator {
    private $obj   = null;
    private $all   = [];
    private $read  = [];
    private $write = [];


    public function __construct($obj, $read = [], $write = [], $readwrite = []) {
        $this->obj = $obj;

        foreach($read as $property) {
            $this->read[$property] = true;
        }

        foreach($write as $property) {
            $this->write[$property] = true;
        }

        foreach($readwrite as $property) {
            $this->read[$property] = true;
            $this->write[$property] = true;
        }

        $this->updateAll();
    }// __construct


    private function updateAll() {
        $this->all = array_unique(array_merge(array_keys($this->read), array_keys($this->write)));
    }// updateAll


    public function __get($name) {
        if(isset($this->read[$name])) {
            return $this->obj->$name;
        } else {
            $classname = get_class($this->obj);
            throw new Exception("No read access for '$classname::$name'.");
        }
    }// __get


    public function __set($name, $value) {
        if(isset($this->write[$name])) {
            return $this->obj->$name = $value;
        } else {
            $classname = get_class($this->obj);
            throw new Exception("No write access for '$classname::$name'.");
        }
    }// __set


    public function __call($name, $arguments) {
        call_user_func_array([$this->obj, $name], $arguments);
    }// __call
    // TODO __unset, __isset, ...



    // Iterator
    public function rewind() {
        reset($this->all);
    }// rewind


    public function current() {
        $name = current($this->all);


        return isset($this->read[$name]) ? $this->__get($name) : null;
    }// current


    public function key() {
        return current($this->all);
    }// key


    public function next() {
        $name = next($this->all);

        if(false === $name) {
            return false;
        } else {
            return isset($this->read[$name]) ? $this->__get($name) : null;
        }
    }// next


    public function valid() {
        $key = key($this->all);


        return ($key !== NULL && $key !== false);
    }// valid
}// Accessor


class User {
    public $id   = 42;
    public $name = 'John';

    private $accessors = [];


    public function __construct() {
        $this->accessors['all']        = new Accessor($this, [], [], ['id', 'name']);
        $this->accessors['form']       = new Accessor($this, [], [], ['name']);
        $this->accessors['only_write'] = new Accessor($this, [], ['id', 'name'], []);
    }// __construct


    public function getAccessor($name) {
        // TODO Check error
        return $this->accessors[$name];
    }// getAccessor


    public function sayHello() {
        echo "say Hello\n";
    }// sayHello
}// User


echo "--------- form\n";
$user  = new User();
$model = $user->getAccessor('form');

echo $model->name, "\n";

try {
    echo $model->id, "\n";
} catch(Exception $e) {
    echo "Exception: {$e->getMessage()}\n";
}

foreach($model as $property => $value) {
    echo "{$property} = '{$value}'\n";
}

$model->sayHello();


echo "--------- all\n";
$all = $user->getAccessor('all');
echo $all->name, "\n";
echo $all->id, "\n";

foreach($all as $property => $value) {
    echo "{$property} = '{$value}'\n";
}

$all->sayHello();
echo "--------- only_write\n";
$onlyWrite = $user->getAccessor('only_write');


try {
    echo $onlyWrite->id, "\n";
} catch(Exception $e) {
    echo "Exception: {$e->getMessage()}\n";
}

foreach($onlyWrite as $property => $value) {
    echo "{$property} = ", is_null($value) ? 'null' : "'{$value}'", "\n";
}

$onlyWrite->sayHello();
?>