У меня есть расширение для создания событий, которое содержит возможность создавать события для пользователей. Это реализовано с использованием метода репозитория extbase. В форме создания мероприятия у меня есть дата начала, дата окончания и дни недели, которые должны повторяться.
Например, если я установил дату начала как 13-10-2015, а дату окончания - 30-10-2015. И выбрал будний день как "среда". Так что событие будет повторяться во всех "средах" между 13 и 30.
Когда я создаю не повторяющееся событие, он будет работать правильно. Но для повторяющегося события я применил метод клонирования репозитория extbase.
if (!empty($endDateRecurring) && !empty($recurringWeekDays)) {
$endDate = new \DateTime($endDateRecurring);
$startDate = $newEvent->getDate();
$startDate->setTime(0, 0);
$datetimeDiff = $startDate->diff($endDate);
for ( $event=1; $event <= $datetimeDiff->days; $event++ ) {
$checkDate = $newEvent->getDate()->add(new \DateInterval('P'.$event.'D'));
$dayOfWeekNo = date('w',$checkDate->getTimestamp());
if ( in_array( $dayOfWeekNo, $recurringWeekDays ) ) {
$eventProperties = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getGettableProperties( $newEvent );
\TYPO3\CMS\Extbase\Reflection\ObjectAccess::setProperty( $eventProperties, 'date', $eventProperties['date']->add(new \DateInterval('P1D') ) );
$eventCopy = $this->objectManager->create('\TYPO3\EventCreate\Domain\Model\Event');
foreach ( $eventProperties as $propertyName => $propertyValue ) {
if (\TYPO3\CMS\Extbase\Reflection\ObjectAccess::isPropertySettable($eventCopy,
$propertyName) && !in_array($propertyName, array('uid','pid'))) {
$propertyValue = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getProperty( $newEvent, $propertyName );
\TYPO3\CMS\Extbase\Reflection\ObjectAccess::setProperty( $eventCopy, $propertyName, $propertyValue );
}
}
//TODO: cloning doesn't work because the id is already set and it thus doesn't add a new object to the repository.
//either create a new object and copy all content properties, or find another way to add more events to the db for recurring days.
$this->eventRepository->add($eventCopy);
$this->objectManger->get('Tx_Extbase_Persistence_Manager')->persistAll();
}
}
}
Здесь $ recurringWeekDays - это массив, который содержит выбранный повторный идентификатор недели недели (для Понедельника-1, вторник-2, как это).
Проблема заключается в том, что есть какое-то количество дней для вставки, а затем только одна запись, вставленная в базу данных. В приведенном выше примере 3 среды с 13 по 30 октября. Но вставлена только одна запись.
Если кто-нибудь знает решение, пожалуйста, помогите.
Еще одна попытка сделать вывод из моего предыдущего ответа:
Как отметил @pgame, проблема заключается в внутреннем идентификаторе, используемом в ORM. В Persistence/ObjectStorage.php
я вижу, что PHP spl_object_hash($object)
используется для создания внутреннего идентификатора для объекта в хранилище. Поэтому мы должны убедиться, что эта функция не производит один и тот же хэш более одного раза.
Как написано в http://php.net/manual/de/function.spl-object-hash.php, вы можете прочитать в первом примечании пользователя, что эта функция не генерирует свой хэш свойствами объекта, а внутренним чтобы гарантировать, что несколько экземпляров в памяти будут иметь разные хэши. Но как только экземпляр будет уничтожен, хэш может быть повторно использован для другого экземпляра.
Следовательно, мы должны убедиться, что в каждой итерации экземпляр $eventCopy
не будет перезаписан (и таким образом уничтожен) следующим экземпляром, так как он может привести к тому же хешу в ObjectStorage. Я бы предложил создать массив $eventCopies
и нажать на каждый новый экземпляр $eventCopy
. Таким образом, каждый экземпляр будет сохранен в этом массиве через все итерации в вашем for-loop. В конце концов, вы можете снова перебирать свои $eventCopies
и добавлять их в свой репозиторий.
Работает ли это на этот раз?
Я думаю, что использование objectManager - проблема. Попробуйте изменить
$eventCopy = $this->objectManager->create('\TYPO3\EventCreate\Domain\Model\Event');
в
$eventCopy = new \TYPO3\EventCreate\Domain\Model\Event();
Это работает?
persistAll()
просто заставляет хранилище сохранять все изменения (например, добавлять, обновлять или удалять объекты) в базе данных. В противном случае это будет сделано только после того, как закончится ваше действие контроллера. Следовательно, этого должно быть достаточно для запуска persistAll () сразу после завершения for
-loop.
$eventCopy
. ... Поэтому мое решение здесь не должно решить проблему. Или это? ... Чувак, я зациклен на поиске решения твоей проблемы сейчас.