Location: PHPKode > projects > Maintainable PHP Framework > vendor/Mad/Model/Serializer/Base.php
<?php
/**
 * @category   Mad
 * @package    Mad_Model
 * @copyright  (c) 2007-2009 Maintainable Software, LLC
 * @license    http://opensource.org/licenses/bsd-license.php BSD
 */

/**
 * The base object from which all DataObjects are extended from
 *
 * @category   Mad
 * @package    Mad_Model
 * @copyright  (c) 2007-2009 Maintainable Software, LLC
 * @license    http://opensource.org/licenses/bsd-license.php BSD
 */
class Mad_Model_Serializer_Base
{
    protected $_record = null;

    protected $_options = array();

    protected $_serializableRecord = array();

    public function __construct($record, $options = array()) 
    {
        $this->_record  = $record;
        $this->_options = $options;
    }


    public function __toString()
    {
        return $this->serialize();
    }
    
    /**
     * To replicate the behavior in ActiveRecord#attributes,
     * <tt>:except</tt> takes precedence over <tt>:only</tt>.  If <tt>:only</tt> is not set
     * for a N level model but is set for the N+1 level models,
     * then because <tt>:except</tt> is set to a default value, the second
     * level model can have both <tt>:except</tt> and <tt>:only</tt> set.  So if
     * <tt>:only</tt> is set, always delete <tt>:except</tt>.
    */
    public function getSerializableAttributeNames()
    {
        $attributeNames = $this->_record->attributeNames();

        // only
        if (!empty($this->_options['only'])) {
            $this->_options['except'] = null;
            $attributeNames = array_intersect($attributeNames, (array)$this->_options['only']);

        // except
        } else {
            $this->_options['only'] = null;
            $except = isset($this->_options['except']) ? (array)$this->_options['except'] : array();
            $except = array_merge($except, (array)$this->_record->inheritanceColumn());
            $this->_options['except'] = array_unique($except);
            $attributeNames = array_diff($attributeNames, $this->_options['except']);
        }
        sort($attributeNames);
        return $attributeNames;
    }

    public function getSerializableMethodNames()
    {
        $methodAttributes = array();

        $methods = isset($this->_options['methods']) ? (array)$this->_options['methods'] : array();
        foreach ($methods as $method) {
            if (method_exists($this->_record, $method)) {
                $methodAttributes[] = $method; 
            }
        }
        sort($methodAttributes);
        return $methodAttributes;
    }

    public function getSerializablePropertyNames()
    {
        $propertyAttributes = array();

        $properties = isset($this->_options['properties']) ? (array)$this->_options['properties'] : array();
        foreach ($properties as $property) {
            $propertyAttributes[] = $property; 
        }
        sort($propertyAttributes);
        return $propertyAttributes;
    }

    public function getSerializableNames()
    {
        $names = array_merge($this->getSerializableAttributeNames(), 
                             $this->getSerializablePropertyNames(),
                             $this->getSerializableMethodNames());
        sort($names);
        return $names;
    }

    /**
     * Add associations specified via the <tt>:includes</tt> option.
     * Expects a block that takes as arguments:
     *   +association+ - name of the association
     *   +records+     - the association record(s) to be serialized
     *   +opts+        - options for the association records
     */
    public function addIncludes()
    {
        if (isset($this->_options['include'])) {
            $includeAssociations = (array)$this->_options['include'];
            unset($this->_options['include']);
        }
        if (empty($includeAssociations)) { return; }

        $baseOnlyOrExcept = array('except' => $this->_options['except'], 
                                  'only'   => $this->_options['only']);

        // associative array includes have additional options
        $includeHasOptions = !is_int(key($includeAssociations));
        $associations = $includeHasOptions ? array_keys($includeAssociations) : $includeAssociations;

        // find records for each association
        foreach ($associations as $association) {
            $assoc = $this->_record->reflectOnAssociation($association);
            $type = $assoc->getMacro();

            $method = Mad_Support_Inflector::camelize($association, 'lower');

            if ($type == 'hasMany' || $type == 'hasAndBelongsToMany') {
                $records = $this->_record->{$method}()->getCollection();

            } elseif ($type == 'hasOne' || $type == 'belongsTo') {
                $records = $this->_record->{$method}();
            }            

            if ($records === null) { continue; }

            // options
            if ($includeHasOptions) {
                $associationOptions = $includeAssociations[$association];
            } else {
                $associationOptions = $baseOnlyOrExcept;
            }

            // sub-records
            $opts = array_merge($this->_options, $associationOptions);

            $this->yieldRecords($association, $records, $opts);
        }

        $this->_options['include'] = $includeAssociations;
    }
    
    /** 
     * Use the record to build associations
     */
    public function yieldRecords($association, $records, $opts)
    {
        // multiple record association
        if (is_array($records)) {
            $serialized = array();
            foreach ($records as $record) {
                $serializer = new self($record, $opts);
                $serialized[] = $serializer->getSerializableRecord();
            }
            $this->_serializableRecord[$association] = $serialized;
                
        // single record association
        } else {
            $serializer = new self($records, $opts);
            $this->_serializableRecord[$association] = $serializer->getSerializableRecord();
        }
    }

    public function getSerializableRecord()
    {
        $this->_serializableRecord = array();
        
        foreach ($this->getSerializableAttributeNames() as $name) {
            $this->_serializableRecord[$name] = $this->_record->$name;
        }
        foreach ($this->getSerializablePropertyNames() as $name) {
            $this->_serializableRecord[$name] = $this->_record->{$name};
        }
        foreach ($this->getSerializableMethodNames() as $name) {
            $this->_serializableRecord[$name] = $this->_record->{$name}();
        }
        $this->addIncludes();

        return $this->_serializableRecord;
    }

    // overwrite to implement
    public function serialize()
    {
        return '';
    }
}
Return current item: Maintainable PHP Framework