Skip to content

Commit f2d097e

Browse files
Merge pull request #46 from AlexKlimenkov/master
[update] plain php guide GS-1734
2 parents 76ad694 + e7df882 commit f2d097e

1 file changed

Lines changed: 70 additions & 57 deletions

File tree

docs/integrations/php/howtostart-plain-php.md

Lines changed: 70 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ Create an `index.html` file in the `scheduler-howto-php-plain` folder and fill i
7373
<div class="dhx_cal_data"></div>
7474
</div>
7575
<script>
76-
scheduler.init('scheduler_here', new Date(2019,0,20), "week");
76+
scheduler.init('scheduler_here', new Date(2026,0,20), "week");
7777
scheduler.load("data/api.php");
7878
</script>
7979
</body>
@@ -193,7 +193,7 @@ To enable dynamic loading in UI, you can set the *setLoadMode* option to any of
193193

194194

195195
~~~js title="index.html"
196-
scheduler.init("scheduler_here", new Date(2019, 0, 20), "week");
196+
scheduler.init("scheduler_here", new Date(2026, 0, 20), "week");
197197
scheduler.setLoadMode("day"); /*!*/
198198

199199
// load data from the backend
@@ -316,14 +316,13 @@ The response JSON can have any number of additional properties, they all can be
316316
Finally, we will configure the client side to utilize the API we've just implemented:
317317

