OSDN Git Service

BugTrack/2396 Support Page redurection rules on make_pagelink()
[pukiwiki/pukiwiki.git] / lib / make_link.php
index 9e8be56..598ce07 100644 (file)
@@ -1,8 +1,8 @@
 <?php
 // PukiWiki - Yet another WikiWikiWeb clone.
-// $Id: make_link.php,v 1.24 2005/05/15 07:45:54 henoheno Exp $
-// Copyright (C)
-//   2003-2005 PukiWiki Developers Team
+// make_link.php
+// Copyright
+//   2003-2016 PukiWiki Development Team
 //   2001-2002 Originally written by yu-ji
 // License: GPL v2 or (at your option) any later version
 //
@@ -52,6 +52,10 @@ class InlineConverter
 
        function InlineConverter($converters = NULL, $excludes = NULL)
        {
+               $this->__construct($converters, $excludes);
+       }
+       function __construct($converters = NULL, $excludes = NULL)
+       {
                if ($converters === NULL) {
                        $converters = array(
                                'plugin',        // Inline plugins
@@ -95,7 +99,7 @@ class InlineConverter
                $string = preg_replace_callback('/' . $this->pattern . '/x',
                        array(& $this, 'replace'), $string);
 
-               $arr = explode("\x08", make_line_rules(htmlspecialchars($string)));
+               $arr = explode("\x08", make_line_rules(htmlsc($string)));
                $retval = '';
                while (! empty($arr)) {
                        $retval .= array_shift($arr) . array_shift($this->result);
@@ -108,7 +112,7 @@ class InlineConverter
                $obj = $this->get_converter($arr);
 
                $this->result[] = ($obj !== NULL && $obj->set($arr, $this->page) !== FALSE) ?
-                       $obj->toString() : make_line_rules(htmlspecialchars($arr[0]));
+                       $obj->toString() : make_line_rules(htmlsc($arr[0]));
 
                return "\x08"; // Add a mark into latest processed part
        }
@@ -150,9 +154,12 @@ class Link
        var $body;
        var $alias;
 
-       // Constructor
        function Link($start)
        {
+               $this->__construct($start);
+       }
+       function __construct($start)
+       {
                $this->start = $start;
        }
 
@@ -185,9 +192,9 @@ class Link
                $this->name = $name;
                $this->body = $body;
                $this->type = $type;
-               if (is_url($alias) && preg_match('/\.(gif|png|jpe?g)$/i', $alias)) {
-                       $alias = htmlspecialchars($alias);
-                       $alias = '<img src="' . $alias . '" alt="' . $name . '" />';
+               if (! PKWK_DISABLE_INLINE_IMAGE_FROM_URI &&
+                       is_url($alias) && preg_match('/\.(gif|png|jpe?g)$/i', $alias)) {
+                       $alias = '<img src="' . htmlsc($alias) . '" alt="' . $name . '" />';
                } else if ($alias != '') {
                        if ($converter === NULL)
                                $converter = new InlineConverter(array('plugin'));
@@ -211,7 +218,11 @@ class Link_plugin extends Link
 
        function Link_plugin($start)
        {
-               parent::Link($start);
+               $this->__construct($start);
+       }
+       function __construct($start)
+       {
+               parent::__construct($start);
        }
 
        function get_pattern()
@@ -270,7 +281,7 @@ EOD;
                } else {
                        // No such plugin, or Failed
                        $body = (($body == '') ? '' : '{' . $body . '}') . ';';
-                       return make_line_rules(htmlspecialchars('&' . $this->plain) . $body);
+                       return make_line_rules(htmlsc('&' . $this->plain) . $body);
                }
        }
 }
@@ -280,14 +291,18 @@ class Link_note extends Link
 {
        function Link_note($start)
        {
-               parent::Link($start);
+               $this->__construct($start);
+       }
+       function __construct($start)
+       {
+               parent::__construct($start);
        }
 
        function get_pattern()
        {
                return <<<EOD
 \(\(
- ((?:(?R)|(?!\)\)).)*) # (1) note body
+ ((?>(?=\(\()(?R)|(?!\)\)).)*) # (1) note body
 \)\)
 EOD;
        }
@@ -304,9 +319,11 @@ EOD;
 
                list(, $body) = $this->splice($arr);
 
-               $script = '';
-               if (! PKWK_ALLOW_RELATIVE_FOOTNOTE_ANCHOR)
-                       $script = get_script_uri() . '?' . $page;
+               if (PKWK_ALLOW_RELATIVE_FOOTNOTE_ANCHOR) {
+                       $script = '';
+               } else {
+                       $script = get_script_uri() . '?' . pagename_urlencode($page);
+               }
 
                $id   = ++$note_id;
                $note = make_link($body);
@@ -319,9 +336,18 @@ EOD;
                        '<span class="small">' . $note . '</span><br />';
 
                // A hyperlink, content-body to footnote
+               if (! is_numeric(PKWK_FOOTNOTE_TITLE_MAX) || PKWK_FOOTNOTE_TITLE_MAX <= 0) {
+                       $title = '';
+               } else {
+                       $title = strip_tags($note);
+                       $count = mb_strlen($title, SOURCE_ENCODING);
+                       $title = mb_substr($title, 0, PKWK_FOOTNOTE_TITLE_MAX, SOURCE_ENCODING);
+                       $abbr  = (mb_strlen($title) < $count) ? '...' : '';
+                       $title = ' title="' . $title . $abbr . '"';
+               }
                $name = '<a id="notetext_' . $id . '" href="' . $script .
-                       '#notefoot_' . $id . '" class="note_super" title="' .
-                       htmlspecialchars(strip_tags($note)) . '">*' . $id . '</a>';
+                       '#notefoot_' . $id . '" class="note_super"' . $title .
+                       '>*' . $id . '</a>';
 
                return parent::setParam($page, $name, $body);
        }
