]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/PopularNearby.php
getName should not translate
[SourceForge/phpwiki.git] / lib / plugin / PopularNearby.php
1 <?php
2
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 along
19  * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 * <<PopularNearby mode=incoming >>
32 * <<PopularNearby mode=outgoing >>
33 * <<PopularNearby mode=nearby >>
34
35 */
36
37 require_once 'lib/PageList.php';
38
39 class WikiPlugin_PopularNearby
40     extends WikiPlugin
41 {
42     function getDescription()
43     {
44         return _("List the most popular pages nearby.");
45     }
46
47     function getDefaultArguments()
48     {
49         return array('pagename' => '[pagename]',
50             'mode' => 'nearby', // or 'incoming' or 'outgoing'
51             //'exclude'  => false,  // not yet
52             'limit' => 5,
53             'noheader' => 0,
54         );
55     }
56
57     function run($dbi, $argstr, &$request, $basepage)
58     {
59         $args = $this->getArgs($argstr, $request);
60         extract($args);
61         $header = '';
62         $page = $dbi->getPage($pagename);
63         switch ($mode) {
64             case 'incoming': // not the hits, but the number of links
65                 if (!$noheader)
66                     $header = sprintf(_("%d best incoming links: "), $limit);
67                 $links = $this->sortedLinks($page->getLinks("reversed"), "reversed", $limit);
68                 break;
69             case 'outgoing': // not the hits, but the number of links
70                 if (!$noheader)
71                     $header = sprintf(_("%d best outgoing links: "), $limit);
72                 $links = $this->sortedLinks($page->getLinks(), false, $limit);
73                 break;
74             case 'nearby': // all linksfrom and linksto, sorted by hits
75                 if (!$noheader)
76                     $header = sprintf(_("%d most popular nearby: "), $limit);
77                 $inlinks = $page->getLinks();
78                 $outlinks = $page->getLinks('reversed');
79                 // array_merge doesn't sort out duplicate page objects here.
80                 $links = $this->sortedLinks(array_merge($inlinks->asArray(),
81                         $outlinks->asArray()),
82                     false, $limit);
83                 break;
84         }
85         $html = HTML($header);
86         for ($i = 0; $i < count($links); $i++) {
87             $html->pushContent($links[$i]['format'], $i < count($links) - 1 ? ', ' : '');
88         }
89         return $html;
90     }
91
92     /**
93      * Get and sort the links:
94      *   mode=nearby:   $pages Array
95      *   mode=incoming: $pages iter and $direction=true
96      *   mode=outgoing: $pages iter and $direction=false
97      *
98      * @access private
99      *
100      * @param $pages array of WikiDB_Page's or a Page_iterator
101      * @param $direction boolean: true if incoming links
102      *
103      * @param int $limit
104      * @return Array of sorted links
105      */
106     function sortedLinks($pages, $direction = false, $limit = 5)
107     {
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     {
142         if (!$links) return array();
143         usort($links, 'cmp_by_hits'); // php-4.0.6 cannot use methods
144         reset($links);
145         return $links;
146     }
147 }
148
149 function cmp_by_hits($a, $b)
150 {
151     if ($a['hits'] == $b['hits']) return 0;
152     return $a['hits'] < $b['hits'] ? 1 : -1;
153 }
154
155 // Local Variables:
156 // mode: php
157 // tab-width: 8
158 // c-basic-offset: 4
159 // c-hanging-comment-ender-p: nil
160 // indent-tabs-mode: nil
161 // End: