Отображать повторяющиеся даты из базы данных SQL с помощью PHP

Я получаю доступ к базе данных, созданной другой веб-компанией, для получения информации о событиях для моего текущего клиента. Мой клиент вводит информацию о событиях и отмечает, повторяется ли дата или нет. Я пытаюсь показать все повторяющиеся даты. До сих пор я мог получить все, чтобы показывать, регулярные даты, а также повторяющиеся.

Таблицы изложены следующим образом:

  • Мероприятия
  • Events_Recurring

Вот часть таблицы Events BIGGER PICTURE

таблица событий

Это выглядит таблица Events_Recurring.

повторяющаяся таблица событий

Когда клиент проверяет его как повторяющийся, таблица events_recurring создает строку с идентификатором события и другой информацией, например, какой день недели или месяца происходит повторение события.

Я просто не знаю, как отображать кратные идентификаторы, которые повторяются. У меня есть дата начала и дата окончания, на которую я могу получить доступ, а также какой день недели повторяется.

Так, например: Если это событие заново возобновилось каждый четверг. и я знал, что это началось 1 января и закончилось 31 января. Могу ли я пройти через это и выплюнуть 4 разных события со всеми каждыми четвергами в январе?

Вот полный код, с которым я работаю, это немного грязно, пытаясь понять это. Я проверяю повторение в сторону дна

// Access external database $events_db = new wpdb(TOP SECRET CREDENTIALS HERE); $events_db->show_errors(); if ($events_db) : // Query Events Database $events = $events_db->get_results( " SELECT ID, RequestDateStart, RequestDateEnd, Ministry, RequestTimeStart, EventName, CoordinatorName, EventDescription, Location FROM gc_events WHERE PrivateEvent = 0 AND Ministry = 15 AND date(RequestDateStart)>=date(NOW()) ORDER BY RequestDateStart " ); // Create the event data that will be displayed foreach ($events as $event) : // Store Event ID in a variable $masterID = $event->ID; echo '<div class="col-12">'; echo '<strong>ID:</strong> ' . $event->ID . '<br /><strong>Event Name:</strong> ' . $event->EventName . '<br /><strong>Leader:</strong> ' . $event->CoordinatorName . '<br /><strong>Date:</strong> ' . date('l, F j',strtotime($event->RequestDateStart)) . '<br /><strong>Start Time:</strong> ' . date('g:i a',strtotime($event->RequestTimeStart)); // CHECK IF RECURRING $recurring_events = $events_db->get_results( " SELECT gc_event_id, period, day FROM gc_event_recurring WHERE gc_event_id = '$masterID' " ); foreach ($recurring_events as $recurring_event) : if ($recurring_event->period === 'week') { echo '<div class="col-12"><strong>&uarr; WEEKLY</strong><br />'; echo $recurring_event->day; echo '</div>'; } endforeach; echo '</div>'; endforeach; endif; 

Результат, который я получаю прямо сейчас (с повторяющимися событиями), является

Событие: Еженедельная молитва
Дата: 1 февраля 2013 г.

В результате я бы хотел

Событие: Еженедельная молитва
Дата: 1 февраля 2013 г.

Событие: Еженедельная молитва
Дата: 8 февраля 2013 г.

Событие: Еженедельная молитва
Дата: 15 февраля 2013 г.

Событие: Еженедельная молитва
Дата: 22 февраля 2013 г.


Это было бы, если дата начала была 1 февраля, а дата окончания – 28 февраля.

  foreach ($events as $event) : // Store Event ID in a variable $masterID = $event->ID; echo '<div class="col-12">'; echo '<strong>ID:</strong> ' . $event->ID . '<br /><strong>Event Name:</strong> ' . $event->EventName . '<br /><strong>Leader:</strong> ' . $event->CoordinatorName . '<br /><strong>Date:</strong> ' . date('l, F j',strtotime($event->RequestDateStart)) . '<br /><strong>Start Time:</strong> ' . date('g:i a',strtotime($event->RequestTimeStart)); // CHECK IF RECURRING $recurring_events = $events_db->get_results( " SELECT gc_event_id, period, day FROM gc_event_recurring WHERE gc_event_id = '$masterID' " ); foreach ($recurring_events as $recurring_event) : if ($recurring_event->period == 'week') { $StartDate = strtotime($event->RequestDateStart); $EndDate = strtotime($event->RequestDateEnd); $TotalDays = round(($EndDate-$StartDate)/(60*60*24*7)); for($i = 0 ;$i<($TotalDays-1);$i++) { $StartDate += (60*60*24*7); echo '<div class="col-12">'; echo '<strong>ID:</strong> ' . $event->ID . '<br /><strong>Event Name:</strong> ' . $event->EventName . '<br /><strong>Leader:</strong> ' . $event->CoordinatorName . '<br /><strong>Date:</strong> ' . date('l, F j',$StartDate) . '<br /><strong>Start Time:</strong> ' . date('g:i a',strtotime($event->RequestTimeStart)); } } endforeach; echo '</div>'; endforeach; 

