11c1d842eSAndreas Gohr<?php 21c1d842eSAndreas Gohr/** 31c1d842eSAndreas Gohr * DokuWiki Plugin amazonlight (Syntax Component) 41c1d842eSAndreas Gohr * 51c1d842eSAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 61c1d842eSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 71c1d842eSAndreas Gohr */ 81c1d842eSAndreas Gohr 91c1d842eSAndreas Gohr// must be run within Dokuwiki 101c1d842eSAndreas Gohrif (!defined('DOKU_INC')) { 111c1d842eSAndreas Gohr die(); 121c1d842eSAndreas Gohr} 131c1d842eSAndreas Gohr 141c1d842eSAndreas Gohrclass syntax_plugin_amazonlight extends DokuWiki_Syntax_Plugin 151c1d842eSAndreas Gohr{ 161c1d842eSAndreas Gohr 171c1d842eSAndreas Gohr /** @var array what regions to use for the different countries */ 181c1d842eSAndreas Gohr const REGIONS = [ 191c1d842eSAndreas Gohr 'us' => 'ws-na', 201c1d842eSAndreas Gohr 'ca' => 'ws-na', 211c1d842eSAndreas Gohr 'de' => 'ws-eu', 221c1d842eSAndreas Gohr 'gb' => 'ws-eu', 231c1d842eSAndreas Gohr 'fr' => 'ws-eu', 241c1d842eSAndreas Gohr 'jp' => 'ws-fe', 251c1d842eSAndreas Gohr ]; 261c1d842eSAndreas Gohr 271c1d842eSAndreas Gohr /** @inheritDoc */ 281c1d842eSAndreas Gohr public function getType() 291c1d842eSAndreas Gohr { 301c1d842eSAndreas Gohr return 'substition'; 311c1d842eSAndreas Gohr } 321c1d842eSAndreas Gohr 331c1d842eSAndreas Gohr /** @inheritDoc */ 341c1d842eSAndreas Gohr public function getPType() 351c1d842eSAndreas Gohr { 361c1d842eSAndreas Gohr return 'block'; 371c1d842eSAndreas Gohr } 381c1d842eSAndreas Gohr 391c1d842eSAndreas Gohr /** @inheritDoc */ 401c1d842eSAndreas Gohr public function getSort() 411c1d842eSAndreas Gohr { 421c1d842eSAndreas Gohr return 160; 431c1d842eSAndreas Gohr } 441c1d842eSAndreas Gohr 451c1d842eSAndreas Gohr /** 461c1d842eSAndreas Gohr * Connect lookup pattern to lexer. 471c1d842eSAndreas Gohr * 481c1d842eSAndreas Gohr * @param string $mode Parser mode 491c1d842eSAndreas Gohr */ 501c1d842eSAndreas Gohr public function connectTo($mode) 511c1d842eSAndreas Gohr { 521c1d842eSAndreas Gohr $this->Lexer->addSpecialPattern('\{\{amazon>[\w:\\- =]+\}\}', $mode, 'plugin_amazonlight'); 531c1d842eSAndreas Gohr } 541c1d842eSAndreas Gohr 551c1d842eSAndreas Gohr /** @inheritDoc */ 561c1d842eSAndreas Gohr public function handle($match, $state, $pos, Doku_Handler $handler) 571c1d842eSAndreas Gohr { 581c1d842eSAndreas Gohr $match = substr($match, 9, -2); 591c1d842eSAndreas Gohr list($ctry, $asin) = explode(':', $match, 2); 601c1d842eSAndreas Gohr 611c1d842eSAndreas Gohr // no country given? 621c1d842eSAndreas Gohr if (empty($asin)) { 631c1d842eSAndreas Gohr $asin = $ctry; 641c1d842eSAndreas Gohr $ctry = 'us'; 651c1d842eSAndreas Gohr } 661c1d842eSAndreas Gohr 671c1d842eSAndreas Gohr // default parameters... 681c1d842eSAndreas Gohr $params = array( 691c1d842eSAndreas Gohr 'imgw' => $this->getConf('imgw'), 701c1d842eSAndreas Gohr 'imgh' => $this->getConf('imgh'), 711c1d842eSAndreas Gohr 'price' => $this->getConf('showprice'), 721c1d842eSAndreas Gohr ); 731c1d842eSAndreas Gohr // ...can be overridden 741c1d842eSAndreas Gohr list($asin, $more) = explode(' ', $asin, 2); 751c1d842eSAndreas Gohr $params['asin'] = $asin; 761c1d842eSAndreas Gohr 771c1d842eSAndreas Gohr if (preg_match('/(\d+)x(\d+)/i', $more, $match)) { 781c1d842eSAndreas Gohr $params['imgw'] = $match[1]; 791c1d842eSAndreas Gohr $params['imgh'] = $match[2]; 801c1d842eSAndreas Gohr } 811c1d842eSAndreas Gohr if (preg_match('/noprice/i', $more, $match)) { 821c1d842eSAndreas Gohr $params['price'] = false; 831c1d842eSAndreas Gohr } elseif (preg_match('/(show)?price/i', $more, $match)) { 841c1d842eSAndreas Gohr $params['price'] = true; 851c1d842eSAndreas Gohr } 861c1d842eSAndreas Gohr 871c1d842eSAndreas Gohr // correct country given? 881c1d842eSAndreas Gohr if ($ctry === 'uk') $ctry = 'gb'; 891c1d842eSAndreas Gohr if (!preg_match('/^(us|gb|jp|de|fr|ca)$/', $ctry)) { 901c1d842eSAndreas Gohr $ctry = 'us'; 911c1d842eSAndreas Gohr } 921c1d842eSAndreas Gohr $params['country'] = $ctry; 931c1d842eSAndreas Gohr 941c1d842eSAndreas Gohr return $params; 951c1d842eSAndreas Gohr } 961c1d842eSAndreas Gohr 971c1d842eSAndreas Gohr /** @inheritDoc */ 981c1d842eSAndreas Gohr public function render($mode, Doku_Renderer $renderer, $data) 991c1d842eSAndreas Gohr { 1001c1d842eSAndreas Gohr if ($mode !== 'xhtml') { 1011c1d842eSAndreas Gohr return false; 1021c1d842eSAndreas Gohr } 1031c1d842eSAndreas Gohr 1041c1d842eSAndreas Gohr $html = $this->output($data); 1051c1d842eSAndreas Gohr $renderer->doc .= $html; 1061c1d842eSAndreas Gohr 1071c1d842eSAndreas Gohr return true; 1081c1d842eSAndreas Gohr } 1091c1d842eSAndreas Gohr 1101c1d842eSAndreas Gohr /** 1111c1d842eSAndreas Gohr * @param array $param 1121c1d842eSAndreas Gohr * @return string 1131c1d842eSAndreas Gohr */ 1141c1d842eSAndreas Gohr protected function output($param) 1151c1d842eSAndreas Gohr { 1161c1d842eSAndreas Gohr global $conf; 1171c1d842eSAndreas Gohr 1181c1d842eSAndreas Gohr try { 1191c1d842eSAndreas Gohr $data = $this->fetchData($param['asin'], $param['country']); 1201c1d842eSAndreas Gohr } catch (\Exception $e) { 1211c1d842eSAndreas Gohr msg(hsc($e->getMessage()), -1); 1221c1d842eSAndreas Gohr return false; 1231c1d842eSAndreas Gohr } 1241c1d842eSAndreas Gohr 1251c1d842eSAndreas Gohr $img = ml($data['img'], array('w' => $param['imgw'], 'h' => $param['imgh'])); 1261c1d842eSAndreas Gohr 1271c1d842eSAndreas Gohr ob_start(); 1281c1d842eSAndreas Gohr echo '<div class="amazon">'; 1291c1d842eSAndreas Gohr echo '<a href="' . $data['url'] . '"'; 1301c1d842eSAndreas Gohr if ($conf['target']['extern']) echo ' target="' . $conf['target']['extern'] . '"'; 1311c1d842eSAndreas Gohr echo '>'; 1321c1d842eSAndreas Gohr echo '<img src="' . $img . '" width="' . $param['imgw'] . '" height="' . $param['imgh'] . '" alt="" />'; 1331c1d842eSAndreas Gohr echo '</a>'; 1341c1d842eSAndreas Gohr 1351c1d842eSAndreas Gohr echo '<div class="amazon_title">'; 1361c1d842eSAndreas Gohr echo '<a href="' . $data['url'] . '"'; 1371c1d842eSAndreas Gohr if ($conf['target']['extern']) echo ' target="' . $conf['target']['extern'] . '"'; 1381c1d842eSAndreas Gohr echo '>'; 1391c1d842eSAndreas Gohr echo hsc($data['title']); 1401c1d842eSAndreas Gohr echo '</a>'; 1411c1d842eSAndreas Gohr echo '</div>'; 1421c1d842eSAndreas Gohr 143*e20d6e78SAndreas Gohr echo '<div class="amazon_isbn">'; 144*e20d6e78SAndreas Gohr echo hsc($data['isbn']); 145*e20d6e78SAndreas Gohr echo '</div>'; 146*e20d6e78SAndreas Gohr 1471c1d842eSAndreas Gohr if ($param['price'] && $data['price']) { 1481c1d842eSAndreas Gohr echo '<div class="amazon_price">' . hsc($data['price']) . '</div>'; 1491c1d842eSAndreas Gohr } 1501c1d842eSAndreas Gohr echo '</div>'; 1511c1d842eSAndreas Gohr 1521c1d842eSAndreas Gohr return ob_get_clean(); 1531c1d842eSAndreas Gohr } 1541c1d842eSAndreas Gohr 1551c1d842eSAndreas Gohr /** 1561c1d842eSAndreas Gohr * Fetch the meta data 1571c1d842eSAndreas Gohr * 1581c1d842eSAndreas Gohr * @param string $asin 1591c1d842eSAndreas Gohr * @param string $country 1601c1d842eSAndreas Gohr * @return array 1611c1d842eSAndreas Gohr * @throws Exception 1621c1d842eSAndreas Gohr */ 1631c1d842eSAndreas Gohr protected function fetchData($asin, $country) 1641c1d842eSAndreas Gohr { 1651c1d842eSAndreas Gohr $partner = $this->getConf('partner_' . $country); 1661c1d842eSAndreas Gohr if (!$partner) $partner = 'none'; 1671c1d842eSAndreas Gohr $region = self::REGIONS[$country]; 1681c1d842eSAndreas Gohr 1691c1d842eSAndreas Gohr $attr = [ 1701c1d842eSAndreas Gohr 'ServiceVersion' => '20070822', 1711c1d842eSAndreas Gohr 'OneJS' => '1', 1721c1d842eSAndreas Gohr 'Operation' => 'GetAdHtml', 1731c1d842eSAndreas Gohr 'MarketPlace' => strtoupper($country), 1741c1d842eSAndreas Gohr 'source' => 'ss', 1751c1d842eSAndreas Gohr 'ref' => 'as_ss_li_til', 1761c1d842eSAndreas Gohr 'ad_type' => 'product_link', 1771c1d842eSAndreas Gohr 'tracking_id' => $partner, 1781c1d842eSAndreas Gohr 'marketplace' => 'amazon', 1791c1d842eSAndreas Gohr 'region' => strtoupper($country), 1801c1d842eSAndreas Gohr 'placement' => '0670022411', 1811c1d842eSAndreas Gohr 'asins' => $asin, 1821c1d842eSAndreas Gohr 'show_border' => 'true', 1831c1d842eSAndreas Gohr 'link_opens_in_new_window' => 'true', 1841c1d842eSAndreas Gohr ]; 1851c1d842eSAndreas Gohr $url = 'http://' . $region . '.amazon-adsystem.com/widgets/q?' . buildURLparams($attr, '&'); 1861c1d842eSAndreas Gohr 1871c1d842eSAndreas Gohr $http = new DokuHTTPClient(); 1881c1d842eSAndreas Gohr $html = $http->get($url); 1891c1d842eSAndreas Gohr if (!$html) { 1901c1d842eSAndreas Gohr throw new \Exception('Failed to fetch data. Status ' . $http->status); 1911c1d842eSAndreas Gohr } 1921c1d842eSAndreas Gohr 1931c1d842eSAndreas Gohr $result = []; 1941c1d842eSAndreas Gohr 1951c1d842eSAndreas Gohr if (preg_match('/class="price".*?>(.*?)<\/span>/s', $html, $m)) { 1961c1d842eSAndreas Gohr $result['price'] = $m[1]; 1971c1d842eSAndreas Gohr } 1981c1d842eSAndreas Gohr 1991c1d842eSAndreas Gohr if (preg_match('/<a .* id="titlehref" [^>]*?>([^<]*?)<\/a>/s', $html, $m)) { 2001c1d842eSAndreas Gohr $result['title'] = $m[1]; 2011c1d842eSAndreas Gohr } 2021c1d842eSAndreas Gohr 2031c1d842eSAndreas Gohr if (preg_match('/<a .* id="titlehref" href=(.*?) /s', $html, $m)) { 2041c1d842eSAndreas Gohr $result['url'] = trim($m[1], '\'"'); 2051c1d842eSAndreas Gohr } 2061c1d842eSAndreas Gohr 207*e20d6e78SAndreas Gohr if (preg_match('/^\d{10}$/', $asin)) { 208*e20d6e78SAndreas Gohr $result['isbn'] = 'ISBN ' . $asin; 209*e20d6e78SAndreas Gohr } 210*e20d6e78SAndreas Gohr 2111c1d842eSAndreas Gohr $result['img'] = $this->getImageURL($asin, $country); 2121c1d842eSAndreas Gohr 2131c1d842eSAndreas Gohr return $result; 2141c1d842eSAndreas Gohr } 2151c1d842eSAndreas Gohr 2161c1d842eSAndreas Gohr /** 2171c1d842eSAndreas Gohr * @param $asin 2181c1d842eSAndreas Gohr * @param $country 2191c1d842eSAndreas Gohr * @return string 2201c1d842eSAndreas Gohr */ 2211c1d842eSAndreas Gohr protected function getImageURL($asin, $country) 2221c1d842eSAndreas Gohr { 2231c1d842eSAndreas Gohr $partner = $this->getConf('partner_' . $country); 2241c1d842eSAndreas Gohr if (!$partner) $partner = 'none'; 2251c1d842eSAndreas Gohr $region = self::REGIONS[$country]; 2261c1d842eSAndreas Gohr 2271c1d842eSAndreas Gohr $attr = [ 2281c1d842eSAndreas Gohr '_encoding' => 'UTF8', 2291c1d842eSAndreas Gohr 'ASIN' => $asin, 2301c1d842eSAndreas Gohr 'Format' => '_SL250_', 2311c1d842eSAndreas Gohr 'ID' => 'AsinImage', 2321c1d842eSAndreas Gohr 'MarketPlace' => strtoupper($country), 2331c1d842eSAndreas Gohr 'ServiceVersion' => '20070822', 2341c1d842eSAndreas Gohr 'WS' => '1', 2351c1d842eSAndreas Gohr 'tag' => $partner, 2361c1d842eSAndreas Gohr ]; 2371c1d842eSAndreas Gohr $url = 'http://' . $region . '.amazon-adsystem.com/widgets/q?' . buildURLparams($attr, '&'); 2381c1d842eSAndreas Gohr 2391c1d842eSAndreas Gohr return $url; 2401c1d842eSAndreas Gohr } 2411c1d842eSAndreas Gohr 2421c1d842eSAndreas Gohr} 2431c1d842eSAndreas Gohr 244