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