попробуйте это и скажите мне, работает ли оно

Слово совета.

Хотя создание базы данных для хранения «описания» шаблона повторения – очень чистый подход с точки зрения дизайна, вы можете столкнуться с множеством проблем.

Я сделал проект с аналогичным подходом некоторое время назад (я посмотрю дизайн базы данных и добавлю это к моему ответу), и, хотя я смог воспроизвести точную дату / время повторяющихся событий, вы столкнетесь с проблемы в следующих ситуациях; большинство из них исходит из этого:

повторяющиеся события описывают шаблон повторения, поэтому фактические (индивидуальные) события не являются физическими данными в вашей базе данных

  1. Если клиент решает добавить новое событие, как вы можете проверить, совпадает ли он с любым существующим событием? Вы должны будете рассчитать все «события» на основе шаблона повторения.
  2. Если клиент решает, что запланированное время для события необходимо изменить, как это изменение применимо ко всем будущим событиям, а не к событиям, которые были в прошлом (вам придется дублировать исходное событие, изменить его конец -date и установить повторяющееся событие с новой датой начала)
  3. Если клиент решает, что хочет удалить один день из шаблона повторения (например, одно событие отменено), вам также придется разделить исходное событие на два отдельных повторения или иметь «отмененные / заблокированные» даты / время Таблица
  4. Если людям необходимо «забронировать» для определенных событий, вы не сможете присоединить их к «реальной» записи событий, потому что отдельные события, потому что они физически не присутствуют в базе данных. например, чтобы проверить, может ли одно событие быть перепланировано или отменено, вам нужно сделать это из кода, поскольку база данных не может использовать ограничения внешнего ключа для автоматического обновления соответствующих резервирований
  5. Что касается производительности; потому что отдельные события физически не хранятся, их нужно будет рассчитывать каждый раз, когда вы хотите их показать. Подумайте о том, чтобы иметь 1000 повторяющихся событий в базе данных и попытаться показать «календарь» недели 23 через два года. Вам придется проанализировать все шаблоны повторяющихся событий и рассчитать все события, которые они производят!

Конечно, все зависит от фактического использования вашей системы, но я хотел предупредить вас о проблемах, с которыми мы столкнулись.

Вот схема таблицы «расписания» (содержит шаблон повторяющихся событий);

 CREATE TABLE IF NOT EXISTS `schedules` ( `id` int(11) NOT NULL auto_increment, `date_start` date NOT NULL, `time_start` time NOT NULL, `time_end` time NOT NULL, `recur_until` date default NULL COMMENT 'end date when recurrence stops', `recur_freq` varchar(30) default NULL COMMENT 'null, "secondly", "minutely", "hourly", "daily", "weekly", "monthly", "yearly"', `recur_interval` smallint(5) unsigned default NULL COMMENT 'eg 1 for each day/week, 2 for every other day/week', `recur_byday` smallint(5) unsigned default NULL COMMENT 'BITWISE; monday = 1, sunday = 64', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; 

Как обойти описанные проблемы

Полное описание решения этих проблем, вероятно, не будет подходящим здесь, но вот некоторые вещи, которые следует учитывать;

Хранение повторяющегося события, как описано в нем, – не плохая практика. Он прекрасно описывает, когда и как часто должно происходить событие. Тем не менее, отсутствие физических записей для фактических событий является причиной проблемы.

  1. При создании или изменении повторяющегося события вычисляйте все результирующие события и храните их как физические записи. Эти записи могут быть запрошены, к ним могут быть прикреплены «оговорки», и вы сможете использовать функции базы данных, такие как ограничения внешнего ключа, чтобы правильно их обрабатывать.
  2. При сохранении отдельных событий, как описано в 1., убедитесь, что вы сохраняете ссылку на «расписание», к которому они принадлежат. Если (например) клиент хочет изменить время повторяющегося события, вы сможете обновить все связанные (отдельные) события.
  3. Имейте в виду, что в ситуации 2 вы, вероятно, только хотите обновить будущие события, поэтому для повторного события все равно нужно «разделить» на два, чтобы достичь этого. В этом случае «будущие» события должны быть привязаны к новому «повторяющемуся событию», старые события остаются привязанными к существующему «повторяющемуся событию»,

инвестируйте время в свою базу данных / разработку программного обеспечения , правильно исследуйте, будет ли дизайн работать на то, чего вы пытаетесь достичь. Протестируйте его, попробуйте что-нибудь, и если они не сработают, не стесняйтесь «выбросить его», часто легче начинать с нуля, чем пытаться «исправить» вещи. Правильный дизайн потребует времени и может занять несколько «редизайнов», чтобы исправить это, но в итоге это сэкономит вам время и деньги.

Надеюсь это поможет. Удачи!