<commit_before><?php
/**
 * Copyright (c) 2012-2013 Aalto University and University of Helsinki
 * MIT License
 * see LICENSE.txt for more information
 */

/**
 * Rest controller is an extension of the controller so that must be imported.
 */
require_once 'controller/Controller.php';

/**
 * RestController is responsible for handling all the requests directed to the /rest address.
 */
class RestController extends Controller
{
  /* supported MIME types that can be used to return RDF data */
  private static $SUPPORTED_MIME_TYPES = 'application/rdf+xml text/turtle application/ld+json application/json';

  /**
   * Echos an error message when the request can't be fulfilled.
   * @param string $code
   * @param string $status
   * @param string $message
   */
  private function return_error($code, $status, $message)
  {
    header("HTTP/1.0 $code $status");
    header("Content-type: text/plain");
    echo "$code $status : $message";
    exit();
  }

  /**
   * Handles json encoding, adding the content type headers and optional callback function.
   * @param array $data the data to be returned.
   */
  private function return_json($data)
  {
    if (isset($_GET['callback'])) {
      header("Content-type: application/javascript");
      // wrap with JSONP callback
      echo $_GET['callback'] . "(" . json_encode($data) . ");";
    } else {
      // negotiate suitable format
      $negotiator = new \Negotiation\FormatNegotiator();
      $priorities = array('application/json', 'application/ld+json');
      $best = (isset($_SERVER['HTTP_ACCEPT'])) ? $negotiator->getBest($_SERVER['HTTP_ACCEPT'], $priorities) : null;
      $format = $best != null ? $best->getValue() : $priorities[0];
      header("Content-type: $format");
      header("Vary: Accept"); // inform caches that we made a choice based on Accept header
      echo json_encode($data);
    }
  }

  /**
   * Gets a Vocabulary object. If not found, aborts with a HTTP 404 error.
   * @param string $vocabId identifier string for the vocabulary eg. 'yso'.
   * @return object Vocabulary object
   */

  private function getVocabulary($vocabId)
  {
    try {
      return $this->model->getVocabulary($vocabId);
    } catch (Exception $e) {
      return $this->return_error(404, "Not Found", "Vocabulary id '$vocabId' not found.");
    }
  }

  /**
   * Parses and returns the uri parameter. Returns and error if the parameter is missing.
   */
  private function parseURI()
  {
    if (isset($_GET['uri'])) return $_GET['uri'];
    return $this->return_error(400, "Bad Request", "uri parameter missing");
  }

  /**
   * Parses and returns the limit parameter. Returns and error if the parameter is missing.
   */
  private function parseLimit()
  {
    $limit = isset($_GET['limit']) ?
             intval($_GET['limit']) : DEFAULT_TRANSITIVE_LIMIT;
    if ($limit <= 0)
      $this->return_error(400, "Bad Request", "Invalid limit parameter");

    return $limit;
  }

  /**
   * Determine the language to use, from the lang URL parameter (if set),
   * otherwise from the default language of the current vocabulary.
   * As a side effect, set this language as current language.
   * @param string $vocabId identifier string for the vocabulary eg. 'yso'.
   * @return string current language eg. 'en'.
   */
  private function getAndSetLanguage($vocabId)
  {
    $lang = isset($_GET['lang']) ?
            $_GET['lang'] :
            $this->getVocabulary($vocabId)->getDefaultLanguage();
    $this->setLanguageProperties($lang);

    return $lang;
  }

/** Global REST methods **/

