OSDN Git Service

Notice: Only variable references should be returned by reference
[pukiwiki/pukiwiki.git] / lib / link.php
1 <?php
2 // PukiWiki - Yet another WikiWikiWeb clone
3 // $Id: link.php,v 1.8 2005/12/10 12:00:52 henoheno Exp $
4 // Copyright (C) 2003-2005 PukiWiki Developers Team
5 // License: GPL v2 or (at your option) any later version
6 //
7 // Backlinks / AutoLinks related functions
8
9 // ------------------------------------------------------------
10 // DATA STRUCTURE of *.ref and *.rel files
11
12 // CACHE_DIR/encode('foobar').ref
13 // ---------------------------------
14 // Page-name1<tab>0<\n>
15 // Page-name2<tab>1<\n>
16 // ...
17 // Page-nameN<tab>0<\n>
18 //
19 //      0 = Added when link(s) to 'foobar' added clearly at this page
20 //      1 = Added when the sentence 'foobar' found from the page
21 //          by AutoLink feature
22
23 // CACHE_DIR/encode('foobar').rel
24 // ---------------------------------
25 // Page-name1<tab>Page-name2<tab> ... <tab>Page-nameN
26 //
27 //      List of page-names linked from 'foobar'
28
29 // ------------------------------------------------------------
30
31
32 // ¥Ç¡¼¥¿¥Ù¡¼¥¹¤«¤é´ØÏ¢¥Ú¡¼¥¸¤òÆÀ¤ë
33 function links_get_related_db($page)
34 {
35         $ref_name = CACHE_DIR . encode($page) . '.ref';
36         if (! file_exists($ref_name)) return array();
37
38         $times = array();
39         foreach (file($ref_name) as $line) {
40                 list($_page) = explode("\t", rtrim($line));
41                 $time = get_filetime($_page);   
42                 if($time != 0) $times[$_page] = $time;
43         }
44         return $times;
45 }
46
47 //¥Ú¡¼¥¸¤Î´ØÏ¢¤ò¹¹¿·¤¹¤ë
48 function links_update($page)
49 {
50         if (PKWK_READONLY) return; // Do nothing
51
52         if (ini_get('safe_mode') == '0') set_time_limit(0);
53
54         $time = is_page($page, TRUE) ? get_filetime($page) : 0;
55
56         $rel_old        = array();
57         $rel_file       = CACHE_DIR . encode($page) . '.rel';
58         $rel_file_exist = file_exists($rel_file);
59         if ($rel_file_exist === TRUE) {
60                 $lines = file($rel_file);
61                 unlink($rel_file);
62                 if (isset($lines[0]))
63                         $rel_old = explode("\t", rtrim($lines[0]));
64         }
65         $rel_new  = array(); // »²¾ÈÀè
66         $rel_auto = array(); // ¥ª¡¼¥È¥ê¥ó¥¯¤·¤Æ¤¤¤ë»²¾ÈÀè
67         $links    = links_get_objects($page, TRUE);
68         foreach ($links as $_obj) {
69                 if (! isset($_obj->type) || $_obj->type != 'pagename' ||
70                     $_obj->name == $page || $_obj->name == '')
71                         continue;
72
73                 if (is_a($_obj, 'Link_autolink')) { // ¹Ôµ·¤¬°­¤¤
74                         $rel_auto[] = $_obj->name;
75                 } else {
76                         $rel_new[]  = $_obj->name;
77                 }
78         }
79         $rel_new = array_unique($rel_new);
80         
81         // autolink¤·¤«¸þ¤¤¤Æ¤¤¤Ê¤¤¥Ú¡¼¥¸
82         $rel_auto = array_diff(array_unique($rel_auto), $rel_new);
83
84         // Á´¤Æ¤Î»²¾ÈÀè¥Ú¡¼¥¸
85         $rel_new = array_merge($rel_new, $rel_auto);
86
87         // .rel:$page¤¬»²¾È¤·¤Æ¤¤¤ë¥Ú¡¼¥¸¤Î°ìÍ÷
88         if ($time) {
89                 // ¥Ú¡¼¥¸¤¬Â¸ºß¤·¤Æ¤¤¤ë
90                 if (! empty($rel_new)) {
91                         $fp = fopen($rel_file, 'w')
92                                 or die_message('cannot write ' . htmlspecialchars($rel_file));
93                         fputs($fp, join("\t", $rel_new));
94                         fclose($fp);
95                 }
96         }
97
98         // .ref:$_page¤ò»²¾È¤·¤Æ¤¤¤ë¥Ú¡¼¥¸¤Î°ìÍ÷
99         links_add($page, array_diff($rel_new, $rel_old), $rel_auto);
100         links_delete($page, array_diff($rel_old, $rel_new));
101
102         global $WikiName, $autolink, $nowikiname, $search_non_list;
103
104         // $page¤¬¿·µ¬ºîÀ®¤µ¤ì¤¿¥Ú¡¼¥¸¤Ç¡¢AutoLink¤ÎÂоݤȤʤêÆÀ¤ë¾ì¹ç
105         if ($time && ! $rel_file_exist && $autolink
106                 && (preg_match("/^$WikiName$/", $page) ? $nowikiname : strlen($page) >= $autolink))
107         {
108                 // $page¤ò»²¾È¤·¤Æ¤¤¤½¤¦¤Ê¥Ú¡¼¥¸¤ò°ìÀƹ¹¿·¤¹¤ë(¤ª¤¤)
109                 $search_non_list = 1;
110                 $pages           = do_search($page, 'AND', TRUE);
111                 foreach ($pages as $_page) {
112                         if ($_page != $page)
113                                 links_update($_page);
114                 }
115         }
116         $ref_file = CACHE_DIR . encode($page) . '.ref';
117
118         // $page¤¬ºï½ü¤µ¤ì¤¿¤È¤­¤Ë¡¢
119         if (! $time && file_exists($ref_file)) {
120                 foreach (file($ref_file) as $line) {
121                         list($ref_page, $ref_auto) = explode("\t", rtrim($line));
122
123                         // $page¤òAutoLink¤Ç¤·¤«»²¾È¤·¤Æ¤¤¤Ê¤¤¥Ú¡¼¥¸¤ò°ìÀƹ¹¿·¤¹¤ë(¤ª¤¤¤ª¤¤)
124                         if ($ref_auto)
125                                 links_delete($ref_page, array($page));
126                 }
127         }
128 }
129
130 // Init link cache (Called from link plugin)
131 function links_init()
132 {
133         global $whatsnew;
134
135         if (PKWK_READONLY) return; // Do nothing
136
137         if (ini_get('safe_mode') == '0') set_time_limit(0);
138
139         // Init database
140         foreach (get_existfiles(CACHE_DIR, '.ref') as $cache)
141                 unlink($cache);
142         foreach (get_existfiles(CACHE_DIR, '.rel') as $cache)
143                 unlink($cache);
144
145         $pages = get_existpages();
146         $ref   = array(); // »²¾È¸µ
147         $ref_notauto = array();
148         foreach ($pages as $page) {
149                 if ($page == $whatsnew) continue;
150
151                 $rel   = array(); // »²¾ÈÀè
152                 $links = links_get_objects($page);
153                 foreach ($links as $_obj) {
154                         if (! isset($_obj->type) || $_obj->type != 'pagename' ||
155                             $_obj->name == $page || $_obj->name == '')
156                                 continue;
157
158                         $rel[] = $_obj->name;
159                         if (! is_a($_obj, 'Link_autolink')) {
160                                 $ref_notauto[$_obj->name][$page] = TRUE;
161                         }
162                         $ref[$_obj->name][] = $page;
163                 }
164                 $rel = array_unique($rel);
165                 if (! empty($rel)) {
166                         $fp = fopen(CACHE_DIR . encode($page) . '.rel', 'w')
167                                 or die_message('cannot write ' . htmlspecialchars(CACHE_DIR . encode($page) . '.rel'));
168                         fputs($fp, join("\t", $rel));
169                         fclose($fp);
170                 }
171         }
172
173         foreach ($ref as $page=>$arr) {
174                 if (empty($arr)) continue;
175
176                 $arr = array_unique($arr);
177                 $fp  = fopen(CACHE_DIR . encode($page) . '.ref', 'w')
178                         or die_message('cannot write ' . htmlspecialchars(CACHE_DIR . encode($page) . '.ref'));
179                 foreach ($arr as $ref_page) {
180                         $ref_auto = (isset($ref_notauto[$page])
181                                 && isset($ref_notauto[$page][$ref_page])) ? 0 : 1;
182                         fputs($fp, "$ref_page\t$ref_auto\n");
183                 }
184                 fclose($fp);
185         }
186 }
187
188 function links_add($page, $add, $rel_auto)
189 {
190         if (PKWK_READONLY) return; // Do nothing
191
192         $rel_auto = array_flip($rel_auto);
193         
194         foreach ($add as $_page) {
195                 $all_auto = isset($rel_auto[$_page]);
196                 $is_page  = is_page($_page);
197                 $ref      = $page . "\t" . ($all_auto ? 1 : 0) . "\n";
198
199                 $ref_file = CACHE_DIR . encode($_page) . '.ref';
200                 if (file_exists($ref_file)) {
201                         foreach (file($ref_file) as $line) {
202                                 list($ref_page, $ref_auto) = explode("\t", rtrim($line));
203                                 if (! $ref_auto) $all_auto = FALSE;
204                                 if ($ref_page != $page) $ref .= $line;
205                         }
206                         unlink($ref_file);
207                 }
208                 if ($is_page || ! $all_auto) {
209                         $fp = fopen($ref_file, 'w')
210                                  or die_message('cannot write ' . htmlspecialchars($ref_file));
211                         fputs($fp, $ref);
212                         fclose($fp);
213                 }
214         }
215 }
216
217 function links_delete($page, $del)
218 {
219         if (PKWK_READONLY) return; // Do nothing
220
221         foreach ($del as $_page) {
222                 $ref_file = CACHE_DIR . encode($_page) . '.ref';
223                 if (! file_exists($ref_file)) continue;
224
225                 $all_auto = TRUE;
226                 $is_page = is_page($_page);
227
228                 $ref = '';
229                 foreach (file($ref_file) as $line) {
230                         list($ref_page, $ref_auto) = explode("\t", rtrim($line));
231                         if ($ref_page != $page) {
232                                 if (! $ref_auto) $all_auto = FALSE;
233                                 $ref .= $line;
234                         }
235                 }
236                 unlink($ref_file);
237                 if ($is_page && ! $all_auto && $ref != '') {
238                         $fp = fopen($ref_file, 'w')
239                                 or die_message('cannot write ' . htmlspecialchars($ref_file));
240                         fputs($fp, $ref);
241                         fclose($fp);
242                 }
243         }
244 }
245
246 function & links_get_objects($page, $refresh = FALSE)
247 {
248         static $obj;
249
250         if (! isset($obj) || $refresh)
251                 $obj = & new InlineConverter(NULL, array('note'));
252
253         $result = $obj->get_objects(join('', preg_grep('/^(?!\/\/|\s)./', get_source($page))), $page);
254         return $result;
255 }
256 ?>