1<?php 2/** 3 * DokuWiki Plugin WikipediaSnippet 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Anika Henke <anika@selfthinker.org> 7 */ 8 9if (!defined('DOKU_INC')) die(); 10if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 11require_once(DOKU_PLUGIN.'syntax.php'); 12 13class syntax_plugin_wikipediasnippet extends DokuWiki_Syntax_Plugin { 14 15 function getType() { return 'substition'; } 16 function getPType() { return 'block'; } 17 function getSort() { return 192; } 18 19 function connectTo($mode) { 20 $this->Lexer->addSpecialPattern('{{wp(?:\:[a-z-]+)?>[^}]+}}',$mode,'plugin_wikipediasnippet'); 21 } 22 23 function handle($match, $state, $pos, Doku_Handler $handler) { 24 $data = substr($match, 2, -2); 25 list($command, $article) = explode('>', $data); 26 27 // if no specific language was given (e.g. {{wp>Wiki}}), use configured language 28 if (strpos($command, ':') === false) { 29 global $conf; 30 $lang = $conf['lang']; 31 32 // correct some non-standard language codes 33 $langCorrectionsFile = dirname(__FILE__).'/conf/langCorrections.conf'; 34 if (@file_exists($langCorrectionsFile)) { 35 $langCorrections = confToHash($langCorrectionsFile); 36 $lang = strtr($lang, $langCorrections); 37 } 38 39 // if different language was given (e.g. {{wp:fr>Wiki}}), use that 40 } else { 41 list($null, $lang) = explode(':', $command); 42 } 43 44 return trim($lang).'::'.trim($article); 45 } 46 47 function render($mode, Doku_Renderer $renderer, $data) { 48 if($mode == 'xhtml') { 49 if ($data) { 50 list($lang, $article) = explode('::', $data); 51 $wpUrl = 'http://'.$lang.'.wikipedia.org/'; 52 53 $wpContent = $this->_getWPcontent($article, $lang, $wpUrl); 54 if ($wpContent) { 55 $renderer->doc .= $wpContent; 56 } else { 57 // if all fails, build interwiki link 58 $renderer->doc .= '<a href="'.$wpUrl.'wiki/'.rawurlencode($article).'" class="interwiki iw_wp">'.hsc($article).'</a>'; 59 } 60 } 61 // if no parameter was given, just don't display anything 62 } 63 } 64 65 /** 66 * Get the content of the article from Wikipedia, create a useful snippet 67 * and create its container 68 */ 69 function _getWPcontent($article, $articleLang, $wpUrl) { 70 // config options 71 $snippetLength = ($this->getConf('snippetLength')) ? '&exsentences='.$this->getConf('snippetLength') : '&exintro='; 72 $useHtml = ($this->getConf('useHtml')) ? '' : '&explaintext='; 73 $page = '&titles='.rawurlencode($article); 74 75 $url = $wpUrl.'w/api.php?action=query&prop=extracts&redirects=&format=xml'.$snippetLength.$useHtml.$page; 76 77 // fetch article data from Wikipedia 78 $http = new DokuHTTPClient(); 79 $http->agent .= ' (DokuWiki WikipediaSnippet Plugin)'; 80 $data = $http->get($url); 81 if(!$data) { 82 msg('Error: Fetching the article from Wikipedia failed.', -1); 83 if ($http->error) { 84 msg($http->error, -1); 85 } 86 return false; 87 } 88 89 // parse XML 90 $xml = simplexml_load_string($data, 'SimpleXMLElement'); 91 if (!$xml) { 92 msg('Error: Loading the XML failed.', -1); 93 foreach(libxml_get_errors() as $error) { 94 msg($error->message, -1); 95 } 96 libxml_clear_errors(); 97 return false; 98 } 99 $title = $xml->query->pages->page['title']; 100 $text = $xml->query->pages->page->extract; 101 if (!$text) { 102 msg('Error: Parsing the XML failed.', -1); 103 $error = $xml->error; 104 if ($error) { 105 msg($error['code'].': '.$error['info'] ,-1); 106 } 107 return false; 108 } 109 110 // @todo: extracts don't seem to have any links or images; when verified, remove: 111 // all relative links should point to wikipedia 112 $text = str_replace('href="/', 'href="'.$wpUrl , $text); 113 // make protocol relative URLs use http 114 $text = str_replace('src="//', 'src="http://' , $text); 115 if (!$this->getConf('useHtml')) { 116 $text = '<p>'.$text.'</p>'; 117 } 118 119 $articleLink = $wpUrl.'wiki/'.rawurlencode($article); 120 $langParams = $this->_getLangParams($articleLang); 121 122 // display snippet and container 123 $wpContent = '<dl class="wpsnip">'.NL; 124 $wpContent .= ' <dt>'.NL; 125 $wpContent .= ' <em>'.sprintf($this->getLang('from'), $wpUrl).'<span>: </span></em>'; 126 $wpContent .= '<cite><strong><a href="'.$articleLink.'" class="interwiki iw_wp">'.$title.'</a></strong></cite> '; 127 $wpContent .= ' </dt>'.NL; 128 $wpContent .= ' <dd><blockquote '.$langParams.'>'.$text.NL.'</blockquote>'.$this->_getWPlicense($wpUrl).'</dd>'.NL; 129 $wpContent .= '</dl>'.NL; 130 131 return $wpContent; 132 } 133 134 /** 135 * Get license under which the content is distributed 136 */ 137 function _getWPlicense($wpUrl) { 138 $url = $wpUrl.'w/api.php?action=query&meta=siteinfo&siprop=rightsinfo&format=xml'; 139 140 // fetch license data from Wikipedia 141 $http = new DokuHTTPClient(); 142 $http->agent .= ' (DokuWiki WikipediaSnippet Plugin)'; 143 $data = $http->get($url); 144 if(!$data) return false; 145 $xml = simplexml_load_string($data, 'SimpleXMLElement'); 146 147 if (!$xml) return false; 148 $url = $xml->query->rightsinfo['url']; 149 $text = $xml->query->rightsinfo['text']; 150 151 return '<div class="wplicense"><a href="'.$url.'">'.$text.'</a></div>'; 152 } 153 154 /** 155 * Get lang and dir parameters to add if different from global lang and dir 156 */ 157 function _getLangParams($articleLang) { 158 global $conf; 159 global $lang; 160 161 $diffLang = ''; 162 $diffDir = ''; 163 164 if ($conf['lang'] != $articleLang) { 165 $diffLang = 'lang="'.$articleLang.'" xml:lang="'.$articleLang.'"'; 166 167 // check lang dir 168 $lang2dirFile = dirname(__FILE__).'/conf/lang2dir.conf'; 169 if (@file_exists($lang2dirFile)) { 170 $lang2dir = confToHash($lang2dirFile); 171 $dir = strtr($articleLang, $lang2dir); 172 } 173 // in case lang is not listed 174 if (!isset($dir) || ($dir == $articleLang)) { 175 $dir = $lang['direction']; 176 } 177 178 $diffDir = ($lang['direction'] != $dir) ? 'dir="'.$dir.'"' : ''; 179 } 180 181 return $diffLang.' '.$diffDir; 182 } 183 184}//class 185