function query_direct($args) { $closure = eval($this->body); $result = call_user_func_array($closure->bindTo($this->self), array_values($args)); switch ($this->result) { case 'value': !is_array($result) and !is_object($result) or backend_error('bad_query', 'PHP result is not a value'); return $result; case 'object': if (is_object($result)) { return $result; } elseif (is_array($result) and $result !== array_values($result)) { return (object) $result; } else { backend_error('bad_query', 'PHP result is not an object'); } case 'array': is_array($result) and $result === array_values($result) or backend_error('bad_query', 'PHP result is not an array'); return $result; case 'mixed': return $result; default: backend_error('bad_query', 'Unsupported PHP query result type: ' . $this->result); } }
private function result($multiarray) { if (!empty($multiarray)) { switch ($this->result) { case 'value': count(get_object_vars($multiarray[0][0])) == 1 or backend_error('bad_query', 'SQL result is not a value'); return reset($multiarray[0][0]); case 'object': return $multiarray[0][0]; case 'array': return $multiarray[0]; case 'multiarray': return $multiarray; } } else { switch ($this->result) { case 'value': return null; case 'object': return null; case 'array': return []; case 'multiarray': return []; } } backend_error('bad_query', 'Unsupported SQL query result type: ' . $this->result); }
function query_direct($args) { switch ($this->method) { case 'record': isset($args['_host']) or backend_error('bad_query', 'GeoIP _host argument missing'); if ($record = geoip_record_by_name($args['_host'])) { return (object) ['country' => ['alpha2' => $record['country_code'], 'alpha3' => $record['country_code3'], 'name' => $record['country_name']], 'region' => $record['region'], 'city' => $record['city'], 'latitude' => $record['latitude'], 'longitude' => $record['longitude']]; } else { !$this->required or backend_error('bad_input', 'Empty response from GeoIP procedure'); } break; } return null; }
function query_direct($args) { switch ($this->method) { case 'photos': isset($args['_venue_id']) or backend_error('bad_query', 'Foursquare _venue_id argument missing'); $photos = []; if ($result = json::decode(file_get_contents('https://api.foursquare.com/v2/venues/' . $args['venue_id'] . '/photos?' . $this->foursquare->get()))) { foreach ($result->response->photos->groups as $group) { if ($group->type == 'venue') { foreach ($group->items as $item) { $photo = ['url' => $item->url, 'created' => $item->createdAt, 'user' => ['id' => $item->user->id, 'firstName' => $item->user->firstName, 'lastName' => @$item->user->lastName, 'gender' => $item->user->gender, 'photo' => $item->user->photo]]; $resampled = []; foreach ($item->sizes->items as $size) { $resampled[] = ['url' => $size->url, 'width' => $size->width, 'height' => $size->height]; } $photo['resampled'] = $resampled; $photos[] = $photo; } } } } !(empty($photos) and $this->required) or backend_error('bad_input', 'Empty response from Froursquare procedure'); return (object) $photos; case 'venues': isset($args['_latitude']) or backend_error('bad_query', 'Foursquare _latitude argument missing'); isset($args['_longitude']) or backend_error('bad_query', 'Foursquare _longitude argument missing'); $venues = []; if ($result = json::decode(file_get_contents('https://api.foursquare.com/v2/venues/search?ll=' . $args['_latitude'] . ',' . $args['_longitude'] . '&' . $this->foursquare->get()))) { foreach ($result->response->groups as $group) { if ($group->type == 'nearby') { foreach ($group->items as $item) { $venue[] = ['id' => $item->id, 'name' => $item->name, 'url' => $item->canonicalUrl]; $categories = []; foreach ($item->categories as $category) { $categories[] = ['id' => $category->id, 'name' => $category->name, 'pluralName' => $category->pluralName, 'shortName' => $category->shortName, 'icon' => $category->icon]; } $venue['categories'] = $categories; $venues[] = $venue; } } } } !(empty($venues) and $this->required) or backend_error('bad_input', 'Empty response from Froursquare procedure'); return (object) $venues; } }
function get($name, $args) { $id = procedure::make_id($name, $args); isset($this->procedures[$id]) or backend_error('bad_query', "Unknown procedure: {$id}"); return $this->procedures[$id]; }
function call($get, $post) { $args = []; foreach ($this->get as $name => $param) { if (isset($param->domains) and isset($get[$name])) { if (($value = security::unwrap($get[$name], $param->domains)) !== null) { $get[$name] = $value; } else { unset($get[$name]); } } $value = isset($get[$name]) ? $get[$name] : (isset($param->default) ? $param->default : ($param->required ? backend_error('bad_input', "Missing GET parameter: {$name}") : null)); if (!is_null($value)) { $min = isset($param->min) ? $param->min : null; $max = isset($param->max) ? $param->max : null; !isset($param->type) or datatype::assert($param->type, $value, $min, $max); $args[$name] = $value; } } foreach ($this->post as $name => $param) { if (isset($param->domains) and isset($post[$name])) { if (($value = security::unwrap($post[$name], $param->domains)) !== null) { $post[$name] = $value; } else { unset($post[$name]); } } $value = isset($post[$name]) ? $post[$name] : (isset($param->default) ? $param->default : ($param->required ? backend_error('bad_input', "Missing POST parameter: {$name}") : null)); if (!is_null($value)) { $min = isset($param->min) ? $param->min : null; $max = isset($param->max) ? $param->max : null; !isset($param->type) or datatype::assert($param->type, $value, $min, $max); $args[$name] = $value; } } if ($this->access and !$this->www->parse_query($this->access, $args)) { return [false, null]; } if ($this->body) { return [true, $this->body->query_direct($args)]; } else { $procedure = $this->procedure; return [true, $this->www->{$procedure}($args)]; } }
static function register($name, $min, $max, $validator) { !isset(self::$types[$name]) or backend_error('Duplicate type: ' . $name); self::$types[$name] = ['min' => $min, 'max' => $max, 'validator' => $validator]; }
private function error($message) { $message .= ': ' . $this->get()->errorInfo()[2]; $this->pdo = null; backend_error('bad_query', $message); }
foreach ($domains as &$domain) { $domain = trim($domain); isset($this->domains[$domain]) or backend_error('bad_config', 'Unknown security domain: ' . $domain); $domain = $this->domains[$domain]; } $p['domains'] = $domains; } if (($min = $param->attribute('min')) !== null) { $p['min'] = $min; } if (($max = $param->attribute('max')) !== null) { $p['max'] = $max; } if (($default = $param->attribute('default')) !== null) { $p['default'] = $default; is_null($param->attribute('required')) or backend_error('bad_config', 'Default and required attributes should not be specified both for the same parameter: ' . $url . ' -> ' . $param['@name']); $p['required'] = false; } else { $p['required'] = $param->attribute('required') !== 'false'; } $post[$param['@name']] = (object) $p; } $require = []; foreach ($config->query('require/@src', $method) as $src) { $require[] = $src->value(); } $body = trim($method->value()); if (empty($body)) { $body = null; } $this->insert_method($url, new method($method['@type'], $get, $post, $service['accept'], $service['content-type'], $service['host'], $method->attribute('access'), $method->attribute('procedure'), $require, $body, $this));
private static function substitute($body, $args) { return replace(['/\\$(\\w+)/'], [function ($matches) use($args) { $name = $matches[1]; isset($args[$name]) or backend_error('bad_config', "Unknown Solr procedure parameter: {$name}"); return $args[$name]; }], $body); }
function call($type, $url, $host, $get = [], $post = []) { isset($this->methods[$url]) or backend_error('bad_query', 'Method not found: ' . $url . ' | ' . implode(', ', array_keys($get)) . ' | ' . implode(', ', array_keys($post))); foreach ($this->methods[$url]->find($type, $get, $post) as $method) { if ($method->host() == '*' or $method->host() == $host) { list($matched, $result) = $method->call($get, $post); if ($matched) { return $result; } } } backend_error('bad_query', 'Method not found: ' . $url . ' | ' . implode(', ', array_keys($get)) . ' | ' . implode(', ', array_keys($post))); }