1<?php
2/**
3 * DokuWiki Plugin booking (Action Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Gohr <dokuwiki@cosmocode.de>
7 */
8
9// must be run within Dokuwiki
10if (!defined('DOKU_INC')) {
11    die();
12}
13
14class action_plugin_booking extends DokuWiki_Action_Plugin
15{
16    /** @var helper_plugin_booking */
17    protected $helper;
18
19    protected $issuperuser = false;
20
21    public function __construct()
22    {
23        $this->helper = plugin_load('helper', 'booking');
24    }
25
26
27    /**
28     * Registers a callback function for a given event
29     *
30     * @param Doku_Event_Handler $controller DokuWiki's event controller object
31     *
32     * @return void
33     */
34    public function register(Doku_Event_Handler $controller)
35    {
36        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call_unknown');
37
38    }
39
40    /**
41     * [Custom event handler which performs action]
42     *
43     * Called for event:
44     *
45     * @param Doku_Event $event event object by reference
46     * @param mixed $param [the parameters passed as fifth argument to register_hook() when this
47     *                           handler was registered]
48     *
49     * @return void
50     */
51    public function handle_ajax_call_unknown(Doku_Event $event, $param)
52    {
53        if ($event->data != 'plugin_booking') return;
54        $event->preventDefault();
55        $event->stopPropagation();
56
57        $id = getID();
58        $perm = auth_quickaclcheck($id);
59        if ($perm < AUTH_READ) {
60            http_status('403', 'Bookings not accessible to you');
61            exit;
62        }
63        if ($perm == AUTH_ADMIN) $this->issuperuser = true;
64
65        if (isset($_REQUEST['do'])) {
66            if ($_REQUEST['do'] == 'book') {
67                $this->addBooking($id, $_REQUEST['date'] . ' ' . $_REQUEST['time'], $_REQUEST['length']);
68            } elseif ($_REQUEST['do'] == 'cancel') {
69                $this->cancelBooking($id, (int)$_REQUEST['at']);
70            } elseif ($_REQUEST['do'] == 'csv' && $this->issuperuser) {
71                $this->exportCSV($_REQUEST['id']);
72                exit();
73            }
74
75        }
76
77        $this->outputHTML($id);
78    }
79
80    /**
81     * Create a Booking
82     *
83     * @param string $id
84     * @param string $start
85     * @param string $length
86     */
87    protected function addBooking($id, $start, $length)
88    {
89        if (!$_SERVER['REMOTE_USER']) return;
90
91        try {
92            $this->helper->addBooking($id, $start, $length, $_SERVER['REMOTE_USER']);
93            msg($this->getLang('booked'), 1);
94        } catch (Exception $e) {
95            msg($this->getLang('exception' . $e->getCode()), -1);
96        }
97    }
98
99    /**
100     * Cancel a booking
101     *
102     * @param string $id
103     * @param int $start
104     */
105    protected function cancelBooking($id, $start)
106    {
107        if ($this->issuperuser) {
108            $user = null;
109        } else {
110            $user = $_SERVER['REMOTE_USER'];
111        }
112
113        if ($this->helper->cancelBooking($id, $start, $user)) {
114            msg($this->getLang('cancelled'), 1);
115        } else {
116            msg($this->getLang('notcancelled'), -1);
117        }
118    }
119
120    /**
121     * Export all bookings as CSV
122     *
123     * @param string $id
124     */
125    protected function exportCSV($id)
126    {
127        header('Content-Type', 'text/csv;charset=utf-8');
128        header('Content-Disposition: attachment;filename=' . noNS($id) . '.csv');
129        $bookings = $this->helper->getBookings($id);
130
131        $out = fopen('php://output', 'w');
132        fputcsv($out, ['start', 'end', 'user']);
133        foreach ($bookings as $booking) {
134            fputcsv(
135                $out,
136                [
137                    date('Y-m-d H:i', $booking['start']),
138                    date('Y-m-d H:i', $booking['end']),
139                    $booking['user']
140                ]
141            );
142        }
143        fclose($out);
144    }
145
146    /**
147     * Create the HTML output
148     *
149     * @param string $id
150     */
151    protected function outputHTML($id)
152    {
153        header('Content-Type', 'text/html;charset=utf-8');
154
155        html_msgarea();
156
157        if ($_SERVER['REMOTE_USER']) {
158            $this->showForm();
159        }
160
161        $this->listBookings($id);
162    }
163
164    /**
165     * Display the booking form
166     */
167    protected function showForm()
168    {
169        $form = new dokuwiki\Form\Form();
170        $form->addFieldsetOpen($this->getLang('headline'));
171        $form->addTextInput('date')
172            ->attrs(['type' => 'date', 'min' => date('Y-m-d'), 'required' => 'required'])
173            ->addClass('edit');
174        $form->addTextInput('time')
175            ->attrs(['type' => 'time', 'required' => 'required'])
176            ->val(date('H', time() + 60 * 60) . ':00')
177            ->addClass('edit');
178        $form->addTextInput('length')
179            ->attrs(['required' => 'required', 'placeholder' => '1h'])
180            ->val('1h')
181            ->addClass('edit');
182        $form->addButton('submit', $this->getLang('book'));
183        $form->addFieldsetClose();
184        echo $form->toHTML();
185    }
186
187    /**
188     * Display the current bookings
189     *
190     * @param string $id
191     */
192    protected function listBookings($id)
193    {
194        $bookings = $this->helper->getBookings($id, time());
195        echo '<table>';
196        foreach ($bookings as $booking) {
197            echo '<tr>';
198
199            echo '<td>';
200            echo dformat($booking['start']) . ' - ' . dformat($booking['end']);
201            echo '</td>';
202
203            echo '<td>';
204            echo userlink($booking['user']);
205            echo '</td>';
206
207            echo '<td>';
208            if ($booking['user'] == $_SERVER['REMOTE_USER'] || $this->issuperuser) {
209                echo '<a href="#' . $booking['start'] . '" class="cancel">' . $this->getLang('cancel') . '</a>';
210            } else {
211                echo '&nbsp;';
212            }
213            echo '</td>';
214
215            echo '</tr>';
216        }
217        echo '</table>';
218
219        if ($this->issuperuser) {
220            echo '<a href="' . DOKU_BASE . 'lib/exe/ajax.php?call=plugin_booking&do=csv&id=' . $id . '">' . $this->getLang('csv') . '</a>';
221        }
222    }
223}
224
225