Вход Регистрация
Файл: onlinepoisk.wm-scripts.ru/vendor/AR/lib/Serialization.php
Строк: 242
<?php
/**
 * @package ActiveRecord
 */
namespace ActiveRecord;
use 
XmlWriter;

/**
 * Base class for Model serializers.
 *
 * All serializers support the following options:
 *
 * <ul>
 * <li><b>only:</b> a string or array of attributes to be included.</li>
 * <li><b>exclude:</b> a string or array of attributes to be excluded.</li>
 * <li><b>methods:</b> a string or array of methods to invoke. The method's name will be used as a key for the final attributes array
 * along with the method's returned value</li>
 * <li><b>include:</b> a string or array of associated models to include in the final serialized product.</li>
 * <li><b>skip_instruct:</b> set to true to skip the <?xml ...?> declaration.</li>
 * </ul>
 *
 * Example usage:
 *
 * <code>
 * # include the attributes id and name
 * # run $model->encoded_description() and include its return value
 * # include the comments association
 * # include posts association with its own options (nested)
 * $model->to_json(array(
 *   'only' => array('id','name', 'encoded_description'),
 *   'methods' => array('encoded_description'),
 *   'include' => array('comments', 'posts' => array('only' => 'id'))
 * ));
 *
 * # exclude the password field from being included
 * $model->to_xml(array('exclude' => 'password')));
 * </code>
 *
 * @package ActiveRecord
 * @link http://www.phpactiverecord.org/guides/utilities#topic-serialization
 */
abstract class Serialization
{
    protected 
$model;
    protected 
$options;
    protected 
$attributes;

    
/**
     * Set this to true if the serializer needs to create a nested array keyed
     * on the name of the included classes such as for xml serialization.
     *
     * Setting this to true will produce the following attributes array when
     * the include option was used:
     *
     * <code>
     * $user = array('id' => 1, 'name' => 'Tito',
     *   'permissions' => array(
     *     'permission' => array(
     *       array('id' => 100, 'name' => 'admin'),
     *       array('id' => 101, 'name' => 'normal')
     *     )
     *   )
     * );
     * </code>
     *
     * Setting to false will produce this:
     *
     * <code>
     * $user = array('id' => 1, 'name' => 'Tito',
     *   'permissions' => array(
     *     array('id' => 100, 'name' => 'admin'),
     *     array('id' => 101, 'name' => 'normal')
     *   )
     * );
     * </code>
     *
     * @var boolean
     */
    
protected $includes_with_class_name_element false;

    
/**
     * Constructs a {@link Serialization} object.
     *
     * @param Model $model The model to serialize
     * @param array &$options Options for serialization
     * @return Serialization
     */
    
public function __construct(Model $model, &$options)
    {
        
$this->model $model;
        
$this->options $options;
        
$this->attributes $model->attributes();
        
$this->parse_options();
    }

    private function 
parse_options()
    {
        
$this->check_only();
        
$this->check_except();
        
$this->check_methods();
        
$this->check_include();
    }

    private function 
check_only()
    {
        if (isset(
$this->options['only']))
        {
            
$this->options_to_a('only');

            
$exclude array_diff(array_keys($this->attributes),$this->options['only']);
            
$this->attributes array_diff_key($this->attributes,array_flip($exclude));
        }
    }

    private function 
check_except()
    {
        if (isset(
$this->options['except']) && !isset($this->options['only']))
        {
            
$this->options_to_a('except');
            
$this->attributes array_diff_key($this->attributes,array_flip($this->options['except']));
        }
    }

    private function 
check_methods()
    {
        if (isset(
$this->options['methods']))
        {
            
$this->options_to_a('methods');

            foreach (
$this->options['methods'] as $method)
            {
                if (
method_exists($this->model$method))
                    
$this->attributes[$method] = $this->model->$method();
            }
        }
    }

    private function 
check_include()
    {
        if (isset(
$this->options['include']))
        {
            
$this->options_to_a('include');

            
$serializer_class get_class($this);

            foreach (
$this->options['include'] as $association => $options)
            {
                if (!
is_array($options))
                {
                    
$association $options;
                    
$options = array();
                }

                try {
                    
$assoc $this->model->$association;

                    if (!
is_array($assoc))
                    {
                        
$serialized = new $serializer_class($assoc$options);
                        
$this->attributes[$association] = $serialized->to_a();;
                    }
                    else
                    {
                        
$includes = array();

                        foreach (
$assoc as $a)
                        {
                            
$serialized = new $serializer_class($a$options);

                            if (
$this->includes_with_class_name_element)
                                
$includes[strtolower(get_class($a))][] = $serialized->to_a();
                            else
                                
$includes[] = $serialized->to_a();
                        }

                        
$this->attributes[$association] = $includes;
                    }

                } catch (
UndefinedPropertyException $e) {
                    ;
//move along
                
}
            }
        }
    }

    final protected function 
options_to_a($key)
    {
        if (!
is_array($this->options[$key]))
            
$this->options[$key] = array($this->options[$key]);
    }

    
/**
     * Returns the attributes array.
     * @return array
     */
    
final public function to_a()
    {
        
$date_format Config::instance()->get_date_format();

        foreach (
$this->attributes as &$value)
        {
            if (
$value instanceof DateTime)
                
$value $value->format($date_format);
        }
        return 
$this->attributes;
    }

    
/**
     * Returns the serialized object as a string.
     * @see to_s
     * @return string
     */
    
final public function __toString()
    {
        return 
$this->to_s();
    }

    
/**
     * Performs the serialization.
     * @return string
     */
    
abstract public function to_s();
};

/**
 * JSON serializer.
 *
 * @package ActiveRecord
 */
class JsonSerializer extends Serialization
{
    public static 
$include_root false;

    public function 
to_s()
    {
        return 
json_encode(self::$include_root ? array(strtolower(get_class($this->model)) => $this->to_a()) : $this->to_a());
    }
}

/**
 * XML serializer.
 *
 * @package ActiveRecord
 */
class XmlSerializer extends Serialization
{
    private 
$writer;

    public function 
__construct(Model $model, &$options)
    {
        
$this->includes_with_class_name_element true;
        
parent::__construct($model,$options);
    }

    public function 
to_s()
    {
        return 
$this->xml_encode();
    }

    private function 
xml_encode()
    {
        
$this->writer = new XmlWriter();
        
$this->writer->openMemory();
        
$this->writer->startDocument('1.0''UTF-8');
        
$this->writer->startElement(strtolower(denamespace(($this->model))));
        
$this->write($this->to_a());
        
$this->writer->endElement();
        
$this->writer->endDocument();
        
$xml $this->writer->outputMemory(true);

        if (@
$this->options['skip_instruct'] == true)
            
$xml preg_replace('/<?xml version.*??>/','',$xml);

        return 
$xml;
    }

    private function 
write($data$tag=null)
    {
        foreach (
$data as $attr => $value)
        {
            if (
$tag != null)
                
$attr $tag;

            if (
is_array($value) || is_object($value))
            {
                if (!
is_int(key($value)))
                {
                    
$this->writer->startElement($attr);
                    
$this->write($value);
                    
$this->writer->endElement();
                }
                else
                    
$this->write($value$attr);

                continue;
            }

            
$this->writer->writeElement($attr$value);
        }
    }
}
?>
Онлайн: 0
Реклама