Extending PHP method/property modifiers

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Extending PHP method/property modifiers

Post by VladSun »

The idea comes from viewtopic.php?f=19&t=89300 discussion.
It's an object "wrapper" class ("decorator"?).

Code: Select all

define('PROPERTY_WRITABLE', true);
define('PROPERTY_NOT_WRITABLE', false);
define('PROPERTY_READABLE', true);
define('PROPERTY_NOT_READABLE', false);
define('PROPERTY_NULLABLE', true);
define('PROPERTY_NOT_NULLABLE', false);
 
define('METHOD_EXECUTABLE', true);
define('METHOD_NOT_EXECUTABLE', false);
 
define('MODE_STRICT', true);
define('MODE_NOT_STRICT', false);
 
interface IACL
{
    function isPropertyWritable($class, $property);
    function isPropertyReadable($class, $property);
    function isPropertyNullable($class, $property);
    
    function isMethodExecutable($class, $method);
}
 
class NullObject
{
    public function __call($method, $args) 
    {
        return new NullObject();
    }
    
    public function __get($var)
    {
        return new NullObject();
    }
     
    public function __set($var, $value)
    {
    } 
     
    public function __toString()
    {
        return '';
    }
}
 
class ProtectedPropertyException extends Exception
{
    private $_objectName = null;
    private $_propertyName = null;
    
    public function __construct($message, $objectName, $propertyName) 
    {
        parent::__construct($message, 0);
        $this->_objectName = $objectName;
        $this->_propertyName = $propertyName;
    }   
 
    public function __toString() 
    {
        return ": [{$this->_objectName}::{$this->_propertyName}]: {$this->message}\n";
    }
}
 
class ProtectedMethodException extends Exception
{
    private $_objectName = null;
    private $_methodName = null;
    
    public function __construct($message, $objectName, $methodName) 
    {
        parent::__construct($message, 0);
        $this->_objectName = $objectName;
        $this->_methodName = $methodName;
    }   
 
    public function __toString() 
    {
        return ": [{$this->_objectName}::{$this->_methodName}]: {$this->message}\n";
    }
}
 
class ProtectedProperty
{
    private $_isReadable = false;
    private $_isWritable = false;
    private $_isNullable = false;
    private $_strictMode = false;
    
    private $_object = null;    
    private $_propertyName = null;
 
    public function __toString()
    {
        return $this->get()->__toString();
    }
 
    public function __construct(&$object, 
                                $propertyName, 
                                $value = null, 
                                $isReadable = PROPERTY_READABLE, 
                                $isWritable = PROPERTY_WRITABLE, 
                                $isNullable = PROPERTY_NULLABLE,
                                $strictMode = MODE_NOT_STRICT)
    {
        $this->_object =& $object;
        $this->_propertyName = $propertyName;
        
        $this->_isReadable = $isReadable;
        $this->_isWritable = $isWritable;
        $this->_isNullable = $isNullable;
        
        $this->_strictMode = $strictMode;
        
        if ($this->_isNullable !== PROPERTY_NULLABLE && $value === null)
        {
            if ($this->_strictMode == MODE_STRICT)
                throw new ProtectedPropertyException('Property is not nullable.', get_class($this->_object), $this->_propertyName);
            else
                $this->_object->{$this->_propertyName} = $value;
        }
        else
            $this->_object->{$this->_propertyName} = $value;
 
    }
 
    public function get()
    {
        if ($this->_isReadable !== PROPERTY_READABLE)
        {
            if ($this->_strictMode === MODE_STRICT)
                throw new ProtectedPropertyException('Property is not readable.', get_class($this->_object), $this->_propertyName);
            else
                return new NullObject();
        }       
    
        return $this->_object->{$this->_propertyName};      
    }
     
    public function set($object)
    {
        if ($this->_isWritable !== PROPERTY_WRITABLE)
        {
            if ($this->_strictMode === MODE_STRICT)
                throw new ProtectedPropertyException('Property is not writable.', get_class($this->_object), $this->_propertyName);
            else
                return false;
        }
 
        if ($this->_isNullable !== PROPERTY_NULLABLE && $object == null)
        {
            if ($this->_strictMode === MODE_STRICT)
                throw new ProtectedPropertyException('Property is not nullable.', get_class($this->_object), $this->_propertyName);
            else
                return false;
        }
 
        $this->_object->{$this->_propertyName} = $object;
        return true;        
    } 
    
