function smart_date_recur_generate_rows in Smart Date 3.3.x
Same name and namespace in other branches
- 8.2 modules/smart_date_recur/smart_date_recur.module \smart_date_recur_generate_rows()
- 3.x modules/smart_date_recur/smart_date_recur.module \smart_date_recur_generate_rows()
- 3.0.x modules/smart_date_recur/smart_date_recur.module \smart_date_recur_generate_rows()
- 3.1.x modules/smart_date_recur/smart_date_recur.module \smart_date_recur_generate_rows()
- 3.2.x modules/smart_date_recur/smart_date_recur.module \smart_date_recur_generate_rows()
- 3.4.x modules/smart_date_recur/smart_date_recur.module \smart_date_recur_generate_rows()
Helper function to generate additional field deltas based on user inputs.
1 call to smart_date_recur_generate_rows()
- SmartDateWidgetBase::massageFormValues in src/
Plugin/ Field/ FieldWidget/ SmartDateWidgetBase.php - Massages the form values into the format expected for field values.
File
- modules/
smart_date_recur/ smart_date_recur.module, line 547 - Field hooks for a field that stores a start and end date as timestamps.
Code
function smart_date_recur_generate_rows(&$values, $entity_type, $bundle, $field_name, $month_limit) {
$for_cloning = [];
foreach ($values as $index => &$item) {
// Keep track of the original position for sorting later.
$item['_original_delta'] = $index;
// Skip empty or non-repeating rows.
if (empty($item['value']) || empty($item['repeat'])) {
if (!empty($item['rrule'])) {
// Removed an existing reoccurrence, so delete.
$rrule = SmartDateRule::load($item['rrule']);
$rrule
->delete();
$item['rrule'] = NULL;
}
continue;
}
// Format provided values to be rrule-compatible.
$rrule_values = [
'freq' => $item['repeat'],
'start' => $item['value'],
'end' => $item['end_value'],
'entity_type' => $entity_type,
'bundle' => $bundle,
'field_name' => $field_name,
'parameters' => '',
];
$limit = '';
if ($item['repeat-end'] == 'COUNT') {
$limit = $item['repeat-end-count'];
}
elseif ($item['repeat-end'] == 'UNTIL') {
$limit = $item['repeat-end-date'];
}
if ($item['repeat-end'] && $limit) {
$limit_safe = new FormattableMarkup(':type=:limit', [
':type' => $item['repeat-end'],
':limit' => $limit,
]);
$rrule_values['limit'] = $limit_safe
->__toString();
$rrule_values['unlimited'] = FALSE;
$before = NULL;
}
else {
$rrule_values['limit'] = '';
$rrule_values['unlimited'] = TRUE;
$before = strtotime('+' . (int) $month_limit . ' months');
}
if (!empty($item['interval']) || is_array($item['repeat-advanced'])) {
$params = [];
if (!empty($item['interval']) && $item['interval'] > 1) {
$interval_safe = new FormattableMarkup('INTERVAL=:interval', [
':interval' => $item['interval'],
]);
$params['interval'] = $interval_safe
->__toString();
}
// Only parse appropriate adavnced options based on selected requency.
switch ($rrule_values['freq']) {
case 'MINUTELY':
// Use the array of day checkboxes if one of them is checked.
if (!empty($item['repeat-advanced']['restrict-minutes']['byminute']) && is_array($item['repeat-advanced']['restrict-minutes']['byminute'])) {
$selected = [];
foreach ($item['repeat-advanced']['restrict-minutes']['byminute'] as $value) {
if ($value) {
$selected[] = $value;
}
}
if ($selected) {
$by_minute_safe = new FormattableMarkup('BYMINUTE=:byminute', [
':byminute' => implode(',', $selected),
]);
$params['by_minute'] = $by_minute_safe
->__toString();
}
}
case 'HOURLY':
// Use the array of day checkboxes if one of them is checked.
if (!empty($item['repeat-advanced']['restrict-hours']['byhour']) && is_array($item['repeat-advanced']['restrict-hours']['byhour'])) {
$selected = [];
foreach ($item['repeat-advanced']['restrict-hours']['byhour'] as $value) {
if ($value) {
$selected[] = $value;
}
}
if ($selected) {
$by_hour_safe = new FormattableMarkup('BYHOUR=:byhour', [
':byhour' => implode(',', $selected),
]);
$params['by_hour'] = $by_hour_safe
->__toString();
}
}
case 'DAILY':
case 'WEEKLY':
// Use the array of day checkboxes if one of them is checked.
if (!empty($item['repeat-advanced']['byday']) && is_array($item['repeat-advanced']['byday']) && array_sum(array_map('is_string', $item['repeat-advanced']['byday']))) {
// Remove any zero values.
$selected = [];
foreach ($item['repeat-advanced']['byday'] as $value) {
if ($value) {
$selected[] = $value;
}
}
$by_day_safe = new FormattableMarkup('BYDAY=:byday', [
':byday' => implode(',', $selected),
]);
$params['by_day'] = $by_day_safe
->__toString();
}
break;
case 'MONTHLY':
case 'YEARLY':
if (!empty($item['repeat-advanced']['which'])) {
if (empty($item['repeat-advanced']['weekday'])) {
$by_day_safe = new FormattableMarkup('BYMONTHDAY=:which', [
':which' => $item['repeat-advanced']['which'],
]);
$params['by_day'] = $by_day_safe
->__toString();
}
else {
// Weekday(s) specified so make the condition appropriately.
if (strpos($item['repeat-advanced']['weekday'], ',')) {
// A comma means a special format for multiple days allowed.
$pattern = 'BYDAY=:day;BYSETPOS=:which';
}
else {
$pattern = 'BYDAY=:which:day';
}
$by_day_safe = new FormattableMarkup($pattern, [
':which' => $item['repeat-advanced']['which'],
':day' => $item['repeat-advanced']['weekday'],
]);
$params['by_day'] = $by_day_safe
->__toString();
}
}
if ($rrule_values['freq'] == 'YEARLY') {
$by_month_safe = new FormattableMarkup('BYMONTH=:which', [
':which' => \Drupal::service('date.formatter')
->format($rrule_values['start'], 'custom', 'n'),
]);
$params['by_month'] = $by_month_safe
->__toString();
}
break;
}
$rrule_values['parameters'] = implode(';', $params);
}
if (!empty($item['rrule'])) {
// Existing rrule, so retrieve and update values.
$rrule = SmartDateRule::load($item['rrule']);
$rrule
->set('freq', $rrule_values['freq']);
$rrule
->set('limit', $rrule_values['limit']);
$rrule
->set('unlimited', $rrule_values['unlimited']);
$rrule
->set('start', $rrule_values['start']);
$rrule
->set('end', $rrule_values['end']);
$rrule
->set('parameters', $rrule_values['parameters']);
}
else {
// New rrule, so construct object.
$rrule = SmartDateRule::create($rrule_values);
}
// Generate instances.
$instances = $rrule
->getRuleInstances($before);
$rrule
->set('instances', [
'data' => $instances,
]);
// TODO: store unaltered instances instead?
$rrule
->save();
$item['rrule'] = $rrule
->id();
// Make additional field deltas for the generated instances.
$for_cloning[$index] = $instances;
}
// Now process field values that should be cloned.
foreach ($for_cloning as $index => $instances) {
// Now process the generated instances.
// Use the submitted values as a template.
$new_item = $values[$index];
// Replace the first instance, in case there's an override.
unset($values[$index]);
foreach ($instances as $rrule_index => $instance) {
$new_item['value'] = $instance['value'];
$new_item['end_value'] = $instance['end_value'];
$new_item['duration'] = ($instance['end_value'] - $instance['value']) / 60;
$new_item['rrule_index'] = $rrule_index;
$values[] = $new_item;
}
}
$values = smart_date_array_orderby($values, '_original_delta', SORT_ASC, 'value', SORT_ASC);
return $values;
}