1<?php
2/**
3 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
4 * @author     Michael Klier <chi@chimeric.de>
5 */
6
7// must be run within Dokuwiki
8if (!defined('DOKU_INC')) die();
9
10class action_plugin_blogtng_edit extends DokuWiki_Action_Plugin{
11
12    /** @var helper_plugin_blogtng_entry */
13    var $entryhelper = null;
14    /** @var  helper_plugin_blogtng_tags */
15    var $taghelper;
16    /** @var  helper_plugin_blogtng_tools */
17    var $tools;
18
19    var $preact = null;
20
21    /**
22     * Constructor
23     */
24    function __construct() {
25        $this->entryhelper = plugin_load('helper', 'blogtng_entry');
26        $this->taghelper = plugin_load('helper', 'blogtng_tags');
27        $this->tools = plugin_load('helper', 'blogtng_tools');
28    }
29
30    /**
31     * Registers a callback function for a given event
32     *
33     * @param Doku_Event_Handler $controller
34     */
35    function register(Doku_Event_Handler $controller) {
36        $controller->register_hook('HTML_EDITFORM_OUTPUT', 'BEFORE', $this, 'handle_editform_output', array());
37        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_action_act_preprocess', array('before'));
38        $controller->register_hook('ACTION_ACT_PREPROCESS', 'AFTER', $this, 'handle_action_act_preprocess', array('after'));
39    }
40
41    /**
42     * Adds additional fields of used by the BlogTNG plugin to the editor.
43     *
44     * @param Doku_Event $event
45     * @param $param
46     */
47    function handle_editform_output(Doku_Event $event, $param) {
48        global $ID, $INFO;
49
50        $pos = $event->data->findElementByAttribute('type','submit');
51        if(!$pos) return; // no submit button found, source view
52        $pos -= 1;
53
54        $pid = md5($ID);
55        $this->entryhelper->load_by_pid($pid);
56        $isNotExistingBlog = $this->entryhelper->entry['blog'] === null;
57
58        $blog = $this->tools->getParam('post/blog');
59        if (!$blog) $blog = $this->entryhelper->get_blog();
60        if (!$blog && !$INFO['exists']) $blog = $this->getConf('default_blog');
61        $blogs = $this->entryhelper->get_blogs();
62
63        $event->data->insertElement($pos, form_openfieldset(array('_legend' => 'BlogTNG', 'class' => 'edit', 'id' => 'blogtng__edit')));
64        $pos += 1;
65
66        $event->data->insertElement($pos, form_makeMenuField('btng[post][blog]', $blogs, $blog, 'Blog', 'blogtng__blog', 'edit'));
67        $pos += 1;
68
69        $this->taghelper->load($pid);
70
71        $tags = $this->_get_post_tags();
72        if ($tags === false) $tags = $this->taghelper->getTags();
73        if (!$tags && $isNotExistingBlog) $tags = helper_plugin_blogtng_tools::filterExplodeCSVinput($this->getConf('default_tags'));
74
75        $allowed_tags = $this->_get_allowed_tags();
76        if (count($allowed_tags) > 0) {
77            $event->data->insertElement($pos++, form_makeOpenTag('div', array('class' => 'blogtng__tags_checkboxes')));
78            foreach($this->_get_allowed_tags() as $val) {
79                $data = array('style' => 'margin-top: 0.3em;');
80                if (in_array($val, $tags)) $data['checked'] = 'checked';
81                $event->data->insertElement($pos++, form_makeCheckboxField('btng[post][tags][]', $val, $val, '', '', $data));
82            }
83            $event->data->insertElement($pos++, form_makeCloseTag('div'));
84        } else {
85            $event->data->insertElement($pos, form_makeTextField('btng[post][tags]', join(', ', $tags), 'Tags', 'blogtng__tags', 'edit'));
86            $pos += 1;
87        }
88
89        $commentstatus = $this->tools->getParam('post/commentstatus');
90        if(!$commentstatus) $commentstatus = $this->entryhelper->entry['commentstatus'];
91        if(!$commentstatus) $commentstatus = $this->getConf('default_commentstatus');
92
93
94        $event->data->insertElement($pos, form_makeMenuField('btng[post][commentstatus]', array('enabled', 'closed', 'disabled'), $commentstatus, $this->getLang('commentstatus'), 'blogtng__commentstatus', 'edit'));
95        $pos += 1;
96
97        if($this->getConf('editform_set_date')) {
98            $postdate = $this->tools->getParam('post/date');
99            if($postdate) {
100                $YY = $postdate['YY'];
101                $MM = $postdate['MM'];
102                $DD = $postdate['DD'];
103                $hh = $postdate['hh'];
104                $mm = $postdate['mm'];
105            } else {
106                $created = $this->entryhelper->entry['created'];
107                if($created) {
108                    $YY = strftime('%Y', $created);
109                    $MM = strftime('%m', $created);
110                    $DD = strftime('%d', $created);
111                    $hh = strftime('%H', $created);
112                    $mm = strftime('%M', $created);
113                } else {
114                    $time = time();
115                    $YY = strftime('%Y', $time);
116                    $MM = strftime('%m', $time);
117                    $DD = strftime('%d', $time);
118                    $hh = strftime('%H', $time);
119                    $mm = strftime('%M', $time);
120                }
121            }
122
123            $event->data->insertElement($pos, form_makeTextField('btng[post][date][YY]', $YY, 'YYYY', 'blogtng__date_YY', 'edit btng__date_YY', array('maxlength'=>4)));
124            $pos += 1;
125            $event->data->insertElement($pos, form_makeTextField('btng[post][date][MM]', $MM, 'MM', 'blogtng__date_MM', 'edit btng__date', array('maxlength'=>2)));
126            $pos += 1;
127            $event->data->insertElement($pos, form_makeTextField('btng[post][date][DD]', $DD, 'DD', 'blogtng__date_DD', 'edit btng__date', array('maxlength'=>2)));
128            $pos += 1;
129            $event->data->insertElement($pos, form_makeTextField('btng[post][date][hh]', $hh, 'hh', 'blogtng__date_hh', 'edit btng__date', array('maxlength'=>2)));
130            $pos += 1;
131            $event->data->insertElement($pos, form_makeTextField('btng[post][date][mm]', $mm, 'mm', 'blogtng__date_mm', 'edit btng__date', array('maxlength'=>2)));
132            $pos += 1;
133        }
134
135        $event->data->insertElement($pos, form_closefieldset());
136    }
137
138    /**
139     * Save the blog related meta data of a page to the sqlite DB
140     *
141     * @param Doku_Event $event
142     * @param $param
143     */
144    function handle_action_act_preprocess(Doku_Event $event, $param) {
145        list($type) = $param;
146
147        if (is_array($event->data)) {
148            list($act) = array_keys($event->data);
149        } else {
150            $act = $event->data;
151        }
152
153        if ($type === 'before' && $act === 'save') {
154            $this->preact = 'save';
155        // Before Greebo, intercept the after type where $act is 'show'.
156        // In Greebo and later, the before type is triggered again but with action 'draftdel'.
157        } else if ($this->preact === 'save' && (($act === 'show' && $type === 'after') || ($act === 'draftdel' && $type === 'before'))) {
158            global $ID;
159
160            // does the page still exist? might be a deletion
161            if(!page_exists($ID)) return;
162
163            $blog = $this->tools->getParam('post/blog');
164            $blogs = $this->entryhelper->get_blogs();
165            if (!in_array($blog, $blogs)) $blog = null;
166
167            if($blog === null) {
168                $this->entryhelper->poke();
169            } else {
170                $pid = md5($ID);
171
172                $this->entryhelper->load_by_pid($pid);
173
174                $entry = $this->_collectInfoForEntry();
175                $this->entryhelper->set($entry);
176
177                $this->entryhelper->entry['blog'] = $blog;
178                $this->entryhelper->entry['commentstatus'] = $this->tools->getParam('post/commentstatus');
179
180                if (empty($this->entryhelper->entry['page'])) {
181
182                    $this->entryhelper->entry['page'] = $ID;
183
184                }
185
186                // allow to override created date
187                if($this->tools->getParam('post/date') && $this->getConf('editform_set_date')) {
188                    foreach(array('hh', 'mm', 'MM', 'DD') as $key) {
189                        $_REQUEST['btng']['post']['date'][$key] = ($_REQUEST['btng']['post']['date'][$key]{0} == 0) ? $_REQUEST['btng']['post']['date'][$key]{1} : $_REQUEST['btng']['post']['date'][$key];
190                    }
191                    $time = mktime($this->tools->getParam('post/date/hh'),
192                                   $this->tools->getParam('post/date/mm'),
193                                   0,
194                                   $this->tools->getParam('post/date/MM'),
195                                   $this->tools->getParam('post/date/DD'),
196                                   $this->tools->getParam('post/date/YY'));
197                    $this->entryhelper->entry['created'] = $time;
198                }
199
200                $this->entryhelper->save();
201
202                $tags = $this->_get_post_tags();
203                if ($tags === false) $tags = array();
204                $allowed_tags = $this->_get_allowed_tags();
205                if (count($allowed_tags) > 0) {
206                    foreach($tags as $n => $tag) {
207                        if (!in_array($tag, $allowed_tags)) {
208                            unset($tags[$n]);
209                        }
210                    }
211                }
212                $this->taghelper->load($pid);
213                $this->taghelper->setTags($tags);
214                $this->taghelper->save();
215            }
216        }
217    }
218
219    /**
220     * Return the configured allowed tags as an array
221     *
222     * @return array
223     */
224    private function _get_allowed_tags() {
225        return helper_plugin_blogtng_tools::filterExplodeCSVinput($this->getConf('tags'));
226    }
227
228    /**
229     * Return the tags received in the current $_REQUEST
230     *
231     * @return array|mixed
232     */
233    private function _get_post_tags() {
234        $tags = $this->tools->getParam('post/tags');
235        if ($tags === false) return $tags;
236        if (!is_array($tags)) {
237            $tags = helper_plugin_blogtng_tools::filterExplodeCSVinput($tags);
238        }
239        return $tags;
240    }
241
242    /**
243     * Gather general info for a blogentry
244     *
245     * @return array
246     */
247    protected function _collectInfoForEntry() {
248        /** @var DokuWiki_Auth_Plugin $auth */
249        global $auth;
250        global $ID;
251
252        // fetch author info
253        $login = $this->entryhelper->entry['login'];
254        if(!$login) $login = p_get_metadata($ID, 'user');
255        if(!$login) $login = $_SERVER['REMOTE_USER'];
256
257        $userdata = false;
258        if($login) {
259            if($auth != null) {
260                $userdata = $auth->getUserData($login);
261            }
262        }
263
264        // fetch dates
265        $date_created = p_get_metadata($ID, 'date created');
266        $date_modified = p_get_metadata($ID, 'date modified');
267
268        // prepare entry ...
269        $entry = array(
270            'page' => $ID,
271            'title' => p_get_metadata($ID, 'title'),
272            'image' => p_get_metadata($ID, 'relation firstimage'),
273            'created' => $date_created,
274            'lastmod' => (!$date_modified) ? $date_created : $date_modified,
275            'login' => $login,
276            'author' => ($userdata) ? $userdata['name'] : $login,
277            'mail' => ($userdata) ? $userdata['mail'] : '',
278        );
279        return $entry;
280    }
281}
282
283// vim:ts=4:sw=4:et:
284