@@ -337,18 +363,23 @@ class Link_url extends Link
 {
        function Link_url($start)
        {
-               parent::Link($start);
+               $this->__construct($start);
+       }
+       function __construct($start)
+       {
+               parent::__construct($start);
        }
 
        function get_pattern()
        {
                $s1 = $this->start + 1;
                return <<<EOD
-(\[\[             # (1) open bracket
- ((?:(?!\]\]).)+) # (2) alias
+((?:\[\[))?       # (1) open bracket
+((?($s1)          # (2) alias
+((?:(?!\]\]).)+)  # (3) alias name
  (?:>|:)
-)?
-(                 # (3) url
+))?
+(                 # (4) url
  (?:(?:https?|ftp|news):\/\/|mailto:)[\w\/\@\$()!?&%#:;.,~'=*+-]+
 )
 (?($s1)\]\])      # close bracket
@@ -357,13 +388,13 @@ EOD;
 
        function get_count()
        {
-               return 3;
+               return 4;
        }
 
        function set($arr, $page)
        {
-               list(, , $alias, $name) = $this->splice($arr);
-               return parent::setParam($page, htmlspecialchars($name),
+               list(, , $alias, $name) = $this->splice($arr);
+               return parent::setParam($page, htmlsc($name),
                        '', 'url', $alias == '' ? $name : $alias);
        }
 
@@ -383,7 +414,11 @@ class Link_url_interwiki extends Link
 {
        function Link_url_interwiki($start)
        {
-               parent::Link($start);
+               $this->__construct($start);
+       }
+       function __construct($start)
+       {
+               parent::__construct($start);
        }
 
        function get_pattern()
@@ -407,7 +442,7 @@ EOD;
        function set($arr, $page)
        {
                list(, $name, $alias) = $this->splice($arr);
-               return parent::setParam($page, htmlspecialchars($name), '', 'url', $alias);
+               return parent::setParam($page, htmlsc($name), '', 'url', $alias);
        }
 
        function toString()
@@ -423,7 +458,11 @@ class Link_mailto extends Link
 
        function Link_mailto($start)
        {
-               parent::Link($start);
+               $this->__construct($start);
+       }
+       function __construct($start)
+       {
+               parent::__construct($start);
        }
 
        function get_pattern()
@@ -465,7 +504,11 @@ class Link_interwikiname extends Link
 
        function Link_interwikiname($start)
        {
-               parent::Link($start);
+               $this->__construct($start);
+       }
+       function __construct($start)
+       {
+               parent::__construct($start);
        }
 
        function get_pattern()
@@ -508,12 +551,12 @@ EOD;
 
                $url = get_interwiki_url($name, $this->param);
                $this->url = ($url === FALSE) ?
-                       $script . '?' . rawurlencode('[[' . $name . ':' . $this->param . ']]') :
-                       htmlspecialchars($url);
+                       $script . '?' . pagename_urlencode('[[' . $name . ':' . $this->param . ']]') :
+                       htmlsc($url);
 
                return parent::setParam(
                        $page,
-                       htmlspecialchars($name . ':' . $this->param),
+                       htmlsc($name . ':' . $this->param),
                        '',
                        'InterWikiName',
                        $alias == '' ? $name . ':' . $this->param : $alias
@@ -534,7 +577,11 @@ class Link_bracketname extends Link
 
        function Link_bracketname($start)
        {
-               parent::Link($start);
+               $this->__construct($start);
+       }
+       function __construct($start)
+       {
+               parent::__construct($start);
        }
 
        function get_pattern()
@@ -596,7 +643,11 @@ class Link_wikiname extends Link
 {
        function Link_wikiname($start)
        {
-               parent::Link($start);
+               $this->__construct($start);
+       }
+       function __construct($start)
+       {
+               parent::__construct($start);
        }
 
        function get_pattern()
@@ -637,9 +688,13 @@ class Link_autolink extends Link
 
        function Link_autolink($start)
        {
+               $this->__construct($start);
+       }
+       function __construct($start)
+       {
                global $autolink;
 
-               parent::Link($start);
+               parent::__construct($start);
 
                if (! $autolink || ! file_exists(CACHE_DIR . 'autolink.dat'))
                        return;
@@ -675,7 +730,7 @@ class Link_autolink extends Link
 
        function toString()
        {
-               return make_pagelink($this->name, $this->alias, '', $this->page);
+               return make_pagelink($this->name, $this->alias, '', $this->page, TRUE);
        }
 }
 
@@ -683,7 +738,11 @@ class Link_autolink_a extends Link_autolink
 {
        function Link_autolink_a($start)
        {
-               parent::Link_autolink($start);
+               $this->__construct($start);
+       }
+       function __construct($start)
+       {
+               parent::__construct($start);
        }
 
        function get_pattern()
@@ -693,38 +752,57 @@ class Link_autolink_a extends Link_autolink
 }
 
 // Make hyperlink for the page
-function make_pagelink($page, $alias = '', $anchor = '', $refer = '')
+function make_pagelink($page, $alias = '', $anchor = '', $refer = '', $isautolink = FALSE)
 {
        global $script, $vars, $link_compact, $related, $_symbol_noexists;
 
-       $s_page = htmlspecialchars(strip_bracket($page));
+       $s_page = htmlsc(strip_bracket($page));
        $s_alias = ($alias == '') ? $s_page : $alias;
 
        if ($page == '') return '<a href="' . $anchor . '">' . $s_alias . '</a>';
 
-       $r_page  = rawurlencode($page);
+       $r_page  = pagename_urlencode($page);
        $r_refer = ($refer == '') ? '' : '&amp;refer=' . rawurlencode($refer);
 
-       if (! isset($related[$page]) && $page != $vars['page'] && is_page($page))
+       if (! isset($related[$page]) && $page !== $vars['page'] && is_page($page))
                $related[$page] = get_filetime($page);
 
-       if (is_page($page)) {
-               // Hyperlinks
-               $passage = get_pg_passage($page, FALSE);
-               $title   = $link_compact ? '' : ' title="' . $s_page . $passage . '"';
-               return '<a href="' . $script . '?' . $r_page . $anchor . '"' . $title . '>' .
-                       $s_alias . '</a>';
-       } else if (PKWK_READONLY) {
-               // Without hyperlink (= Suppress dangling link)
-               return $s_alias;
+       if ($isautolink || is_page($page)) {
+               // Hyperlink to the page
+               if ($link_compact) {
+                       $title   = '';
+               } else {
+                       $title   = ' title="' . $s_page . get_pg_passage($page, FALSE) . '"';
+               }
+
+               // AutoLink marker
+               if ($isautolink) {
+                       $al_left  = '<!--autolink-->';
+                       $al_right = '<!--/autolink-->';
+               } else {
+                       $al_left = $al_right = '';
+               }
+
+               return $al_left . '<a ' . 'href="' . $script . '?' . $r_page . $anchor .
+                       '"' . $title . '>' . $s_alias . '</a>' . $al_right;
        } else {
-               // Dangling links
+               // Support Page redirection
+               $redirect_page = get_pagename_on_redirect($page);
+               if ($redirect_page !== false) {
+                       return make_pagelink($redirect_page, $s_alias);
+               }
+               // Dangling link
+               if (PKWK_READONLY) return $s_alias; // No dacorations
+
                $retval = $s_alias . '<a href="' .
                        $script . '?cmd=edit&amp;page=' . $r_page . $r_refer . '">' .
                        $_symbol_noexists . '</a>';
-               if (! $link_compact)
-                       $retval = '<span class="noexists">' . $retval . '</span>';
-               return $retval;
+
+               if ($link_compact) {
+                       return $retval;
+               } else {
+                       return '<span class="noexists">' . $retval . '</span>';
+               }
        }
 }
 
@@ -811,7 +889,12 @@ function get_interwiki_url($name, $param)
                if (isset($encode_aliases[$opt])) $opt = & $encode_aliases[$opt];
 
                // Encoding conversion into specified encode, and URLencode
-               $param = rawurlencode(mb_convert_encoding($param, $opt, SOURCE_ENCODING));
+               if (strpos($url, '$1') === FALSE && substr($url, -1) === '?') {
+                       // PukiWiki site
+                       $param = pagename_urlencode(mb_convert_encoding($param, $opt, SOURCE_ENCODING));
+               } else {
+                       $param = rawurlencode(mb_convert_encoding($param, $opt, SOURCE_ENCODING));
+               }
        }
 
        // Replace or Add the parameter
@@ -826,4 +909,3 @@ function get_interwiki_url($name, $param)
 
        return $url;
 }
-?>