    public function isReadable()
    {
        return $this->_isReadable === PROPERTY_READABLE;
    }
    
    public function isWritable()
    {
        return $this->_isWritable === PROPERTY_WRITABLE;
    }
 
    public function isNullable()
    {
        return $this->_isWritable === PROPERTY_NULLABLE;
    }
}
 
class ProtectedMethod
{
    private $_isExecutable = false;
    private $_strictMode = false;
    
    private $_object = null;    
    private $_methodName = null;
 
    public function __construct(&$object, 
                                $methodName, 
                                $isExecutable = METHOD_EXECUTABLE, 
                                $strictMode = MODE_NOT_STRICT)
    {
        $this->_object =& $object;
        $this->_methodName = $methodName;
        $this->_isExecutable = $isExecutable;
        $this->_strictMode = $strictMode;
    }
    
    public function execute($args)
    {
        if ($this->_isExecutable !== METHOD_EXECUTABLE)
            if ($this->_strictMode === MODE_STRICT)
                throw new ProtectedMethodException(' Method is not executable.', get_class($this->_object), $this->_methodName);
            else
                return new NullObject();
                
        $method = new ReflectionMethod(get_class($this->_object), $this->_methodName);
        return $method->invoke($this->_object, $args);
    }
    
    public function isExecutable()
    {
        return $this->_isExecutable;
    }
}
 
class ProtectedObject
{
    public $_object = null;
    private $_class = null;
    private $_strictMode = MODE_NOT_STRICT;
    
    private $_properties = Array();
    private $_methods = Array();
    
    public function __call($method, $args) 
    {
        return $this->_methods[$method]->execute($args);
    }
    
    public function __get($var)
    {
        return $this->_properties[$var]->get();
    }
     
    public function __set($var, $value)
    {
        $this->_properties[$var]->set($value);
    } 
     
    public function __construct($class_name, $ACL, $strictMode = MODE_NOT_STRICT)
    {
        $this->_class = new ReflectionClass($class_name);
        $this->_object = $this->_class->newInstance();
        $this->_strictMode = $strictMode;
 
        foreach ($this->_class->getProperties() as $property)
        {
            if ($property->isPublic())
            {
                $this->_properties[$property->getName()] = new ProtectedProperty($this->_object, $property->getName(), $property->getValue($this->_object),
                $ACL->isPropertyReadable($this->_class->getName(), $property->getName()), 
                $ACL->isPropertyWritable($this->_class->getName(), $property->getName()),
                $ACL->isPropertyNullable($this->_class->getName(), $property->getName()),
                $this->_strictMode);  
            }
        }
        
        foreach ($this->_class->getMethods() as $method)
        {
            if ($method->isPublic())
            {
                $this->_methods[$method->getName()] = new ProtectedMethod($this->_object, $method->getName(), 
                $ACL->isMethodExecutable($this->_class->getName(), $method->getName()),
                $this->_strictMode
                );
            }
        }
    }
}
 
class ProtectedObjectProvider
{
    private static $_instance = null;
    private $_strictMode = MODE_NOT_STRICT;
    private $_ACL = null;
    
    public function setACL($ACL)
    {
        if ($ACL == null)
            throw new Exception('ACL object can not be NULL.');         
 
        $this->_ACL = $ACL;
            
        $class = new ReflectionClass(get_class($this->_ACL));
        if (!$class->implementsInterface('IACL'))
        {
            $this->_ACL = null;
            throw new Exception('ACL object must implement IACL interface.');           
        }
    }
    
    public function setMode($strictMode)
    {
        $this->_strictMode = $strictMode;
    }
    
    public static function getInstance()
    {
        if(!isset(self::$instance))
        {
            $object = __CLASS__;
            self::$_instance = new $object;
        }
        return self::$_instance;
    }
    
    public function construct($class, $strictMode = null)
    {
        if (is_string($class))
            return new ProtectedObject($class, $this->_ACL, $strictMode == null ? $this->_strictMode : $strictMode);
        if (is_object($class))
            return new ProtectedObject(get_class($class), $this->_ACL, $strictMode == null ? $this->_strictMode : $strictMode);
            
        throw new Exception('Could not construct protected object from data <'.var_export($class, true).'>');
    }
}
Any comments on its design, implementation and usability are welcome :)

