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