123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741 |
- <?php
- class TripalWebService {
-
-
-
-
-
-
-
-
- public static $label = 'Base WebService';
-
- public static $description = 'This is the base class for Tripal web services as is not meant to be used on it\'s own';
-
- public static $type = 'services';
-
-
-
-
- protected $resource;
-
- protected $path;
-
- protected $params;
-
- protected $base_path;
-
- protected $documentation;
-
-
-
-
- public function __construct($base_path) {
- if (!$base_path) {
- throw new Exception('Please provide a $base_path argument when creating a new TripalWebService.');
- }
-
- $this->resource = new TripalWebServiceResource($base_path);
-
- $this->path = array();
- $this->params = array();
- $this->base_path = $base_path;
- $this->documentation = array();
- $this->addDocClass(array(
- "id" => "http://www.w3.org/ns/hydra/core#Resource",
- "term" => 'hydra:Resource',
- "title" => "Resource",
- 'subClassOf' => NULL,
- ));
- }
-
-
-
-
- public function handleRequest() {
-
-
- }
-
-
-
-
- public function setPath($path) {
- $this->path = $path;
- }
-
- public function setParams($params) {
- $this->params = $params;
- }
-
- public function getVersion($sanitize = FALSE) {
- $class = get_class($this);
- $major_version = '';
- $minor_version = '';
- if (preg_match('/v(\d+)_(\d+)$/', $class, $matches)) {
- $major_version = $matches[1];
- $minor_version = $matches[2];
- if ($sanitize) {
- return 'v' . $major_version . '_' . $minor_version;
- }
- return 'v' . $major_version . '.' . $minor_version;
- }
- return '';
- }
-
- public function getContext() {
- return $this->resource->getContext();
- }
-
- public function getResponse() {
- $class = get_called_class();
- $context_filename = $class::$type . '.' . $this->getVersion(TRUE);
- foreach ($this->path as $element) {
- $context_filename .= '.' . $element;
- }
- $context_filename .= '.json';
- $context_filename = strtolower($context_filename);
- $context_dir = 'public://tripal/ws/context';
- $context_file_path = $context_dir . '/' . $context_filename;
-
- if (!file_prepare_directory($context_dir, FILE_CREATE_DIRECTORY)) {
- throw new Exception('Could not access the tripal/ws/context directory on the server for storing web services context files.');
- }
- $context = $this->resource ? $this->resource->getContext() : array();
- $context = array(
- '@context' => $context
- );
- $cfh = fopen($context_file_path, "w");
- if (flock($cfh, LOCK_EX)) {
- fwrite($cfh, json_encode($context));
- flock($cfh, LOCK_UN);
- fclose($cfh);
- }
- else {
- throw new Exception(t('Error locking file: @file.', array('@file' => $context_file_path)));
- }
- $fid = db_select('file_managed', 'fm')
- ->fields('fm', array('fid'))
- ->condition('uri', $context_file_path)
- ->execute()
- ->fetchField();
-
- if (!$fid) {
- $context_file = new stdClass();
- $context_file->uri = $context_file_path;
- $context_file->filename = $context_filename;
- $context_file->filemime = 'application/ld+json';
- $context_file->uid = 0;
- file_save($context_file);
- }
- $type = $this->resource ? $this->resource->getType() : 'unknown';
- $json_ld = array(
- '@context' => file_create_url($context_file_path),
- '@id' => '',
- '@type' => $type,
- );
- $data = $this->getData();
- return array_merge($json_ld, $data);
- }
-
- public function getServicePath() {
- $class = get_class($this);
- $version = $this->getVersion();
- $type = $class::$type;
- return $this->base_path . '/' . $type . '/' . $version;
- }
-
- public function getData() {
- if ($this->resource) {
- return $this->resource->getData();
- }
- return array();
- }
-
- public function setResource($resource) {
-
- if (!is_a($resource, 'TripalWebServiceResource')) {
- throw new Exception("Cannot add a new resource to this web service as it is not a TripalWebServiceResource.");
- }
- $this->resource = $resource;
- }
-
- public function setError($message) {
- $this->resource = new TripalWebServiceResource($this->base_path);
- $this->resource->setID('error');
- $this->resource->addContextItem('error', 'rdfs:error');
- $this->resource->setType('error');
- $this->resource->addProperty('error', $message);
- }
-
- public function getDocumentation() {
- return $this->documentation;
- }
-
- protected function addDocClass($details = array(), $ops = array(), $props = array()) {
- $supported_class = new TripalWebServiceResource($this->getServicePath());
-
- $supported_class->addContextItem('description', 'rdfs:comment');
- $supported_class->addContextItem('subClassOf', 'hydra:subClassOf');
- $supported_class->addContextItem('description', 'rdfs:comment');
- $supported_class->addContextItem('label', 'rdfs:label');
-
- $class_id = $details['id'];
- $accession = $details['term'];
- if ($accession != $class_id) {
- $supported_class->addContextItem($accession, $class_id);
- }
- $supported_class->setID($accession);
-
- if (array_key_exists('type', $details)) {
- $supported_class->setType($details['type']);
- }
- else {
- $supported_class->setType('hydra:Class');
- }
-
- $supported_class->addProperty('hydra:title', $details['title']);
- $supported_class->addProperty('hydra:description', array_key_exists('description', $details) ? $details['description'] : NULL);
-
- if (array_key_exists('subClassOf', $details)) {
- if ($details['subClassOf']) {
- $supported_class->addProperty('subClassOf', $details['subClassOf']);
- }
- }
- else {
- $supported_class->addProperty('subClassOf', 'hydra:Resource');
- }
-
- $class_ops = array();
- foreach ($ops as $op => $op_details) {
- $class_ops[] = $this->generateDocClassOp($supported_class, $op, $op_details);
- }
- $supported_class->addContextItem('supportedOperation', 'hydra:supportedOperation');
- $supported_class->addProperty('supportedOperation', $class_ops);
-
- $class_props = array();
- foreach ($props as $prop) {
- $class_props[] = $this->generateDocClassProp($supported_class, $prop);
- }
- $supported_class->addContextItem('supportedProperty', 'hydra:supportedProperty');
- $supported_class->addProperty('supportedProperty', $class_props);
- $this->documentation[] = $supported_class;
- }
-
- private function generateDocClassProp($supported_class, $prop) {
- $supported_class->addContextItem('property', array(
- "@id" => "hydra:property",
- "@type" => "@id"
- ));
- $supported_class->addContextItem('domain', array(
- "@id" => "rdfs:domain",
- "@type" => "@id"
- ));
- $supported_class->addContextItem('range', array(
- "@id" => "rdfs:range",
- "@type" => "@id"
- ));
- $supported_class->addContextItem('readable', 'hydra:readable');
- $supported_class->addContextItem('writeable', 'hydra:writeable');
- $supported_class->addContextItem('required', 'hydra:required');
- $supported_class->addContextItem('tripal_formatters', 'tripal:tripal_formatters');
- $class_prop = array(
- 'property' => $prop['type'],
- 'hydra:title' => $prop['title'],
- 'hydra:description' => array_key_exists('description', $prop) ? $prop['description'] : NULL,
- 'required' => array_key_exists('required', $prop) ? $prop['required'] : NULL,
- 'readable' => array_key_exists('readonly', $prop) ? $prop['readonly'] : NULL,
- 'writeable' => array_key_exists('writeonly', $prop) ? $prop['writeonly'] : NULL,
- );
- if (array_key_exists('domain', $prop)) {
- $class_prop['domain'] = $prop['domain'];
- }
- if (array_key_exists('range', $prop)) {
- $class_prop['range'] = $prop['range'];
- }
- if (array_key_exists('operations', $prop)) {
- $class_prop['supportedOperation'] = array();
- foreach ($prop['operations'] as $op => $op_details) {
- $class_prop['supportedOperation'][] = $this->generateOp($supported_class, $op, $op_details);
- }
- }
- if (array_key_exists('tripal_formatters', $prop)) {
- $class_prop['tripal_formatters'] = array_keys($prop['tripal_formatters']);
- }
- return $class_prop;
- }
-
- private function generateDocClassOp($supported_class, $op, $op_details) {
- if ($op != 'GET' and $op != 'PUT' and $op != 'DELETE' and $op != 'POST') {
- throw new Exception(t('The method, @method, provided to the TripalWebService::addClass function is not an oppropriate operations.', array('@method' => $op)));
- }
- if (!array_key_exists('type', $op_details)) {
- throw new Exception(t('Please provide a type in the operations array passed to the TripalWebService::addClass() function: @details', array('@details' => print_r($op_details, TRUE))));
- }
- if (!array_key_exists('label', $op_details)) {
- throw new Exception(t('Please provide a label in the operations array passed to the TripalWebService::addClass() function: @details', array('@details' => print_r($op_details, TRUE))));
- }
- $class_op = new TripalWebServiceResource($this->base_path);
- $class_op->setID($op_details['type']);
- switch($op) {
- case 'GET':
- $class_op->setType('hydra:Operation');
- break;
- case 'POST':
- $class_op->setType('http://schema.org/AddAction');
- break;
- case 'DELETE':
- $class_op->setType('http://schema.org/DeleteAction');
- break;
- case 'PUT':
- $class_op->setType('http://schema.org/UpdateAction');
- break;
- }
- $class_op->addContextItem('method', 'hydra:method');
- $class_op->addContextItem('label', 'rdfs:label');
- $class_op->addContextItem('description', 'rdfs:comment');
- $class_op->addContextItem('expects', array(
- "@id" => "hydra:expects",
- "@type" => "@id"
- ));
- $class_op->addContextItem('returns', array(
- "@id" => "hydra:returns",
- "@type" => "@id"
- ));
- $class_op->addContextItem('statusCodes', 'hydra:statusCodes');
- $class_op->addContextItem('code', 'hydra:statusCode');
- $class_op->addProperty('method', $op);
- $class_op->addProperty('label', array_key_exists('label', $op_details) ? $op_details['label'] : 'Retrieves an instance of this resource');
- $class_op->addProperty('description', array_key_exists('description', $op_details) ? $op_details['description'] : NULL);
- $status_codes = array_key_exists('statusCodes', $op_details) ? $op_details['statusCodes'] : array();
- foreach ($status_codes as $code) {
- if (array_key_exists('code', $code) and array_key_exists('description', $code)) {
- $class_op->addProperty('statusCodes', $code);
- }
- else {
- throw new Exception(t('The status code provided to TripalWebService::addClass function is improperly formatted @code.', array('@code' => print_r($code, TRUE))));
- }
- }
- if (count($status_codes) == 0) {
- $class_op->addProperty('statusCodes', array());
- }
- $class_op->addProperty('expects', array_key_exists('expects', $op_details) ? $op_details['expects'] : NULL);
- $class_op->addProperty('returns', array_key_exists('returns', $op_details) ? $op_details['returns'] : ' "http://www.w3.org/2002/07/owl#Nothing",');
- return $class_op;
- }
-
- protected function getContextTerm($term, $sanitize = array()) {
- if (!$term) {
- $backtrace = debug_backtrace();
- throw new Exception('getContextTerm: Please provide a non NUll or non empty $term.');
- }
- if (!$term['name']) {
- throw new Exception('getContextTerm: The provided term does not have a name: ' . print_r($term, TRUE));
- }
- $key = $term['name'];
- $key_adj = $key;
- if (in_array('spacing', $sanitize)) {
- $key_adj = preg_replace('/ /', '_', $key_adj);
- }
- if (in_array('lowercase', $sanitize)) {
- $key_adj = strtolower($key_adj);
- }
- return $key_adj;
- }
-
- protected function addContextTerm($resource, $term, $sanitize = array()) {
- if (!is_a($resource, 'TripalWebServiceResource')) {
- throw new Exception('addContextTerm: Please provide a $resource of type TripalWebServiceResource.');
- }
- if (!$term) {
- $backtrace = debug_backtrace();
- throw new Exception('addContextTerm: Please provide a non NUll or non empty $term.');
- }
- if (!$term['name']) {
- throw new Exception('addContextTerm: The provided term does not have a name: ' . print_r($term, TRUE));
- }
-
- $vocab = $term['vocabulary'];
- $this->addContextVocab($resource, $vocab);
-
- $key_adj = $this->getContextTerm($term, $sanitize);
-
- $compact_iri = $vocab['short_name'] . ':' . $term['accession'];
-
-
- if (array_key_exists('full_keys', $this->params)) {
-
- }
- $iri = $term['url'];
- $resource->addContextItem($key_adj, $compact_iri);
- $resource->addContextItem($compact_iri, $iri);
- return $key_adj;
- }
-
- protected function addContextVocab($resource, $vocab) {
- if (!is_a($resource, 'TripalWebServiceResource')) {
- throw new Exception('addContextVocab: Please provide a $resource of type TripalWebServiceResource.');
- }
- $key = $vocab['short_name'];
-
-
-
-
- $iri = $vocab['sw_url'];
- $resource->addContextItem($key, $iri);
- }
-
- public function addResourceProperty($resource, $term, $value, $sanitize = array()) {
- if (!is_a($resource, 'TripalWebServiceResource')) {
- throw new Exception('addProperty: Please provide a $resource of type TripalWebServiceResource.');
- }
-
- $key = $this->addContextTerm($resource, $term, $sanitize);
-
- $resource->addProperty($key, $value);
- }
-
- public function setResourceType($resource, $term, $sanitize = array('spacing')) {
- if (!is_a($resource, 'TripalWebServiceResource')) {
- throw new Exception('addProperty: Please provide a $resource of type TripalWebServiceResource.');
- }
-
- $key = $this->addContextTerm($resource, $term, $sanitize);
-
- $resource->setType($key);
- }
- }
|