View source
<?php
function node_recur_menu() {
$items = array();
$items['node/%node/recur'] = array(
'title' => 'Repeat',
'title callback' => 'node_recur_menu_title_callback',
'title arguments' => array(
1,
),
'description' => 'Set recurring rules on this node',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'node_recur_node_recur_form',
1,
),
'access callback' => 'node_recur_node_recur_form_access',
'access arguments' => array(
1,
),
'file' => 'node_recur.pages.inc',
'type' => MENU_LOCAL_ACTION,
'weight' => 1,
);
return $items;
}
function node_recur_permission() {
return array(
'recur own nodes' => array(
'title' => t('Recur own nodes'),
'description' => t('Can recur nodes that the user is an author of.'),
),
'recur all nodes' => array(
'title' => t('Recur all nodes'),
'description' => t('Can recur all published nodes.'),
),
);
}
function node_recur_form_alter(&$form, &$form_state, $form_id) {
if (isset($form['#node_edit_form']) && $form['#node_edit_form']) {
if (!$form['nid']['#value'] && !$form_state['executed']) {
if (node_recur_node_recur_form_access($form['#node'])) {
if (node_recur_node_form_enabled($form['#node']->type)) {
if (node_recur_recurring_enabled($form['#node']->type)) {
module_load_include('inc', 'node_recur', 'node_recur.pages');
$date_field = node_recur_get_date_field_name($form['#node']->type);
$recur_form = _node_recur_node_recur_form($form['#node']->type);
$recur_form['option']['#default_value'] = 'none';
$recur_form['until']['#required'] = FALSE;
$form['node_recur'] = array(
'#type' => 'fieldset',
'#title' => t('Repeat'),
'#weight' => $form[$date_field]['#weight'] + 0.1,
);
$form['node_recur'] = array_merge($form['node_recur'], $recur_form);
$form['#validate'][] = 'node_recur_node_form_validate';
$form['actions']['submit']['#submit'][] = 'node_recur_node_form_submit';
}
}
}
}
}
}
function node_recur_form_node_type_form_alter(&$form, &$form_state) {
$type = $form['#node_type']->type;
$fields = array();
$instances = field_info_instances();
if (isset($instances['node'][$type])) {
foreach ($instances['node'][$type] as $name => $field) {
if ($field['widget']['module'] == 'date') {
$fields[$name] = $field['label'] . ' (' . $name . ')';
}
}
}
$form['node_recur'] = array(
'#type' => 'fieldset',
'#title' => t('Node Recur'),
'#group' => 'additional_settings',
);
if (!empty($fields)) {
$form['node_recur']['node_recur_enabled_node_type'] = array(
'#type' => 'checkbox',
'#title' => t('Enable recurring for this node type'),
'#default_value' => node_recur_recurring_enabled($type) ? 1 : 0,
'#description' => t('If checked, users with permission can create recurring copies of these nodes.'),
);
$form['node_recur']['node_recur_allow_past_dates_node_type'] = array(
'#type' => 'checkbox',
'#title' => t('Allow dates in the past'),
'#default_value' => node_recur_allow_past_dates($type) ? 1 : 0,
'#description' => t('If checked, recurrences with dates in the past will be allowed.'),
);
$form['node_recur']['node_recur_max_span_node_type'] = array(
'#type' => 'select',
'#title' => t('Max recurring duration'),
'#options' => array(
0 => t('No max'),
'1 week' => t('1 week'),
'2 weeks' => t('2 weeks'),
'1 month' => t('1 month'),
'3 months' => t('3 months'),
'6 months' => t('6 months'),
'1 year' => t('1 year'),
),
'#default_value' => node_recur_max_future_date_span($type),
'#description' => t('Select a maximum time span that recurring will be allowed to continue to.'),
);
$form['node_recur']['node_recur_date_field_node_type'] = array(
'#type' => 'select',
'#title' => t('Date field'),
'#options' => $fields,
'#default_value' => node_recur_get_date_field_name($type),
'#description' => t('Select the date field that will be used to base the recurrences on.'),
);
$form['node_recur']['node_recur_node_form_node_type'] = array(
'#type' => 'checkbox',
'#title' => t('Display recur options on node add form'),
'#default_value' => node_recur_node_form_enabled($type) ? 1 : 0,
'#description' => t('If checked, recurring options will appear on the node add form.'),
);
}
else {
$form['node_recur']['node_recur_null'] = array(
'#markup' => t('To use Node Recur, add at least one date field to this content type.'),
);
}
}
function node_recur_node_recur_form_access($node) {
global $user;
$access = FALSE;
if (node_recur_recurring_enabled($node->type)) {
if (user_access('recur all nodes') || user_access('recur own nodes') && $node->uid == $user->uid) {
if ($node->status || user_access('administer nodes')) {
if (node_recur_get_date_field_name($node->type)) {
$access = TRUE;
}
}
}
drupal_alter('node_recur_access', $access, $node);
}
return $access;
}
function node_recur_recurring_enabled($type) {
return variable_get("node_recur_enabled_node_type_{$type}", FALSE);
}
function node_recur_node_form_enabled($type) {
return variable_get("node_recur_node_form_node_type_{$type}", FALSE);
}
function node_recur_allow_past_dates($type) {
return variable_get("node_recur_allow_past_dates_node_type_{$type}", FALSE);
}
function node_recur_max_future_date_span($type) {
return variable_get("node_recur_max_span_node_type_{$type}", NULL);
}
function node_recur_get_date_field_name($type) {
if ($field_name = variable_get("node_recur_date_field_node_type_{$type}", FALSE)) {
if (field_info_field($field_name)) {
return $field_name;
}
}
return NULL;
}
function node_recur_get_node_date_field_value($node, $start = TRUE) {
if ($field_name = node_recur_get_date_field_name($node->type)) {
$key = $start ? 'value' : 'value2';
$field = $node->{$field_name};
if (isset($field[LANGUAGE_NONE][0][$key])) {
return $field[LANGUAGE_NONE][0][$key];
}
}
return NULL;
}
function node_recur_menu_title_callback($node) {
return t('Repeat this !type', array(
'!type' => strtolower(node_type_get_name($node)),
));
}
function node_recur_generate_dates_rule($node, $date, $frequency, $period, $until, $weekends = TRUE) {
$dates = array();
$month = FALSE;
$date = is_string($date) ? strtotime($date) : $date;
$until = is_string($until) ? strtotime($until) : $until;
if (!is_numeric($date) || !is_numeric($until)) {
return FALSE;
}
if ($date >= $until) {
return FALSE;
}
if ($period == 'month') {
$frequency = $frequency * 4;
$period = 'week';
$month = TRUE;
}
$current = $date;
while (TRUE) {
$next = strtotime("+{$frequency} " . format_plural($frequency, $period, "{$period}s"), $current);
if ($month && date('n', $next) == date('n', $current)) {
$next = strtotime('+1 week', $next);
}
$current = $next;
if (!node_recur_allow_past_dates($node->type) && $next < REQUEST_TIME) {
continue;
}
if (!$weekends) {
$day = date('D', $next);
if ($day == 'Sun' || $day == 'Sat') {
continue;
}
}
if ($next > $until) {
break;
}
$dates[] = $current;
}
return $dates;
}
function node_recur_generate_dates_days($node, $date, $days, $until, $offset = NULL) {
$dates = array();
$date = is_string($date) ? strtotime($date) : $date;
$until = is_string($until) ? strtotime($until) : $until;
$hour = date('G', $date);
if ($offset) {
$date = $date - $offset * 86400;
}
if (!is_numeric($date) || !is_numeric($until)) {
return FALSE;
}
if ($date >= $until) {
return FALSE;
}
$current = $date;
$first_day = NULL;
foreach ($days as $day) {
$z = date('z', strtotime("next {$day}", $current));
if (!$first_day || $z < $first_day) {
$first_day = $z;
}
}
while (TRUE) {
foreach ($days as $day) {
$next_day = date('z', strtotime("next {$day}", $current));
$days_apart = $next_day - date('z', $current);
if ($days_apart < 0) {
$days_apart += 366;
}
$current += $days_apart * 86400;
$current_hour = date('G', $current);
if ($current_hour != $hour) {
$current += ($hour - $current_hour) * 3600;
}
if ($current > $until) {
break 2;
}
$date_to_use = $current;
if ($offset) {
$date_to_use = $current + $offset * 86400;
}
if (!node_recur_allow_past_dates($node->type) && $date_to_use < REQUEST_TIME) {
continue;
}
if ($first_day && $first_day != $next_day && $first_day > $next_day) {
continue;
}
$first_day = NULL;
$dates[] = $date_to_use;
}
}
return $dates;
}
function node_recur_generate_dates_from_form($node, $form_state) {
$option = $form_state['values']['option'];
$days = array();
foreach ($form_state['values']['days'] as $day => $value) {
if ($value) {
$days[] = $day;
}
}
$frequency = $form_state['values']['frequency'];
$period = $form_state['values']['period'];
$until = strtotime($form_state['values']['until']);
$until += 86399;
$weekends = !$form_state['values']['exclude_weekends'];
$start_date = node_recur_get_node_date_field_value($node);
$end_date = node_recur_get_node_date_field_value($node, FALSE);
$start_dates = array();
$end_dates = array();
if ($start_date) {
if ($option == 'days') {
$start_dates = node_recur_generate_dates_days($node, $start_date, $days, $until);
}
else {
if ($option == 'rules') {
$start_dates = node_recur_generate_dates_rule($node, $start_date, $frequency, $period, $until, $weekends);
}
}
}
if ($end_date) {
$days_apart = NULL;
if ($start_date) {
if (date('j', strtotime($start_date)) != date('j', strtotime($end_date))) {
$days_apart = floor((strtotime($end_date) - strtotime($start_date)) / 86400);
$until += $days_apart * 86400;
}
}
if ($option == 'days') {
$end_dates = node_recur_generate_dates_days($node, $end_date, $days, $until, $days_apart);
}
else {
if ($option == 'rules') {
$end_dates = node_recur_generate_dates_rule($node, $end_date, $frequency, $period, $until, $weekends);
}
}
}
$dates = array(
'start' => $start_dates,
'end' => $end_dates,
);
$variables = array(
'node' => $node,
'start_date' => $start_date,
'end_date' => $end_date,
'option' => $option,
'until' => $until,
);
if ($option == 'days') {
$variables['days'] = $days;
}
if ($option == 'rules') {
$variables += array(
'frequency' => $frequency,
'period' => $period,
'weekends' => $weekends,
);
}
drupal_alter('node_recur_dates', $dates, $variables);
return $dates;
}
function node_recur_node_form_validate(&$form, &$form_state) {
module_load_include('inc', 'node_recur', 'node_recur.pages');
node_recur_node_recur_form_validate($form, $form_state);
}
function node_recur_node_form_submit(&$form, &$form_state) {
module_load_include('inc', 'node_recur', 'node_recur.pages');
if ($form_state['values']['option'] == 'none') {
return;
}
$node = $form_state['node'];
$dates = node_recur_generate_dates_from_form($node, $form_state);
$form['#start_dates'] = $dates['start'];
$form['#end_dates'] = $dates['end'];
$form['#node'] = $node;
node_recur_node_recur_confirm_submit($form, $form_state);
}
function node_recur_format_date($start, $end = NULL, $format = 'long') {
$string = '';
$start = is_string($start) ? strtotime($start) : $start;
$start = format_date($start, $format);
$string .= $start;
if ($end) {
$end = is_string($end) ? strtotime($end) : $end;
$end = format_date($end, $format);
if ($start != $end) {
$string .= ' - ' . $end;
}
else {
$string .= ' (' . t('All day') . ')';
}
}
return $string;
}
function node_recur_clone_node_alter(&$node, &$context) {
$node->title = $context['original_node']->title;
}
function node_recur_field_extra_fields() {
$extra = array();
foreach (array_keys(node_type_get_names()) as $type) {
if (node_recur_node_form_enabled($type) == TRUE) {
$extra['node'][$type]['form']['node_recur'] = array(
'label' => t('Node recurring options'),
'description' => t('Node recur module form elements'),
'weight' => 5,
);
}
}
return $extra;
}