Frage

I've been struggling with this for a while and would love some fresh ideas.

I have an events calendar that has recurring events. I've run into some problems when I try to update recurring events.

I have a simple form where I ask the user for a day of the week and a start date.

I want to get the next day of the week after the start date (no problem here) and update the exiting event that week to the new starting day(still no problem). Then I want to increment all the other events after that to be 7 days after the event before it. (<--problem)

<?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();

        }

Now I need to loop through every event (with the same parent_id) after this one and increment it by 7 days (or whatever my repeat_freq is). I've tried using

UPDATE events
SET  start = :start + INTERVAL 7 DAY, end = :end + INTERVAL 7 DAY

but this just updates all the events to 7 days after the new start date and not from 7 days from the last event. If I could put this in a loop without having to reference the specific event id and just go sequentially, that'd be great. I'm open to any solutions though. Thanks for reading.

UPDATE FOR SCHEMA

My parent_events table has

parent_id (auto increment) | start_date | repeats | repeat_freq |

My events table has the following

event_id (auto increment) | parent_id | start | end |

When a new recurring event is created I insert a row into the parent_events table. I get the new parent_id using lastInsertId() and use it when I insert all of the recurring instances (of that parent event) into the events table. Basically, the events table holds all of the instances of a specific (parent) event.

UPDATE FOR WORKING CODE

$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);
        }
War es hilfreich?

Lösung

I think the easiest way is loop through the SET of events via PHP.

I will write below the important pieces of code:

$sql='SELECT event_id AS id from events WHERE parent_id=:parent_id AND start=:start

Running this Query will get an array with all IDs that required update

 $mysqli = new mysqli("localhost", "my_user", "my_password", "world");
 if (mysqli_connect_errno()) {
  printf("Connect failed: %s\n", mysqli_connect_error());
  exit();
 }
 $row_date=array();
 $row_date[0]=$start  //get start date
 foreach ($rows as $row)

  $sql_date="SELECT TIMESTAMPADD(week,1,$row_date[0])"; //increment start date by 1 week
  $date =  $mysqli->query($sql_date);
  $row_date = $result->fetch_array(MYSQLI_NUM); //Set the start date as Start date + 1 week to reflect in the next loop.

  $sql_update="UPDATE events SET start=$row_date[0] WHERE event_id=$row['id']";
  $mysqli->query($sql_update);
 end foreach

The code my need some adjustment, but I think it helps outlay the idea.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top