fORMRequest #11

Open
wbond opened this Issue Apr 27, 2012 · 2 comments

Comments

Projects
None yet
2 participants
Owner

wbond commented Apr 27, 2012

Ticket #537 by @wbond:

Make fORMRequest to hold the populate() method, and more methods for secure filtering of populate and population of individual columns.

Comment by @benhaines:

Attached above is a draft of the fORMRequest which i use currently, its not set up to work with relationships yet tho. Hope it helps with getting started with this integrated into the core flourish library, you can either whitelist or blacklist columns to be used with populate.

Attached file:

<?php 

    class fORMRequest{

        const populate  = 'fORMRequest::populate';
        const hydrate  = 'fORMRequest::hydrate';
        const addProtectedColumns  = 'fORMRequest::addProtectedColumns';
        const addAccessibleColumns  = 'fORMRequest::addAccessibleColumns';

        static private $protected_columns = array();

        static public function extend(){
            fORM::registerActiveRecordMethod(
                '*',
                'populate',
                self::populate
            );

            fORM::registerActiveRecordMethod(
                '*',
                'hydrate',
                self::hydrate
            );
        }

        static public function hydrate($object, &$values, &$old_values, &$related_records, &$cache, $method_name, $parameters){
            $class = get_class($object);
            $new_values = $parameters[0];

            fORM::callHookCallbacks(
                $object,
                'pre::hydrate()',
                $values,
                $old_values,
                $related_records,
                $cache
            );

            if(!is_array($new_values)){
                throw fProgrammerException(
                    'The hydrate method requires an associated array to populate the values'
                );
            }

            $schema = fORMSchema::retrieve($class);
            $table  = fORM::tablize($class);
            $new_value_keys = array_keys($new_values);
            $column_info = $schema->getColumnInfo($table);
            foreach ($column_info as $column => $info) {
                if (in_array($column,$new_value_keys)) {
                    $method = 'set' . fGrammar::camelize($column, TRUE);
                    $cast_to = ($info['type'] == 'blob') ? 'binary' : NULL;
                    $object->$method($new_values[$column]);
                }
            }

            fORM::callHookCallbacks(
                $object,
                'post::hydrate()',
                $values,
                $old_values,
                $related_records,
                $cache
            );

            return $object;
        }

        static public function populate($object, &$values, &$old_values, &$related_records, &$cache, $method_name, $parameters)
        {
            $class = get_class($object);

            fORM::callHookCallbacks(
                $object,
                'pre::populate()',
                $values,
                $old_values,
                $related_records,
                $cache
            );

            $schema = fORMSchema::retrieve($class);
            $table  = fORM::tablize($class);

            $column_info = $schema->getColumnInfo($table);

            foreach ($column_info as $column => $info) {
                //Ignore protected coulmns
                if(isset(self::$protected_columns[$class]) && in_array($column,self::$protected_columns[$class])){
                    continue;
                }
                if (fRequest::check($column)) {
                    $method = 'set' . fGrammar::camelize($column, TRUE);
                    $cast_to = ($info['type'] == 'blob') ? 'binary' : NULL;
                    $object->$method(fRequest::get($column, $cast_to));
                }
            }

            fORM::callHookCallbacks(
                $object,
                'post::populate()',
                $values,
                $old_values,
                $related_records,
                $cache
            );

            return $object;
        }

        static public function addProtectedColumns($class, $columns){

            $class = fORM::getClass($class);

            settype($columns, 'array');


            if (!isset(self::$protected_columns[$class])) {
                self::$protected_columns[$class] = array();
            }

            foreach ($columns as $column) {
                if(!in_array($column,self::$protected_columns[$class])){
                    self::$protected_columns[$class][] = $column;
                }   
            }
        }

        static public function addAccessibleColumns($class, $columns){

            $class = fORM::getClass($class);

            $schema = fORMSchema::retrieve($class);
            $table  = fORM::tablize($class);
            $column_info = $schema->getColumnInfo($table);
            $column_names = array_keys($column_info);

                settype($columns, 'array');

            if (!isset(self::$protected_columns[$class])) {
                self::$protected_columns[$class] = array();
            }

            foreach ($column_names as $column) {
                if(!in_array($column,$columns) && !in_array($column,self::$protected_columns[$class])){
                    self::$protected_columns[$class][] = $column;
                }   
            }
        }
    }

Not entirely sure how and why, but I didn't post the previous comment. Will bring the issue to the attention of Github support.

Owner

wbond commented Apr 28, 2012

@benhaines Over the past couple of days myself and a few other Flourish users have been porting comments from the old Trac ticketing system to GitHub. I just put an @ in front of your username, I apologize if it was a different ben haines who posted the original comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment