/** * * Process HTTP PUT request on collections * * collections/{collection} | Update {collection} * collections/{collection}/{feature} | Update {feature} * * @param array $segments * @param array $data */ private function PUT_collections($segments, $data) { /* * {collection} is mandatory and no modifier is allowed */ if (!isset($segments[1]) || isset($segments[3])) { RestoLogUtil::httpError(404); } $collection = new RestoCollection($segments[1], $this->context, $this->user, array('autoload' => true)); $featureIdentifier = isset($segments[2]) ? $segments[2] : null; if (isset($featureIdentifier)) { $feature = new RestoFeature($this->context, $this->user, array('featureIdentifier' => $featureIdentifier, 'collection' => $collection)); if (!$feature->isValid()) { RestoLogUtil::httpError(404); } } /* * Only owner of the collection can update it */ if (!$this->user->hasRightsTo(RestoUser::UPDATE, array('collection' => $collection))) { RestoLogUtil::httpError(403); } /* * collections/{collection} */ if (!isset($feature)) { $collection->loadFromJSON($data, true); if ($this->context->storeQuery === true) { $this->user->storeQuery($this->context->method, 'update', $collection->name, null, $this->context->query, $this->context->getUrl()); } return RestoLogUtil::success('Collection ' . $collection->name . ' updated'); } else { RestoLogUtil::httpError(501); } }
/** * Add feature to collection * * @param RestoCollection $collection * @param array $data * */ private function addFeatureToCollection($collection, $data) { $feature = $collection->addFeature($data); /* * Store query */ if ($this->context->storeQuery === true) { $this->user->storeQuery($this->context->method, 'insert', $collection->name, $feature->identifier, $this->context->query, $this->context->getUrl()); } return RestoLogUtil::success('Feature ' . $feature->identifier . ' inserted within ' . $collection->name, array('featureIdentifier' => $feature->identifier)); }
/** * Create a collection and store it within database * * @param array $object : collection description as json file */ public function create($object) { $name = isset($object['name']) ? $object['name'] : null; /* * Check that collection does not exist */ if (isset($name) && isset($this->collections[$name])) { RestoLogUtil::httpError(2003); } /* * Load collection */ $collection = new RestoCollection($name, $this->context, $this->user); $collection->loadFromJSON($object, true); /* * Store query */ if ($this->context->storeQuery === true) { $this->user->storeQuery($this->context->method, 'create', $name, null, $this->context->query, $this->context->getUrl()); } return true; }
/** * @depends testGetCollection */ public function testSearchOnCollection() { $this->initContext(); $collection = new RestoCollection('Landsat', $this->context, $this->admin, array('autoload' => true)); $this->context->query = array('q' => 'summer'); $searchResult = $collection->search(); $searchResult = $searchResult->toArray(); $errors = $searchResult['properties']['query']['analysis']['analyze']['Errors']; $features = $searchResult['features']; $this->assertEquals(0, count($errors)); $this->assertEquals(0, count($features)); /* * Test error - request not understood */ $this->context->query = array('q' => 'nawak'); $searchResult = $collection->search(); $searchResult = $searchResult->toArray(); $errors = $searchResult['properties']['query']['analysis']['analyze']['Errors']; $features = $searchResult['features']; $this->assertEquals(1, count($errors)); $this->assertEquals(0, count($features)); /* * Test year selection */ $this->context->query = array('q' => '2011'); $searchResult = $collection->search(); $searchResult = $searchResult->toArray(); $errors = $searchResult['properties']['query']['analysis']['analyze']['Errors']; $features = $searchResult['features']; $this->assertEquals(0, count($errors)); $this->assertEquals(1, count($features)); $this->assertEquals('c5dc1f32-002d-5ee9-bd4a-c690461eb734', $features[0]['id']); /* * Test empty results on year selection */ $this->context->query = array('q' => '2012'); $searchResult = $collection->search(); $searchResult = $searchResult->toArray(); $errors = $searchResult['properties']['query']['analysis']['analyze']['Errors']; $features = $searchResult['features']; $this->assertEquals(0, count($errors)); $this->assertEquals(0, count($features)); /* * Test model */ $this->context->query = array('identifier' => 'LANDSAT5_TM_XS_20110520_N2A_France-MetropoleD0005H0003'); $searchResult = $collection->search(); $searchResult = $searchResult->toArray(); $features = $searchResult['features']; $this->assertEquals(1, count($features)); $this->assertEquals('c5dc1f32-002d-5ee9-bd4a-c690461eb734', $features[0]['id']); $this->assertEquals('Landsat', $features[0]['properties']['collection']); $this->assertEquals('Example', $features[0]['properties']['license']['licenseId']); $this->assertEquals('once', $features[0]['properties']['license']['hasToBeSigned']); $this->assertEquals('LANDSAT5_TM_XS_20110520_N2A_France-MetropoleD0005H0003', $features[0]['properties']['productIdentifier']); $this->assertEquals('urn:ogc:def:EOP:CNES::Landsat:', $features[0]['properties']['parentIdentifier']); $this->assertEquals('http:///resto/collections/Landsat/c5dc1f32-002d-5ee9-bd4a-c690461eb734/wms?map=/mount/landsat/wms/map.map&file=LANDSAT5_TM_XS_20110520_N2A_France-MetropoleD0005H0003&LAYERS=landsat&FORMAT=image%2Fpng&TRANSITIONEFFECT=resize&TRANSPARENT=true&VERSION=1.1.1&SERVICE=WMS&REQUEST=GetMap&STYLES=&SRS=EPSG%3A3857&BBOX={:bbox3857:}&WIDTH=256&HEIGHT=256', $features[0]['properties']['services']['browse']['layer']['url']); $this->assertEquals('http:///resto/collections/Landsat/c5dc1f32-002d-5ee9-bd4a-c690461eb734/download', $features[0]['properties']['services']['download']['url']); $this->assertEquals('http://spirit.cnes.fr/cgi-bin/mapserv?map=/mount/landsat/wms/map.map&file=LANDSAT5_TM_XS_20110520_N2A_France-MetropoleD0005H0003&LAYERS=landsat&FORMAT=image%2Fpng&TRANSITIONEFFECT=resize&TRANSPARENT=true&VERSION=1.1.1&SERVICE=WMS&REQUEST=GetMap&STYLES=&SRS=EPSG%3A3857&BBOX={:bbox3857:}&WIDTH=256&HEIGHT=256', $features[0]['properties']['wmsInfos']); $this->assertEquals('/mount/landsat/archives/LANDSAT5_TM_XS_20110520_N2A_France-MetropoleD0005H0003.tgz', $features[0]['properties']['resourceInfos']['path']); /* * Test identifier */ $this->context->query = array('identifier' => 'XX'); $searchResult = $collection->search(); $searchResult = $searchResult->toArray(); $features = $searchResult['features']; $this->assertEquals(0, count($features)); $this->context->query = array('identifier' => 'c5dc1f32-002d-5ee9-bd4a-c690461eb734'); $searchResult = $collection->search(); $searchResult = $searchResult->toArray(); $features = $searchResult['features']; $this->assertEquals(1, count($features)); $this->assertEquals('c5dc1f32-002d-5ee9-bd4a-c690461eb734', $features[0]['id']); /* * Test startDate */ $this->context->query = array('startDate' => '2011-01-01'); $searchResult = $collection->search(); $searchResult = $searchResult->toArray(); $features = $searchResult['features']; $this->assertEquals(1, count($features)); $this->assertEquals('c5dc1f32-002d-5ee9-bd4a-c690461eb734', $features[0]['id']); $this->context->query = array('startDate' => '2014-01-01'); $searchResult = $collection->search(); $searchResult = $searchResult->toArray(); $features = $searchResult['features']; $this->assertEquals(0, count($features)); /* * Test updated */ $this->context->query = array('updated' => '2015-01-01'); $searchResult = $collection->search(); $searchResult = $searchResult->toArray(); $features = $searchResult['features']; $this->assertEquals(1, count($features)); $this->assertEquals('c5dc1f32-002d-5ee9-bd4a-c690461eb734', $features[0]['id']); $this->context->query = array('updated' => '2016-01-01'); $searchResult = $collection->search(); $searchResult = $searchResult->toArray(); $features = $searchResult['features']; $this->assertEquals(0, count($features)); }
/** * Store feature within {collection}.features table following the class model * * @param array $data : array (MUST BE GeoJSON in abstract Model) * @param RestoCollection $collection * */ public function storeFeature($data, $collection) { /* * Assume input file or stream is a JSON Feature */ if (!RestoGeometryUtil::isValidGeoJSONFeature($data)) { RestoLogUtil::httpError(500, 'Invalid feature description'); } /* * Remap properties between RESTo model and input * GeoJSON Feature file */ $properties = $this->mapInputProperties($data); /* * Add collection to $properties to initialize facet counts on collection */ $properties['collection'] = isset($properties['collection']) ? $properties['collection'] : $collection->name; /* * Compute unique identifier */ if (!isset($data['id']) || !RestoUtil::isValidUUID($data['id'])) { $featureIdentifier = $collection->toFeatureId(isset($properties['productIdentifier']) ? $properties['productIdentifier'] : md5(microtime() . rand())); } else { $featureIdentifier = $data['id']; } /* * First check if feature is already in database * (do this before getKeywords to avoid iTag process) */ if ($collection->context->dbDriver->check(RestoDatabaseDriver::FEATURE, array('featureIdentifier' => $featureIdentifier))) { RestoLogUtil::httpError(500, 'Feature ' . $featureIdentifier . ' already in database'); } /* * Tag module */ $keywords = array(); if (isset($collection->context->modules['Tag'])) { $tagger = RestoUtil::instantiate($collection->context->modules['Tag']['className'], array($collection->context, $collection->user)); $keywords = $tagger->getKeywords($properties, $data['geometry']); } /* * Store feature */ $collection->context->dbDriver->store(RestoDatabaseDriver::FEATURE, array('collection' => $collection, 'featureArray' => array('type' => 'Feature', 'id' => $featureIdentifier, 'geometry' => $data['geometry'], 'properties' => array_merge($properties, array('keywords' => $keywords))))); return new RestoFeature($collection->context, $collection->user, array('featureIdentifier' => $featureIdentifier)); }
/** * * Process collections * * collections/{collection} | Delete {collection} * collections/{collection}/{feature} | Delete {feature} * * @param array $segments */ private function DELETE_collections($segments) { /* * {collection} is mandatory and no modifier is allowed */ if (!isset($segments[1]) || isset($segments[3])) { RestoLogUtil::httpError(404); } $collection = new RestoCollection($segments[1], $this->context, $this->user, array('autoload' => true)); if (isset($segments[2])) { $feature = new RestoFeature($this->context, $this->user, array('featureIdentifier' => $segments[2], 'collection' => $collection)); if (!$feature->isValid()) { RestoLogUtil::httpError(404); } } /* * Only owner of a collection can delete it */ if (!$this->user->hasRightsTo(RestoUser::UPDATE, array('collection' => $collection))) { RestoLogUtil::httpError(403); } /** * collections/{collection} * * @SWG\Delete( * tags={"collection"}, * path="/collections/{collectionId}", * summary="Delete collection", * description="Delete collection {collectionId} if collection is not empty", * operationId="deleteCollection", * produces={"application/json"}, * @SWG\Parameter( * name="collectionId", * in="path", * description="Collection identifier", * required=true, * type="string", * @SWG\Items(type="string") * ), * @SWG\Response( * response="200", * description="Acknowledgment on successful collection deletion" * ), * @SWG\Response( * response="404", * description="Collection not found" * ), * @SWG\Response( * response="403", * description="Forbidden" * ) * ) */ if (!isset($feature)) { $collection->removeFromStore(); /* * Store query */ if ($this->context->storeQuery === true) { $this->user->storeQuery($this->context->method, 'remove', $collection->name, null, $this->context->query, $this->context->getUrl()); } return RestoLogUtil::success('Collection ' . $collection->name . ' deleted'); } else { $feature->removeFromStore(); /* * Store query */ if ($this->context->storeQuery === true) { $this->user->storeQuery($this->context->method, 'remove', $collection->name, $feature->identifier, $this->context->query, $this->context->getUrl()); } return RestoLogUtil::success('Feature ' . $feature->identifier . ' deleted', array('featureIdentifier' => $feature->identifier)); } }
public function testRemoveCollection() { $this->initContext(); $collection = new RestoCollection('Example', $this->context, $this->admin, array('autoload' => true)); $collection->removeFromStore(); $collection = new RestoCollection('Land', $this->context, $this->admin, array('autoload' => true)); $collection->removeFromStore(); }