1<?php
2/**
3 @file       linkbonus/syntax/external.php
4 @brief      External syntax component for Linkbonus plugin.
5 @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 @author     Luis Machuca Bezzaza <luis.machuca [at] gulix.cl>
7 @version    0.04
8**/
9
10if(!defined('DW_LF')) define('DW_LF',"\n");
11
12if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
13if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
14require_once(DOKU_PLUGIN.'syntax.php');
15require_once(DOKU_PLUGIN. 'linkbonus/common.php'); // for common functions
16
17/**
18 * All DokuWiki plugins to extend the parser/rendering mechanism
19 * need to inherit from this class
20 */
21class syntax_plugin_linkbonus_external extends DokuWiki_Syntax_Plugin {
22
23    /**
24     * return some info
25     */
26    function getInfo() {
27        return DW_common_linkbonus::getInfo($this);
28    }
29
30    function getType() {
31        return DW_common_linkbonus::getType();
32    }
33
34    // priority can be increased via the 'priority' option
35    function getSort() {
36        return ($this->getConf('priority') == 0) ? 290 : 240;
37    }
38
39//    function getAllowedTypes() {
40//        return array();
41//    }
42
43    function connectTo($mode) {
44
45        /**
46        * we catch the following syntax:
47        * [[http(s)://somewhere.com/some/path|Link name|Link title|(fetchname?)|]]
48        *
49        */
50        $linkpart  = '[^\|\]]+'; // everything 'till the pipe
51        $namepart  = '[^\|\](?:\{\{|\}\})]+'; // we must NOT catch image links
52        $otherpart = '[^\]]+';
53        $REGEX     =
54        '\[\[http:\/\/'.$linkpart. '\|'. $namepart. '\|'. $otherpart. '\]\]';
55        $this->Lexer->addSpecialPattern(
56            $REGEX,$mode,'plugin_linkbonus_external');
57    }
58
59
60    /**
61     * Handle the match
62     */
63    function handle($match, $state, $pos, &$handler) {
64        $match = substr($match, 2, -2);
65        /* split with non-escaped pipes ;)
66           result should be something like:
67           http://link  |  Name  | [Title] [ | parameters... ] */
68        $data  = preg_split('/(?<!\\\\)\|/', $match);
69        $link= array();
70        $link['url']     = array_shift($data);
71        $link['name']    = array_shift($data);
72        $link['title']   = array_shift($data);
73
74        /* If link-title is empty, use the same contents as link-name */
75        if (empty($link['title']) ) $link['title']= $link['name'];
76
77        /* Unescape pipes */
78        $link['name']  = str_replace ('\|', '|', $link['name']);
79        $link['title'] = str_replace ('\|', '|', $link['title']);
80
81
82        /* normal-link sanity check:
83           if at this point $data is empty, we are dealing with a
84           "normal" dokuwiki link and we can let DokuWiki take care of it
85        */
86        if (empty($data) && empty($link['title']) ) {
87          $handler->_addCall('externallink',array( $link['url'],$link['name'] ), $pos);
88          return array();
89          }
90        /* there is still the chance that we are dealing with a media link
91        */
92
93        /* check the rest of the parameters */
94        $set      = array(); // {false} if paramenter has not been detected
95        $dofetch  = false;
96        $dodoa    = false;
97
98        /* check if the page is actually a web page (eg.: not an image) */
99        //if (mimetype($link['url']) !== 'text/html') {
100        //  $handler->_addCall('externallink',array( $link['url'],$link['name'] ), $pos);
101        //  return array();
102        //  }
103
104        // list of allowed parameters
105        $keys     = array(
106        'fetchname', 'doa', 'class', 'rel', 'target',
107        );
108        if ($this->getConf('link_favicons') == true) $keys[]= 'favicon';
109
110        $options  = array();
111        DW_common_linkbonus::parse_options ($data, $link, $keys);
112
113        // parse fetchname
114        if (array_key_exists('fetchname', $link)) {
115            $dofetch= true;
116            if ($link['fetchname'] === '' || empty($link['fetchname'])) $link['fetchname'] = 'title';
117            }
118
119        /* -----------------------------------------------------------
120           PostProcess some requirements
121         */
122
123        /* if there is any need to fetch external page, do so */
124        $xcontents= '';
125        $xstatus= array();
126
127        $pagestatus= false;
128        if ($link['doa'] || $link['fetchname']) {
129          $pagestatus = DW_common_linkbonus::_doTestPage($link['url']);
130          }
131
132        if ($link['fetchname']) {
133          if ($pagestatus == 'text/html') $ext_title= DW_common_linkbonus::_doGetPageTitle($link['url']);
134          else $ext_title = $link['name']. " file $pagestatus";
135
136          if ($link['fetchname'] == 'tooltip') $link['title'] = $ext_title;
137          else if ($link['fetchname'] == 'title') $link['name']= $ext_title;
138          } // end try fetch title
139
140        if (array_key_exists('doa', $link)) {
141          $link['class'].= ($pagestatus === false) ? 'doa_error' : 'doa_ok';
142          $link['title'].= ' '. $this->getLang(($pagestatus===false) ? 'doa_no' : 'doa_ok');
143          unset($link['doa']);
144          } // end dead-or-alive check
145
146        $link['class']= 'urlextern '. $link['class']; // default DW external-link class
147        $link['format'] = $this->getConf('in_formatting');
148
149        /* -----------------------------------------------------
150          at this point we have all the information required to
151          ask the Renderer system to create the link */
152
153        $data= array(
154         'link'   => $link,
155         'match'  => $match,
156         'state'  => $state
157         );
158        return $data;
159      }
160
161    /**
162     * Create output
163     */
164    function render($mode, &$renderer, $data) {
165      return DW_common_linkbonus::syntax_render($mode, $renderer, $data, 'external');
166      }
167
168}
169
170