1<?php
2/**
3 * @file       linkbonus/common.php
4 * @brief      Common functions for the linkbonus plugin
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @version    0.2
7 * @author     Luis Machuca Bezzaza <luis.machuca [at] gulix.cl>
8 */
9
10/* must be invoked from syntax/*.php
11 */
12if(!defined('DOKU_INC')) die();
13if(!defined('DOKU_PLUGIN')) die();
14@require_once (DOKU_INC. 'inc/confutils.php'); // for mimetype()
15
16/**
17 * @class DW_common_linkbonus
18 * @brief Common interface for linkbonus preliminar
19 */
20
21class DW_common_linkbonus {
22
23    static public function getInfo ($phandle=null) {
24        return array(
25        'author' => 'Luis Machuca Bezzaza',
26        'email'  => 'luis.machuca [at] gulix.cl',
27        'date'   => '2010-09-30',
28        'name'   => 'Linkbonus Plugin [preliminar]',
29        'desc'   => $phandle->getLang('descr'),
30        'url'    => 'http://ryan.gulix.cl/tests/doku.php/playground:linkbonus',
31        );
32      }
33
34    static public function getType () {
35      return 'formatting';
36      }
37
38    static public function getAllowedTypes() {
39      return array('formatting');
40      }
41
42    static public function getPType () {
43      return 'normal';
44      }
45
46
47    static public function syntax_render ($mode, &$renderer, $data, $type='external') {
48      if ($mode == 'xhtml') {
49        if (!empty($data) ) {
50          // do XHTML rendering
51          $info= array();
52          $link = $data['link'];
53          $link['url']  = hsc($link['url']);
54          // the following lines allow for rendering of internal syntax
55          // but it is done the "wrong" way -- weird things may happen!
56          //$link['name']= htmlentities($link['name'], ENT_NOQUOTES);
57          //$link['name']= p_render('xhtml', p_get_instructions($link['name']) , $info);
58          //$link['name']= substr($link['name'], 4, -5); // remove surrounding <p>..</p>
59
60          if (array_key_exists('favicon', $link) && $type==='external' && !DW_common_linkbonus::_isSSL()) {
61            $domain= parse_url($link['url']);
62            $domain= $domain['scheme']. '://'. $domain['host'];
63            $fvicon= $domain.'/favicon.ico';
64            $link['more'].= ' style="background-image: url('. $fvicon. ');"';
65            }
66          $fmt_enabled= $link['format'];
67          if ($fmt_enabled) {
68              $link['name']= preg_replace('#//(.+?)//#', '<em>$1</em>', $link['name']);
69              $link['name']= preg_replace('#\*\*(.+?)\*\*#', '<b>$1</b>', $link['name']);
70              //$link['name']= preg_replace('#//(.+?)//#', '<em>$1</em>', $link['name']);
71          }
72          $outp= $renderer->_formatLink($link);
73          // substitute //italics// and **bold**
74
75          //$renderer->doc .= '<pre>'. htmlspecialchars($outp). '</pre>';
76          $renderer->doc .= '<!-- linkbonus to ['. $link['url']. '] -->';
77          $renderer->doc .= $outp;
78          }
79        return true;
80        } // end XHTML parsing
81      return false;
82      }
83
84
85
86    /**
87     * Helper functions from this point
88     */
89
90    /**
91     * @fn     _getServerBase
92     * @brief  Returns the base URL of the server
93     * For use of the external syntax mode, maybe others.
94     */
95    static public function _getServerBase () {
96        return ($_SERVER['HTTPS']) ? 'https' : 'http'. '://'. $_SERVER['SERVER_NAME'];
97        //return $ans;
98        }
99
100    static public function _isSSL () {
101        return ($_SERVER['HTTPS']) ? true : false;
102        }
103
104    /**
105     * @fn     _doTestPage
106     * @brief  Tests if the page is available
107     * @return false if there is a retrieve error; the target type otherwise
108     */
109    function _doTestPage ($url) {
110
111      $context = stream_context_create(DW_common_linkbonus::_getDLContext());
112      $fc      = @file_get_contents ($url, false, $context, 0, 2048);
113      if ($fc === false) return false; // can not retrieve;
114      else {
115        // store the contents in a file to identify
116        $tmpfname = tempnam('/tmp', 'dwlb_');
117        //echo "**$tmpfname*";
118        $handle = fopen($tmpfname, "w");
119        fwrite($handle, $fc);
120        fclose($handle);
121        $type= '';
122        // use fileinfo to identify, we want a "text/html" file
123        $type = trim(shell_exec("file -bi " . $tmpfname));
124        return $type;
125
126        }
127      } // end function
128
129
130    function _doGetPageTitle ($url) {
131        $fetchsz  = 2048; // will try to locate the title in the first 2kib
132        $context  = stream_context_create(DW_common_linkbonus::_getDLContext());
133        $fc       = @file_get_contents ($url, NULL , $context , 0, $fetchsz);
134        $title    = array();
135        // try find the title inside
136        $res      = preg_match ("/<title>(.+)<\/title>/is", $fc, $title);
137        if ($res == 1) {
138            $title= trim($title[1]);
139            }
140        else {
141            $title= false;
142            }
143      // if there is a title limit, we return only the indicated number of words
144/*
145      $limit= $this->getConf('titlelimit');
146      if ($limit != 'no') {
147        $words= explode (' ', $title);
148        $wc   = count($words);
149        for ($i= $limit; $i < $wc; $i++) {
150          array_pop($words);
151          }
152        $title= implode(' ', $words);
153        }
154*/
155
156      return $title;
157    }
158
159    /**
160     @brief parse a "key=value|key2=value2" string into an options map
161     @param data the array containing the input data
162     @param[Out] options a { key=>value } map that will contain the parsed values
163     @param keys the list of allowed keys
164    **/
165    static public function parse_options ($data, &$options, $keys) {
166        $allow_all = ($keys === null);
167        foreach ($data as $D) {
168            list ($key, $val) = explode ('=', $D, 2);
169            if (!empty($val)) $val= substr($val, 1, -1); // unquote
170            else $val= ''; // explicit empty string
171            // if the key can be added and check in, add it in with its value
172            if ($allow_all || in_array($key, $keys, true)) {
173                $options[$key] = $val;
174                }
175            }
176        // exhausted all keys at this point
177
178    }
179
180    static private function _getDLContext () {
181        $timeout= 1.0;
182        if ($timeout > 5.0) $timeout= 5.0;
183        else if ($timeout < 0.5) $timeout= 0.5;
184        $copts = array(
185        'http' => array(
186                 'method' => 'GET',
187                 'max_redirects' => '2',
188                 'timeout' => "$timeout",
189                 )
190        );
191        return $copts;
192    } // end function
193
194
195} // end class
196
197
198