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