Make an interface called IRenderer, like
interface IRenderer {
    public static function render($object, $options = array());
}

where render means rendering the object into an array. The renderer is 
called in JsonView.
Then, there could be some interesting implementation of renderer, for 
example, ArrayRenderer, ModelObjectRenderer, FlexibleRenderer (with this 
renderer, $object can be of any type). And, here's an example, which 
renders the attributes of an Object.

<?php
class ObjectAttributesRenderer implements IRenderer {
    /**
     * The ATTRIBUTES array is in key -> value format. The attributes in 
value can be,
     *     maxArrayDepth: if arrayDepth > maxArrayDepth, the attribute will 
not be rendered.
     *     needed: whether the attribute is needed, can be Closure which 
returns TRUE or FALSE.
     *     rendererName: the name of renderer to render the object.
     *     value: the value of the attribute, can be Closure.
     */

    private static function processAttributeField($fieldData, $object, 
$options = array()) {
        if ($fieldData instanceof Closure){
            return $fieldData($object, $options);
        }  else {
            return $fieldData;
        }
    }

    public static function render($object, $options = array()) {
        if (!isset(static::$ATTRIBUTES)) return array();

        $result = array();
        foreach (static::$ATTRIBUTES as $key => $value) {
            $necessary = true;
            if (isset($value["maxArrayDepth"])){
                $arrayDepth = ArrayUtil::getWithDefault($options, 
"arrayDepth", 0);
                if ($arrayDepth > $value["maxArrayDepth"]){
                    $necessary = false;
                }
            }
            if ($necessary && isset($value["needed"])){
                $necessary = self::processAttributeField($value["needed"], 
$object, $options);
            }
            if ($necessary){
                if (isset($value["value"])){
                    $result[$key] = 
self::processAttributeField($value["value"], $object, $options);
                }  else if (isset($value["rendererName"])){
                    if (isset($object->$key)) {
                        $rendererName = 
self::processAttributeField($value["rendererName"], $object->$key, 
$options);
                        $result[$key] = 
$rendererName::render($object->$key, $options);
                    }
                } else {
                    if (isset($object->$key)){
                        if ($object->$key instanceof MongoId) $result[$key] 
= (string)$object->$key;
                        else $result[$key] = $object->$key;
                    }
                }
            }
        }
        return $result;
    }
}

This solution (with renderers) is more simple and flexible.

-- 
Like Us on FaceBook https://www.facebook.com/CakePHP
Find us on Twitter http://twitter.com/CakePHP

--- 
You received this message because you are subscribed to the Google Groups 
"CakePHP" group.
To post to this group, send email to cake-php@googlegroups.com.
To unsubscribe from this group, send email to 
cake-php+unsubscr...@googlegroups.com.
Visit this group at http://groups.google.com/group/cake-php?hl=en.


Reply via email to