]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/PopularNearby.php
Activated Id substitution for Subversion
[SourceForge/phpwiki.git] / lib / plugin / PopularNearby.php
1 <?php // -*-php-*-
2 rcs_id('$Id$');
3 /*
4  Copyright 2004 $ThePhpWikiProgrammingTeam
5
6  This file is part of PhpWiki.
7
8  PhpWiki is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12
13  PhpWiki is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with PhpWiki; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 /** Re-implement the classic phpwiki-1.2 feature of the 
24  *  popular nearby pages, specific to the from/to links:
25  *    5 best incoming links: xx, xx, xx, ...
26  *    5 best outgoing links: xx, xx, xx, ...
27  *    5 most popular nearby: xx, xx, xx, ...
28  */
29 /* Usage:
30
31 * <small><?plugin PopularNearby mode=incoming ?></small>
32 * <small><?plugin PopularNearby mode=outgoing ?></small>
33 * <small><?plugin PopularNearby mode=nearby ?></small>
34
35 */
36  
37
38 require_once('lib/PageList.php');
39
40 class WikiPlugin_PopularNearby
41 extends WikiPlugin
42 {
43     function getName () {
44         return _("PopularNearby");
45     }
46
47     function getDescription () {
48         return _("List the most popular pages nearby.");
49     }
50
51     function getVersion() {
52         return preg_replace("/[Revision: $]/", '',
53                             "\$Revision: 1.5 $");
54     }
55
56     function getDefaultArguments() {
57         return array('pagename' => '[pagename]',
58                      'mode'     => 'nearby', // or 'incoming' or 'outgoing'
59                      //'exclude'  => false,  // not yet
60                      'limit'    => 5,
61                      'noheader' => 0,
62                     );
63     }
64     
65     function run($dbi, $argstr, &$request, $basepage) {
66         $args = $this->getArgs($argstr, $request);
67         extract($args);
68         $header = '';
69         $page = $dbi->getPage($pagename);
70         switch ($mode) {
71         case 'incoming': // not the hits, but the number of links
72             if (! $noheader )
73                 $header = sprintf(_("%d best incoming links: "),$limit); 
74             $links = $this->sortedLinks($page->getLinks("reversed"),"reversed",$limit);
75             break;
76         case 'outgoing': // not the hits, but the number of links
77             if (! $noheader )
78                 $header = sprintf(_("%d best outgoing links: "),$limit); 
79             $links = $this->sortedLinks($page->getLinks(),false,$limit);
80             break;
81         case 'nearby':  // all linksfrom and linksto, sorted by hits 
82             if (! $noheader )
83                 $header = sprintf(_("%d most popular nearby: "),$limit); 
84             $inlinks = $page->getLinks();
85             $outlinks = $page->getLinks('reversed');
86             // array_merge doesn't sort out duplicate page objects here.
87             $links = $this->sortedLinks(array_merge($inlinks->asArray(),
88                                                     $outlinks->asArray()),
89                                         false, $limit);
90             break;
91         }
92         $html = HTML($header);
93         for ($i=0; $i<count($links); $i++) {
94             $html->pushContent($links[$i]['format'],$i<count($links)-1?', ':'');
95         }
96         return $html;
97     }
98
99     /**
100      * Get and sort the links:
101      *   mode=nearby:   $pages Array
102      *   mode=incoming: $pages iter and $direction=true
103      *   mode=outgoing: $pages iter and $direction=false
104      *
105      * @access private
106      *
107      * @param $pages array of WikiDB_Page's or a Page_iterator
108      * @param $direction boolean: true if incoming links
109      * 
110      * @return Array of sorted links
111      */
112     function sortedLinks($pages, $direction=false, $limit=5) {
113         $links = array();
114         if (is_array($pages)) {
115             $already = array(); // need special duplicate check
116             foreach ($pages as $page) {
117                 if (isset($already[$page->_pagename])) continue;
118                 else $already[$page->_pagename] = 1;
119                 // just the number of hits
120                 $hits = $page->get('hits');
121                 if (!$hits) continue;
122                 $links[] = array('hits' => $hits,
123                                  'pagename' => $page->_pagename,
124                                  'format' => HTML(WikiLink($page->_pagename),' (' . $hits . ')'));
125             }
126         } else {
127             while ($page = $pages->next()) {
128                 // different score algorithm: 
129                 //   the number of links to/from the page
130                 $l = $page->getLinks(!$direction);
131                 $score = $l->count();
132                 if (!$score) continue;
133                 $name = $page->_pagename;
134                 $links[] = array('hits' => $score,
135                                  'pagename' => $name,
136                                  'format' => HTML(WikiLink($name),' (' . $score . ')'));
137             }
138             $pages->free();
139         }
140         if (count($links) > $limit)
141             array_splice($links, $limit);
142         return $this->sortByHits($links);
143     }
144
145     function sortByHits($links) {
146         if (!$links) return array();
147         usort($links,'cmp_by_hits'); // php-4.0.6 cannot use methods
148         reset($links);
149         return $links;
150     }
151 };
152
153 function cmp_by_hits($a, $b) {
154      if ($a['hits'] == $b['hits']) return 0;
155      return $a['hits'] < $b['hits'] ? 1 : -1;
156 }
157
158
159 // $Log: not supported by cvs2svn $
160 // Revision 1.4  2004/05/01 18:02:41  rurban
161 // 4.0.6 obviously cannot use methods as cmp function. so it must be a global func
162 //
163 // Revision 1.2  2004/04/29 23:25:12  rurban
164 // re-ordered locale init (as in 1.3.9)
165 // fixed loadfile with subpages, and merge/restore anyway
166 //   (sf.net bug #844188)
167 //
168 // Revision 1.1  2004/04/29 18:32:38  rurban
169 // Re-implement the classic phpwiki-1.2 feature of the
170 //  * 5 best incoming links: xx, xx, xx, ...
171 //  * 5 best outgoing links: xx, xx, xx, ...
172 //  * 5 most popular nearby: xx, xx, xx, ...
173 //
174
175 // Local Variables:
176 // mode: php
177 // tab-width: 8
178 // c-basic-offset: 4
179 // c-hanging-comment-ender-p: nil
180 // indent-tabs-mode: nil
181 // End:
182 ?>