1<?php
2/**
3 * DokuWiki Plugin top (Helper Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Gohr <gohr@cosmocode.de>
7 */
8
9class helper_plugin_top extends DokuWiki_Plugin {
10
11    /** @var helper_plugin_sqlite */
12    protected $sqlite = null;
13
14    public function __construct()
15    {
16        $this->sqlite = plugin_load('helper', 'sqlite');
17        if (!$this->sqlite) {
18            msg('The top plugin requires the sqlite plugin', -1);
19            return null;
20        }
21
22        if (!$this->sqlite->init('top', __DIR__ . '/db')) {
23            msg('top plugin: sqlite initialization failed', -1);
24            return null;
25        }
26    }
27
28    /**
29     * Access to plugin's database
30     * @return helper_plugin_sqlite
31     */
32    public function getDBHelper()
33    {
34       return $this->sqlite;
35    }
36
37    /**
38     * Adds a hit for the given page
39     *
40     * @param string $page the page id
41     */
42    public function add($page)
43    {
44        // ignore any bot accesses
45        if (!class_exists('Jaybizzle\CrawlerDetect\CrawlerDetect')){
46            require (__DIR__ . '/CrawlerDetect.php');
47        }
48        $CrawlerDetect = new Jaybizzle\CrawlerDetect\CrawlerDetect();
49        if ($CrawlerDetect->isCrawler()) return;
50
51        $translation = plugin_load('helper', 'translation');
52        if (!$translation) {
53            $lang = '';
54        } else {
55            $lang = $translation->getLangPart($page);
56        }
57
58        $month = date('Ym');
59
60        $sql = "INSERT OR REPLACE INTO toppages (page, value, lang, month)
61                  VALUES ( ?, COALESCE( (SELECT value FROM toppages WHERE page = ? and month = ? ) + 1, 1), ?, ?)";
62        $res = $this->sqlite->query($sql, $page, $page, $month, $lang, $month);
63        $this->sqlite->res_close($res);
64    }
65
66    /**
67     * Get the most visited pages
68     *
69     * @param string|null $lang
70     * @param string|null $month
71     * @param int $num
72     * @return array
73     */
74    public function best($lang, $month, $num = 10)
75    {
76        $sqlbegin  = "SELECT SUM(value) as value, page FROM toppages ";
77        $sqlend = "GROUP BY page ORDER BY value DESC LIMIT ?";
78        if ($lang === null && $month === null){
79            $sql = $sqlbegin . $sqlend;
80            $res  = $this->sqlite->query($sql, $num);
81        } elseif ($lang !== null && $month === null) {
82            $sql = $sqlbegin . "WHERE lang = ? " . $sqlend;
83            $res  = $this->sqlite->query($sql, $lang, $num);
84        } elseif ($lang === null && $month !== null){
85            $sql = $sqlbegin . "WHERE month >= ? " . $sqlend;
86            $res  = $this->sqlite->query($sql, intval($month), $num);
87        } else {
88            $sql = $sqlbegin . "WHERE lang = ? AND month >= ? " . $sqlend;
89            $res  = $this->sqlite->query($sql, $lang, intval($month), $num);
90        }
91        $list = $this->sqlite->res2arr($res);
92        $this->sqlite->res_close($res);
93
94        if ($this->getConf('hide_start_pages')) {
95            $list = $this->removeStartPages($list);
96        }
97        return $list;
98    }
99
100    /**
101     * @param array $list
102     * @return array
103     */
104    public function removeStartPages($list) {
105        global $conf;
106        $start = $conf['start'];
107        $startpages = array();
108        $startpages[] = $start;
109
110        if ($conf['plugin']['translation']['translations'] !== '') {
111            $translations = explode(' ', $conf['plugin']['translation']['translations']);
112            foreach($translations as $translation) {
113                $startpages[] = $translation . ':' . $start;
114            }
115        }
116
117        foreach ($list as $index => $listitem) {
118            if (in_array($listitem['page'],$startpages, true) === true ) {
119                unset($list[$index]);
120            }
121        }
122        $list = array_values($list);
123        return $list;
124    }
125
126    /**
127     * Returns true if the given page can be read by current user
128     *
129     * @param $id
130     * @return bool
131     */
132    public function isReadable($id)
133    {
134        if ($this->getConf('show_only_public')) {
135            if (auth_aclcheck($id, '', null) < AUTH_READ) return false;
136        } else {
137            if (auth_quickaclcheck($id) < AUTH_READ) return false;
138        }
139        if (!page_exists($id)) return false;
140        if (isHiddenPage($id)) return false;
141
142        return true;
143    }
144}
145// vim:ts=4:sw=4:et:
146