1<?php
2/**
3 * Imageflow Plugin
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     i-net software <tools@inetsoftware.de>
7 * @author     Gerry Weissbach <gweissbach@inetsoftware.de>
8 */
9
10if(!defined('DOKU_INC')) die();
11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
12
13require_once(DOKU_PLUGIN.'syntax.php');
14require_once(DOKU_INC.'inc/search.php');
15require_once(DOKU_INC.'inc/JpegMeta.php');
16
17class syntax_plugin_imageflow_imageflow extends DokuWiki_Syntax_Plugin {
18
19    private $glideToImage = 0;
20    private $saveimages = '';
21    private $imagedoc = '';
22    private $namespace = null;
23    private $reflection_conf = false;
24    private $sectionID = array();
25    private $header = array();
26
27    function getType(){ return 'protected';}
28    function getAllowedTypes() { return array('container','substition','protected','disabled','formatting','paragraphs'); }
29    function getPType(){ return 'block';}
30
31    /**
32     * Where to sort in?
33     */
34    function getSort(){ return 301; }
35
36    /**
37     * Connect pattern to lexer
38     */
39    function connectTo($mode) {
40        $this->Lexer->addEntryPattern('<imageflow>(?=.*?</imageflow.*?>)',$mode,'plugin_imageflow_imageflow');
41        $this->Lexer->addEntryPattern('<imageflow [^>]+>(?=</imageflow.*?>)',$mode,'plugin_imageflow_imageflow');
42    }
43
44    function postConnect() {
45        $this->Lexer->addPattern('<image\s.*?>.*?</image>','plugin_imageflow_imageflow');
46        $this->Lexer->addPattern('[\r|\n]','plugin_imageflow_imageflow');
47        $this->Lexer->addExitPattern('</imageflow.*?>', 'plugin_imageflow_imageflow');
48    }
49
50    /**
51     * Handle the match
52     */
53    function handle($match, $state, $pos, Doku_Handler $handler){
54
55        switch ($state) {
56            case DOKU_LEXER_ENTER:
57
58                if ( $match == '<imageflow>' ) { return array('imageflow__start', null); }
59
60                if( preg_match('%<imageflow ([^>]+)>%', $match, $matches) ) {
61                    return array('imageflow__start', $matches[1]);
62                }
63
64                break;
65
66            case DOKU_LEXER_MATCHED:
67
68                if ( !(strstr($match, '<image') || strstr($match, '</image>')) ) { return false; }
69                list($orig, $desc) = explode('>', substr($match, 6, -8), 2);
70                list($src, $title) = explode('|', $orig, 2);
71                list($src, $params) = explode('?', $src, 2);
72                $paramsFull = explode('&', str_replace('&amp;', '&', $params));
73
74                $params = array();
75                foreach( $paramsFull as $item ) {
76                    list($key, $value) = explode('=', $item, 2);
77                    if ( $key == 'width' ) $key = 'w';
78                    if ( $key == 'height' ) $key = 'h';
79
80                    $params[$key] = $value;
81                }
82
83                $data = array('src' => trim($src), 'params' => $params, 'desc' => trim($desc), 'w' => 200, 'title' => trim($title));
84
85                if ( empty( $params['linkto'] ) ) {
86                    $data['isImage'] = true;
87                } else {
88                    $data['linkto'] = cleanID($params['linkto']);
89                    unset($params['linkto']);
90                }
91
92                return array('image', $data);
93                break;
94            case DOKU_LEXER_UNMATCHED:
95                break;
96            case DOKU_LEXER_EXIT:
97
98                if ( $match == '</imageflow>' ) { return array('imageflow__end', null); }
99                break;
100        }
101        return false;
102    }
103
104    /**
105     * Create output
106     */
107    function render($mode, Doku_Renderer $renderer, $input) {
108        global $conf;
109
110        list($instr, $data) = $input;
111
112        if( $mode == 'xhtml' || $mode == 'metadata' ) {
113
114            if ( !is_array($this->header[$mode]) ) {
115                $this->header[$mode] = array();
116            }
117
118            switch ( $instr ) {
119
120                case 'imageflow__start' :
121
122                    $this->sectionID[] = sectionID("imageflow_container_", $this->header[$mode]);
123                    $scID = $this->sectionID[sizeof($this->sectionID)-1];
124
125                    if ($mode == 'xhtml') $renderer->doc .= <<<OUTPUT
126    <div class="imageflow_wrapper" id="$scID">
127        <noscript>
128            <div class="hasscript">
129OUTPUT;
130                    if ( $data === null) { break; }
131
132                    $retData = array();
133                    list($id, $width) = explode('?', $data, 2);
134
135                    $dir = str_replace(':','/',cleanID($id));
136                    search($retData,$conf['mediadir'],'search_media',null,$dir);
137
138                    foreach ( $retData as $item ) {
139                        if ( !$item['isimg'] ) { continue; }
140
141                        $imgData = array( 'src' => $item['id'] );
142
143                        if ( empty($width)) $width = 300;
144                        $imgData['params'] = array('w' => intval($width));
145                        $imgData['id'] = sectionID(noNS($item['id']), $this->header[$mode]);
146                        $imgData['isImage'] = true;
147
148                        $this->_image($imgData, $renderer, $mode);
149                    }
150
151                    break;
152
153                case 'image' :
154                    $this->_image($data, $renderer, $mode);
155                    break;
156                case 'imageflow__end' :
157
158                    if (is_array($sectionID) && sizeOf($sectionID) > 0) {
159                        array_pop($sectionID);
160                    }
161                    if ($mode == 'xhtml') {
162                        $renderer->doc .= <<<OUTPUT
163            </div>
164        </noscript>
165    </div>
166OUTPUT;
167                    }
168                    break;
169            }
170            return true;
171        }
172
173        return false;
174    }
175
176    /**
177     * Defines how a thumbnail should look like
178     */
179    function _image($data, &$renderer=null, $mode='xhtml'){
180        global $ID;
181
182        if ( is_null($renderer) || empty($data['src']) ) { return false;}
183        if ( !is_array($data['params'])) { $data['params'] = array(); }
184
185        //prepare link attributes
186        // can use reflected images
187        $reflect = array();
188        if ( $reflection = plugin_load('syntax', 'reflect')) {
189            $reflect = array('reflect' => $this->getConf('reflect') ? 1 : 0, 'bgc' => $this->getConf('reflectBackground'));
190        }
191
192        // Start Section
193        if ($mode != 'metadata' ) $renderer->doc .= '<div class="imageflow_image">' . NL;
194
195        // Display
196        $data['params']['tok'] = media_get_token($data['src'], $data['params']['w'], $data['params']['h']);
197
198        $href = ml($data['src'], array_merge($data['params'], $reflect), true, '&');
199        if ($mode != 'metadata' && empty($data['alternate_desc']) ) $renderer->doc .= '<img src="' . $href . '" alt="" class="imageflow__noscript__image media"/>';
200
201        // Set Data
202        $fn = mediaFN($data['src']);
203        $data['src'] = ml($data['src']);
204        $data['params'] = array_merge($data['params'], $reflect); // Remove everything except the params.
205        $data['desc'] = trim($data['desc']);
206        $data['title'] = trim($data['title']);
207
208        if ( empty($data['desc']) && ($meta = new JpegMeta($fn))) {
209
210            $data['title'] = $meta->getField('Iptc.Headline');
211            $data['desc'] = $meta->getField('Iptc.Caption');
212        }
213
214        if ($mode != 'metadata') {
215
216            if ( !empty($data['alternate_desc']) ) {
217                $renderer->doc .= $data['alternate_desc'];
218            } else {
219
220                $renderer->doc .= '<div class="imageflow_caption">' . NL;
221                if ( !empty($data['title']) ) {
222                    $renderer->doc .= "<h3 class=\"imageflow__title\">{$data['title']}</h3>" . NL;
223                }
224                if ( !empty($data['desc']) ) {
225                    $renderer->doc .= "<p class=\"imageflow__text\">{$data['desc']}</p>" . NL;
226                }
227
228                // End Caption
229                $renderer->doc .= '</div>' . NL;
230            }
231            // End Section
232            $renderer->doc .= '<div class="clearer"></div>' . NL . '</div>' . NL;
233        } else {
234            // Add Metadata
235            unset($data['alternate_desc']);
236            if ( !$data['isImage'] && !empty( $data['linkto'] ) ) {
237                $data['id'] = $data['linkto'];
238                unset( $data['linkto'] );
239            }
240
241            $renderer->meta['relation']['imageflow'][$this->sectionID[sizeof($this->sectionID)-1]][] = $data;
242        }
243
244        return $data;
245    }
246
247    function isSingleton() {
248        return true;
249    }
250}
251
252//Setup VIM: ex: et ts=4 enc=utf-8 :
253