EDIT: Some bugs fixed
Last edited by VladSun on Sun Oct 19, 2008 6:12 pm, edited 5 times in total.
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Extending PHP method/property modifiers

Post by VladSun »

Well, the wrapper does not implement object constants and other things. It's a "known bug" which is should be considered not in the scope of current discussion :)
There are 10 types of people in this world, those who understand binary and those who don't
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Extending PHP method/property modifiers

Post by alex.barylski »

From what I understood of this disscussion last time...you were trying to implement an ACL system of sorts, using reflection for some reason or another?

I think I see now wht you wanted to use reflection. From just a quick browse of the code it seems you are using reflection and PHP's default access control modifiers to determine whether the function executes. Dude, your insane. :P

I can tell you spend a lot of time at the Linux system level tinkering. Not just becuase you always help me with my Linux woes but because you are implementing system level security at the application level. :P

Do I understand correctly, are you implementing an ACL system so fine grained, that you control whihc *functions* get executed or not?

Do you actually have a requirement for something so precise? I'm sure there are some situations, but personally I'd be worried about affecting the over all user experience with that tight of control on everything. It's hard/confusing enough managing roles and permission tables at a higher level events/controllers.

Some observations:

This method on line 170:

Code: Select all

 
public function isNullable()
{
  return $this->_isWritable === PROPERTY_NULLABLE;
}
 
Shouldn't that test isNullable?

I noticed you have a few 'references' in your code. PHP5 that isn't required all objects are passed as/by reference. If you need to copy a object by value you actually have to explicitly __clone() it.


p.s-I like your coding style. Very similar to my own. I almost sense a C/C++ background? :)

p.p.s-Some usage examples would be nice so I better understand how this code would be used rather than going over the implementation (ie: unit tests) :P

Interesting idea for sure...

Cheers,
Alex
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Extending PHP method/property modifiers

Post by VladSun »

PCSpectra wrote:From what I understood of this disscussion last time...you were trying to implement an ACL system of sorts, using reflection for some reason or another?

I think I see now wht you wanted to use reflection. From just a quick browse of the code it seems you are using reflection and PHP's default access control modifiers to determine whether the function executes. Dude, your insane. :P
I use default access control modifiers to determine if the property/method belongs to the object "API" - that is, is it public or not.
PCSpectra wrote:I can tell you spend a lot of time at the Linux system level tinkering. Not just becuase you always help me with my Linux woes but because you are implementing system level security at the application level. :P

Do I understand correctly, are you implementing an ACL system so fine grained, that you control whihc *functions* get executed or not?

Do you actually have a requirement for something so precise? I'm sure there are some situations, but personally I'd be worried about affecting the over all user experience with that tight of control on everything. It's hard/confusing enough managing roles and permission tables at a higher level events/controllers.
The solution is to use default policy for an object :)
I.e., in my ACL ony the permitions which differ from the default policy permissions are defined.
PCSpectra wrote:Some observations:

This method on line 170:

Code: Select all

 
public function isNullable()
{
  return $this->_isWritable === PROPERTY_NULLABLE;
}
 
Shouldn't that test isNullable?
Obviously :) A copy-paste issue ;)
PCSpectra wrote:I noticed you have a few 'references' in your code. PHP5 that isn't required all objects are passed as/by reference. If you need to copy a object by value you actually have to explicitly __clone() it.
PHP4 bad habbits :)
PCSpectra wrote:p.s-I like your coding style. Very similar to my own. I almost sense a C/C++ background? :)
A lot of C/C++ ;)
PCSpectra wrote:p.p.s-Some usage examples would be nice so I better understand how this code would be used rather than going over the implementation (ie: unit tests) :P
I'll do it in my next post :)
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Extending PHP method/property modifiers

Post by Christopher »

