Changeset 57417
- Timestamp:
- 04/07/08 16:38:19 (3 months ago)
- Location:
- modules/sapphire/branches/roa/api
- Files:
-
- 4 modified
-
DataFormatter.php (modified) (2 diffs)
-
JSONDataFormatter.php (modified) (1 diff)
-
RestfulServer.php (modified) (6 diffs)
-
XMLDataFormatter.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
modules/sapphire/branches/roa/api/DataFormatter.php
r56976 r57417 62 62 */ 63 63 protected $outputContentType = null; 64 65 /** 66 * Used to set totalSize properties on the output 67 * of {@link convertDataObjectSet()}, shows the 68 * total number of records without the "limit" and "offset" 69 * GET parameters. Useful to implement pagination. 70 * 71 * @var int 72 */ 73 protected $totalSize; 64 74 65 75 /** … … 184 194 185 195 /** 196 * @param int $size 197 */ 198 public function setTotalSize($size) { 199 $this->totalSize = (int)$size; 200 } 201 202 /** 203 * @return int 204 */ 205 public function getTotalSize() { 206 return $this->totalSize; 207 } 208 209 /** 186 210 * Returns all fields on the object which should be shown 187 211 * in the output. Can be customised through {@link self::setCustomFields()}. -
modules/sapphire/branches/roa/api/JSONDataFormatter.php
r55564 r57417 91 91 if($item->canView()) $jsonParts[] = $this->convertDataObject($item); 92 92 } 93 return "[\n" . implode(",\n", $jsonParts) . "\n]"; 93 $json = "{\n"; 94 $json .= 'totalSize: '; 95 $json .= (is_numeric($this->totalSize)) ? $this->totalSize : 'null'; 96 $json .= ",\n"; 97 $json .= "items: [\n" . implode(",\n", $jsonParts) . "\n]\n"; 98 $json .= "}\n"; 99 100 return $json; 94 101 } 95 102 -
modules/sapphire/branches/roa/api/RestfulServer.php
r57048 r57417 141 141 * @return String The serialized representation of the requested object(s) - usually XML or JSON. 142 142 */ 143 protected function getHandler($className, $id, $relation ) {143 protected function getHandler($className, $id, $relationName) { 144 144 $sort = array( 145 145 'sort' => $this->request->getVar('sort'), … … 151 151 ); 152 152 153 $params = $this->request->getVars(); 154 153 155 $responseFormatter = $this->getResponseDataFormatter(); 154 156 if(!$responseFormatter) return $this->unsupportedMediaType(); 155 157 158 // $obj can be either a DataObject or a DataObjectSet, 159 // depending on the request 156 160 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()); 158 164 if(!$obj) return $this->notFound(); 165 $obj = $obj->First(); 159 166 if(!$obj->canView()) return $this->permissionFailure(); 160 167 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()); 179 173 } 180 174 181 175 } 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 183 180 // show empty serialized result when no records are present 184 181 if(!$obj) $obj = new DataObjectSet(); … … 186 183 187 184 $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 } 191 192 } 192 193 … … 203 204 * @return DataObjectSet 204 205 */ 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) { 206 207 if(singleton($className)->hasMethod('getRestfulSearchContext')) { 207 208 $searchContext = singleton($className)->{'getRestfulSearchContext'}(); … … 210 211 } 211 212 $query = $searchContext->getQuery($params, $sort, $limit, $existingQuery); 212 213 return singleton($className)->buildDataObjectSet($query->execute());214 } 215 213 214 return $query; 215 } 216 216 217 /** 217 218 * Returns a dataformatter instance based on the request … … 356 357 } 357 358 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 358 413 protected function permissionFailure() { 359 414 // return a 401 -
modules/sapphire/branches/roa/api/XMLDataFormatter.php
r55565 r57417 97 97 $className = $set->class; 98 98 99 $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<$className>\n"; 99 $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 100 $xml .= (is_numeric($this->totalSize)) ? "<$className totalSize=\"{$this->totalSize}\">\n" : "<$className>\n"; 100 101 foreach($set as $item) { 101 102 if($item->canView()) $xml .= $this->convertDataObjectWithoutHeader($item);
