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