Show
Ignore:
Timestamp:
04/07/08 16:38:19 (5 months ago)
Author:
ischommer
Message:

FEATURE Added getSearchQuery(), getObjectQuery(), getObjectsQuery(), getObjectRelationQuery() to RestfulServer?
FEATURE Added $totalSize to DataFormatter? to add useful output for pagination via "limit" and "offset" parameters
API CHANGE Removed RestfulServer?->search()
API CHANGE Changed output format for convertDataObjectSet() in XMLDataFormatter and JSONDataFormatter

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • modules/sapphire/branches/roa/api/RestfulServer.php

    r57048 r57417  
    141141         * @return String The serialized representation of the requested object(s) - usually XML or JSON. 
    142142         */ 
    143         protected function getHandler($className, $id, $relation) { 
     143        protected function getHandler($className, $id, $relationName) { 
    144144                $sort = array( 
    145145                        'sort' => $this->request->getVar('sort'), 
     
    151151                ); 
    152152                 
     153                $params = $this->request->getVars(); 
     154                 
    153155                $responseFormatter = $this->getResponseDataFormatter(); 
    154156                if(!$responseFormatter) return $this->unsupportedMediaType(); 
    155157                 
     158                // $obj can be either a DataObject or a DataObjectSet, 
     159                // depending on the request 
    156160                if($id) { 
    157                         $obj = DataObject::get_by_id($className, $id); 
     161                        // Format: /api/v1/<MyClass>/<ID> 
     162                        $query = $this->getObjectQuery($className, $id, $params); 
     163                        $obj = singleton($className)->buildDataObjectSet($query->execute()); 
    158164                        if(!$obj) return $this->notFound(); 
     165                        $obj = $obj->First(); 
    159166                        if(!$obj->canView()) return $this->permissionFailure(); 
    160167 
    161                         if($relation) { 
    162                                 if($relationClass = $obj->many_many($relation)) { 
    163                                         $query = $obj->getManyManyComponentsQuery($relation); 
    164                                 } elseif($relationClass = $obj->has_many($relation)) { 
    165                                         $query = $obj->getComponentsQuery($relation); 
    166                                 } elseif($relationClass = $obj->has_one($relation)) { 
    167                                         $query = null; 
    168                                 } elseif($obj->hasMethod("{$relation}Query")) { 
    169                                         // @todo HACK Switch to ComponentSet->getQuery() once we implement it (and lazy loading) 
    170                                         $query = $obj->{"{$relation}Query"}(null, $sort, null, $limit); 
    171                                         $relationClass = $obj->{"{$relation}Class"}(); 
    172                                 } else { 
    173                                         return $this->notFound(); 
    174                                 } 
    175  
    176                                 // get all results 
    177                                 $obj = $this->search($relationClass, $this->request->getVars(), $sort, $limit, $query); 
    178                                 if(!$obj) $obj = new DataObjectSet(); 
     168                        // Format: /api/v1/<MyClass>/<ID>/<Relation> 
     169                        if($relationName) { 
     170                                $query = $this->getObjectRelationQuery($obj, $params, $sort, $limit, $relationName); 
     171                                if($query === false) return $this->notFound(); 
     172                                $obj = singleton($className)->buildDataObjectSet($query->execute()); 
    179173                        }  
    180174                         
    181175                } else { 
    182                         $obj = $this->search($className, $this->request->getVars(), $sort, $limit); 
     176                        // Format: /api/v1/<MyClass> 
     177                        $query = $this->getObjectsQuery($className, $params, $sort, $limit); 
     178                        $obj = singleton($className)->buildDataObjectSet($query->execute()); 
     179 
    183180                        // show empty serialized result when no records are present 
    184181                        if(!$obj) $obj = new DataObjectSet(); 
     
    186183                 
    187184                $this->getResponse()->addHeader('Content-Type', $responseFormatter->getOutputContentType()); 
    188                  
    189                 if($obj instanceof DataObjectSet) return $responseFormatter->convertDataObjectSet($obj); 
    190                 else return $responseFormatter->convertDataObject($obj); 
     185 
     186                if($obj instanceof DataObjectSet) { 
     187                        $responseFormatter->setTotalSize($query->unlimitedRowCount()); 
     188                        return $responseFormatter->convertDataObjectSet($obj); 
     189                } else { 
     190                        return $responseFormatter->convertDataObject($obj); 
     191                } 
    191192        } 
    192193         
     
    203204         * @return DataObjectSet 
    204205         */ 
    205         protected function search($className, $params = null, $sort = null, $limit = null, $existingQuery = null) { 
     206        protected function getSearchQuery($className, $params = null, $sort = null, $limit = null, $existingQuery = null) { 
    206207                if(singleton($className)->hasMethod('getRestfulSearchContext')) { 
    207208                        $searchContext = singleton($className)->{'getRestfulSearchContext'}(); 
     
    210211                } 
    211212                $query = $searchContext->getQuery($params, $sort, $limit, $existingQuery); 
    212  
    213                 return singleton($className)->buildDataObjectSet($query->execute()); 
    214         } 
    215  
     213                 
     214                return $query; 
     215        } 
     216         
    216217        /** 
    217218         * Returns a dataformatter instance based on the request 
     
    356357        } 
    357358         
     359        /** 
     360         * Gets a single DataObject by ID, 
     361         * through a request like /api/v1/<MyClass>/<MyID> 
     362         *  
     363         * @param string $className 
     364         * @param int $id 
     365         * @param array $params 
     366         * @return SQLQuery 
     367         */ 
     368        protected function getObjectQuery($className, $id, $params) { 
     369                return singleton($className)->buildSQL( 
     370                        "ID = {$id}" 
     371                ); 
     372        } 
     373         
     374        /** 
     375         * @param DataObject $obj 
     376         * @param array $params 
     377         * @param int|array $sort 
     378         * @param int|array $limit 
     379         * @return SQLQuery 
     380         */ 
     381        protected function getObjectsQuery($className, $params, $sort, $limit) { 
     382                return $this->getSearchQuery($className, $params, $sort, $limit); 
     383        } 
     384         
     385         
     386        /** 
     387         * @param DataObject $obj 
     388         * @param array $params 
     389         * @param int|array $sort 
     390         * @param int|array $limit 
     391         * @param string $relationName 
     392         * @return SQLQuery|boolean 
     393         */ 
     394        protected function getObjectRelationQuery($obj, $params, $sort, $limit, $relationName) { 
     395                if($relationClass = $obj->many_many($relationName)) { 
     396                        $query = $obj->getManyManyComponentsQuery($relationName); 
     397                } elseif($relationClass = $obj->has_many($relationName)) { 
     398                        $query = $obj->getComponentsQuery($relationName); 
     399                } elseif($relationClass = $obj->has_one($relationName)) { 
     400                        $query = null; 
     401                } elseif($obj->hasMethod("{$relation}Query")) { 
     402                        // @todo HACK Switch to ComponentSet->getQuery() once we implement it (and lazy loading) 
     403                        $query = $obj->{"{$relation}Query"}(null, $sort, null, $limit); 
     404                        $relationClass = $obj->{"{$relation}Class"}(); 
     405                } else { 
     406                        return false; 
     407                } 
     408 
     409                // get all results 
     410                return $this->getSearchQuery($relationClass, $params, $sort, $limit); 
     411        } 
     412         
    358413        protected function permissionFailure() { 
    359414                // return a 401