Skip to content
Snippets Groups Projects
OERHostOERSI.php 8.09 KiB
Newer Older
<?php

class OERHostOERSI extends OERHost
{

    /**
     * Executes a search request on the host.
     * @param string|null $text : the search string
     * @param string|null $tag : a tag to search for
     */
    public function fetchRemoteSearch($text = null, $tag = null)
    {
        $endpoint_url = 'https://oersi.org/resources/api/search/oer_data/_search';
        $appendix = Config::get()->OER_OERSI_ONLY_DOWNLOADABLE ? ' AND _exists_:encoding.contentUrl' : '';
        if ($tag) {
            $endpoint_url .= '?q=' . urlencode("keywords:" . $tag . $appendix);
        } else {
            $endpoint_url .= '?q=' . urlencode($text . $appendix);
        }
        $cr = curl_init();
        curl_setopt($cr, CURLOPT_URL, $endpoint_url);
        curl_setopt($cr, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($cr, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($cr, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($cr, CURLOPT_SSL_VERIFYHOST, false);
        $stream_context_options = stream_context_get_options(get_default_http_stream_context($endpoint_url));
        curl_setopt($cr, CURLOPT_PROXY, isset($stream_context_options['http']['proxy']) ? Config::get()->HTTP_PROXY : '');
        $output = curl_exec($cr);
        $error = curl_error($cr);
        if ($error) {
            $error_number = curl_getinfo($cr,    CURLINFO_HTTP_CODE);
            error_log('OERSI search is not working. '.$error_number.': '.$error);
        }
        curl_close($cr);
            $json = json_decode($output, true);
            if ($json !== null) {
                foreach ((array)$json['hits']['hits'] as $material_data) {
                    //check if material already in database from this or another OER Campus host
                    if (OERHost::URIExists($material_data['_source']['id'])) {
                        continue;
                    }
                    $material = OERMaterial::findOneBySQL('foreign_material_id = ? AND host_id = ?', [
                        md5($material_data['_source']['id']),
                        $this->getId()
                    ]);
                    if (!$material) {
                        $material = new OERMaterial();
                        $material['foreign_material_id'] = md5($material_data['_source']['id']);
                        $material['host_id'] = $this->getId();
                    }
                    $material['name'] = mb_substr($material_data['_source']['name'], 0, 64);
                    $material['draft'] = '0';
                    $material['filename'] = '';
                    $material['short_description'] = '';
                    $material['description'] = $material_data['_source']['description'] ?: '';
                    $material['difficulty_start'] = 0;
                    $material['difficulty_end'] = 12;
                    $material['uri'] = $material_data['_source']['id'];
                    $material['source_url'] = $material_data['_source']['id'];
                    $material['content_type'] = $material_data['_source']['encoding'][0]['encodingFormat'] ?: '';
                    $material['license_identifier'] = $this->getLicenseID($material_data['_source']['license']['id']) ?: '';
                    if (!$material['category']) {
                        $material['category'] = $material->autoDetectCategory();
                    }
                    $material['front_image_content_type'] = $material_data['_source']['image'] ? 'image/jpg' : null;
                    $material['data'] = [
                        'front_image_url' => $material_data['_source']['image'],
                        'download' => $material_data['_source']['encoding'][0]['contentUrl'] ?: '',
                        'id' => $material_data['_id'],
                        'authors' => $material_data['_source']['creator'],
                        'organization' => $material_data['_source']['sourceOrganization'][0]['name'] ?: $material_data['_source']['publisher'][0]['name']
                    ];
                    $material->store();
                    //set topics:
                    //$material->setUsers([]);
                    //set topics:
                    $material->setTopics($material_data['_source']['keywords']);
                }
            } else {
                error_log('OERSI returns bad JSON data: '.$output);
            }
        }
    }

    /**
     * Pushes some data to the foreign OERHost.
     * @param string $endpoint : part behind the host-url like "push_data"
     * @param array $data : the data to be pushed as an associative array
     * @return bool|CurlHandle|resource
     */
    public function pushDataToEndpoint($endpoint, $data)
    {
    }

    /**
     * Fetches all information of an item from that host. This is a request.
     * @param string $foreign_material_id : foreign id of that oer-material
     * @return array|null : data of that material or null on error.
     */
    public function fetchItemData(OERMaterial $material)
    {
        $endpoint_url = 'https://oersi.org/resources/' . urlencode($material['data']['id']) . '?format=json';
        $output = @file_get_contents($endpoint_url, false, get_default_http_stream_context($endpoint_url));
        if ($output) {
            $output = json_decode($output, true);
            if ($output) {
                $data = [];
                $data['name'] = mb_substr($output['name'], 0, 64);
                $data['draft'] = '0';
                $data['filename'] = '';
                $data['short_description'] = '';
                $data['description'] = $output['description'] ?: '';
                $data['difficulty_start'] = 12;
                $data['uri'] = $output['encoding'][0]['contentUrl'] ?: '';
                $data['source_url'] = $output['id'];
                $data['content_type'] = $output['encoding'][0]['encodingFormat'] ?: '';
                $data['license_identifier'] = $this->getLicenseID($output['license']['id']) ?: '';
                if (empty($data['category'])) {
                    $data['category'] = $material->autoDetectCategory();
                }
                $data['front_image_content_type'] = $output['image'] ? 'image/jpg' : null;
                $data['data'] = $material['data']->getArrayCopy();
                $data['data']['download'] = $output['encoding'][0]['contentUrl'] ?: '';
                $data['data']['front_image_url'] = $output['image'];
                $data['data']['authors'] = $output['creator'];
                $data['data']['organization'] = $output['sourceOrganization'][0]['name'] ?: $output['publisher'][0]['name'];
                    'topics' => $output['keywords'] ?? []
                ];
            }
        } else {
            return ['deleted' => 1];
        }
    }

    public function getFrontImageURL(OERMaterial $material)
    {
        return $material['data'] ? $material['data']['front_image_url'] : null;
    }

    /**
     * Tries to match the CC-license URL from OERSI to an spdx-identifier, which is used in Stud.IP
     * @param $license : an URL
     * @return string|null
     */
    protected function getLicenseID($license)
    {
        preg_match("^https:\/\/creativecommons.org\/licenses\/([\w\d\-\.]+)\/([\w\d\-\.]+)^", $license, $matches);
        if ($matches[0]) {
            $spdx_id = 'CC-' . strtoupper($matches[1]) . '-' . strtoupper($matches[2]);
            if (License::find($spdx_id)) {
                return $spdx_id;
            }
        }
        return null;
    }

    public function isReviewable()
    {
        return false;
    }

    public function getAuthorsForMaterial(OERMaterial $material)
    {
        $users = [];
        $data = $material->data->getArrayCopy();
        foreach ((array) $data['authors'] as $author) {
            $users[] = [
                'name' => $author['name'],
                'hostname' => $data['organization'] ?: $this['name']
            ];
        }
        return $users;
    }

    public function getDownloadURLForMaterial(OERMaterial $material)
    {
        return $material['uri'];
    }