  /**
   * Returns all the vocabularies available on the server in a json object.
   */
  public function vocabularies()
  {
    if (!isset($_GET['lang']))
      return $this->return_error(400, "Bad Request", "lang parameter missing");
    $lang = $_GET['lang'];
    $this->setLanguageProperties($lang);

    $vocabs = array();
    foreach ($this->model->getVocabularies() as $voc) {
      $vocabs[$voc->getId()] = $voc->getTitle();
    }
    ksort($vocabs);
    $results = array();
    foreach ($vocabs as $id => $title) {
      $results[] = array(
        'uri' => $id,
        'id' => $id,
        'title' => $title);
    }

    /* encode the results in a JSON-LD compatible array */
    $ret = array(
        '@context' => array(
            'onki' => 'http://schema.onki.fi/onki#',
            'title' => array('@id'=>'rdfs:label', '@language'=>$lang),
            'vocabularies' => 'onki:hasVocabulary',
            'id' => 'onki:vocabularyIdentifier',
            'uri' => '@id',
        ),
        'uri' => '',
        'vocabularies' => $results,
    );

    return $this->return_json($ret);
  }

  /**
   * Performs the search function calls. And wraps the result in a json-ld object.
   * @param string $vocab identifier string for the vocabulary eg. 'yso'.
   */
  public function search($vocab=null)
  {
    if(isset($_GET['query']))
      $term = $_GET['query'];
    else
      return $this->return_error(400, "Bad Request", "query parameter missing");
    if (isset($_GET['maxhits']) && (!is_numeric($_GET['maxhits']) || $_GET['maxhits'] <= 0)) {
      return $this->return_error(400, "Bad Request", "maxhits parameter is invalid");
    }
    if (isset($_GET['offset']) && (!is_numeric($_GET['offset']) || $_GET['offset'] < 0)) {
      return $this->return_error(400, "Bad Request", "offset parameter is invalid");
    }

    $vocid = isset($_GET['vocab']) ? $_GET['vocab'] : $vocab; # optional
    $lang = isset($_GET['lang']) ? $_GET['lang'] : null; # optional
    $labellang = isset($_GET['labellang']) ? $_GET['labellang'] : null; # optional
    $type = isset($_GET['type']) ? $_GET['type'] : 'skos:Concept';
    $parent = isset($_GET['parent']) ? $_GET['parent'] : null;
    $group = isset($_GET['group']) ? $_GET['group'] : null;
    $fields = isset($_GET['fields']) ? explode(' ', $_GET['fields']) : null;

    // convert to vocids array to support multi-vocabulary search
    $vocids = !empty($vocid) ? explode(' ', $vocid) : null;

    $maxhits = isset($_GET['maxhits']) ? ($_GET['maxhits']) : null; # optional
    $offset = isset($_GET['offset']) ? ($_GET['offset']) : 0; # optional
    $results = $this->model->searchConcepts($term, $vocids, $labellang, $lang, $type, $parent, $group, $offset, $maxhits, true, $fields);
    // before serializing to JSON, get rid of the Vocabulary object that came with each resource
    foreach ($results as &$res) {
      unset($res['voc']);
    }

    $ret = array(
        '@context' => array(
            'skos' => 'http://www.w3.org/2004/02/skos/core#',
            'onki' => 'http://schema.onki.fi/onki#',
            'uri' => '@id',
            'type' => '@type',
            'results' => array(
                '@id' => 'onki:results',
                '@container' => '@list',
            ),
            'prefLabel' => 'skos:prefLabel',
            'altLabel' => 'skos:altLabel',
            'hiddenLabel' => 'skos:hiddenLabel',
            'broader' => 'skos:broader',
        ),
        'uri' => '',
        'results' => $results,
    );

    if ($lang)
      $ret['@context']['@language'] = $lang;

    return $this->return_json($ret);
  }

/** Vocabulary-specific methods **/

