xref: /plugin/doi/syntax/doi.php (revision 26b57c75afc4fc107c7f94d3d6fc20313ea9020d)
1*26b57c75SAndreas Gohr<?php
2*26b57c75SAndreas Gohr
3*26b57c75SAndreas Gohr/**
4*26b57c75SAndreas Gohr * DokuWiki Plugin doi (Syntax Component)
5*26b57c75SAndreas Gohr *
6*26b57c75SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7*26b57c75SAndreas Gohr * @author  Andreas Gohr <gohr@cosmocode.de>
8*26b57c75SAndreas Gohr */
9*26b57c75SAndreas Gohrclass syntax_plugin_doi_doi extends \dokuwiki\Extension\SyntaxPlugin
10*26b57c75SAndreas Gohr{
11*26b57c75SAndreas Gohr    /** @inheritDoc */
12*26b57c75SAndreas Gohr    public function getType()
13*26b57c75SAndreas Gohr    {
14*26b57c75SAndreas Gohr        return 'substition';
15*26b57c75SAndreas Gohr    }
16*26b57c75SAndreas Gohr
17*26b57c75SAndreas Gohr    /** @inheritDoc */
18*26b57c75SAndreas Gohr    public function getPType()
19*26b57c75SAndreas Gohr    {
20*26b57c75SAndreas Gohr        return 'normal';
21*26b57c75SAndreas Gohr    }
22*26b57c75SAndreas Gohr
23*26b57c75SAndreas Gohr    /** @inheritDoc */
24*26b57c75SAndreas Gohr    public function getSort()
25*26b57c75SAndreas Gohr    {
26*26b57c75SAndreas Gohr        return 155;
27*26b57c75SAndreas Gohr    }
28*26b57c75SAndreas Gohr
29*26b57c75SAndreas Gohr    /** @inheritDoc */
30*26b57c75SAndreas Gohr    public function connectTo($mode)
31*26b57c75SAndreas Gohr    {
32*26b57c75SAndreas Gohr        $this->Lexer->addSpecialPattern('\[\[doi>[^\]]+\]\]', $mode, 'plugin_doi_doi');
33*26b57c75SAndreas Gohr    }
34*26b57c75SAndreas Gohr
35*26b57c75SAndreas Gohr    /** @inheritDoc */
36*26b57c75SAndreas Gohr    public function handle($match, $state, $pos, Doku_Handler $handler)
37*26b57c75SAndreas Gohr    {
38*26b57c75SAndreas Gohr        $doi = substr($match, 6, -2);
39*26b57c75SAndreas Gohr
40*26b57c75SAndreas Gohr        return ['doi' => $doi];
41*26b57c75SAndreas Gohr    }
42*26b57c75SAndreas Gohr
43*26b57c75SAndreas Gohr    /** @inheritDoc */
44*26b57c75SAndreas Gohr    public function render($mode, Doku_Renderer $renderer, $data)
45*26b57c75SAndreas Gohr    {
46*26b57c75SAndreas Gohr        $publication = $this->fetchInfo($data['doi']);
47*26b57c75SAndreas Gohr        $title = $publication['message']['title'][0] ?? $data['doi'];
48*26b57c75SAndreas Gohr        $url = $publication['message']['URL'] ?? 'https://doi.org/' . $data['doi'];
49*26b57c75SAndreas Gohr
50*26b57c75SAndreas Gohr        if ($mode !== 'xhtml' || !$publication) {
51*26b57c75SAndreas Gohr            $renderer->externallink($url, $title);
52*26b57c75SAndreas Gohr            return true;
53*26b57c75SAndreas Gohr        }
54*26b57c75SAndreas Gohr
55*26b57c75SAndreas Gohr        /** @var Doku_Renderer_xhtml $renderer */
56*26b57c75SAndreas Gohr        $this->formatPub($publication['message'], $renderer);
57*26b57c75SAndreas Gohr
58*26b57c75SAndreas Gohr        return true;
59*26b57c75SAndreas Gohr    }
60*26b57c75SAndreas Gohr
61*26b57c75SAndreas Gohr    /**
62*26b57c75SAndreas Gohr     * Render the given message
63*26b57c75SAndreas Gohr     *
64*26b57c75SAndreas Gohr     * @param array $message
65*26b57c75SAndreas Gohr     * @param Doku_Renderer_xhtml $renderer
66*26b57c75SAndreas Gohr     * @return void
67*26b57c75SAndreas Gohr     */
68*26b57c75SAndreas Gohr    protected function formatPub($message, $renderer)
69*26b57c75SAndreas Gohr    {
70*26b57c75SAndreas Gohr        $doi = $message['DOI'];
71*26b57c75SAndreas Gohr        $title = $message['title'][0] ?? $doi;
72*26b57c75SAndreas Gohr        $url = $message['URL'] ?? 'https://doi.org/' . $doi;
73*26b57c75SAndreas Gohr
74*26b57c75SAndreas Gohr        $class = hsc($message['type']);
75*26b57c75SAndreas Gohr
76*26b57c75SAndreas Gohr        $authorList = [];
77*26b57c75SAndreas Gohr        foreach ($message['author'] ?? [] as $author) {
78*26b57c75SAndreas Gohr            $authorList[] = '<strong>' . hsc($author['given'].' '.$author['family']) . '</strong>';
79*26b57c75SAndreas Gohr        }
80*26b57c75SAndreas Gohr
81*26b57c75SAndreas Gohr        if (isset($message['container-title'][0])) {
82*26b57c75SAndreas Gohr            $journal = $message['container-title'][0];
83*26b57c75SAndreas Gohr            $journal .= ' ' . join('/', [$message['volume'] ?? null, $message['issue'] ?? null]);
84*26b57c75SAndreas Gohr            $journal = '<span>' . hsc($journal) . '</span>';
85*26b57c75SAndreas Gohr            if (isset($message['page'])) {
86*26b57c75SAndreas Gohr                $journal .= ' <i>p' . hsc($message['page']) . '</i>';
87*26b57c75SAndreas Gohr            }
88*26b57c75SAndreas Gohr            $journal = ' <span class="journal">' . $journal . '</span>';
89*26b57c75SAndreas Gohr        } else {
90*26b57c75SAndreas Gohr            $journal = '';
91*26b57c75SAndreas Gohr        }
92*26b57c75SAndreas Gohr
93*26b57c75SAndreas Gohr        $published = $message['issued']['date-parts'][0][0] ?? '';
94*26b57c75SAndreas Gohr        if ($published) $published = ' <span>(' . hsc($published) . ')</span>';
95*26b57c75SAndreas Gohr
96*26b57c75SAndreas Gohr        $publisher = hsc($message['publisher'] ?? '');
97*26b57c75SAndreas Gohr
98*26b57c75SAndreas Gohr        //output
99*26b57c75SAndreas Gohr        $renderer->doc .= '<div class="plugin_doi ' . $class . '">';
100*26b57c75SAndreas Gohr        $renderer->externallink($url, $title);
101*26b57c75SAndreas Gohr        $renderer->doc .= $published;
102*26b57c75SAndreas Gohr
103*26b57c75SAndreas Gohr        $renderer->doc .= '<div class="meta">';
104*26b57c75SAndreas Gohr        if ($authorList) {
105*26b57c75SAndreas Gohr            $renderer->doc .= '<span class="authors">' . join(', ', $authorList) . '</span>';
106*26b57c75SAndreas Gohr        }
107*26b57c75SAndreas Gohr        if ($journal) {
108*26b57c75SAndreas Gohr            $renderer->doc .= $journal;
109*26b57c75SAndreas Gohr        }
110*26b57c75SAndreas Gohr        $renderer->doc .= '</div>';
111*26b57c75SAndreas Gohr
112*26b57c75SAndreas Gohr        $renderer->doc .= '<div class="meta">';
113*26b57c75SAndreas Gohr        if ($publisher) {
114*26b57c75SAndreas Gohr            $renderer->doc .= '<span class="publisher">' . $publisher . '</span>';
115*26b57c75SAndreas Gohr        }
116*26b57c75SAndreas Gohr        $renderer->doc .= ' <code class="doi">DOI:' . $doi . '</code>';
117*26b57c75SAndreas Gohr        $renderer->doc .= '</div>';
118*26b57c75SAndreas Gohr
119*26b57c75SAndreas Gohr        $renderer->doc .= '</div>';
120*26b57c75SAndreas Gohr    }
121*26b57c75SAndreas Gohr
122*26b57c75SAndreas Gohr    /**
123*26b57c75SAndreas Gohr     * Fetch the info for the given DOI
124*26b57c75SAndreas Gohr     *
125*26b57c75SAndreas Gohr     * @param string $doi
126*26b57c75SAndreas Gohr     * @return false|array
127*26b57c75SAndreas Gohr     */
128*26b57c75SAndreas Gohr    protected function fetchInfo($doi)
129*26b57c75SAndreas Gohr    {
130*26b57c75SAndreas Gohr        $http = new \dokuwiki\HTTP\DokuHTTPClient();
131*26b57c75SAndreas Gohr
132*26b57c75SAndreas Gohr        $json = $http->get('https://api.crossref.org/works/' . $doi);
133*26b57c75SAndreas Gohr        if (!$json) return false;
134*26b57c75SAndreas Gohr
135*26b57c75SAndreas Gohr        return json_decode($json, true);
136*26b57c75SAndreas Gohr    }
137*26b57c75SAndreas Gohr}
138*26b57c75SAndreas Gohr
139