xref: /plugin/doi/syntax/doi.php (revision d9393efffc2437993c41b3c76759060e2c3de657)
126b57c75SAndreas Gohr<?php
226b57c75SAndreas Gohr
326b57c75SAndreas Gohr/**
426b57c75SAndreas Gohr * DokuWiki Plugin doi (Syntax Component)
526b57c75SAndreas Gohr *
626b57c75SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
726b57c75SAndreas Gohr * @author  Andreas Gohr <gohr@cosmocode.de>
826b57c75SAndreas Gohr */
926b57c75SAndreas Gohrclass syntax_plugin_doi_doi extends \dokuwiki\Extension\SyntaxPlugin
1026b57c75SAndreas Gohr{
1126b57c75SAndreas Gohr    /** @inheritDoc */
1226b57c75SAndreas Gohr    public function getType()
1326b57c75SAndreas Gohr    {
1426b57c75SAndreas Gohr        return 'substition';
1526b57c75SAndreas Gohr    }
1626b57c75SAndreas Gohr
1726b57c75SAndreas Gohr    /** @inheritDoc */
1826b57c75SAndreas Gohr    public function getPType()
1926b57c75SAndreas Gohr    {
2026b57c75SAndreas Gohr        return 'normal';
2126b57c75SAndreas Gohr    }
2226b57c75SAndreas Gohr
2326b57c75SAndreas Gohr    /** @inheritDoc */
2426b57c75SAndreas Gohr    public function getSort()
2526b57c75SAndreas Gohr    {
2626b57c75SAndreas Gohr        return 155;
2726b57c75SAndreas Gohr    }
2826b57c75SAndreas Gohr
2926b57c75SAndreas Gohr    /** @inheritDoc */
3026b57c75SAndreas Gohr    public function connectTo($mode)
3126b57c75SAndreas Gohr    {
3226b57c75SAndreas Gohr        $this->Lexer->addSpecialPattern('\[\[doi>[^\]]+\]\]', $mode, 'plugin_doi_doi');
3326b57c75SAndreas Gohr    }
3426b57c75SAndreas Gohr
3526b57c75SAndreas Gohr    /** @inheritDoc */
3626b57c75SAndreas Gohr    public function handle($match, $state, $pos, Doku_Handler $handler)
3726b57c75SAndreas Gohr    {
3826b57c75SAndreas Gohr        $doi = substr($match, 6, -2);
3926b57c75SAndreas Gohr
4026b57c75SAndreas Gohr        return ['doi' => $doi];
4126b57c75SAndreas Gohr    }
4226b57c75SAndreas Gohr
4326b57c75SAndreas Gohr    /** @inheritDoc */
4426b57c75SAndreas Gohr    public function render($mode, Doku_Renderer $renderer, $data)
4526b57c75SAndreas Gohr    {
4626b57c75SAndreas Gohr        $publication = $this->fetchInfo($data['doi']);
4790f426f5SAndreas Gohr        $title = $publication['title'][0] ?? $data['doi'];
4890f426f5SAndreas Gohr        $url = $publication['URL'] ?? 'https://doi.org/' . $data['doi'];
4926b57c75SAndreas Gohr
5026b57c75SAndreas Gohr        if ($mode !== 'xhtml' || !$publication) {
5126b57c75SAndreas Gohr            $renderer->externallink($url, $title);
5226b57c75SAndreas Gohr            return true;
5326b57c75SAndreas Gohr        }
5426b57c75SAndreas Gohr
5526b57c75SAndreas Gohr        /** @var Doku_Renderer_xhtml $renderer */
5690f426f5SAndreas Gohr        $this->formatPub($publication, $renderer);
5726b57c75SAndreas Gohr
5826b57c75SAndreas Gohr        return true;
5926b57c75SAndreas Gohr    }
6026b57c75SAndreas Gohr
6126b57c75SAndreas Gohr    /**
6226b57c75SAndreas Gohr     * Render the given message
6326b57c75SAndreas Gohr     *
6426b57c75SAndreas Gohr     * @param array $message
6526b57c75SAndreas Gohr     * @param Doku_Renderer_xhtml $renderer
6626b57c75SAndreas Gohr     * @return void
6726b57c75SAndreas Gohr     */
6826b57c75SAndreas Gohr    protected function formatPub($message, $renderer)
6926b57c75SAndreas Gohr    {
7026b57c75SAndreas Gohr        $doi = $message['DOI'];
7190f426f5SAndreas Gohr        $title = $message['title'] ?? $doi;
7226b57c75SAndreas Gohr        $url = $message['URL'] ?? 'https://doi.org/' . $doi;
7326b57c75SAndreas Gohr
7426b57c75SAndreas Gohr        $class = hsc($message['type']);
7526b57c75SAndreas Gohr
7626b57c75SAndreas Gohr        $authorList = [];
77*d9393effSAndreas Gohr        foreach ($message['author'] ?? $message['editor'] ?? [] as $author) {
7826b57c75SAndreas Gohr            $authorList[] = '<strong>' . hsc($author['given'].' '.$author['family']) . '</strong>';
7926b57c75SAndreas Gohr        }
8026b57c75SAndreas Gohr
81*d9393effSAndreas Gohr        if (!empty($message['container-title'])) {
8290f426f5SAndreas Gohr            $journal = $message['container-title'];
8326b57c75SAndreas Gohr            $journal .= ' ' . join('/', [$message['volume'] ?? null, $message['issue'] ?? null]);
8426b57c75SAndreas Gohr            $journal = '<span>' . hsc($journal) . '</span>';
8526b57c75SAndreas Gohr            if (isset($message['page'])) {
8626b57c75SAndreas Gohr                $journal .= ' <i>p' . hsc($message['page']) . '</i>';
8726b57c75SAndreas Gohr            }
8826b57c75SAndreas Gohr            $journal = ' <span class="journal">' . $journal . '</span>';
8926b57c75SAndreas Gohr        } else {
9026b57c75SAndreas Gohr            $journal = '';
9126b57c75SAndreas Gohr        }
9226b57c75SAndreas Gohr
9326b57c75SAndreas Gohr        $published = $message['issued']['date-parts'][0][0] ?? '';
9426b57c75SAndreas Gohr        if ($published) $published = ' <span>(' . hsc($published) . ')</span>';
9526b57c75SAndreas Gohr
9626b57c75SAndreas Gohr        $publisher = hsc($message['publisher'] ?? '');
9726b57c75SAndreas Gohr
9826b57c75SAndreas Gohr        //output
9926b57c75SAndreas Gohr        $renderer->doc .= '<div class="plugin_doi ' . $class . '">';
10026b57c75SAndreas Gohr        $renderer->externallink($url, $title);
10126b57c75SAndreas Gohr        $renderer->doc .= $published;
10226b57c75SAndreas Gohr
10326b57c75SAndreas Gohr        $renderer->doc .= '<div class="meta">';
10426b57c75SAndreas Gohr        if ($authorList) {
10526b57c75SAndreas Gohr            $renderer->doc .= '<span class="authors">' . join(', ', $authorList) . '</span>';
10626b57c75SAndreas Gohr        }
10726b57c75SAndreas Gohr        if ($journal) {
10826b57c75SAndreas Gohr            $renderer->doc .= $journal;
10926b57c75SAndreas Gohr        }
11026b57c75SAndreas Gohr        $renderer->doc .= '</div>';
11126b57c75SAndreas Gohr
11226b57c75SAndreas Gohr        $renderer->doc .= '<div class="meta">';
11326b57c75SAndreas Gohr        if ($publisher) {
11426b57c75SAndreas Gohr            $renderer->doc .= '<span class="publisher">' . $publisher . '</span>';
11526b57c75SAndreas Gohr        }
11626b57c75SAndreas Gohr        $renderer->doc .= ' <code class="doi">DOI:' . $doi . '</code>';
11726b57c75SAndreas Gohr        $renderer->doc .= '</div>';
11826b57c75SAndreas Gohr
11926b57c75SAndreas Gohr        $renderer->doc .= '</div>';
12026b57c75SAndreas Gohr    }
12126b57c75SAndreas Gohr
12226b57c75SAndreas Gohr    /**
12326b57c75SAndreas Gohr     * Fetch the info for the given DOI
12426b57c75SAndreas Gohr     *
12526b57c75SAndreas Gohr     * @param string $doi
12626b57c75SAndreas Gohr     * @return false|array
12726b57c75SAndreas Gohr     */
12826b57c75SAndreas Gohr    protected function fetchInfo($doi)
12926b57c75SAndreas Gohr    {
13026b57c75SAndreas Gohr        $http = new \dokuwiki\HTTP\DokuHTTPClient();
13190f426f5SAndreas Gohr        $http->headers['Accept'] = 'application/vnd.citationstyles.csl+json';
13226b57c75SAndreas Gohr
13390f426f5SAndreas Gohr        $json = $http->get('https://doi.org/' . $doi);
13426b57c75SAndreas Gohr        if (!$json) return false;
13526b57c75SAndreas Gohr
13626b57c75SAndreas Gohr        return json_decode($json, true);
13726b57c75SAndreas Gohr    }
13826b57c75SAndreas Gohr}
13926b57c75SAndreas Gohr
140