私はしばらくこれに苦労していて、いくつかの新鮮なアイデアが大好きです。
定期的なイベントがあるイベントカレンダーがあります。定期的なイベントを更新しようとすると、いくつかの問題が発生しました。
ユーザーに曜日と開始日を尋ねる簡単なフォームがあります。
開始日の翌週の曜日(ここでは問題ありません)を取得し、その週の終了イベントを新しい開始日(まだ問題ありません)に更新したいと思います。次に、その後の他のすべてのイベントを、その前のイベントの7日後にインクリメントしたいと思います。(<-問題)
<?php
session_start();
require_once '../../../config/db-config.php';
$weekday = $_POST['weekday']; // day of the week the event should take place on
$start_date = $_POST['start-date']; //new starting date of the event
if (date('N', strtotime($start_date)) == $weekday)
{
$start_date = $_POST['start-date'];
}
else
{
$start_date = date('Y-m-d', strtotime("next $weekday", strtotime($start_date))); //gets the first day of the week after the starting date. First event should start on this day.
}
$start_time = $_POST['start-time'];
$end_time = $_POST['end-time'];
$start = $start_date . " " . $start_time; //'yyyy-dd-mm hh:mm:ii' format
$end = $start_date . " " . $end_time;
$repeats = $_POST['repeats']; // 1 for repeats 0 for no repeats
$repeat_freq = $_POST['repeat-freq']; //7 for 7 days, 14 for 14 days etc
$parent_id = $_POST['parent-id']; //common parent_id to the event group
$stmt = $dbh->prepare("
UPDATE events
SET start = :start, end = :end
WHERE parent_id = :parent_id AND WEEK(start) =WEEK(:start)"); //This updates the existing event of that week to the new starting date
$stmt->bindParam(':start', $start);
$stmt->bindParam(':end', $end);
$stmt->bindParam(':parent_id', $parent_id);
$stmt->execute();
}
次に、このイベントの後に(同じparent_idを持つ)すべてのイベントをループして、7日(またはrepeat_freqが何であれ)インクリメントする必要があります。使ってみました
UPDATE events
SET start = :start + INTERVAL 7 DAY, end = :end + INTERVAL 7 DAY
ただし、これにより、すべてのイベントが、最後のイベントから7日ではなく、新しい開始日の7日後に更新されます。特定のイベントIDを参照せずにこれをループに入れて、順番に実行できれば、それは素晴らしいことです。しかし、私はどんな解決策にもオープンです。読んでくれてありがとう。
スキーマの更新
私のparent_eventsテーブルには
parent_id (auto increment) | start_date | repeats | repeat_freq |
私のイベントテーブルには次のものがあります
event_id (auto increment) | parent_id | start | end |
新しい定期的なイベントが作成されたら、parent_eventsテーブルに行を挿入します。lastInsertId()を使用して新しいparent_idを取得し、(その親イベントの)すべての繰り返しインスタンスをイベントテーブルに挿入するときに使用します。基本的に、eventsテーブルには、特定の(親)イベントのすべてのインスタンスが保持されます。
作業コードの更新
$stmt = $dbh->prepare("
SELECT event_id
FROM events
WHERE parent_id = :parent_id AND WEEK(start) >=WEEK(:start)");
$stmt->bindParam(':start', $start_date);
$stmt->bindParam(':parent_id', $parent_id);
$stmt->execute();
$updateArray = array();
$last_class = 0;
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if ($last_event != $row['event_id']) {
$last_event = $row['event_id'];
$updateArray[$last_event] = array('event_id' => $row['event_id']);
}
}
foreach($updateArray as $update){
$event_id = $update['event_id'];
$stmt = $dbh->prepare("
UPDATE events
SET title = start = :start, end=:end
WHERE event_id = :event_id");
$stmt->bindParam(':start', $start);
$stmt->bindParam(':end', $end);
$stmt->bindParam(':event_id', $event_id);
$stmt->execute();
$new_start = strtotime($start . '+' . $repeat_freq . 'DAYS');
$new_end = strtotime($end . '+' . $repeat_freq . 'DAYS');
$start = gmdate("Y-m-d H:i", $new_start);
$end = gmdate("Y-m-d H:i", $new_end);
}