View source
<?php
function archive_help($section) {
switch ($section) {
case 'admin/help#archive':
$output = '<p>' . t('The archive module provides a suggested menu item, which shows a page allowing content to be filtered by date and node type. The date selectors allow visitors to view content published in any given year, month or day. The node type selectors allow visitors to view content of all node types or only specific ones.') . '</p>';
$output .= t('<p>You can</p>
<ul>
<li>view your <a href="!archive">archive page</a>.</li>
<li><a href="!admin-menu">enable or disable the archive menu item</a>.</li>
</ul>
', array(
'!archive' => url('archive'),
'!admin-menu' => url('admin/menu'),
));
$output .= '<p>' . t('For more information please read the configuration and customization handbook <a href="http://drupal.org/handbook/modules/archive/">Archive page</a>.') . '</p>';
return $output;
}
}
function archive_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'archive',
'access' => user_access('access content'),
'callback' => 'archive_page',
'description' => t('Browse the archives'),
'type' => MENU_SUGGESTED_ITEM,
);
$items[] = array(
'path' => 'admin/settings/archive',
'title' => t('Archive Settings'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'archive_admin_settings',
),
'description' => t('Configure node types available for archive browsing.'),
'type' => MENU_NORMAL_ITEM,
);
}
else {
drupal_add_css(drupal_get_path('module', 'archive') . '/archive.css');
}
return $items;
}
function archive_page($type = 'all', $year = NULL, $month = NULL, $day = NULL) {
include_once 'archive.inc';
return _archive_page($type, $year, $month, $day);
}
function archive_admin_settings() {
$types = node_get_types();
$final_types = array();
foreach ($types as $key => $value) {
$final_types[$key] = $value->name;
}
$form['archive_type_filters'] = array(
'#type' => 'checkboxes',
'#title' => t('What nodes are available as filters'),
'#default_value' => variable_get('archive_type_filters', array_keys($final_types)),
'#options' => $final_types,
'#description' => t('Whichever node type you choose here will be available as a filter to the user.'),
);
return system_settings_form($form);
}
function _archive_validate_year($year) {
return 1970 <= $year && $year <= 2038;
}
function _archive_validate_month($month) {
return 1 <= $month && $month <= 12;
}
function _archive_validate_day($year, $month, $day) {
if (_archive_validate_month($month) && _archive_validate_year($year)) {
$last = gmdate('t', gmmktime(0, 0, 0, $month, 1, $year));
return 1 <= $day && $day <= $last;
}
else {
return FALSE;
}
}
function _archive_validate_type($type) {
$types = variable_get('archive_type_filters', array());
foreach ($types as $key => $value) {
if (!$value) {
unset($types[$key]);
}
else {
$types[$key] = 0;
}
}
return in_array($type, array_keys($types));
}
function _archive_url($type, $y = 0, $m = 0, $d = 0) {
$url = 'archive';
if (_archive_validate_type($type)) {
$url .= '/' . $type;
}
else {
$url .= '/all';
}
if (_archive_validate_year($y)) {
$url .= '/' . $y;
if (_archive_validate_month($m)) {
$url .= '/' . $m;
if (_archive_validate_day($y, $m, $d)) {
$url .= '/' . $d;
}
}
}
return $url;
}
function _archive_get_timezone() {
global $user;
if (variable_get('configurable_timezones', 1) && $user->uid && strlen($user->timezone)) {
return $user->timezone;
}
else {
return variable_get('date_default_timezone', 0);
}
}
function _archive_date($type, $year = NULL, $month = NULL, $day = NULL) {
$date = (object) array(
'tz' => _archive_get_timezone(),
);
$date->year = 0;
$date->month = 0;
$date->day = 0;
if (_archive_validate_year($year)) {
$date->year = $year;
if (_archive_validate_month($month)) {
$date->month = $month;
if (_archive_validate_day($year, $month, $day)) {
$date->day = $day;
}
}
}
$post_counts = _archive_post_count($type, $date);
$date->years = $post_counts['years'];
ksort($date->years);
$date->months = $post_counts['months'];
ksort($date->months);
$date->days = $post_counts['days'];
ksort($date->days);
$date->next_month_days = $post_counts['next_month_days'];
$date->prev_month_days = $post_counts['prev_month_days'];
return $date;
}
function _archive_post_count($type, $date) {
$final_types = _archive_types_sql_string($type);
$node_query = db_query(db_rewrite_sql('SELECT n.created FROM {node} n WHERE n.status = 1 ' . $final_types));
$with_posts = array(
'years' => array(),
'months' => array(),
'days' => array(),
'next_month_days' => array(),
'prev_month_days' => array(),
);
$next_month = $date->month == 12 ? 1 : $date->month + 1;
$next_year = $date->month == 12 ? $date->year + 1 : $date->year;
$prev_month = $date->month == 1 ? 12 : $date->month - 1;
$prev_year = $date->month == 1 ? $date->year - 1 : $date->year;
while ($o = db_fetch_object($node_query)) {
list($year, $month, $day) = explode(' ', format_date($o->created, 'custom', 'Y n j'));
$with_posts['years'][$year] = array_key_exists($year, $with_posts['years']) ? $with_posts['years'][$year] + 1 : 1;
if ($date->year && $year == $date->year) {
$with_posts['months'][$month] = array_key_exists($month, $with_posts['months']) ? $with_posts['months'][$month] + 1 : 1;
if ($date->month && $month == $date->month) {
$with_posts['days'][$day] = array_key_exists($day, $with_posts['days']) ? $with_posts['days'][$day] + 1 : 1;
}
}
if ($year == $next_year && $month == $next_month) {
if (isset($with_posts['next_month_days'][$day])) {
$with_posts['next_month_days'][$day]++;
}
else {
$with_posts['next_month_days'][$day] = 1;
}
}
if ($year == $prev_year && $month == $prev_month) {
if (isset($with_posts['prev_month_days'][$day])) {
$with_posts['prev_month_days'][$day]++;
}
else {
$with_posts['prev_month_days'][$day] = 1;
}
}
}
return $with_posts;
}
function _archive_types_sql_string($type) {
$final_types = '';
if (_archive_validate_type($type) && $type != 'all') {
$final_types = $type;
}
else {
$types = variable_get('archive_type_filters', array());
if (!array_key_exists('0', $types)) {
foreach ($types as $key => $value) {
if (!$value) {
unset($types[$key]);
}
}
$final_types = join(array_keys($types), '", "');
}
}
if (strlen($final_types) > 0) {
$final_types = 'AND n.type IN ("' . $final_types . '") ';
}
return $final_types;
}
function theme_archive_block_calendar($timestamp) {
$the_date = explode(' ', format_date($timestamp, 'custom', 'F Y n t'));
$title = $the_date[0] . ' ' . $the_date[1];
$year = $the_date[1];
$month = $the_date[2];
$num_days = (int) $the_date[3];
$prev_month = $month == 1 ? 12 : $month - 1;
$prev_year = $month == 1 ? $year - 1 : $year;
$num_days_prev = cal_days_in_month(CAL_GREGORIAN, $month - 1, $year);
$next_month = $month == 12 ? 1 : $month + 1;
$next_year = $month == 12 ? $year + 1 : $year;
$date = _archive_date('all', $year, $month);
$month_title = '';
if ($date->months[$month]) {
$month_title = l($title, _archive_url('all', $year, $month), array(
'title' => format_plural($date->months[format_date($timestamp, 'custom', 'n')], '1 post', '@count posts'),
));
}
else {
$month_title = $title;
}
$first_day_of_week = variable_get('date_first_day', 0);
$week = array(
t('Sun'),
t('Mon'),
t('Tue'),
t('Wed'),
t('Thu'),
t('Fri'),
t('Sat'),
);
$day_headers = array();
for ($i = $first_day_of_week; $i < $first_day_of_week + 7; $i++) {
$day_headers[] = $week[$i % 7];
}
list($start_year, $start_month) = explode(' ', format_date($timestamp, 'custom', 'Y m'));
$start = gmmktime(0, 0, 0, (int) $start_month, 1, (int) $start_year);
$weekday = gmdate('w', $start) - $first_day_of_week;
$days_row = array();
for ($i = 1 - $weekday; $i <= ceil(($weekday + $num_days) / 7) * 7; $i++) {
if ($i > 0) {
if (array_key_exists($i, $date->days)) {
$days_row[] = l($i, _archive_url('all', $year, $month, $i), array(
'title' => format_plural($date->days[$i], '1 post', '@count posts'),
));
}
else {
if ($i <= $num_days) {
$days_row[] = $i;
}
else {
$curr_cal_date = $i - $num_days;
if (isset($date->next_month_days[$curr_cal_date])) {
$data = l($curr_cal_date, _archive_url('all', $next_year, $next_month, $curr_cal_date), array(
'title' => format_plural($date->next_month_days[$curr_cal_date], '1 post', '@count posts'),
));
}
else {
$data = $curr_cal_date;
}
$days_row[] = array(
'data' => $data,
'class' => 'out-of-month',
);
}
}
if (($i + $weekday) % 7 == 0) {
$rows[] = $days_row;
$days_row = array();
}
}
else {
$curr_cal_date = $num_days_prev + $i;
if (isset($date->prev_month_days[$curr_cal_date])) {
$data = l($curr_cal_date, _archive_url('all', $prev_year, $prev_month, $curr_cal_date), array(
'title' => format_plural($date->prev_month_days[$curr_cal_date], '1 post', '@count posts'),
));
}
else {
$data = $curr_cal_date;
}
$days_row[] = array(
'data' => $data,
'class' => 'out-of-month',
);
}
}
return theme('table', $day_headers, $rows, array(), $month_title);
}
function archive_block($op = 'list', $delta = 0, $edit = array()) {
if ($op == 'list') {
$blocks = array(
array(
'info' => t('Archive calendar'),
),
array(
'info' => t('Archive months'),
),
);
return $blocks;
}
else {
if ($op == 'view') {
switch ($delta) {
case 0:
drupal_add_css(drupal_get_path('module', 'archive') . '/archive.css');
$block = array(
'subject' => t('Archives'),
'content' => theme('archive_block_calendar', time()),
);
break;
case 1:
$block = array(
'subject' => t('Archives'),
'content' => theme('archive_month_list', archive_month_list()),
);
break;
}
return $block;
}
else {
if ($op == 'configure') {
if ($delta == 1) {
$form['archive_block_months'] = array(
'#type' => 'select',
'#title' => t('Maximum number of months to display'),
'#default_value' => variable_get('archive_block_months', 6),
'#options' => array(
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
),
);
return $form;
}
}
else {
if ($op == 'save') {
if ($delta == 1) {
variable_set('archive_block_months', $edit['archive_block_months']);
}
}
}
}
}
}
function archive_month_list() {
$node_query = db_query(db_rewrite_sql('SELECT n.created FROM {node} n WHERE n.status = 1 AND DATE(FROM_UNIXTIME(n.created)) BETWEEN DATE_SUB(CURDATE(), INTERVAL 6 MONTH) AND CURDATE() ORDER BY n.created DESC'));
$months = array();
$total_months = 0;
$max_months = variable_get('archive_block_months', 6);
while ($node = db_fetch_object($node_query)) {
list($month_name, $year, $month) = explode(' ', format_date($node->created, 'custom', 'F Y n'));
if (isset($months[$year][$month])) {
$months[$year][$month]['count']++;
}
else {
if ($total_months++ < $max_months) {
$months[$year][$month] = array(
'count' => 1,
'month_name' => $month_name,
);
}
}
}
return $months;
}
function theme_archive_month_list($list_items) {
krsort($list_items);
foreach ($list_items as $year => $v) {
krsort($list_items[$year]);
}
$links = array();
foreach ($list_items as $year => $months) {
foreach ($months as $month => $data) {
$links[] = l(t($data['month_name'] . ' ' . $year), 'archive/all/' . $year . '/' . $month, array(
'title' => format_plural($data['count'], '1 post', '@count posts'),
));
}
}
if (count($links) == variable_get('archive_block_months', 6)) {
$links[] = '<div class="more-link">' . l(t('all'), 'archive', array(
'title' => t('Browse all of the archives'),
)) . '</div>';
}
return theme('item_list', $links);
}