1*1c1d842eSAndreas Gohr<?php 2*1c1d842eSAndreas Gohr/** 3*1c1d842eSAndreas Gohr * DokuWiki Plugin amazonlight (Syntax Component) 4*1c1d842eSAndreas Gohr * 5*1c1d842eSAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6*1c1d842eSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 7*1c1d842eSAndreas Gohr */ 8*1c1d842eSAndreas Gohr 9*1c1d842eSAndreas Gohr// must be run within Dokuwiki 10*1c1d842eSAndreas Gohrif (!defined('DOKU_INC')) { 11*1c1d842eSAndreas Gohr die(); 12*1c1d842eSAndreas Gohr} 13*1c1d842eSAndreas Gohr 14*1c1d842eSAndreas Gohrclass syntax_plugin_amazonlight extends DokuWiki_Syntax_Plugin 15*1c1d842eSAndreas Gohr{ 16*1c1d842eSAndreas Gohr 17*1c1d842eSAndreas Gohr /** @var array what regions to use for the different countries */ 18*1c1d842eSAndreas Gohr const REGIONS = [ 19*1c1d842eSAndreas Gohr 'us' => 'ws-na', 20*1c1d842eSAndreas Gohr 'ca' => 'ws-na', 21*1c1d842eSAndreas Gohr 'de' => 'ws-eu', 22*1c1d842eSAndreas Gohr 'gb' => 'ws-eu', 23*1c1d842eSAndreas Gohr 'fr' => 'ws-eu', 24*1c1d842eSAndreas Gohr 'jp' => 'ws-fe', 25*1c1d842eSAndreas Gohr ]; 26*1c1d842eSAndreas Gohr 27*1c1d842eSAndreas Gohr /** @inheritDoc */ 28*1c1d842eSAndreas Gohr public function getType() 29*1c1d842eSAndreas Gohr { 30*1c1d842eSAndreas Gohr return 'substition'; 31*1c1d842eSAndreas Gohr } 32*1c1d842eSAndreas Gohr 33*1c1d842eSAndreas Gohr /** @inheritDoc */ 34*1c1d842eSAndreas Gohr public function getPType() 35*1c1d842eSAndreas Gohr { 36*1c1d842eSAndreas Gohr return 'block'; 37*1c1d842eSAndreas Gohr } 38*1c1d842eSAndreas Gohr 39*1c1d842eSAndreas Gohr /** @inheritDoc */ 40*1c1d842eSAndreas Gohr public function getSort() 41*1c1d842eSAndreas Gohr { 42*1c1d842eSAndreas Gohr return 160; 43*1c1d842eSAndreas Gohr } 44*1c1d842eSAndreas Gohr 45*1c1d842eSAndreas Gohr /** 46*1c1d842eSAndreas Gohr * Connect lookup pattern to lexer. 47*1c1d842eSAndreas Gohr * 48*1c1d842eSAndreas Gohr * @param string $mode Parser mode 49*1c1d842eSAndreas Gohr */ 50*1c1d842eSAndreas Gohr public function connectTo($mode) 51*1c1d842eSAndreas Gohr { 52*1c1d842eSAndreas Gohr $this->Lexer->addSpecialPattern('\{\{amazon>[\w:\\- =]+\}\}', $mode, 'plugin_amazonlight'); 53*1c1d842eSAndreas Gohr } 54*1c1d842eSAndreas Gohr 55*1c1d842eSAndreas Gohr /** @inheritDoc */ 56*1c1d842eSAndreas Gohr public function handle($match, $state, $pos, Doku_Handler $handler) 57*1c1d842eSAndreas Gohr { 58*1c1d842eSAndreas Gohr $match = substr($match, 9, -2); 59*1c1d842eSAndreas Gohr list($ctry, $asin) = explode(':', $match, 2); 60*1c1d842eSAndreas Gohr 61*1c1d842eSAndreas Gohr // no country given? 62*1c1d842eSAndreas Gohr if (empty($asin)) { 63*1c1d842eSAndreas Gohr $asin = $ctry; 64*1c1d842eSAndreas Gohr $ctry = 'us'; 65*1c1d842eSAndreas Gohr } 66*1c1d842eSAndreas Gohr 67*1c1d842eSAndreas Gohr // default parameters... 68*1c1d842eSAndreas Gohr $params = array( 69*1c1d842eSAndreas Gohr 'imgw' => $this->getConf('imgw'), 70*1c1d842eSAndreas Gohr 'imgh' => $this->getConf('imgh'), 71*1c1d842eSAndreas Gohr 'price' => $this->getConf('showprice'), 72*1c1d842eSAndreas Gohr ); 73*1c1d842eSAndreas Gohr // ...can be overridden 74*1c1d842eSAndreas Gohr list($asin, $more) = explode(' ', $asin, 2); 75*1c1d842eSAndreas Gohr $params['asin'] = $asin; 76*1c1d842eSAndreas Gohr 77*1c1d842eSAndreas Gohr if (preg_match('/(\d+)x(\d+)/i', $more, $match)) { 78*1c1d842eSAndreas Gohr $params['imgw'] = $match[1]; 79*1c1d842eSAndreas Gohr $params['imgh'] = $match[2]; 80*1c1d842eSAndreas Gohr } 81*1c1d842eSAndreas Gohr if (preg_match('/noprice/i', $more, $match)) { 82*1c1d842eSAndreas Gohr $params['price'] = false; 83*1c1d842eSAndreas Gohr } elseif (preg_match('/(show)?price/i', $more, $match)) { 84*1c1d842eSAndreas Gohr $params['price'] = true; 85*1c1d842eSAndreas Gohr } 86*1c1d842eSAndreas Gohr 87*1c1d842eSAndreas Gohr // correct country given? 88*1c1d842eSAndreas Gohr if ($ctry === 'uk') $ctry = 'gb'; 89*1c1d842eSAndreas Gohr if (!preg_match('/^(us|gb|jp|de|fr|ca)$/', $ctry)) { 90*1c1d842eSAndreas Gohr $ctry = 'us'; 91*1c1d842eSAndreas Gohr } 92*1c1d842eSAndreas Gohr $params['country'] = $ctry; 93*1c1d842eSAndreas Gohr 94*1c1d842eSAndreas Gohr return $params; 95*1c1d842eSAndreas Gohr } 96*1c1d842eSAndreas Gohr 97*1c1d842eSAndreas Gohr /** @inheritDoc */ 98*1c1d842eSAndreas Gohr public function render($mode, Doku_Renderer $renderer, $data) 99*1c1d842eSAndreas Gohr { 100*1c1d842eSAndreas Gohr if ($mode !== 'xhtml') { 101*1c1d842eSAndreas Gohr return false; 102*1c1d842eSAndreas Gohr } 103*1c1d842eSAndreas Gohr 104*1c1d842eSAndreas Gohr $html = $this->output($data); 105*1c1d842eSAndreas Gohr $renderer->doc .= $html; 106*1c1d842eSAndreas Gohr 107*1c1d842eSAndreas Gohr return true; 108*1c1d842eSAndreas Gohr } 109*1c1d842eSAndreas Gohr 110*1c1d842eSAndreas Gohr /** 111*1c1d842eSAndreas Gohr * @param array $param 112*1c1d842eSAndreas Gohr * @return string 113*1c1d842eSAndreas Gohr */ 114*1c1d842eSAndreas Gohr protected function output($param) 115*1c1d842eSAndreas Gohr { 116*1c1d842eSAndreas Gohr global $conf; 117*1c1d842eSAndreas Gohr 118*1c1d842eSAndreas Gohr try { 119*1c1d842eSAndreas Gohr $data = $this->fetchData($param['asin'], $param['country']); 120*1c1d842eSAndreas Gohr } catch (\Exception $e) { 121*1c1d842eSAndreas Gohr msg(hsc($e->getMessage()), -1); 122*1c1d842eSAndreas Gohr return false; 123*1c1d842eSAndreas Gohr } 124*1c1d842eSAndreas Gohr 125*1c1d842eSAndreas Gohr $img = ml($data['img'], array('w' => $param['imgw'], 'h' => $param['imgh'])); 126*1c1d842eSAndreas Gohr 127*1c1d842eSAndreas Gohr ob_start(); 128*1c1d842eSAndreas Gohr echo '<div class="amazon">'; 129*1c1d842eSAndreas Gohr echo '<a href="' . $data['url'] . '"'; 130*1c1d842eSAndreas Gohr if ($conf['target']['extern']) echo ' target="' . $conf['target']['extern'] . '"'; 131*1c1d842eSAndreas Gohr echo '>'; 132*1c1d842eSAndreas Gohr echo '<img src="' . $img . '" width="' . $param['imgw'] . '" height="' . $param['imgh'] . '" alt="" />'; 133*1c1d842eSAndreas Gohr echo '</a>'; 134*1c1d842eSAndreas Gohr 135*1c1d842eSAndreas Gohr echo '<div class="amazon_title">'; 136*1c1d842eSAndreas Gohr echo '<a href="' . $data['url'] . '"'; 137*1c1d842eSAndreas Gohr if ($conf['target']['extern']) echo ' target="' . $conf['target']['extern'] . '"'; 138*1c1d842eSAndreas Gohr echo '>'; 139*1c1d842eSAndreas Gohr echo hsc($data['title']); 140*1c1d842eSAndreas Gohr echo '</a>'; 141*1c1d842eSAndreas Gohr echo '</div>'; 142*1c1d842eSAndreas Gohr 143*1c1d842eSAndreas Gohr if ($param['price'] && $data['price']) { 144*1c1d842eSAndreas Gohr echo '<div class="amazon_price">' . hsc($data['price']) . '</div>'; 145*1c1d842eSAndreas Gohr } 146*1c1d842eSAndreas Gohr echo '</div>'; 147*1c1d842eSAndreas Gohr 148*1c1d842eSAndreas Gohr return ob_get_clean(); 149*1c1d842eSAndreas Gohr } 150*1c1d842eSAndreas Gohr 151*1c1d842eSAndreas Gohr /** 152*1c1d842eSAndreas Gohr * Fetch the meta data 153*1c1d842eSAndreas Gohr * 154*1c1d842eSAndreas Gohr * @param string $asin 155*1c1d842eSAndreas Gohr * @param string $country 156*1c1d842eSAndreas Gohr * @return array 157*1c1d842eSAndreas Gohr * @throws Exception 158*1c1d842eSAndreas Gohr */ 159*1c1d842eSAndreas Gohr protected function fetchData($asin, $country) 160*1c1d842eSAndreas Gohr { 161*1c1d842eSAndreas Gohr $partner = $this->getConf('partner_' . $country); 162*1c1d842eSAndreas Gohr if (!$partner) $partner = 'none'; 163*1c1d842eSAndreas Gohr $region = self::REGIONS[$country]; 164*1c1d842eSAndreas Gohr 165*1c1d842eSAndreas Gohr $attr = [ 166*1c1d842eSAndreas Gohr 'ServiceVersion' => '20070822', 167*1c1d842eSAndreas Gohr 'OneJS' => '1', 168*1c1d842eSAndreas Gohr 'Operation' => 'GetAdHtml', 169*1c1d842eSAndreas Gohr 'MarketPlace' => strtoupper($country), 170*1c1d842eSAndreas Gohr 'source' => 'ss', 171*1c1d842eSAndreas Gohr 'ref' => 'as_ss_li_til', 172*1c1d842eSAndreas Gohr 'ad_type' => 'product_link', 173*1c1d842eSAndreas Gohr 'tracking_id' => $partner, 174*1c1d842eSAndreas Gohr 'marketplace' => 'amazon', 175*1c1d842eSAndreas Gohr 'region' => strtoupper($country), 176*1c1d842eSAndreas Gohr 'placement' => '0670022411', 177*1c1d842eSAndreas Gohr 'asins' => $asin, 178*1c1d842eSAndreas Gohr 'show_border' => 'true', 179*1c1d842eSAndreas Gohr 'link_opens_in_new_window' => 'true', 180*1c1d842eSAndreas Gohr ]; 181*1c1d842eSAndreas Gohr $url = 'http://' . $region . '.amazon-adsystem.com/widgets/q?' . buildURLparams($attr, '&'); 182*1c1d842eSAndreas Gohr 183*1c1d842eSAndreas Gohr $http = new DokuHTTPClient(); 184*1c1d842eSAndreas Gohr $html = $http->get($url); 185*1c1d842eSAndreas Gohr if (!$html) { 186*1c1d842eSAndreas Gohr throw new \Exception('Failed to fetch data. Status ' . $http->status); 187*1c1d842eSAndreas Gohr } 188*1c1d842eSAndreas Gohr 189*1c1d842eSAndreas Gohr $result = []; 190*1c1d842eSAndreas Gohr 191*1c1d842eSAndreas Gohr if (preg_match('/class="price".*?>(.*?)<\/span>/s', $html, $m)) { 192*1c1d842eSAndreas Gohr $result['price'] = $m[1]; 193*1c1d842eSAndreas Gohr } 194*1c1d842eSAndreas Gohr 195*1c1d842eSAndreas Gohr if (preg_match('/<a .* id="titlehref" [^>]*?>([^<]*?)<\/a>/s', $html, $m)) { 196*1c1d842eSAndreas Gohr $result['title'] = $m[1]; 197*1c1d842eSAndreas Gohr } 198*1c1d842eSAndreas Gohr 199*1c1d842eSAndreas Gohr if (preg_match('/<a .* id="titlehref" href=(.*?) /s', $html, $m)) { 200*1c1d842eSAndreas Gohr $result['url'] = trim($m[1], '\'"'); 201*1c1d842eSAndreas Gohr } 202*1c1d842eSAndreas Gohr 203*1c1d842eSAndreas Gohr $result['img'] = $this->getImageURL($asin, $country); 204*1c1d842eSAndreas Gohr 205*1c1d842eSAndreas Gohr return $result; 206*1c1d842eSAndreas Gohr } 207*1c1d842eSAndreas Gohr 208*1c1d842eSAndreas Gohr /** 209*1c1d842eSAndreas Gohr * @param $asin 210*1c1d842eSAndreas Gohr * @param $country 211*1c1d842eSAndreas Gohr * @return string 212*1c1d842eSAndreas Gohr */ 213*1c1d842eSAndreas Gohr protected function getImageURL($asin, $country) 214*1c1d842eSAndreas Gohr { 215*1c1d842eSAndreas Gohr $partner = $this->getConf('partner_' . $country); 216*1c1d842eSAndreas Gohr if (!$partner) $partner = 'none'; 217*1c1d842eSAndreas Gohr $region = self::REGIONS[$country]; 218*1c1d842eSAndreas Gohr 219*1c1d842eSAndreas Gohr $attr = [ 220*1c1d842eSAndreas Gohr '_encoding' => 'UTF8', 221*1c1d842eSAndreas Gohr 'ASIN' => $asin, 222*1c1d842eSAndreas Gohr 'Format' => '_SL250_', 223*1c1d842eSAndreas Gohr 'ID' => 'AsinImage', 224*1c1d842eSAndreas Gohr 'MarketPlace' => strtoupper($country), 225*1c1d842eSAndreas Gohr 'ServiceVersion' => '20070822', 226*1c1d842eSAndreas Gohr 'WS' => '1', 227*1c1d842eSAndreas Gohr 'tag' => $partner, 228*1c1d842eSAndreas Gohr ]; 229*1c1d842eSAndreas Gohr $url = 'http://' . $region . '.amazon-adsystem.com/widgets/q?' . buildURLparams($attr, '&'); 230*1c1d842eSAndreas Gohr 231*1c1d842eSAndreas Gohr return $url; 232*1c1d842eSAndreas Gohr } 233*1c1d842eSAndreas Gohr 234*1c1d842eSAndreas Gohr} 235*1c1d842eSAndreas Gohr 236