318318
~~~js title="index.html"
319-
scheduler.init("scheduler_here", new Date(2019, 0, 20), "week");
320-
scheduler.setLoadMode("day");
321-
319+
scheduler.init('scheduler_here', new Date(2026, 0, 20), "week");
320+
322321
// load data from the backend
323322
scheduler.load("data/api.php"); /*!*/
324-
323+
325324
// send updates to the backend
326-
var dp = scheduler.createDataProcessor({ /*!*/
325+
const dp = scheduler.createDataProcessor({ /*!*/
327326
url: "data/api.php", /*!*/
328327
mode: "JSON" /*!*/
329328
}); /*!*/
@@ -337,6 +336,10 @@ Now you have a basic scheduler that stores its events in the mysql database.
337336

338337
## Recurring events
339338

339+
:::note
340+
The implementation below applies to Scheduler v7.1 and newer, which uses the `rrule` based recurring events format. If you are still using the legacy recurring events (`rec_type`, `event_pid`, `event_length`) shipped before v7.1, the previous approach with those columns continues to work for that data.
341+
:::
342+
340343
In order to enable recurrence (e.g. "repeat event daily") you'll need to add an appropriate extension to the scheduler page:
341344

342345
~~~html
@@ -347,7 +350,7 @@ In order to enable recurrence (e.g. "repeat event daily") you'll need to add an
347350
scheduler.plugins({
348351
recurring: true /*!*/
349352
});
350-
scheduler.init('scheduler_here', new Date(2019,0,20), "week");
353+
scheduler.init('scheduler_here', new Date(2026,0,20), "week");
351354
...
352355
</script>
353356
</body>
@@ -356,28 +359,28 @@ In order to enable recurrence (e.g. "repeat event daily") you'll need to add an
356359
The "events" table needs additional columns to store info of recurring events. Here is an SQL query for creating a recurring events table:
357360

358361
~~~js
359-
CREATE DATABASE IF NOT EXISTS `scheduler_howto_php`;
360-
USE `scheduler_howto_php`;
361-
362-
DROP TABLE IF EXISTS `events`;
363362
CREATE TABLE `events` (
364-
`id` int(11) AUTO_INCREMENT,
363+
`id` bigint(20) unsigned AUTO_INCREMENT,
364+
`text` varchar(255) DEFAULT NULL,
365365
`start_date` datetime NOT NULL,
366366
`end_date` datetime NOT NULL,
367-
`text` varchar(255) DEFAULT NULL,
368-
`event_pid` int(11) DEFAULT 0,
369-
`event_length` bigint(20) unsigned DEFAULT 0,
370-
`rec_type` varchar(25) DEFAULT '',
367+
`duration` bigint(20) unsigned DEFAULT NULL,
368+
`rrule` varchar(255) DEFAULT NULL,
369+
`recurring_event_id` varchar(255) DEFAULT NULL,
370+
`original_start` varchar(255) DEFAULT NULL,
371+
`deleted` BOOLEAN DEFAULT NULL,
371372
PRIMARY KEY (`id`)
372-
) DEFAULT CHARSET="utf8;"
373+
) DEFAULT CHARSET=utf8;
373374
~~~
374375

375376
Or, you can update the events table from our previous step:
376377

377378
~~~js
378-
ALTER TABLE `events` ADD COLUMN `event_pid` int(11) DEFAULT '0';
379-
ALTER TABLE `events` ADD COLUMN `event_length` bigint(20) unsigned DEFAULT '0';
380-
ALTER TABLE `events` ADD COLUMN `rec_type` varchar(25) DEFAULT '';
379+
ALTER TABLE `events` ADD COLUMN `duration` bigint(20) unsigned DEFAULT NULL;
380+
ALTER TABLE `events` ADD COLUMN `rrule` varchar(255) DEFAULT NULL;
381+
ALTER TABLE `events` ADD COLUMN `recurring_event_id` varchar(255) DEFAULT NULL;
382+
ALTER TABLE `events` ADD COLUMN `original_start` varchar(255) DEFAULT NULL;
383+
ALTER TABLE `events` ADD COLUMN `deleted` tinyint(1) DEFAULT NULL;
381384
~~~
382385

383386
### Updating the backend
@@ -390,22 +393,27 @@ Secondly, you need to process a special case for recurring events - deletion of
390393

391394

392395
~~~js title="data/api.php"
396+
// create a new event
393397
function create($db, $event){
394398
$queryText = "INSERT INTO `events` SET
395399
`start_date`=?,
396400
`end_date`=?,
397401
`text`=?,
398-
`event_pid`=?, /*!*/
399-
`event_length`=?, /*!*/
400-
`rec_type`=?"; /*!*/
402+
`duration`=?, /*!*/
403+
`rrule`=?, /*!*/
404+
`recurring_event_id`=?, /*!*/
405+
`original_start`=?, /*!*/
406+
`deleted`=?"; /*!*/
401407
$queryParams = [
402408
$event["start_date"],
403409
$event["end_date"],
404410
$event["text"],
405411
// recurring events columns
406-
$event["event_pid"] ? $event["event_pid"] : 0, /*!*/
407-
$event["event_length"] ? $event["event_length"] : 0, /*!*/
408-
$event["rec_type"] /*!*/
412+
$event["duration"] ? $event["duration"] : null, /*!*/
413+
$event["rrule"] ? $event["rrule"] : null, /*!*/
414+
$event["recurring_event_id"] ? $event["recurring_event_id"] : null, /*!*/
415+
$event["original_start"] ? $event["original_start"] : null, /*!*/
416+
$event["deleted"] = array_key_exists("deleted", $event) ? $event["deleted"] : null, /*!*/
409417
];
410418
$query = $db->prepare($queryText);
411419
$query->execute($queryParams);
@@ -419,7 +427,7 @@ You'll also need to update the `POST` request handler, since the client requires
419427
switch ($_SERVER["REQUEST_METHOD"]) {
420428
case "GET":
421429
$result = read($db, $_GET);
422-
break;
430+
break;
423431
case "POST":
424432
$requestPayload = json_decode(file_get_contents("php://input"));
425433
$id = $requestPayload->id;
@@ -432,80 +440,85 @@ switch ($_SERVER["REQUEST_METHOD"]) {
432440
$databaseId = create($db, $body);
433441
$result["tid"] = $databaseId;
434442
// delete a single occurrence from recurring series
435-
if ($body["rec_type"] === "none") {
436-
$result["action"] = "deleted";/*!*/
443+
if ($body["deleted"]) { /*!*/
444+
$result["action"] = "deleted"; /*!*/
437445
}
438446
} elseif($action == "updated") {
439447
update($db, $body, $id);
440448
} elseif($action == "deleted") {
441449
delete($db, $id);
442450
}
443451
break;
444-
default:
445-
throw new Exception("Unexpected Method");
452+
default:
453+
throw new Exception("Unexpected Method");
446454
break;
447455
}
448456
~~~
449457

450458
The update handler requires the same changes in the SQL query. Additionally, you need to handle a different special case there: when a recurring series is modified, you need to delete all modified occurrences of that series:
451459

452460
~~~js title="data/api.php"
461+
// update an event
453462
function update($db, $event, $id){
454463
$queryText = "UPDATE `events` SET
455464
`start_date`=?,
456465
`end_date`=?,
457466
`text`=?,
458-
`event_pid`=?, /*!*/
459-
`event_length`=?, /*!*/
460-
`rec_type`=? /*!*/
467+
`duration`=?, /*!*/
468+
`rrule`=?, /*!*/
469+
`recurring_event_id`=?, /*!*/
470+
`original_start`=?, /*!*/
471+
`deleted`=? /*!*/
461472
WHERE `id`=?";
462473
$queryParams = [
463474
$event["start_date"],
464475
$event["end_date"],
465476
$event["text"],
466-
$event["event_pid"] ? $event["event_pid"] : 0, /*!*/
467-
$event["event_length"] ? $event["event_length"] : 0, /*!*/
468-
$event["rec_type"], /*!*/
477+
$event["duration"] ? $event["duration"] : null, /*!*/
478+
$event["rrule"] ? $event["rrule"] : null, /*!*/
479+
$event["recurring_event_id"] ? $event["recurring_event_id"] : null, /*!*/
480+
$event["original_start"] ? $event["original_start"] : null, /*!*/
481+
$event["deleted"] ? $event["deleted"] : null, /*!*/
469482
$id
470483
];
471-
if ($event["rec_type"] && $event["rec_type"] != "none") { /*!*/
472-
//all modified occurrences must be deleted when you update recurring series /*!*/
473-
//https://docs.dhtmlx.com/scheduler/ server_integration.html#recurringevents /*!*/
474-
$subQueryText = "DELETE FROM `events` WHERE `event_pid`=? ;"; /*!*/
475-
$subQuery = $db->prepare($subQueryText); /*!*/
476-
$subQuery->execute([$id]); /*!*/
477-
} /*!*/
484+
if ($event["rrule"] && $event["recurring_event_id"] == null) { /*!*/
485+
//all modified occurrences must be deleted when you update recurring series
486+
//https://docs.dhtmlx.com/scheduler/server_integration.html#recurringevents
487+
$subQueryText = "DELETE FROM `events` WHERE `recurring_event_id`=? ;"; /*!*/
488+
$subQuery = $db->prepare($subQueryText);
489+
$subQuery->execute([$id]);
490+
}
478491
$query = $db->prepare($queryText);
479492
$query->execute($queryParams);
480493
}
481494
~~~
482495

483496
And finally, the `DELETE` action. Here we have to check two special cases:
484-
485-
- if the event you are going to delete has a non-empty `event_pid`, it means a user deletes a modified instance of the recurring series. Instead of deleting such a record from the database, you need to give it `rec_type='none'`, in order for scheduler to skip this occurrence.
486-
497+
498+
- if the event you are going to delete is a modified instance of the recurring series. Instead of deleting, update the record to mark `deleted`.
499+
487500
- if a user deletes a whole recurring series, you also need to delete all the modified instances of that series.
488501

489502
~~~js title="data/api.php"
503+
// delete an event
490504
function delete($db, $id){
491505
// some logic specific to recurring events support
492506
// https://docs.dhtmlx.com/scheduler/server_integration.html#recurringevents
493-
$subQueryText = "SELECT * FROM `events` WHERE id="?" LIMIT 1;";
507+
$subQueryText = "SELECT * FROM `events` WHERE id=? LIMIT 1;";
494508
$subQuery = $db->prepare($subQueryText);
495509
$subQuery->execute([$id]);
496510
$event = $subQuery->fetch();
497-
if ($event["event_pid"]) {
511+
if ($event["recurring_event_id"]) { /*!*/
498512
// deleting a modified occurrence from a recurring series
499-
// If an event with the event_pid value was deleted - it needs updating
500-
// with rec_type==none instead of deleting.
501-
$subQueryText="UPDATE `events` SET `rec_type`='none' WHERE `id`=?;";
513+
// Instead of deleting, update the record to mark deleted (soft delete)
514+
$subQueryText="UPDATE `events` SET `deleted`= 1 WHERE `id`=?;"; /*!*/
502515
$subQuery = $db->prepare($subQueryText);
503516
$subQuery->execute([$id]);
504517
}else{
505-
if ($event["rec_type"] && $event["rec_type"] != "none") { /*!*/
506-
// if a recurring series deleted, delete all modified occurrences
518+
if ($event["rrule"]) { /*!*/
519+
// if a recurring series deleted, delete all modified occurrences
507520
// of the series
508-
$subQueryText = "DELETE FROM `events` WHERE `event_pid`=? ;";
521+
$subQueryText = "DELETE FROM `events` WHERE `recurring_event_id`=? ;"; /*!*/
509522
$subQuery = $db->prepare($subQueryText);
510523
$subQuery->execute([$id]);
511524
}
@@ -579,7 +592,7 @@ try {
579592
$databaseId = create($db, $body);
580593
$result["tid"] = $databaseId;
581594
// delete a single occurrence from recurring series
582-
if ($body["rec_type"] === "none") {
595+
if ($body["deleted"]) {
583596
$result["action"] = "deleted";/*!*/
584597
}
585598
} elseif($action == "updated") {

0 commit comments

Comments
 (0)