xref: /plugin/calendar/action.php (revision 19378907f6c3c154fcddd2ddfe78fa2d88d43359)
1*19378907SAtari911<?php
2*19378907SAtari911/**
3*19378907SAtari911 * DokuWiki Plugin calendar (Action Component)
4*19378907SAtari911 *
5*19378907SAtari911 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6*19378907SAtari911 * @author  DokuWiki Community
7*19378907SAtari911 */
8*19378907SAtari911
9*19378907SAtari911if (!defined('DOKU_INC')) die();
10*19378907SAtari911
11*19378907SAtari911class action_plugin_calendar extends DokuWiki_Action_Plugin {
12*19378907SAtari911
13*19378907SAtari911    public function register(Doku_Event_Handler $controller) {
14*19378907SAtari911        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjax');
15*19378907SAtari911        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'addAssets');
16*19378907SAtari911    }
17*19378907SAtari911
18*19378907SAtari911    public function handleAjax(Doku_Event $event, $param) {
19*19378907SAtari911        if ($event->data !== 'plugin_calendar') return;
20*19378907SAtari911        $event->preventDefault();
21*19378907SAtari911        $event->stopPropagation();
22*19378907SAtari911
23*19378907SAtari911        $action = $_REQUEST['action'] ?? '';
24*19378907SAtari911
25*19378907SAtari911        switch ($action) {
26*19378907SAtari911            case 'save_event':
27*19378907SAtari911                $this->saveEvent();
28*19378907SAtari911                break;
29*19378907SAtari911            case 'delete_event':
30*19378907SAtari911                $this->deleteEvent();
31*19378907SAtari911                break;
32*19378907SAtari911            case 'get_event':
33*19378907SAtari911                $this->getEvent();
34*19378907SAtari911                break;
35*19378907SAtari911            case 'load_month':
36*19378907SAtari911                $this->loadMonth();
37*19378907SAtari911                break;
38*19378907SAtari911            case 'toggle_task':
39*19378907SAtari911                $this->toggleTaskComplete();
40*19378907SAtari911                break;
41*19378907SAtari911            default:
42*19378907SAtari911                echo json_encode(['success' => false, 'error' => 'Unknown action']);
43*19378907SAtari911        }
44*19378907SAtari911    }
45*19378907SAtari911
46*19378907SAtari911    private function saveEvent() {
47*19378907SAtari911        global $INPUT;
48*19378907SAtari911
49*19378907SAtari911        $namespace = $INPUT->str('namespace', '');
50*19378907SAtari911        $date = $INPUT->str('date');
51*19378907SAtari911        $eventId = $INPUT->str('eventId', '');
52*19378907SAtari911        $title = $INPUT->str('title');
53*19378907SAtari911        $time = $INPUT->str('time', '');
54*19378907SAtari911        $description = $INPUT->str('description', '');
55*19378907SAtari911        $color = $INPUT->str('color', '#3498db');
56*19378907SAtari911        $oldDate = $INPUT->str('oldDate', ''); // Track original date for moves
57*19378907SAtari911        $isTask = $INPUT->bool('isTask', false);
58*19378907SAtari911        $completed = $INPUT->bool('completed', false);
59*19378907SAtari911        $endDate = $INPUT->str('endDate', '');
60*19378907SAtari911
61*19378907SAtari911        if (!$date || !$title) {
62*19378907SAtari911            echo json_encode(['success' => false, 'error' => 'Missing required fields']);
63*19378907SAtari911            return;
64*19378907SAtari911        }
65*19378907SAtari911
66*19378907SAtari911        list($year, $month, $day) = explode('-', $date);
67*19378907SAtari911
68*19378907SAtari911        $dataDir = DOKU_INC . 'data/meta/';
69*19378907SAtari911        if ($namespace) {
70*19378907SAtari911            $dataDir .= str_replace(':', '/', $namespace) . '/';
71*19378907SAtari911        }
72*19378907SAtari911        $dataDir .= 'calendar/';
73*19378907SAtari911
74*19378907SAtari911        if (!is_dir($dataDir)) {
75*19378907SAtari911            mkdir($dataDir, 0755, true);
76*19378907SAtari911        }
77*19378907SAtari911
78*19378907SAtari911        $eventFile = $dataDir . sprintf('%04d-%02d.json', $year, $month);
79*19378907SAtari911
80*19378907SAtari911        $events = [];
81*19378907SAtari911        if (file_exists($eventFile)) {
82*19378907SAtari911            $events = json_decode(file_get_contents($eventFile), true);
83*19378907SAtari911        }
84*19378907SAtari911
85*19378907SAtari911        // If editing and date changed, remove from old date first
86*19378907SAtari911        if ($eventId && $oldDate && $oldDate !== $date) {
87*19378907SAtari911            list($oldYear, $oldMonth, $oldDay) = explode('-', $oldDate);
88*19378907SAtari911            $oldEventFile = $dataDir . sprintf('%04d-%02d.json', $oldYear, $oldMonth);
89*19378907SAtari911
90*19378907SAtari911            if (file_exists($oldEventFile)) {
91*19378907SAtari911                $oldEvents = json_decode(file_get_contents($oldEventFile), true);
92*19378907SAtari911                if (isset($oldEvents[$oldDate])) {
93*19378907SAtari911                    $oldEvents[$oldDate] = array_filter($oldEvents[$oldDate], function($evt) use ($eventId) {
94*19378907SAtari911                        return $evt['id'] !== $eventId;
95*19378907SAtari911                    });
96*19378907SAtari911
97*19378907SAtari911                    if (empty($oldEvents[$oldDate])) {
98*19378907SAtari911                        unset($oldEvents[$oldDate]);
99*19378907SAtari911                    }
100*19378907SAtari911
101*19378907SAtari911                    file_put_contents($oldEventFile, json_encode($oldEvents, JSON_PRETTY_PRINT));
102*19378907SAtari911                }
103*19378907SAtari911            }
104*19378907SAtari911        }
105*19378907SAtari911
106*19378907SAtari911        if (!isset($events[$date])) {
107*19378907SAtari911            $events[$date] = [];
108*19378907SAtari911        }
109*19378907SAtari911
110*19378907SAtari911        $eventData = [
111*19378907SAtari911            'id' => $eventId ?: uniqid(),
112*19378907SAtari911            'title' => $title,
113*19378907SAtari911            'time' => $time,
114*19378907SAtari911            'description' => $description,
115*19378907SAtari911            'color' => $color,
116*19378907SAtari911            'isTask' => $isTask,
117*19378907SAtari911            'completed' => $completed,
118*19378907SAtari911            'endDate' => $endDate,
119*19378907SAtari911            'created' => date('Y-m-d H:i:s')
120*19378907SAtari911        ];
121*19378907SAtari911
122*19378907SAtari911        // If editing, replace existing event
123*19378907SAtari911        if ($eventId) {
124*19378907SAtari911            $found = false;
125*19378907SAtari911            foreach ($events[$date] as $key => $evt) {
126*19378907SAtari911                if ($evt['id'] === $eventId) {
127*19378907SAtari911                    $events[$date][$key] = $eventData;
128*19378907SAtari911                    $found = true;
129*19378907SAtari911                    break;
130*19378907SAtari911                }
131*19378907SAtari911            }
132*19378907SAtari911            if (!$found) {
133*19378907SAtari911                $events[$date][] = $eventData;
134*19378907SAtari911            }
135*19378907SAtari911        } else {
136*19378907SAtari911            $events[$date][] = $eventData;
137*19378907SAtari911        }
138*19378907SAtari911
139*19378907SAtari911        file_put_contents($eventFile, json_encode($events, JSON_PRETTY_PRINT));
140*19378907SAtari911
141*19378907SAtari911        echo json_encode(['success' => true, 'events' => $events, 'eventId' => $eventData['id']]);
142*19378907SAtari911    }
143*19378907SAtari911
144*19378907SAtari911    private function deleteEvent() {
145*19378907SAtari911        global $INPUT;
146*19378907SAtari911
147*19378907SAtari911        $namespace = $INPUT->str('namespace', '');
148*19378907SAtari911        $date = $INPUT->str('date');
149*19378907SAtari911        $eventId = $INPUT->str('eventId');
150*19378907SAtari911
151*19378907SAtari911        list($year, $month, $day) = explode('-', $date);
152*19378907SAtari911
153*19378907SAtari911        $dataDir = DOKU_INC . 'data/meta/';
154*19378907SAtari911        if ($namespace) {
155*19378907SAtari911            $dataDir .= str_replace(':', '/', $namespace) . '/';
156*19378907SAtari911        }
157*19378907SAtari911        $dataDir .= 'calendar/';
158*19378907SAtari911
159*19378907SAtari911        $eventFile = $dataDir . sprintf('%04d-%02d.json', $year, $month);
160*19378907SAtari911
161*19378907SAtari911        if (file_exists($eventFile)) {
162*19378907SAtari911            $events = json_decode(file_get_contents($eventFile), true);
163*19378907SAtari911
164*19378907SAtari911            if (isset($events[$date])) {
165*19378907SAtari911                $events[$date] = array_filter($events[$date], function($event) use ($eventId) {
166*19378907SAtari911                    return $event['id'] !== $eventId;
167*19378907SAtari911                });
168*19378907SAtari911
169*19378907SAtari911                if (empty($events[$date])) {
170*19378907SAtari911                    unset($events[$date]);
171*19378907SAtari911                }
172*19378907SAtari911
173*19378907SAtari911                file_put_contents($eventFile, json_encode($events, JSON_PRETTY_PRINT));
174*19378907SAtari911            }
175*19378907SAtari911        }
176*19378907SAtari911
177*19378907SAtari911        echo json_encode(['success' => true]);
178*19378907SAtari911    }
179*19378907SAtari911
180*19378907SAtari911    private function getEvent() {
181*19378907SAtari911        global $INPUT;
182*19378907SAtari911
183*19378907SAtari911        $namespace = $INPUT->str('namespace', '');
184*19378907SAtari911        $date = $INPUT->str('date');
185*19378907SAtari911        $eventId = $INPUT->str('eventId');
186*19378907SAtari911
187*19378907SAtari911        list($year, $month, $day) = explode('-', $date);
188*19378907SAtari911
189*19378907SAtari911        $dataDir = DOKU_INC . 'data/meta/';
190*19378907SAtari911        if ($namespace) {
191*19378907SAtari911            $dataDir .= str_replace(':', '/', $namespace) . '/';
192*19378907SAtari911        }
193*19378907SAtari911        $dataDir .= 'calendar/';
194*19378907SAtari911
195*19378907SAtari911        $eventFile = $dataDir . sprintf('%04d-%02d.json', $year, $month);
196*19378907SAtari911
197*19378907SAtari911        if (file_exists($eventFile)) {
198*19378907SAtari911            $events = json_decode(file_get_contents($eventFile), true);
199*19378907SAtari911
200*19378907SAtari911            if (isset($events[$date])) {
201*19378907SAtari911                foreach ($events[$date] as $event) {
202*19378907SAtari911                    if ($event['id'] === $eventId) {
203*19378907SAtari911                        echo json_encode(['success' => true, 'event' => $event]);
204*19378907SAtari911                        return;
205*19378907SAtari911                    }
206*19378907SAtari911                }
207*19378907SAtari911            }
208*19378907SAtari911        }
209*19378907SAtari911
210*19378907SAtari911        echo json_encode(['success' => false, 'error' => 'Event not found']);
211*19378907SAtari911    }
212*19378907SAtari911
213*19378907SAtari911    private function loadMonth() {
214*19378907SAtari911        global $INPUT;
215*19378907SAtari911
216*19378907SAtari911        $namespace = $INPUT->str('namespace', '');
217*19378907SAtari911        $year = $INPUT->int('year');
218*19378907SAtari911        $month = $INPUT->int('month');
219*19378907SAtari911
220*19378907SAtari911        $dataDir = DOKU_INC . 'data/meta/';
221*19378907SAtari911        if ($namespace) {
222*19378907SAtari911            $dataDir .= str_replace(':', '/', $namespace) . '/';
223*19378907SAtari911        }
224*19378907SAtari911        $dataDir .= 'calendar/';
225*19378907SAtari911
226*19378907SAtari911        $eventFile = $dataDir . sprintf('%04d-%02d.json', $year, $month);
227*19378907SAtari911
228*19378907SAtari911        $events = [];
229*19378907SAtari911        if (file_exists($eventFile)) {
230*19378907SAtari911            $events = json_decode(file_get_contents($eventFile), true);
231*19378907SAtari911        }
232*19378907SAtari911
233*19378907SAtari911        echo json_encode(['success' => true, 'events' => $events, 'year' => $year, 'month' => $month]);
234*19378907SAtari911    }
235*19378907SAtari911
236*19378907SAtari911    private function toggleTaskComplete() {
237*19378907SAtari911        global $INPUT;
238*19378907SAtari911
239*19378907SAtari911        $namespace = $INPUT->str('namespace', '');
240*19378907SAtari911        $date = $INPUT->str('date');
241*19378907SAtari911        $eventId = $INPUT->str('eventId');
242*19378907SAtari911        $completed = $INPUT->bool('completed', false);
243*19378907SAtari911
244*19378907SAtari911        list($year, $month, $day) = explode('-', $date);
245*19378907SAtari911
246*19378907SAtari911        $dataDir = DOKU_INC . 'data/meta/';
247*19378907SAtari911        if ($namespace) {
248*19378907SAtari911            $dataDir .= str_replace(':', '/', $namespace) . '/';
249*19378907SAtari911        }
250*19378907SAtari911        $dataDir .= 'calendar/';
251*19378907SAtari911
252*19378907SAtari911        $eventFile = $dataDir . sprintf('%04d-%02d.json', $year, $month);
253*19378907SAtari911
254*19378907SAtari911        if (file_exists($eventFile)) {
255*19378907SAtari911            $events = json_decode(file_get_contents($eventFile), true);
256*19378907SAtari911
257*19378907SAtari911            if (isset($events[$date])) {
258*19378907SAtari911                foreach ($events[$date] as $key => $event) {
259*19378907SAtari911                    if ($event['id'] === $eventId) {
260*19378907SAtari911                        $events[$date][$key]['completed'] = $completed;
261*19378907SAtari911                        break;
262*19378907SAtari911                    }
263*19378907SAtari911                }
264*19378907SAtari911
265*19378907SAtari911                file_put_contents($eventFile, json_encode($events, JSON_PRETTY_PRINT));
266*19378907SAtari911                echo json_encode(['success' => true, 'events' => $events]);
267*19378907SAtari911                return;
268*19378907SAtari911            }
269*19378907SAtari911        }
270*19378907SAtari911
271*19378907SAtari911        echo json_encode(['success' => false, 'error' => 'Event not found']);
272*19378907SAtari911    }
273*19378907SAtari911
274*19378907SAtari911    public function addAssets(Doku_Event $event, $param) {
275*19378907SAtari911        $event->data['link'][] = array(
276*19378907SAtari911            'type' => 'text/css',
277*19378907SAtari911            'rel' => 'stylesheet',
278*19378907SAtari911            'href' => DOKU_BASE . 'lib/plugins/calendar/style.css'
279*19378907SAtari911        );
280*19378907SAtari911
281*19378907SAtari911        $event->data['script'][] = array(
282*19378907SAtari911            'type' => 'text/javascript',
283*19378907SAtari911            'src' => DOKU_BASE . 'lib/plugins/calendar/script.js'
284*19378907SAtari911        );
285*19378907SAtari911    }
286*19378907SAtari911}
287