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 $isbn = substr($match, 7, -2); 39 $isbn = preg_replace('/[^0-9X]/i', '', $isbn); 40 41 return ['isbn' => $isbn]; 42 } 43 44 /** @inheritDoc */ 45 public function render($mode, Doku_Renderer $renderer, $data) 46 { 47 $publication = $this->fetchInfo($data['isbn']); 48 $title = $publication['details']['title'] ?? $data['isbn']; 49 $url = $publication['details']['info_url'] ?? 'https://www.google.com/search?q=isbn+' . $data['isbn']; 50 51 if ($mode !== 'xhtml' || !$publication) { 52 $renderer->externallink($url, $title); 53 return true; 54 } 55 56 /** @var Doku_Renderer_xhtml $renderer */ 57 $this->formatPub($publication, $renderer); 58 59 return true; 60 } 61 62 /** 63 * Render the given message 64 * 65 * @param array $message 66 * @param Doku_Renderer_xhtml $renderer 67 * @return void 68 */ 69 protected function formatPub($message, $renderer) 70 { 71 $url = $message['info_url']; 72 $message = $message['details']; 73 74 $isbn = $message['isbn_13'][0] ?? $message['isbn_10'][0] ?? ''; 75 $title = $message['full_title'] ?? $message['title'] ?? $isbn; 76 77 $class = 'book'; 78 79 $authorList = []; 80 foreach ($message['authors'] ?? [] as $author) { 81 $authorList[] = '<strong>' . hsc($author['name']) . '</strong>'; 82 } 83 84 $published = $message['publish_date'] ?? ''; 85 if (preg_match('/\b(\d{4})\b/', $published, $m)) { 86 $published = ' <span>(' . hsc($m[1]) . ')</span>'; 87 } else { 88 $published = ''; 89 } 90 91 $publisher = hsc($message['publishers'][0] ?? ''); 92 93 //output 94 $renderer->doc .= '<div class="plugin_doi ' . $class . '">'; 95 $renderer->externallink($url, $title); 96 $renderer->doc .= $published; 97 98 $renderer->doc .= '<div class="meta">'; 99 if ($authorList) { 100 $renderer->doc .= '<span class="authors">' . join(', ', $authorList) . '</span>'; 101 } 102 $renderer->doc .= '</div>'; 103 104 $renderer->doc .= '<div class="meta">'; 105 if ($publisher) { 106 $renderer->doc .= '<span class="publisher">' . $publisher . '</span>'; 107 } 108 $renderer->doc .= ' <code class="isbn">ISBN:' . $isbn . '</code>'; 109 $renderer->doc .= '</div>'; 110 111 $renderer->doc .= '</div>'; 112 } 113 114 /** 115 * Fetch the info for the given ISBN 116 * 117 * @param string $isbn 118 * @return false|array 119 */ 120 protected function fetchInfo($isbn) 121 { 122 $cache = getCacheName($isbn, '.isbn.json'); 123 if (@filemtime($cache) > filemtime(__FILE__)) { 124 $data = json_decode(file_get_contents($cache), true); 125 } else { 126 $http = new \dokuwiki\HTTP\DokuHTTPClient(); 127 $json = $http->get('https://openlibrary.org/api/books?jscmd=details&format=json&bibkeys=ISBN:' . $isbn); 128 if (!$json) return false; 129 130 file_put_contents($cache, $json); 131 $data = json_decode($json, true); 132 } 133 return array_shift($data); // first entry 134 } 135} 136 137