Вход Регистрация
Файл: framework/api/DataFormatter.php
Строк: 246
<?php
/**
 * A DataFormatter object handles transformation of data from SilverStripe model objects to a particular output
 * format, and vice versa.  This is most commonly used in developing RESTful APIs.
 *
 * @package framework
 * @subpackage formatters
 */
abstract class DataFormatter extends Object {

    
/**
     * Set priority from 0-100.
     * If multiple formatters for the same extension exist,
     * we select the one with highest priority.
     *
     * @var int
     */
    
private static $priority 50;

    
/**
     * Follow relations for the {@link DataObject} instances
     * ($has_one, $has_many, $many_many).
     * Set to "0" to disable relation output.
     *
     * @todo Support more than one nesting level
     *
     * @var int
     */
    
public $relationDepth 1;

    
/**
     * Allows overriding of the fields which are rendered for the
     * processed dataobjects. By default, this includes all
     * fields in {@link DataObject::inheritedDatabaseFields()}.
     *
     * @var array
     */
    
protected $customFields null;

    
/**
     * Allows addition of fields
     * (e.g. custom getters on a DataObject)
     *
     * @var array
     */
    
protected $customAddFields null;

    
/**
     * Allows to limit or add relations.
     * Only use in combination with {@link $relationDepth}.
     * By default, all relations will be shown.
     *
     * @var array
     */
    
protected $customRelations null;

    
/**
     * Fields which should be expicitly excluded from the export.
     * Comes in handy for field-level permissions.
     * Will overrule both {@link $customAddFields} and {@link $customFields}
     *
     * @var array
     */
    
protected $removeFields null;

    
/**
     * Specifies the mimetype in which all strings
     * returned from the convert*() methods should be used,
     * e.g. "text/xml".
     *
     * @var string
     */
    
protected $outputContentType null;

    
/**
     * Used to set totalSize properties on the output
     * of {@link convertDataObjectSet()}, shows the
     * total number of records without the "limit" and "offset"
     * GET parameters. Useful to implement pagination.
     *
     * @var int
     */
    
protected $totalSize;

    
/**
     * Get a DataFormatter object suitable for handling the given file extension.
     *
     * @param string $extension
     * @return DataFormatter
     */
    
public static function for_extension($extension) {
        
$classes ClassInfo::subclassesFor("DataFormatter");
        
array_shift($classes);
        
$sortedClasses = array();
        foreach(
$classes as $class) {
            
$sortedClasses[$class] = singleton($class)->stat('priority');
        }
        
arsort($sortedClasses);
        foreach(
$sortedClasses as $className => $priority) {
            
$formatter = new $className();
            if(
in_array($extension$formatter->supportedExtensions())) {
                return 
$formatter;
            }
        }
    }

    
/**
     * Get formatter for the first matching extension.
     *
     * @param array $extensions
     * @return DataFormatter
     */
    
public static function for_extensions($extensions) {
        foreach(
$extensions as $extension) {
            if(
$formatter self::for_extension($extension)) return $formatter;
        }

        return 
false;
    }

    
/**
     * Get a DataFormatter object suitable for handling the given mimetype.
     *
     * @param string $mimeType
     * @return DataFormatter
     */
    
public static function for_mimetype($mimeType) {
        
$classes ClassInfo::subclassesFor("DataFormatter");
        
array_shift($classes);
        
$sortedClasses = array();
        foreach(
$classes as $class) {
            
$sortedClasses[$class] = singleton($class)->stat('priority');
        }
        
arsort($sortedClasses);
        foreach(
$sortedClasses as $className => $priority) {
            
$formatter = new $className();
            if(
in_array($mimeType$formatter->supportedMimeTypes())) {
                return 
$formatter;
            }
        }
    }

    
/**
     * Get formatter for the first matching mimetype.
     * Useful for HTTP Accept headers which can contain
     * multiple comma-separated mimetypes.
     *
     * @param array $mimetypes
     * @return DataFormatter
     */
    
public static function for_mimetypes($mimetypes) {
        foreach(
$mimetypes as $mimetype) {
            if(
$formatter self::for_mimetype($mimetype)) return $formatter;
        }

        return 
false;
    }

    
/**
     * @param array $fields
     */
    
public function setCustomFields($fields) {
        
$this->customFields $fields;
    }

    
/**
     * @return array
     */
    
public function getCustomFields() {
        return 
$this->customFields;
    }

    
/**
     * @param array $fields
     */
    
public function setCustomAddFields($fields) {
        
$this->customAddFields $fields;
    }

    
/**
     * @param array $relations
     */
    
public function setCustomRelations($relations) {
        
$this->customRelations $relations;
    }

    
/**
     * @return array
     */
    
public function getCustomRelations() {
        return 
$this->customRelations;
    }

    
/**
     * @return array
     */
    
public function getCustomAddFields() {
        return 
$this->customAddFields;
    }

    
/**
     * @param array $fields
     */
    
public function setRemoveFields($fields) {
        
$this->removeFields $fields;
    }

    
/**
     * @return array
     */
    
public function getRemoveFields() {
        return 
$this->removeFields;
    }

    public function 
getOutputContentType() {
        return 
$this->outputContentType;
    }

    
/**
     * @param int $size
     */
    
public function setTotalSize($size) {
        
$this->totalSize = (int)$size;
    }

    
/**
     * @return int
     */
    
public function getTotalSize() {
        return 
$this->totalSize;
    }

    
/**
     * Returns all fields on the object which should be shown
     * in the output. Can be customised through {@link self::setCustomFields()}.
     *
     * @todo Allow for custom getters on the processed object (currently filtered through inheritedDatabaseFields)
     * @todo Field level permission checks
     *
     * @param DataObject $obj
     * @return array
     */
    
protected function getFieldsForObj($obj) {
        
$dbFields = array();

        
// if custom fields are specified, only select these
        
if(is_array($this->customFields)) {
            foreach(
$this->customFields as $fieldName) {
                
// @todo Possible security risk by making methods accessible - implement field-level security
                
if($obj->hasField($fieldName) || $obj->hasMethod("get{$fieldName}")) {
                    
$dbFields[$fieldName] = $fieldName;
                }
            }
        } else {
            
// by default, all database fields are selected
            
$dbFields $obj->inheritedDatabaseFields();
        }

        if(
is_array($this->customAddFields)) {
            foreach(
$this->customAddFields as $fieldName) {
                
// @todo Possible security risk by making methods accessible - implement field-level security
                
if($obj->hasField($fieldName) || $obj->hasMethod("get{$fieldName}")) {
                    
$dbFields[$fieldName] = $fieldName;
                }
            }
        }

        
// add default required fields
        
$dbFields array_merge($dbFields, array('ID'=>'Int'));

        if(
is_array($this->removeFields)) {
            
$dbFields array_diff_key($dbFieldsarray_combine($this->removeFields,$this->removeFields));
        }

        return 
$dbFields;
    }

    
/**
     * Return an array of the extensions that this data formatter supports
     */
    
abstract public function supportedExtensions();

    abstract public function 
supportedMimeTypes();


    
/**
     * Convert a single data object to this format.  Return a string.
     */
    
abstract public function convertDataObject(DataObjectInterface $do);

    
/**
     * Convert a data object set to this format.  Return a string.
     */
    
abstract public function convertDataObjectSet(SS_List $set);

    
/**
     * @param string $strData HTTP Payload as string
     */
    
public function convertStringToArray($strData) {
        
user_error('DataFormatter::convertStringToArray not implemented on subclass'E_USER_ERROR);
    }

}
Онлайн: 1
Реклама