OSDN Git Service

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