  /**
   * Loads the vocabulary metadata. And wraps the result in a json-ld object.
   * @param string $vocabId identifier string for the vocabulary eg. 'yso'.
   */
  public function vocabularyInformation($vocabId)
  {
    $lang = $this->getAndSetLanguage($vocabId);
    $vocab = $this->getVocabulary($vocabId);

    /* encode the results in a JSON-LD compatible array */<commit_msg>use correct JSON-LD label language in REST search method. Fixes #102<commit_after><?php
/**
 * Copyright (c) 2012-2013 Aalto University and University of Helsinki
 * MIT License
 * see LICENSE.txt for more information
 */

/**
 * Rest controller is an extension of the controller so that must be imported.
 */
require_once 'controller/Controller.php';

/**
 * RestController is responsible for handling all the requests directed to the /rest address.
 */
class RestController extends Controller
{
  /* supported MIME types that can be used to return RDF data */
  private static $SUPPORTED_MIME_TYPES = 'application/rdf+xml text/turtle application/ld+json application/json';

  /**
   * Echos an error message when the request can't be fulfilled.
   * @param string $code
   * @param string $status
   * @param string $message
   */
  private function return_error($code, $status, $message)
  {
    header("HTTP/1.0 $code $status");
    header("Content-type: text/plain");
    echo "$code $status : $message";
    exit();
  }

  /**
   * Handles json encoding, adding the content type headers and optional callback function.
   * @param array $data the data to be returned.
   */
  private function return_json($data)
  {
    if (isset($_GET['callback'])) {
      header("Content-type: application/javascript");
      // wrap with JSONP callback
      echo $_GET['callback'] . "(" . json_encode($data) . ");";
    } else {
      // negotiate suitable format
      $negotiator = new \Negotiation\FormatNegotiator();
      $priorities = array('application/json', 'application/ld+json');
      $best = (isset($_SERVER['HTTP_ACCEPT'])) ? $negotiator->getBest($_SERVER['HTTP_ACCEPT'], $priorities) : null;
      $format = $best != null ? $best->getValue() : $priorities[0];
      header("Content-type: $format");
      header("Vary: Accept"); // inform caches that we made a choice based on Accept header
      echo json_encode($data);
    }
  }

  /**
   * Gets a Vocabulary object. If not found, aborts with a HTTP 404 error.
   * @param string $vocabId identifier string for the vocabulary eg. 'yso'.
   * @return object Vocabulary object
   */

  private function getVocabulary($vocabId)
  {
    try {
      return $this->model->getVocabulary($vocabId);
    } catch (Exception $e) {
      return $this->return_error(404, "Not Found", "Vocabulary id '$vocabId' not found.");
    }
  }

  /**
   * Parses and returns the uri parameter. Returns and error if the parameter is missing.
   */
  private function parseURI()
  {
    if (isset($_GET['uri'])) return $_GET['uri'];
    return $this->return_error(400, "Bad Request", "uri parameter missing");
  }

  /**
   * Parses and returns the limit parameter. Returns and error if the parameter is missing.
   */
  private function parseLimit()
  {
    $limit = isset($_GET['limit']) ?
             intval($_GET['limit']) : DEFAULT_TRANSITIVE_LIMIT;
    if ($limit <= 0)
      $this->return_error(400, "Bad Request", "Invalid limit parameter");

    return $limit;
  }

  /**
   * Determine the language to use, from the lang URL parameter (if set),
   * otherwise from the default language of the current vocabulary.
   * As a side effect, set this language as current language.
   * @param string $vocabId identifier string for the vocabulary eg. 'yso'.
   * @return string current language eg. 'en'.
   */
  private function getAndSetLanguage($vocabId)
  {
    $lang = isset($_GET['lang']) ?
            $_GET['lang'] :
            $this->getVocabulary($vocabId)->getDefaultLanguage();
    $this->setLanguageProperties($lang);

    return $lang;
  }

/** Global REST methods **/

  /**
   * Returns all the vocabularies available on the server in a json object.
   */
  public function vocabularies()
  {
    if (!isset($_GET['lang']))
      return $this->return_error(400, "Bad Request", "lang parameter missing");
    $lang = $_GET['lang'];
    $this->setLanguageProperties($lang);

    $vocabs = array();
    foreach ($this->model->getVocabularies() as $voc) {
      $vocabs[$voc->getId()] = $voc->getTitle();
    }
    ksort($vocabs);
    $results = array();
    foreach ($vocabs as $id => $title) {
      $results[] = array(
        'uri' => $id,
        'id' => $id,
        'title' => $title);
    }

    /* encode the results in a JSON-LD compatible array */
    $ret = array(
        '@context' => array(
            'onki' => 'http://schema.onki.fi/onki#',
            'title' => array('@id'=>'rdfs:label', '@language'=>$lang),
            'vocabularies' => 'onki:hasVocabulary',
            'id' => 'onki:vocabularyIdentifier',
            'uri' => '@id',
        ),
        'uri' => '',
        'vocabularies' => $results,
    );

    return $this->return_json($ret);
  }

  /**
   * Performs the search function calls. And wraps the result in a json-ld object.
   * @param string $vocab identifier string for the vocabulary eg. 'yso'.
   */
  public function search($vocab=null)
  {
    if(isset($_GET['query']))
      $term = $_GET['query'];
    else
      return $this->return_error(400, "Bad Request", "query parameter missing");
    if (isset($_GET['maxhits']) && (!is_numeric($_GET['maxhits']) || $_GET['maxhits'] <= 0)) {
      return $this->return_error(400, "Bad Request", "maxhits parameter is invalid");
    }
    if (isset($_GET['offset']) && (!is_numeric($_GET['offset']) || $_GET['offset'] < 0)) {
      return $this->return_error(400, "Bad Request", "offset parameter is invalid");
    }

    $vocid = isset($_GET['vocab']) ? $_GET['vocab'] : $vocab; # optional
    $lang = isset($_GET['lang']) ? $_GET['lang'] : null; # optional
    $labellang = isset($_GET['labellang']) ? $_GET['labellang'] : null; # optional
    $type = isset($_GET['type']) ? $_GET['type'] : 'skos:Concept';
    $parent = isset($_GET['parent']) ? $_GET['parent'] : null;
    $group = isset($_GET['group']) ? $_GET['group'] : null;
    $fields = isset($_GET['fields']) ? explode(' ', $_GET['fields']) : null;

    // convert to vocids array to support multi-vocabulary search
    $vocids = !empty($vocid) ? explode(' ', $vocid) : null;

    $maxhits = isset($_GET['maxhits']) ? ($_GET['maxhits']) : null; # optional
    $offset = isset($_GET['offset']) ? ($_GET['offset']) : 0; # optional
    $results = $this->model->searchConcepts($term, $vocids, $labellang, $lang, $type, $parent, $group, $offset, $maxhits, true, $fields);
    // before serializing to JSON, get rid of the Vocabulary object that came with each resource
    foreach ($results as &$res) {
      unset($res['voc']);
    }

    $ret = array(
        '@context' => array(
            'skos' => 'http://www.w3.org/2004/02/skos/core#',
            'onki' => 'http://schema.onki.fi/onki#',
            'uri' => '@id',
            'type' => '@type',
            'results' => array(
                '@id' => 'onki:results',
                '@container' => '@list',
            ),
            'prefLabel' => 'skos:prefLabel',
            'altLabel' => 'skos:altLabel',
            'hiddenLabel' => 'skos:hiddenLabel',
            'broader' => 'skos:broader',
        ),
        'uri' => '',
        'results' => $results,
    );

    if ($lang)
      $ret['@context']['@language'] = $labellang;

    return $this->return_json($ret);
  }

/** Vocabulary-specific methods **/

  /**
   * Loads the vocabulary metadata. And wraps the result in a json-ld object.
   * @param string $vocabId identifier string for the vocabulary eg. 'yso'.
   */
  public function vocabularyInformation($vocabId)
  {
    $lang = $this->getAndSetLanguage($vocabId);
    $vocab = $this->getVocabulary($vocabId);

    /* encode the results in a JSON-LD compatible array */
{'fraction_non_alphanumeric': 0.16644797270699382, 'fraction_numerical': 0.006232777850675764, 'mean_word_length': 2.9788566953797964, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 109, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2619390', 'n_tokens_mistral': 4827, 'n_tokens_neox': 4711, 'n_words': 1290}