]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/PopularNearby.php
rcs_id no longer makes sense with Subversion global version number
[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 getDefaultArguments() {
52         return array('pagename' => '[pagename]',
53                      'mode'     => 'nearby', // or 'incoming' or 'outgoing'
54                      //'exclude'  => false,  // not yet
55                      'limit'    => 5,
56                      'noheader' => 0,
57                     );
58     }
59
60     function run($dbi, $argstr, &$request, $basepage) {
61             $args = $this->getArgs($argstr, $request);
62         extract($args);
63         $header = '';
64         $page = $dbi->getPage($pagename);
65         switch ($mode) {
66         case 'incoming': // not the hits, but the number of links
67             if (! $noheader )
68                 $header = sprintf(_("%d best incoming links: "),$limit);
69             $links = $this->sortedLinks($page->getLinks("reversed"),"reversed",$limit);
70             break;
71         case 'outgoing': // not the hits, but the number of links
72             if (! $noheader )
73                 $header = sprintf(_("%d best outgoing links: "),$limit);
74             $links = $this->sortedLinks($page->getLinks(),false,$limit);
75             break;
76         case 'nearby':  // all linksfrom and linksto, sorted by hits
77             if (! $noheader )
78                 $header = sprintf(_("%d most popular nearby: "),$limit);
79             $inlinks = $page->getLinks();
80             $outlinks = $page->getLinks('reversed');
81             // array_merge doesn't sort out duplicate page objects here.
82             $links = $this->sortedLinks(array_merge($inlinks->asArray(),
83                                                     $outlinks->asArray()),
84                                         false, $limit);
85             break;
86         }
87         $html = HTML($header);
88         for ($i=0; $i<count($links); $i++) {
89             $html->pushContent($links[$i]['format'],$i<count($links)-1?', ':'');
90         }
91         return $html;
92     }
93
94     /**
95      * Get and sort the links:
96      *   mode=nearby:   $pages Array
97      *   mode=incoming: $pages iter and $direction=true
98      *   mode=outgoing: $pages iter and $direction=false
99      *
100      * @access private
101      *
102      * @param $pages array of WikiDB_Page's or a Page_iterator
103      * @param $direction boolean: true if incoming links
104      *
105      * @return Array of sorted links
106      */
107     function sortedLinks($pages, $direction=false, $limit=5) {
108             $links = array();
109         if (is_array($pages)) {
110             $already = array(); // need special duplicate check
111             foreach ($pages as $page) {
112                 if (isset($already[$page->_pagename])) continue;
113                 else $already[$page->_pagename] = 1;
114                 // just the number of hits
115                 $hits = $page->get('hits');
116                 if (!$hits) continue;
117                 $links[] = array('hits' => $hits,
118                                  'pagename' => $page->_pagename,
119                                  'format' => HTML(WikiLink($page->_pagename),' (' . $hits . ')'));
120             }
121         } else {
122             while ($page = $pages->next()) {
123                 // different score algorithm:
124                 //   the number of links to/from the page
125                 $l = $page->getLinks(!$direction);
126                 $score = $l->count();
127                 if (!$score) continue;
128                 $name = $page->_pagename;
129                 $links[] = array('hits' => $score,
130                                  'pagename' => $name,
131                                  'format' => HTML(WikiLink($name),' (' . $score . ')'));
132             }
133             $pages->free();
134         }
135         if (count($links) > $limit)
136             array_splice($links, $limit);
137         return $this->sortByHits($links);
138     }
139
140     function sortByHits($links) {
141         if (!$links) return array();
142         usort($links,'cmp_by_hits'); // php-4.0.6 cannot use methods
143         reset($links);
144         return $links;
145     }
146 };
147
148 function cmp_by_hits($a, $b) {
149      if ($a['hits'] == $b['hits']) return 0;
150      return $a['hits'] < $b['hits'] ? 1 : -1;
151 }
152
153
154 // Local Variables:
155 // mode: php
156 // tab-width: 8
157 // c-basic-offset: 4
158 // c-hanging-comment-ender-p: nil
159 // indent-tabs-mode: nil
160 // End:
161 ?>