Hey Vlad. Can you post some example code or tests that show the code above working?
(#10850)
koen.h
Forum Contributor
Posts: 268
Joined: Sat May 03, 2008 8:43 am

Re: Extending PHP method/property modifiers

Post by koen.h »

I'm interested in examples too.

Am I right that with this system, the only way to get x number of objects that the user is allowed to read out of the db, is to get them one by one, then check permission and get the next one until at x?
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Extending PHP method/property modifiers

Post by Weirdan »

This approach should be quite expensive resource-wise... I'm interested to see benchmarks =)

The reason to ask is that I implemented a quite similar solution once. We were passing model objects to templates, but wanted to limit the list of methods template authors were able to use. It turned out to be very expensive to use such wrapper - rendering times increased significantly (I don't remember exact numbers, but it was like 20%-30% slowdown).
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Extending PHP method/property modifiers

Post by VladSun »

OK ... some examples:

Code: Select all

 
define('BM_PROPERTY_WRITABLE', 1);
define('BM_PROPERTY_READABLE', 2);
define('BM_PROPERTY_NULLABLE', 4);
define('BM_PROPERTY_NOT_WRITABLE', 0);
define('BM_PROPERTY_NOT_READABLE', 0);
define('BM_PROPERTY_NOT_NULLABLE', 0);
 
define('BM_METHOD_EXECUTABLE', 1);
define('BM_METHOD_NOT_EXECUTABLE', 0);
 
 
$roles = Array();
 
$roles['user'] = Array();
$roles['user']['object'] = Array();
 
$roles['user']['object']['UserProfile'] = Array();
$roles['user']['object']['UserProfile']['property'] = Array();
$roles['user']['object']['UserProfile']['property']['id'] = BM_PROPERTY_READABLE;
$roles['user']['object']['UserProfile']['property']['password'] = BM_PROPERTY_NOT_READABLE + BM_PROPERTY_NOT_WRITABLE + BM_PROPERTY_NOT_NULLABLE;
$roles['user']['object']['UserProfile']['property']['name'] = BM_PROPERTY_READABLE + BM_PROPERTY_NOT_WRITABLE + PROPERTY_NOT_NULLABLE;
$roles['user']['object']['UserProfile']['property']['address'] = BM_PROPERTY_READABLE + BM_PROPERTY_WRITABLE + BM_PROPERTY_NULLABLE;
 
$roles['user']['object']['UserProfile']['method'] = Array(); 
$roles['user']['object']['UserProfile']['method']['load'] = METHOD_EXECUTABLE; 
$roles['user']['object']['UserProfile']['method']['save'] = METHOD_NOT_EXECUTABLE; 
 
 
$roles['admin'] = Array();
$roles['admin']['object'] = Array();
 
$roles['admin']['object']['UserProfile'] = Array();
$roles['admin']['object']['UserProfile']['property'] = Array();
$roles['admin']['object']['UserProfile']['property']['id'] = BM_PROPERTY_READABLE + BM_PROPERTY_NOT_WRITABLE + BM_PROPERTY_NOT_NULLABLE;
$roles['admin']['object']['UserProfile']['property']['password'] = BM_PROPERTY_NOT_READABLE + BM_PROPERTY_WRITABLE + PROPERTY_NOT_NULLABLE;
$roles['admin']['object']['UserProfile']['property']['name'] = BM_PROPERTY_READABLE + BM_PROPERTY_WRITABLE + PROPERTY_NOT_NULLABLE;
$roles['admin']['object']['UserProfile']['property']['address'] = BM_PROPERTY_READABLE + BM_PROPERTY_WRITABLE + BM_PROPERTY_NULLABLE;
 
$roles['admin']['object']['UserProfile']['method'] = Array(); 
$roles['admin']['object']['UserProfile']['method']['load'] = METHOD_EXECUTABLE; 
$roles['admin']['object']['UserProfile']['method']['save'] = METHOD_EXECUTABLE; 
 
class ACL implements IACL
{
    private static $_instance = null;
    private $_role = '';
    
    public function setRole($roleName)
    {
        $this->_role = $roleName; 
    }
    
    public function getRole()
    {
        return $this->_role; 
    }
    
    public static function getInstance()
    {
        if(!isset(self::$_instance))
        {
            $object= __CLASS__;
            self::$_instance=new $object;
        }
        return self::$_instance;
    }
    
    public function isPropertyWritable($class, $property)
    {
        global $roles;
        return ($roles[$this->_role]['object'][$class]['property'][$property] & BM_PROPERTY_WRITABLE) > 0;
    }
 
    public function isPropertyReadable($class, $property)
    {
        global $roles;
        return ($roles[$this->_role]['object'][$class]['property'][$property] & BM_PROPERTY_READABLE) > 0;
    }
 
    public function isPropertyNullable($class, $property)
    {
        global $roles;
        return ($roles[$this->_role]['object'][$class]['property'][$property] & BM_PROPERTY_NULLABLE) > 0;
    }
 
    public function isMethodExecutable($class, $method)
    {
        if ($class === $method)
            return true;
            
        global $roles;
        return ($roles[$this->_role]['object'][$class]['method'][$method] & BM_METHOD_EXECUTABLE) > 0;
    }
}
 
class UserProfile
{
    public $id = 0;
    public $name = '';
    public $password = '';
    public $address = '';
    
    public function load($id)
    {
        $row = DB::query('
            select 
                * 
            from 
                user 
            where id='.$id
        );
        
        $this->id = $id;
        $this->name = $row['name'];
        $this->password = $row['password'];
        $this->address = $row['address'];
    }
    
    public function save()
    {
        DB::query("
            update 
                user 
            set 
                name='".$this->name."',
                password='".$this->password."',
                address='".$this->address."'
            where
                id = ".$this->id
        );
    }
}
 
$objectProvider = ProtectedObjectProvider::getInstance();
$ACL = ACL::getInstance();
 
$objectProvider->setACL($ACL);
$ACL->setRole('user');
 
$userProfile = $objectProvider->construct('UserProfile', MODE_NOT_STRICT);
//$userProfile->load(1);
 
// View?
echo "id:       ".$userProfile->id."\n";
echo "name:     ".$userProfile->name."\n";
echo "password: ".$userProfile->password."\n";
echo "address:  ".$userProfile->address."\n";
 
// Model?
$userProfile->id = 2;
$userProfile->name = 'new name';
$userProfile->password = 'new password';
$userProfile->address = 'new address';
 
var_dump($userProfile->_object);
 
echo "<hr />";
 
$ACL->setRole('admin');
 
$userProfile = $objectProvider->construct('UserProfile', MODE_NOT_STRICT);
//$userProfile->load(1);
 
// View?
echo "id:       ".$userProfile->id."\n";
echo "name:     ".$userProfile->name."\n";
echo "password: ".$userProfile->password."\n";
echo "address:  ".$userProfile->address."\n";
 
// Model?
$userProfile->id = 2;
$userProfile->name = 'new name';
$userProfile->password = 'new password';
$userProfile->address = 'new address';
 
var_dump($userProfile->_object);
 
Simple ACL system and simple actions on a simple object - UserProfile ;)

It's in "silent mode" - that's the mode I'm going to use in future projects.

The load/save methods I've defined are to show that the object itself is not aware of being "wrapped".
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Extending PHP method/property modifiers

Post by VladSun »

And some benchmarking :(

Code: Select all

define('TEST_COUNT', 10000);
 
$up->name = 'new name';
$time_start = microtime(true);
for ($i=0; $i<TEST_COUNT; $i++)
    $s = "name:     ".$up->name."\n";
$time_end = microtime(true);
$time1 = $time_end - $time_start;
echo "UserProfile read : $time1 seconds\n";
 
$userProfile->name = 'new name';
$time_start = microtime(true);
for ($i=0; $i<TEST_COUNT; $i++)
    $s = "name:     ".$userProfile->name."\n";
$time_end = microtime(true);
$time2 = $time_end - $time_start;
echo "UserProfile (protected) read : $time2 seconds\n";
 
$time_start = microtime(true);
for ($i=0; $i<TEST_COUNT; $i++)
    $up->name = 'new name';
$time_end = microtime(true);
$time3 = $time_end - $time_start;
echo "UserProfile write : $time3 seconds\n";
 
$time_start = microtime(true);
for ($i=0; $i<TEST_COUNT; $i++)
    $userProfile->name = 'new name';
$time_end = microtime(true);
$time4 = $time_end - $time_start;
echo "UserProfile (protected) write : $time4 seconds\n";
 
echo "UserProfile (protected) / UserProfile [read] : ".($time2 / $time1)."\n";
echo "UserProfile (protected) / UserProfile [write] : ".($time4 / $time3)."\n";
 
Results:
UserProfile read : 0.0058071613311768 seconds
UserProfile (protected) read : 0.036082983016968 seconds
UserProfile write : 0.00496506690979 seconds
UserProfile (protected) write : 0.047213077545166 seconds
UserProfile (protected) / UserProfile [read] : 6.2135320441762
UserProfile (protected) / UserProfile [write] : 9.5090516206483
Pretty bad :(
It's much slower ... not percent, but times slower :(
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Extending PHP method/property modifiers

Post by VladSun »

LOL:

Code: Select all

define('TEST_COUNT', 10000);
 
$time_start = microtime(true);
for ($i=0; $i<TEST_COUNT; $i++)
    $up = new UserProfile();
$time_end = microtime(true);
$time11 = $time_end - $time_start;
echo "UserProfile create : $time11 seconds\n";
 
$userProfile->name = 'new name';
$time_start = microtime(true);
for ($i=0; $i<TEST_COUNT; $i++)
    $userProfile = $objectProvider->construct('UserProfile', MODE_NOT_STRICT);
$time_end = microtime(true);
$time12 = $time_end - $time_start;
echo "UserProfile (protected) create : $time12 seconds\n";
 
echo "UserProfile (protected) / UserProfile [create] : ".($time12 / $time11)."\n";
UserProfile create : 0.020024061203003 seconds
UserProfile (protected) create : 1.8288569450378 seconds
UserProfile (protected) / UserProfile [create] : 91.332968197459
BAD!
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Extending PHP method/property modifiers

Post by VladSun »

Any comments, suggestions, ideas?
There are 10 types of people in this world, those who understand binary and those who don't
koen.h
Forum Contributor
Posts: 268
Joined: Sat May 03, 2008 8:43 am

Re: Extending PHP method/property modifiers

Post by koen.h »

While the speed seems really bad remember that this isn't a real world application you are testing. It does say you are going to lose some performance. However, I always tell myself that if I think I have a killer feature, a performance hit of about .02 seconds is allowed (on my old ubuntu machine, my new vista machine gives worse performance benchmarks actually =).

How many objects do you think need the ACL encapsulation?

Next, I still don't see how this system can get a number of items out of the database without checking access rights after each one is created.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Extending PHP method/property modifiers

Post by VladSun »

koen.h wrote:How many objects do you think need the ACL encapsulation?
All the action controllers and all of the subviews/models in the current action controller.
koen.h wrote:Next, I still don't see how this system can get a number of items out of the database without checking access rights after each one is created.
I'm not sure I understand what "items" refer to. Can you give me a pseudo-code example?
There are 10 types of people in this world, those who understand binary and those who don't
koen.h
Forum Contributor
Posts: 268
Joined: Sat May 03, 2008 8:43 am

Re: Extending PHP method/property modifiers

Post by koen.h »

VladSun wrote: All the action controllers and all of the subviews/models in the current action controller.
For a given request that's a couple of controllers (mostly 1) plus a couple of models (also not many) plus a couple of subview (not many) = a couple. Given 10 seconds for 10000 controlled objects this will give about 0.02 seconds extra load for these couple of controlled objects. I know it's not a scientific enquiry but it would encourage me to test my current framework with it.
I'm not sure I understand what "items" refer to. Can you give me a pseudo-code example?
Eg a page with the latest 10 blog posts. Do you have to get them out of the db one by one and check them, or can you do it in one query (eg SELECT * FROM posts WHERE allowed to view)?
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Extending PHP method/property modifiers

Post by VladSun »

koen.h wrote:
I'm not sure I understand what "items" refer to. Can you give me a pseudo-code example?
Eg a page with the latest 10 blog posts. Do you have to get them out of the db one by one and check them, or can you do it in one query (eg SELECT * FROM posts WHERE allowed to view)?
If I understand you right, it's still beyond the ability of the current implementation. I still can't figure out a implementation of permitions based on a value of a property of an object.

I.e. I still can't define "owner", "group" etc.

In a common situation, the query will be SELECT * FROM posts.
Then a new protected object Post is created for every row. It has a public property "text". If the ACL says: it's not readable and it's not writable then the View (again protected object) associated with object Post, propery "text" will be an instance of NullObject.
It's not very clear yet, but it would be something like this.
There are 10 types of people in this world, those who understand binary and those who don't
Post Reply