1 <?php
2 /**
3  * Backlinks: Show a list of backlinks for the given pagename
4  * Usage:
5  * {{backlinks>page}} to display the backlinks page in the current namespace
6  * {{backlinks>:page}} for "page" in top namespace
7  * {{backlinks>namespace:page}} for "page" in namespace "namespace"
8  * {{backlinks>.namespace:page}} for "page" in subnamespace "namespace"
9  *
10  */
11 
12 if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
13 if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
14 require_once(DOKU_PLUGIN.'syntax.php');
15 require_once(DOKU_INC.'inc/fulltext.php');
16 
17 /**
18  * All DokuWiki plugins to extend the parser/rendering mechanism
19  * need to inherit from this class
20  */
21 class syntax_plugin_backlinks extends DokuWiki_Syntax_Plugin {
22     /**
23      * return some info
24      */
25     function getInfo(){
26         return array(
27             'author' => 'Jonathan Arkell',
28             'email'  => 'jonnay@jonnay.net',
29             'date'   => '2005-10-24',
30             'name'   => 'Backlink Plugin',
31             'desc'   => 'Displays the backlinks for the given wikipage',
32             'url'    => 'https://www.dokuwiki.org/plugin:backlinks',
33         );
34     }
35 
36     /**
37      * What kind of syntax are we?
38      */
39     function getType(){
40         return 'substition';
41     }
42 
43     /**
44      * Where to sort in?
45      */
46     function getSort(){
47         return 30;
48     }
49 
50     /**
51      * Paragraph Type
52      */
53     function getPType(){
54         return 'block';
55     }
56 
57     /**
58      * Connect pattern to lexer
59      */
60     function connectTo($mode) {
61       $this->Lexer->addSpecialPattern("{{backlinks}}",$mode,'plugin_backlinks');
62     }
63 
64     /**
65      * Handle the match
66      */
67     function handle($match, $state, $pos, &$handler){
68         global $ID;
69 
70         $syntax = substr($match,12,-2);             // strip markup
71         $page = $ID;
72 
73         resolve_pageid(getNS($ID),$page,$exists);   // resolve shortcuts
74 
75         // check for permission
76         if (auth_quickaclcheck($page) < 1) return false;
77 
78         $links = ft_backlinks($page);
79         foreach ($links as $link)
80         {
81             $backlinks[substr($link, strrpos($link, ':')+1)] = $link;
82         }
83         ksort($backlinks);
84 
85         return array($page,$backlinks);
86     }
87 
88     /**
89      * Create output
90      */
91     function render($mode, &$renderer, $data) {
92         if($mode == 'xhtml'){
93             $file = wikiFN($data[0]);
94 
95             $renderer->doc .= '<div class="backlinks">';
96 
97             if (!empty($data[1]))
98             {
99                 $lastLetter = '';
100                 $pageList = array();
101                 array_push($data[1]," Dummy Entry"); // ugh.  Hacky Kludge.
102                 foreach($data[1] as $name => $page) {
103                     if ($name{0} != $lastLetter) {
104                         if (!empty($pageList)) {
105                             $renderer->doc .= '<h3>'.strtoupper($lastLetter).'</h3>';
106                             $this->renderPageList($renderer, $pageList);
107                             $pageList = array();
108                         }
109                     }
110                     $pageList[] = $page;
111                     $lastLetter = $name{0};
112                 }
113             } else {
114             	$renderer->doc .= "{$data[0]} has no backlinks";
115             }
116 
117             $renderer->doc .= '</div>';
118             return true;
119         }
120         return false;
121     }
122 
123     function renderpageList(&$renderer, $pageList)
124     {
125         if (empty ($pageList)) {
126             return;
127         }
128 
129         $renderer->doc .= '<ul>';
130         foreach($pageList as $page) {
131           $renderer->doc .= '<li>';
132           $renderer->internalLink($page, $page);
133           $renderer->doc .= '</li>';
134         }
135         $renderer->doc .= '</ul>';
136     }
137 
138     /**
139      * Corrects relative internal links and media
140      */
141     function _correctRelNS($instr,$incl){
142         global $ID;
143 
144         // check if included page is in same namespace
145         $iNS = getNS($incl);
146         if (getNS($ID) == $iNS) return $instr;
147 
148         // convert internal links and media from relative to absolute
149         $n = count($instr);
150         for($i = 0; $i < $n; $i++){
151             if (substr($instr[$i][0], 0, 8) == 'internal'){
152 
153                 // relative subnamespace
154                 if ($instr[$i][1][0]{0} == '.'){
155                     $instr[$i][1][0] = $iNS.':'.substr($instr[$i][1][0], 1);
156 
157                 // relative link
158                 } elseif (strpos($instr[$i][1][0],':') === false) {
159                     $instr[$i][1][0] = $iNS.':'.$instr[$i][1][0];
160                 }
161             }
162         }
163         return $instr;
164     }
165 }
166 
167 //Setup VIM: ex: et ts=4 enc=utf-8 :