带有时间戳列表的事件列表,以 PHP 形式以表格显示按小时分组。
在重构时,我正在寻找 PHP 中时间表(日历)的优化算法。
我有一个事件列表,其中包含时间戳列表。这必须以表格方式呈现。当前的代码可以工作,但是a)有一些怪癖并且b)非常不灵活。我正在寻求重构这篇文章并寻找优化方法的输入。
示例,请注意带有小时数的表格标题。该小时内的时间被分组在该列中。一小时内有两个时间戳的一个事件可以被忽略(根据技术文档,理论上可能只会发生)
该表是用 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(删除了不必要的数据)如下所示:
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"
}
}
}
While refactoring, I am looking for an optimised algorithm for a timetable (calendar) in PHP.
I have a list of events which have a list of timestamps. This must be presented in a tabular way. The current code works, but has a) quite some quircks and is b) very inflexible. I am looking to refactor this piece and looking for input on optimised ways.
Example here, notice the header of the table bearing the hours. And the times within that hour being grouped in that column. One event, having two timestamps in one hour can be ignored (may only happen in theory, as per the technical docs)
The table is built with Drupals theme_table(), which I can build up from any array, bearing arrays for each row. the Drupal part, however, is of little interest here :)
Current code (snippets):
<?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');
}
So, the pattern is: grab (and order) the list of events. Loop over that, for each event, loop over the timestamps and create an array with the key being the hour of the timestamp (group by hours).
Are there better patterns? Is there a more generic way to achieve this? Any keywords that I can search for (I have no idea how such a pattern would be called)?
example dataset
The $nodes (unnessecary data removed) look like this:
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"
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我对Drupal一点也不熟悉,所以我将根据我自己的方法对您的请求提出建议,重构一列中电影标题列表的显示,以及适当时间列中的开始时间。
您从包含电影标题和开始时间戳的一系列电影(或“电影”)开始。我假设您可以在某个地方检索或创建列标题的小时数组。
下面的示例忽略了您正在处理一个对象,或者该对象包含数组,只是为了展示一种替代模式方法。此模式不是您似乎正在执行的所有格式化和排序,而是迭代每部电影并使用第二个 foreach 迭代小时列,并测试电影时间是否与小时时间匹配。
我已跳过设置表格,当然,您可以将我的 html 实体替换为您喜欢设置表格的方式。
我认为这是一个可行的模式,它似乎简化了原始模式的逻辑,并且保持了灵活性。希望我没有误解并遗漏了你问题的关键部分。
I'm not familiar with Drupal at all, so I'm going to make a suggestion based on my own approach to your request to refactor the display of a list of movie titles in one column, and the start time in the appropriate time column.
You are starting with an array of movies (or 'films') containing movie titles and start timestamps. I assume somewhere you can retrieve or create an array of hours for the column title.
The example below ignores that you are dealing with an object, or that the object contains arrays, only to exhibit an alternate pattern approach. Rather than all the formatting and sorting you appear to be doing, this pattern iterates over each movie and uses a second foreach to iterate over the hour columns, and tests if the movie time matches the hour time.
I've skipped setting up the table, and of course, you could replace my html entities with however you prefer to set up the table.
I think this is a viable pattern that seems to simplify the logic of your original pattern, and remains flexible. Hopefully I haven't misunderstood and omitted a critical part of your problem.
您是否尝试过“日历”模块。日历模块可用于将事件列为日历。它具有视图、分类和 cck 支持。定制也非常容易。
我建议在考虑我们的脚本之前先找出贡献的模块。只有当没有贡献的模块满足我们的要求时,我们才能考虑我们的脚本。
Have you tried "Calendar" module. The Calendar module can be used to list the events as calendar. It is having views, taxonomy and cck support. The customization is also very easy.
I am suggesting to find out contributed modules before thinking about our script. We can think about our script only if there is no contributed modules which satisfies our requirements.