1<?php
2/*
3description : Display Airtight AutoViewer
4author      : Ikuo Obataya
5email       : I.Obataya@gmail.com
6lastupdate  : 2008-07-03
7depends     : cache (2008-03-22 or later)
8license     : GPL 2 (http://www.gnu.org/licenses/gpl.html)
9*/
10
11if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
12  require_once(DOKU_INC.'inc/init.php');
13if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
14  require_once(DOKU_PLUGIN.'syntax.php');
15if (!class_exists('JpegMeta')) @require(DOKU_INC.'inc/JpegMeta.php');
16
17if(!file_exists(DOKU_PLUGIN.'cache/plugin_cache.php')){
18  echo '<b>AViewer plugin requires <a href="http://wiki.symplus.co.jp/computer/en/cache_plugin" target="_blank">cache plugin.</b>';
19  exit;
20}
21if (!class_exists('plugin_cache')) @require(DOKU_PLUGIN.'cache/plugin_cache.php');
22
23class syntax_plugin_aviewer extends DokuWiki_Syntax_Plugin {
24  var $xmlCache;
25  var $attrPattern;
26  var $listPattern;
27  var $swfLoc;
28  var $swfObjPath;
29  // Constructor
30  function syntax_plugin_aviewer(){
31    $this->xmlCache    = new plugin_cache("aviewer",'',"xml");
32    $this->attrPattern = '/(\d+) (\d+)( left| right| noalign)?>|(clear_cache)>|(remove_dir)>/';
33
34    $this->listPattern = '/\{\{([^}|]+)\|?([^}]*)\}\}/';
35    $this->swfLoc      = DOKU_BASE.'lib/plugins/aviewer/autoviewer/autoviewer.swf';
36    $this->swfJsPath   = DOKU_BASE.'lib/plugins/aviewer/autoviewer/swfobject.js';
37  }
38  function getInfo(){
39    return array(
40      'author' => 'Ikuo Obataya',
41      'email'  => 'I.Obataya@gmail.com',
42      'date'  => '2008-07-03',
43      'name'  => 'Airtight AutoViewer plugin',
44      'desc'  => 'Create AutoViewer by www.airtightinteractive.com
45      <aviewer>
46      image files or media namespace
47      </aviewer>',
48      'url'  => 'http://wiki.symplus.co.jp/computer/en/aviewer_plugin',
49    );
50  }
51  function getType(){  return 'protected';  }
52  function getSort(){  return 917;  }
53  // Entry
54  function connectTo($mode) {
55    $this->Lexer->addEntryPattern('<aviewer(?=.*?>.*?</aviewer>)',$mode,'plugin_aviewer');
56  }
57  // Exit
58  function postConnect() {
59    $this->Lexer->addExitPattern('</aviewer>','plugin_aviewer');
60  }
61  // Handler
62  function handle($match, $state, $pos) {
63    global $ID;
64    global $conf;
65    switch ($state) {
66      case DOKU_LEXER_UNMATCHED :
67        $m = preg_match_all($this->attrPattern,$match,$cmd);
68
69        if ($m!=1){
70          $width  = $this->getConf('width');
71          $height = $this->getConf('height');
72        }else{
73          // extra commands
74          if ($cmd[3][0]=='clear_cache'){$this->xmlCache->ClearCache();return array($state,'');}
75          if ($cmd[4][0]=='remove_dir') {$this->xmlCache->RemoveDir(); return array($state,'');}
76
77          // width/height/alignment
78          $width  = $cmd[1][0];
79          $height = $cmd[2][0];
80          $align  = $cmd[3][0];
81        }
82        if(empty($align)) $align = $this->getConf('align');
83
84        $sz = preg_match_all($this->listPattern,$match,$img);
85        if ($sz==0){
86          $img = array();
87          $img[1][0] = getNS($ID);
88          $img[2][0] = $ID;
89          $sz = 1;
90        }
91
92        $xml.=sprintf('<?xml version="1.0" encoding="UTF-8"?>
93                       <gallery frameColor="%s" frameWidth="%d" imagePadding="%d" displayTime="%d" enableRightClickOpen="%s">',
94                       $this->getConf('frameColor'),
95                       $this->getConf('frameWidth'),
96                       $this->getConf('imagePadding'),
97                       $this->getConf('displayTime'),
98                       $this->getConf('enableRightClickOpen')?'true':'false').NL;
99
100        for($i=0;$i<$sz;$i++){
101
102          // build filepaths from an input line
103          $mediaID   = (substr($mediaID,0,1)==':')?substr($img[1][$i],1):$img[1][$i];
104          $path      = mediaFN($mediaID);
105          $mlink     = ml($mediaID,'',true,'',true);
106          $caption   = $img[2][$i];
107          $paths     = array();
108          $urls      = array();
109
110          if(is_dir($path)){
111            // get file paths from a namespace
112            $d = $conf['useslash']?'/':':';
113            $dir_handle = @opendir($path);
114            $caption = '(in '.$mediaID.')';
115            while(($f = readdir($dir_handle))!==false){
116              $p = $path.'/'.$f;
117              if ($f=='.'||$f=='..'||is_dir($p)) continue;
118              $paths[] = $p;
119              $urls[]  = $mlink.$d.$f;
120            }
121            @closedir($dir_handle);
122          }else{
123            // get file path
124            $paths[] = $path;
125            $urls[]  = $mlink;
126          }
127
128          $fsz = count($paths);
129          for($j=0;$j<$fsz;$j++){
130            $path = $paths[$j];
131            $url = $urls[$j];
132            $title = (empty($caption))?$path:$caption;
133            if(!file_exists($path))continue;
134            $jm      = new JpegMeta($path);
135            $f       = @$jm->getResizeRatio($width,$height);
136            $info    = @$jm->getBasicInfo();
137            $rwidth  = floor($info['Width']*$f);
138            $rheight = floor($info['Height']*$f);
139            $xml.='<image>'.NL;
140            $xml.='  <url>'.$url.'</url>'.NL;
141            $xml.='  <caption>'.$title.'</caption>'.NL;
142            $xml.='  <width>'.$rwidth.'</width>'.NL;
143            $xml.='  <height>'.$rheight.'</height>'.NL;
144            $xml.='</image>'.NL;
145          }
146        }
147        $xml.='</gallery>'.NL;
148        return array($state, array($xml,$width,$height,$align));
149
150      case DOKU_LEXER_ENTER :return array($state,$match);
151      case DOKU_LEXER_EXIT  :return array($state, '');
152    }
153  }
154  // Render
155  function render($mode, &$renderer, $data){
156    if ($mode!='xhtml') return false;
157    global $conf;
158    list($state, $match) = $data;
159    switch ($state) {
160      case DOKU_LEXER_ENTER: break;
161      case DOKU_LEXER_UNMATCHED:
162        if (empty($match))
163          return;
164
165        list($xml,$width,$height,$align)=$match;
166        $hash = md5(serialize($match));
167        $savePath = $this->xmlCache->GetMediaPath($hash);
168        if (!file_exists($savePath)){
169          if(io_saveFile($savePath, $xml)){
170            chmod($savePath,$conf['fmode']);
171          }
172        }
173        $fetchPath = ml('aviewer:'.$hash.'.xml','',true,'',true);
174        $renderer->doc.=sprintf('<div class="aviewer"><div class="%s">
175                                 <div id="flashcontent">AutoViewer requires JavaScript and the Flash Player. <a href="http://www.macromedia.com/go/getflashplayer/">Get Flash here.</a></div>
176                                 <script type="text/javascript" src="%s"></script>
177                                 <script type="text/javascript">
178                                   var fo = new SWFObject("%s", "autoviewer", "%s", "%s", "8", "%s");
179                                   fo.addVariable("xmlURL","%s");
180                                   fo.write("flashcontent");
181                                 </script>
182                                 </div></div>',
183                                $align,
184                                $this->swfJsPath,
185                                $this->swfLoc,
186                                $width,
187                                $height,
188                                $this->getConf('bgcolor'),
189                                $fetchPath);
190        break;
191      case DOKU_LEXER_EXIT: break;
192    }
193    return true;
194  }
195 /**
196  * Build <image> element by fetch url and caption
197  */
198  function getImageElement($url,$caption){
199    $path = $paths[$j];
200    $url = $urls[$j];
201    $title = (empty($caption))?$path:$caption;
202    if(!file_exists($path))continue;
203    $jm      = new JpegMeta($path);
204    $f       = @$jm->getResizeRatio($width,$height);
205    $info    = @$jm->getBasicInfo();
206    $rwidth  = floor($info['Width']*$f);
207    $rheight = floor($info['Height']*$f);
208    $xml.='<image>'.NL;
209    $xml.='  <url>'.$url.'</url>'.NL;
210    $xml.='  <caption>'.$title.'</caption>'.NL;
211    $xml.='  <width>'.$rwidth.'</width>'.NL;
212    $xml.='  <height>'.$rheight.'</height>'.NL;
213    $xml.='</image>'.NL;
214    return $xml;
215  }
216 /**
217  * print debug info
218  */
219  function _aviewer_debug($msg){
220    global $conf;
221    if($conf['allowdebug']!=0){
222      echo '<!-- aviewer plugin debug:'.$msg.'-->'.NL;
223    }
224  }
225}
226?>