带有时间戳列表的事件列表,以表格形式显示的小时分组,以PHP表示。

时间:2010-10-08 07:46:13

标签: php datetime drupal calendar

在重构时,我正在寻找PHP中时间表(日历)的优化算法。

我有一个包含时间戳列表的事件列表。这必须以表格方式呈现。目前的代码有效,但有一些相当的怪癖,是b)非常不灵活。我希望重构这篇文章并寻找有关优化方法的输入。

Example here,注意带有小时数的表格标题。并且该小时内的时间被分组在该列中。一个事件,在一小时内有两个时间戳可以忽略(可能只在理论上发生,根据技术文档)

该表是使用Drupals theme_table()构建的,我可以从任何数组构建,为每个提供数组。然而,Drupal部分在这里没什么兴趣:)

当前代码(摘要):

<?php
//inside function that builds the content for the page linked to above:
$this_morning = _playdates_get_start_of_day_with($timestamp);
$this_night = _playdates_get_end_of_day_with($timestamp);
$nodes = _playdates_load_all_in_range($types, $this_morning, $this_night);
usort($nodes, '_playdates_cmp_titles');
//we now have a list of "nodes", being the events listed in the first column, which have
//  a list of playdates, the timestamps. $node->nid is a unique id for each event.  
foreach ($nodes as $node) {
  $times = $dates = array();
  if (is_array($node->starts_at)) {
    foreach ($node->starts_at as $starts_at) {
      $date = getdate($starts_at);
      $dates[$starts_at] = $date;
      if (!isset($active) && ($timestamp <= ($date[0] + $timezone))) {
        $active = _playdates_get_idx_hour($date);
      }
    }
    $times = _playdates_group_by_hour($dates);
    foreach ($times as $key => $value) {
      $header_times[$key] = $key;
    }
    $header = array_merge($header, $header_times);
    $entries[$node->nid] = $node;
    $entries[$node->nid]->times = $times;
  }
}

function _playdates_group_by_hour($timestamps, $playdate = NULL) {
  $indexes = array();
  foreach ($timestamps as $key => $value) {
    $indexes[_playdates_get_idx_hour($value)] = theme('playdates_format_time', $value, $playdate);
  }
  ksort($indexes);
  return $indexes;
}   

function _playdates_get_idx_hour($date) {
  return playdates_format_date($date[0], 'custom', 'H:00');
}

因此,模式是:抓取(并订购)事件列表。循环遍历,为每个事件循环遍历时间戳并创建一个数组,其中键是时间戳的小时(按小时分组)。

有更好的模式吗?有没有更通用的方法来实现这一目标?我可以搜索的任何关键字(我不知道如何调用这样的模式)?

示例数据集 $ nodes(删除的unnessecary数据)如下所示:

array(15) {
  [1]=>
  object(stdClass)#48 (6) {
    ["title"]=> 
    string(19) "Cosa voglio di più"
    ["type"]=>
    string(4) "film"
    ["nid"]=>
    string(4) "2823"
    ["premiere"]=>
    object(stdClass)#49 (1) {
      ["starts_at"]=>
      string(10) "1286550000"
    }
    ["starts_at"]=>
    array(2) {
      [0]=>
      string(10) "1286550000"
      [1]=>
      string(10) "1286559000"
    }
    ["ends_at"]=>
    array(2) {
      [0]=>
      string(1) "0"
      [1]=>
      string(1) "0"
    }
  }
  [12]=>
  object(stdClass)#46 (6) {
    ["title"]=>
    string(5) "Tirza"
    ["type"]=>
    string(4) "film"
    ["nid"]=>
    string(4) "2813"
    ["premiere"]=>
    object(stdClass)#47 (1) {
      ["starts_at"]=>
      string(10) "1286550000"
    }
    ["starts_at"]=>
    array(3) {
      [0]=>
      string(10) "1286550000"
      [1]=>
      string(10) "1286558100"
      [2]=>
      string(10) "1286566200"
    }
    ["ends_at"]=>
    array(3) {
      [0]=>
      string(1) "0"
      [1]=>
      string(1) "0"
      [2]=>
      string(1) "0"
    }
  }
  [14]=>
  object(stdClass)#36 (6) {
    ["title"]=>
    string(47) "Vision - aus dem Leben der Hildegard von Bingen"
    ["type"]=>
    string(4) "film"
    ["nid"]=>
    string(4) "2783"
    ["premiere"]=>
    object(stdClass)#39 (1) {
      ["starts_at"]=>
      string(10) "1286541900"
    }
    ["starts_at"]=>
    array(1) {
      [0]=>
      string(10) "1286541900"
    }
    ["ends_at"]=>
    array(1) {
      [0]=>
      string(1) "0"
    }
  }
}

2 个答案:

答案 0 :(得分:0)

我根本不熟悉Drupal,所以我将基于我自己的方法提出建议,以重构一列中的电影标题列表的显示,以及开始时间。适当的时间栏。

您将从一系列包含电影标题和开始时间戳的电影(或“电影”)开始。我假设您可以在某处检索或创建列标题的小时数组。

下面的示例忽略您正在处理一个对象,或者该对象包含数组, 仅显示替代模式方法。这个模式不是你看起来正在进行的所有格式化和排序,而是迭代每部电影,并使用第二个foreach迭代小时列,并测试电影时间是否与小时时间匹配。

<?php foreach($movie_array as $movie){
    echo '<td>'.$movie['title'].'</td>';
    foreach($hours as $hour){
        if(date('H',$movie['starts_at']) == date('H',$hour)){
            echo '<td>'.date('H:i',$movie['starts_at']).'</td>';
        }//endif
        else{
            echo '<td></td>';
        }//endelse
    }//endforeach
 }//endforeach
?>

我已经跳过设置表格,当然,您可以替换我的html实体,但是您希望设置表格。

我认为这是一种可行的模式,似乎可以简化原始模式的逻辑,并保持灵活性。希望我没有误解并省略了问题的关键部分。

答案 1 :(得分:0)

您是否尝试过“Calendar”模块。 Calendar模块可用于将事件列为日历。它有视图,分类和cck支持。定制也很容易。

我建议在考虑我们的脚本之前找出贡献的模块。只有在没有满足我们要求的贡献模块时,我们才能考虑我们的脚本。