1<?php
2/**
3 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
4 * @author     Esther Brunner <wikidesign@gmail.com>
5 */
6
7class helper_plugin_blog extends DokuWiki_Plugin {
8
9    var $sort       = '';      // sort key
10
11    /**
12     * Constructor
13     */
14    function __construct() {
15        // load sort key from settings
16        $this->sort = $this->getConf('sortkey');
17    }
18
19    function getMethods() {
20        $result = array();
21        $result[] = array(
22                'name'   => 'getBlog',
23                'desc'   => 'returns blog entries in reverse chronological order',
24                'params' => array(
25                    'namespace' => 'string',
26                    'number (optional)' => 'integer'),
27                'return' => array('pages' => 'array'),
28                );
29        $result[] = array(
30                'name'   => 'getFlags',
31                'desc'   => 'get values for flags, or defaults where not supplied',
32                'params' => array('flags' => 'array'),
33                'return' => array('flags' => 'array'),
34                );
35        return $result;
36    }
37
38    /**
39     * Get blog entries from a given namespace
40     *
41     * @param $ns
42     * @param null $num
43     * @param null $author
44     * @return array
45     */
46    function getBlog($ns, $num = NULL, $author = NULL) {
47        // add pages in given namespace
48        $result  = array();
49        global $conf;
50
51        $pages = array();
52        $unique_keys_memoize = array();
53
54        $dir = str_replace(':', '/', $ns);
55        search($pages, $conf['datadir'], 'search_pagename', array('query' => '.txt'), $dir);
56
57        foreach ($pages as $page) {
58            $id = $page['id'];
59            $file = wikiFN($id);
60
61            // do some checks first
62            if (isHiddenPage($id)) continue;                     // skip excluded pages
63            $excluded_pages = $this->getConf('excluded_pages');
64            if (strlen($excluded_pages) > 0 && preg_match($excluded_pages, $id)) continue;
65            if (($ns) && (strpos($id, $ns.':') !== 0)) continue; // filter namespaces
66            if (!@file_exists($file)) continue;                  // skip deleted
67
68            $perm = auth_quickaclcheck($id);
69            if ($perm < AUTH_READ) continue;                     // check ACL
70
71            // skip drafts unless for users with create priviledge
72            $meta = p_get_metadata($id, '', false);
73            $draft = isset($meta['type']) && ($meta['type'] == 'draft');
74            if ($draft && ($perm < AUTH_CREATE)) continue;
75
76            // filter by author
77            if ($author && ($meta['user'] != $author)) continue;
78
79            $date = $meta['date']['modified'];
80            if (!$date) $date = filemtime(wikiFN($id));
81            if ($this->sort != 'mdate') {
82                $cdate = $meta['date']['created'];
83                if (!$cdate) $cdate = filectime(wikiFN($id));
84                // prefer the date further in the past:
85                $date = min($date, $cdate);
86            }
87
88            if (isset($meta['title'])) {
89                $title = $meta['title'];
90            } else {
91                $title = $id;
92            }
93
94            // determine the sort key
95            if ($this->sort == 'id') $key = $id;
96            elseif ($this->sort == 'pagename') $key = noNS($id);
97            elseif ($this->sort == 'title') $key = $title;
98            else $key = $date;
99
100            // get a unique sortable key
101            $key = $this->_uniqueKey($key, $unique_keys_memoize);
102
103            $result[$key] = array(
104                    'id'     => $id,
105                    'title'  => $title,
106                    'date'   => $date,
107                    'user'   => $meta['creator'],
108                    'desc'   => $meta['description']['abstract'],
109                    'exists' => true,
110                    'perm'   => $perm,
111                    'draft'  => $draft,
112            );
113        }
114
115        // finally sort by sort key
116        if ($this->getConf('sortorder') == 'ascending') ksort($result);
117        else krsort($result);
118
119        if (is_numeric($num)) $result = array_slice($result, 0, $num);
120
121        return $result;
122    }
123
124    /**
125     * Turn a list of user-supplied flags into a complete list of all flags
126     * required by the Blog plugin (not including those for the Include plugin),
127     * using global configuration options or plugin defaults where flags have
128     * not been supplied.
129     *
130     * Currently handles 'formpos' and 'newentrytitle'.
131     *
132     * @author Sam Wilson <sam@samwilson.id.au>
133     * @param array $setflags Flags that have been set by the user
134     * @return array All flags required by the Blog plugin (only)
135     */
136    function getFlags($setflags) {
137        $flags = array();
138
139        // Form Position
140        $flags['formpos'] = $this->getConf('formposition');
141        if(in_array('topform', $setflags)) {
142            $flags['formpos'] = 'top';
143        }elseif(in_array('bottomform', $setflags)) {
144            $flags['formpos'] = 'bottom';
145        }elseif(in_array('noform', $setflags)) {
146            $flags['formpos'] = 'none';
147        }
148
149        // New Entry Title
150        $newentrytitle = preg_grep('|newentrytitle=.*|', $setflags);
151        if (count($newentrytitle) > 0) {
152            $newentrytitle = array_pop(explode('=', array_pop($newentrytitle), 2));
153            if (!empty($newentrytitle)) {
154                $flags['newentrytitle'] = $newentrytitle;
155            }
156        } elseif ($conf_title = $this->getConf('newentrytitle')) {
157            $flags['newentrytitle'] = $conf_title;
158        } else {
159            $flags['newentrytitle'] = $this->getLang('newentry');
160        }
161
162        // Paging Controls
163        $flags['pagingcontrols'] = !in_array('nopagingcontrols', $setflags);
164
165        return $flags;
166    }
167
168    /**
169     * Function to create sortable, unique array keys
170     *
171     * @param $key
172     * @param $unique_keys_memoize
173     * @return string
174     *
175     * @author    Esther Brunner <wikidesign@gmail.com>
176     * @author    Ilya S. Lebedev <ilya@lebedev.net>
177     * @author    Balazs Attila-Mihaly <x_at_y_or_z@yahoo.com>
178     */
179    function _uniqueKey($key, &$unique_keys_memoize){
180        //convert numeric keys to string
181        if (is_numeric($key))
182            $key = sprintf('%08x', $key);
183        if (!array_key_exists($key, $unique_keys_memoize))
184            $unique_keys_memoize[$key] = 0;
185
186        return sprintf('%s_%s', $key, $unique_keys_memoize[$key]++);
187    }
188
189}
190