/** * Run module - this function should be called by Resto.php * * @param array $segments : route segments * @param array $data : POST or PUT parameters * * @return string : result from run process in the $context->outputFormat */ public function run($segments, $data = array()) { if (!$this->context) { RestoLogUtil::httpError(500, 'Invalid Context'); } /* * Set POST data from resto */ $this->data = $data; /* * Authentication issuer is identified as the first $elements */ $issuerId = isset($segments[0]) ? RestoUtil::sanitize($segments[0]) : null; /* * Get provider */ $provider = $this->getProvider($issuerId); /* * Authenticate from input protocol */ switch ($provider['protocol']) { case 'oauth2': return $this->oauth2($issuerId, $provider); default: RestoLogUtil::httpError(400, 'Unknown sso protocol for issuer "' . $issuerId . '"'); } }
/** * Generate a unique cache fileName from input array * * @param array $arr */ private function getCacheFileName($arr) { if (!isset($arr) || !is_array($arr) || count($arr) === 0) { return null; } return RestoUtil::encrypt(serialize($arr)) . '.cache'; }
/** * Process HTTP PUT request * * @param array $segments */ public function route($segments) { /* * Input data is mandatory for PUT request */ $data = RestoUtil::readInputData($this->context->uploadDirectory); if (!is_array($data) || count($data) === 0) { RestoLogUtil::httpError(400); } switch ($segments[0]) { case 'collections': return $this->PUT_collections($segments, $data); case 'user': return $this->PUT_user($segments, $data); default: return $this->processModuleRoute($segments, $data); } }
public function test() { $this->initContext(); $this->assertEquals(false, RestoUtil::UUIDv5('toto', 'toto')); $this->assertEquals('tototototiti', RestoUtil::superImplode('toto', array('toto', 'titi', null))); $this->assertEquals('http://localhost/titi/toto/tata.format?huhu=tty.json', RestoUtil::updateUrlFormat('http://localhost/titi/toto/tata?huhu=tty.json', 'format')); $this->assertEquals('http://localhost/tata.format?huhu=tty.json', RestoUtil::updateUrlFormat('http://localhost/tata.json?huhu=tty.json', 'format')); $this->assertEquals('1977-01-01T00:00:00Z', RestoUtil::toISO8601('1977')); $this->assertEquals('1977-02-01T00:00:00Z', RestoUtil::toISO8601('1977-02')); $this->assertEquals('1977-02-10T00:00:00Z', RestoUtil::toISO8601('1977-02-10')); $this->assertEquals('1977-02-10T12:11:30Z', RestoUtil::toISO8601('1977-02-10T12:11:30Z')); $this->assertEquals(array('toto', 'titi', 'tata', 'tet', ' tifi ', 'cdd'), RestoUtil::splitString('toto"titi"tata tet" tifi "cdd')); $this->assertEquals(false, RestoUtil::isUrl(null)); $this->assertEquals(false, RestoUtil::isUrl('tokijhfomqzcdna')); $this->assertEquals(true, RestoUtil::isUrl('http://tititit.com/foiherfoh')); $this->assertEquals(null, RestoUtil::sanitize(null)); $this->assertEquals(array('tototot', 'tydsnc'), RestoUtil::sanitize(array('tototot', 'tydsnc'))); $this->assertEquals('ogfdrhefvdjsncosd', RestoUtil::sanitize('ogfdrhefvdjsncosd')); $this->assertEquals('', RestoUtil::kvpsToQueryString('ogfdrhefvdjsncosd')); $this->assertEquals('?&toto=ttiti&frfr=trtr', RestoUtil::kvpsToQueryString(array('toto' => 'ttiti', 'frfr' => 'trtr'))); $this->assertEquals('?&toto=ttiti&frfr=trtr&arr[]=titi&arr[]=toto', RestoUtil::kvpsToQueryString(array('toto' => 'ttiti', 'frfr' => 'trtr', 'arr' => array('toto', 'titi')))); $this->assertEquals(array('totot_tiiti_titi' => ''), RestoUtil::queryStringToKvps('totot tiiti titi')); }
/** * Output collections descriptions as a JSON stream * * @param boolean $pretty : true to return pretty print */ public function toJSON($pretty) { $collections = array('synthesis' => array('name' => '*', 'osDescription' => isset($this->context->osDescription[$this->context->dictionary->language]) ? $this->context->osDescription[$this->context->dictionary->language] : $this->context->osDescription['en'], 'statistics' => $this->context->dbDriver->get(RestoDatabaseDriver::STATISTICS, array('collectionName' => null, 'facetFields' => $this->model->getFacetFields()))), 'collections' => array()); foreach (array_keys($this->collections) as $key) { $collections['collections'][] = $this->collections[$key]->toArray(true); } return RestoUtil::json_format($collections, $pretty); }
/** * Send reset password link to user email adress * */ public function sendResetPasswordLink() { /* * Only existing local user can change there password */ if (!$this->context->dbDriver->check(RestoDatabaseDriver::USER, array('email' => $this->profile['email'])) || $this->context->dbDriver->get(RestoDatabaseDriver::USER_PASSWORD, array('email' => $this->profile['email'])) === str_repeat('*', 40)) { RestoLogUtil::httpError(3005); } /* * Send email with reset link */ $shared = $this->context->dbDriver->get(RestoDatabaseDriver::SHARED_LINK, array('email' => $this->profile['email'], 'resourceUrl' => $this->context->resetPasswordUrl . '/' . base64_encode($this->profile['email']), 'duration' => isset($this->context->sharedLinkDuration) ? $this->context->sharedLinkDuration : null)); $fallbackLanguage = isset($this->context->mail['resetPassword'][$this->context->dictionary->language]) ? $this->context->dictionary->language : 'en'; if (!RestoUtil::sendMail(array('to' => $this->profile['email'], 'senderName' => $this->context->mail['senderName'], 'senderEmail' => $this->context->mail['senderEmail'], 'subject' => $this->context->dictionary->translate($this->context->mail['resetPassword'][$fallbackLanguage]['subject'], $this->context->title), 'message' => $this->context->dictionary->translate($this->context->mail['resetPassword'][$fallbackLanguage]['message'], $this->context->title, $shared['resourceUrl'] . '?_tk=' . $shared['token'])))) { RestoLogUtil::httpError(3003); } return RestoLogUtil::success('Reset link sent to ' . $this->profile['email']); }
/** * Prepare SQL query for keywords- i.e. searchTerms * * !! IMPORTANT NOTE !! * * Searches are done on the array 'hashes' column * * @param RestoModel $model * @param string $filterName * @param array $requestParams * @param boolean $exclusion * @return type */ private function prepareFilterQuery_keywords($model, $filterName, $requestParams, $exclusion) { $terms = array(); $splitted = RestoUtil::splitString($requestParams[$filterName]); $filters = array('with' => array(), 'without' => array()); /* * Process each searchTerms * * Note: replace geohash: by hash: (see rocket) */ for ($i = 0, $l = count($splitted); $i < $l; $i++) { $terms = array_merge($this->processSearchTerms(str_replace('geohash:', 'hash:', $splitted[$i]), $filters, $model, $filterName, $exclusion)); } return join(' AND ', array_merge($terms, $this->mergeHashesFilters($model->getDbKey($model->searchFilters[$filterName]['key']), $filters))); }
/** * Encode input $array to JSON * * @param array $array * @throws Exception */ private function toJSON($array) { /* * JSON-P case */ $pretty = isset($this->context->query['_pretty']) ? filter_var($this->context->query['_pretty'], FILTER_VALIDATE_BOOLEAN) : false; if (isset($this->context->query['callback'])) { return $this->context->query['callback'] . '(' . json_encode($array, $pretty) . ')'; } return RestoUtil::json_format($array, $pretty); }
/** * Sanitize input parameter to avoid code injection * - remove html tags * * @param {String or Array} $strOrArray */ public static function sanitize($strOrArray) { if (!isset($strOrArray)) { return null; } if (is_array($strOrArray)) { $result = array(); foreach ($strOrArray as $key => $value) { $result[$key] = RestoUtil::sanitizeString($value); } return $result; } return RestoUtil::sanitizeString($strOrArray); }
/** * Set dictionary from input language - default is english */ private function setDictionary() { $lang = filter_input(INPUT_GET, 'lang', FILTER_SANITIZE_STRING); if (!isset($lang) || !in_array($lang, $this->languages) || !class_exists('RestoDictionary_' . $lang)) { $lang = 'en'; } $this->dictionary = RestoUtil::instantiate('RestoDictionary_' . $lang, array($this->dbDriver)); }
/** * Extend search params with gazetteer results * * @param RestoContext $context * @param RestoUser $user * @param array $params */ private function extendParamsWithGazetteer($params) { if (!isset($params['searchTerms']) && !isset($params['geo:lon']) && !isset($params['geo:geometry']) && !isset($params['geo:box'])) { if (isset($this->context->modules['GazetteerPro'])) { $gazetteer = RestoUtil::instantiate($this->context->modules['GazetteerPro']['className'], array($this->context, $this->user)); } else { if (isset($this->context->modules['Gazetteer'])) { $gazetteer = RestoUtil::instantiate($this->context->modules['Gazetteer']['className'], array($this->context, $this->user)); } } if ($gazetteer) { $location = $gazetteer->search(array('q' => $params['geo:name'], 'wkt' => true)); if (count($location['results']) > 0) { if (isset($location['results'][0]['hash'])) { $params['searchTerms'] = 'geohash:' . $location['results'][0]['hash']; } else { if (isset($location['results'][0]['geo:geometry'])) { $params['geo:geometry'] = $location['results'][0]['geo:geometry']; } else { if (isset($location['results'][0]['geo:lon'])) { $params['geo:lon'] = $location['results'][0]['geo:lon']; $params['geo:lat'] = $location['results'][0]['geo:lat']; } } } } } } return $params; }
/** * Update user profile to database * * @param array $profile * @return integer (userid) * @throws exception */ public function updateUserProfile($profile) { if (!is_array($profile) || !isset($profile['email'])) { RestoLogUtil::httpError(500, 'Cannot update user profile - invalid user identifier'); } /* * The following parameters cannot be updated : * - email * - userid * - activationcode * - registrationdate */ $values = array(); foreach (array_values(array('username', 'givenname', 'lastname', 'groups', 'country', 'organization', 'topics', 'organizationcountry', 'flags')) as $field) { if (isset($profile[$field])) { switch ($field) { case 'password': $values[] = 'password=\'' . RestoUtil::encrypt($profile['password']) . '\''; break; case 'activated': $values[] = 'activated=' . $profile['activated']; break; default: $values[] = $field . '=\'' . pg_escape_string($profile[$field]) . '\''; } } } $results = array(); if (count($values) > 0) { $results = $this->dbDriver->fetch($this->dbDriver->query('UPDATE usermanagement.users SET ' . join(',', $values) . ' WHERE email=\'' . pg_escape_string(trim(strtolower($profile['email']))) . '\' RETURNING userid')); } return count($results) === 1 ? $results[0]['userid'] : null; }
/** * * Explode query into normalized array of words * * In order : * - replace "," and ";" characters by space * - transliterate query string afterward (i.e. all words in lowercase without accent) * - split remaining query - split each terms with (" " character) * - add a space between numeric value and '%' character * * @param string $query * @return array */ private function queryToWords($query) { $rawWords = RestoUtil::splitString($this->escapeMultiwords($this->context->dbDriver->normalize($this->removePrefixes(str_replace(array(',', ';'), ' ', $query))))); $words = array(); for ($i = 0, $ii = count($rawWords); $i < $ii; $i++) { $term = trim($rawWords[$i]); if ($term === '') { continue; } $splitted = explode('%', $term); if (count($splitted) === 2 && is_numeric($splitted[0])) { $words[] = $splitted[0]; $words[] = '%'; } else { $words[] = $rawWords[$i]; } } return $words; }
/** * Proxify WMS URL depending on user rights * * @param $properties * @param $user * @param $baseUrl * @return string relative path in the form of YYYYMMdd/thumbnail_filename with YYYYMMdd is the formated startDate parameter */ private function proxifyWMSUrl($properties, $user, $baseUrl) { if (!isset($properties['wms'])) { return null; } $wmsUrl = RestoUtil::restoUrl($baseUrl, '/collections/' . $properties['collection'] . '/' . $properties['identifier'] . '/wms') . '?'; if (isset($user->token)) { $wmsUrl .= '_bearer=' . $user->token . '&'; } $wmsUrl .= substr($properties['wms'], strpos($properties['wms'], '?') + 1); /* * If the feature has a license check authentication */ if (isset($properties['license']) && $properties['license'] != null) { /* * User is not authenticated * Returns wms url only if license has a 'public' view service */ if ($user->profile['userid'] === -1) { return $properties['license']['viewService'] === 'public' ? $wmsUrl : null; } } return $wmsUrl; }
/** * Return Low Resolution WMS URL from the Full resolution URL * * !! IMPORTANT !! * * It is supposed that WMS server provides a low resolution version * of the input layers. * * The low resolution layer should be named with the following convention * * <fullResolutionName>_lowres * * Example: * * LAYERS=mylayer for full resolution implies that low resolution * layer is named LAYERS=mylayer_lowres * * @param String $wms */ private function getLowResolutionUrl($wms) { /* * Convert full resolution WMS layer to KVP */ list($url, $kvpString) = explode('?', $wms, 2); $kvps = RestoUtil::queryStringToKvps($kvpString, true); if ($kvps['LAYERS']) { $kvps['LAYERS'] = $kvps['LAYERS'] . '_lowres'; } return $url . RestoUtil::kvpsToQueryString($kvps); }
/** * Set model * * @param string $name */ private function setModel($name) { /* * Check that input file is for the current collection */ if (isset($this->model)) { if ($this->model->name !== $name) { RestoLogUtil::httpError(500, 'Property "model" and collection name differ'); } } else { $this->model = RestoUtil::instantiate($name, array($this->context, $this->user)); } }
/** * 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)); }
/** * Return year, month or day from date * * @param integer $position */ private function getYearMonthDay($position) { $word = $this->queryManager->words[$position]['word']; if (preg_match('/^\\d{4}$/i', $word)) { return array('year' => $word); } $month = $this->queryManager->dictionary->get(RestoDictionary::MONTH, $word); if (isset($month)) { return array('month' => $month); } $number = $this->queryManager->dictionary->getNumber($word); if (is_numeric($number)) { $day = intval($number); if ($day > 0 && $day < 31) { return array('day' => $day < 10 ? '0' . $day : $day); } } /* * ISO8601 date */ if (RestoUtil::isISO8601($word)) { return $this->iso8601ToDate($word); } return null; }
/** * Generate items informations * * Get an array containing two lists : * -> items : Downloadable items with url * -> errors : Not downloadable items with explanations * * @return array */ private function generateItemsInformations() { /* * Features with errors */ $errors = array(); /* * Features without errors */ $items = array(); /* * Loop over items */ foreach ($this->order['items'] as $item) { /* * Check if item get an id */ if (!isset($item['id'])) { array_push($errors, array('type' => 'Feature', 'ErrorMessage' => 'Wrong item', 'ErrorCode' => 404, 'properties' => isset($item['properties']) ? $item['properties'] : null)); continue; } /* * Create RestoFeature */ $feature = new RestoFeature($this->context, $this->user, array('featureIdentifier' => $item['id'])); /* * Check if User is fullfilling license requirements */ if (!$feature->getLicense()->isApplicableToUser($this->user)) { array_push($errors, array('type' => 'Feature', 'id' => $feature->identifier, 'ErrorMessage' => 'User does not fulfill license requirements', 'ErrorCode' => 403, 'properties' => isset($item['properties']) ? $item['properties'] : null)); continue; } /* * Check if user has to sign license */ if ($feature->getLicense()->hasToBeSignedByUser($this->user)) { array_push($errors, array('type' => 'Feature', 'id' => $feature->identifier, 'ErrorMessage' => 'User has to sign license', 'ErrorCode' => 3002, 'license' => $feature->getLicense()->toArray(), 'properties' => isset($item['properties']) ? $item['properties'] : null)); continue; } /* * Check if item is valid */ if (!isset($item['properties']) || !isset($item['properties']['services']) || !isset($item['properties']['services']['download'])) { array_push($errors, array('type' => 'Feature', 'id' => $feature->identifier, 'ErrorMessage' => 'Invalid item', 'ErrorCode' => 404, 'properties' => isset($item['properties']) ? $item['properties'] : null)); continue; } /* * Check is item is downloadable */ if (!isset($item['properties']['services']['download']['url']) || !RestoUtil::isUrl($item['properties']['services']['download']['url'])) { array_push($errors, array('type' => 'Feature', 'id' => $feature->identifier, 'ErrorMessage' => 'Item not downloadable', 'ErrorCode' => 404, 'properties' => isset($item['properties']) ? $item['properties'] : null)); continue; } /* * Check user rights */ if (!$this->user->hasRightsTo(RestoUser::DOWNLOAD, array('collectionName' => $item['properties']['collection'], 'featureIdentifier' => $feature->identifier))) { array_push($errors, array('type' => 'Feature', 'id' => $feature->identifier, 'ErrorMessage' => "User hasn't enough rights. Please contact an administrator", 'ErrorCode' => 403, 'properties' => isset($item['properties']) ? $item['properties'] : null)); continue; } /* * Update local download url with a shared link */ $exploded = explode('?', $item['properties']['services']['download']['url']); if ($exploded[0] === $this->context->baseUrl . join('/', array('/collections', $item['properties']['collection'], $feature->identifier, 'download'))) { $item['properties']['services']['download']['url'] = $this->getSharedLink($item['properties']['services']['download']['url']); } /* * Add item to downloadable items list */ array_push($items, array('type' => 'Feature', 'id' => $feature->identifier, 'properties' => isset($item['properties']) ? $item['properties'] : null)); } /* * Return array containing errors and downloadable items */ return array('errors' => $errors, 'items' => $items); }
/** * Reset user password * * @param string $email * @param string $password * @param string $url * * @return type */ private function resetUserPassword($email, $password, $url) { /* * Explod data['url'] into resourceUrl and queryString */ $pair = explode('?', $url); if (!isset($pair[1])) { RestoLogUtil::httpError(403); } /* * Only initiator of reset password can change its email */ $splittedUrl = explode('/', $pair[0]); if (strtolower(base64_decode($splittedUrl[count($splittedUrl) - 1])) !== $email) { RestoLogUtil::httpError(403); } $query = RestoUtil::queryStringToKvps($pair[1]); if (!isset($query['_tk']) || !$this->context->dbDriver->check(RestoDatabaseDriver::SHARED_LINK, array('resourceUrl' => $pair[0], 'token' => $query['_tk']))) { RestoLogUtil::httpError(403); } if ($this->context->dbDriver->get(RestoDatabaseDriver::USER_PASSWORD, array('email' => $email)) === str_repeat('*', 40)) { RestoLogUtil::httpError(3004); } if ($this->context->dbDriver->update(RestoDatabaseDriver::USER_PROFILE, array('profile' => array('email' => $email, 'password' => $password)))) { return RestoLogUtil::success('Password updated'); } else { RestoLogUtil::httpError(400); } }
/** * Return template url for format * * @param string $format * @return string */ private function getUrlTemplate($format) { /* * HTML output is based on htmlEndpoint */ $url = ($format === 'html' ? $this->context->htmlSearchUrl : RestoUtil::restoUrl($this->context->baseUrl, '/api/collections' . (isset($this->collection) ? '/' . $this->collection->name : '') . '/search', $format)) . '?' . $this->clientId; $count = 0; foreach ($this->model->searchFilters as $filterName => $filter) { if (isset($filter)) { if ($format === 'html' && (!isset($filter['htmlFilter']) || $filter['htmlFilter'] === false)) { continue; } $optional = isset($filter['minimum']) && $filter['minimum'] === 1 ? '' : '?'; $url .= ($count > 0 ? '&' : '') . $filter['osKey'] . '={' . $filterName . $optional . '}'; $count++; } } return $url; }
/** * Get keywords from iTag 'population' property * * @param array $populationProperty */ private function getPopulationKeywords($populationProperty) { return array('id' => RestoUtil::getHash('other:population'), 'name' => 'Population', 'type' => 'other', 'count' => $populationProperty['count'], 'densityPerSquareKm' => $populationProperty['densityPerSquareKm']); }
/** * Set ATOM feed links element for FeatureCollection * * @param array $properties */ private function setCollectionLinks($properties) { if (is_array($properties['links'])) { for ($i = 0, $l = count($properties['links']); $i < $l; $i++) { $this->startElement('link'); $this->writeAttributes(array('rel' => $properties['links'][$i]['rel'], 'title' => $properties['links'][$i]['title'])); if ($properties['links'][$i]['type'] === 'application/opensearchdescription+xml') { $this->writeAttributes(array('type' => $properties['links'][$i]['type'], 'href' => $properties['links'][$i]['href'])); } else { $this->writeAttributes(array('type' => RestoUtil::$contentTypes['atom'], 'href' => RestoUtil::updateUrlFormat($properties['links'][$i]['href'], 'atom'))); } $this->endElement(); // link } } }
/** * Create a shared resource and return it * * @param string $identifier * @param string $resourceUrl * @param integer $duration * @return array */ public function createSharedLink($identifier, $resourceUrl, $duration = 86400) { if (!isset($resourceUrl) || !RestoUtil::isUrl($resourceUrl)) { return null; } if (!is_int($duration)) { $duration = 86400; } $results = $this->dbDriver->fetch($this->dbDriver->query('INSERT INTO usermanagement.sharedlinks (url, token, email, validity) VALUES (\'' . pg_escape_string($resourceUrl) . '\',\'' . RestoUtil::encrypt(mt_rand() . microtime()) . '\',\'' . pg_escape_string($identifier) . '\',now() + ' . $duration . ' * \'1 second\'::interval) RETURNING token', 500, 'Cannot share link')); if (count($results) === 1) { return array('resourceUrl' => $resourceUrl, 'token' => $results[0]['token']); } return null; }
/** * Output product description as a GeoJSON Feature * * @param boolean $pretty : true to return pretty print */ public function toJSON($pretty = false) { return RestoUtil::json_format($this->toArray(true), $pretty); }
/** * Place order for user from cart - empty cart afterward * * @param string $identifier * @param array $items * * @return array * @throws exception */ private function storeOrder($identifier, $items) { /* * Do not create empty orders */ if (!isset($items) || count($items) === 0) { return -1; } try { $orderId = RestoUtil::encrypt($identifier . microtime()); $values = array('\'' . pg_escape_string($orderId) . '\'', '\'' . pg_escape_string($identifier) . '\'', '\'' . pg_escape_string(json_encode($items)) . '\'', 'now()'); $this->dbDriver->query('INSERT INTO usermanagement.orders (orderid, email, items, querytime) VALUES (' . join(',', $values) . ')'); } catch (Exception $e) { RestoLogUtil::httpError($e->getCode(), $e->getMessage()); } return $orderId; }
/** * Launch module run() function if exist otherwise returns 404 Not Found * * @param array $segments - path (i.e. a/b/c/d) exploded as an array (i.e. array('a', 'b', 'c', 'd') * @param array $data - data (POST or PUT) */ protected function processModuleRoute($segments, $data = array()) { $module = null; foreach (array_keys($this->context->modules) as $moduleName) { if (isset($this->context->modules[$moduleName]['route'])) { $moduleSegments = explode('/', $this->context->modules[$moduleName]['route']); $routeIsTheSame = true; $count = 0; for ($i = 0, $l = count($moduleSegments); $i < $l; $i++) { $count++; if (!isset($segments[$i]) || $moduleSegments[$i] !== $segments[$i]) { $routeIsTheSame = false; break; } } if ($routeIsTheSame) { $module = RestoUtil::instantiate($moduleName, array($this->context, $this->user)); for ($i = $count; $i--;) { array_shift($segments); } return $module->run($segments, $data); } } } if (!isset($module)) { RestoLogUtil::httpError(404); } }
/** * Return the cart as a JSON file * * @param boolean $pretty */ public function toJSON($pretty) { return RestoUtil::json_format($this->getItems(), $pretty); }