在重构时,我正在寻找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"
}
}
}
答案 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支持。定制也很容易。
我建议在考虑我们的脚本之前找出贡献的模块。只有在没有满足我们要求的贡献模块时,我们才能考虑我们的脚本。