事件列表,带有时间戳列表,在PHP中以表格形式按小时分组。 [英] List of events with a list of timestamps, grouped by hour in a tabular display, in PHP.

查看:82
本文介绍了事件列表,带有时间戳列表,在PHP中以表格形式按小时分组。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

While refactoring, I am looking for an optimised algorithm for a timetable (calendar) in PHP.

我有一个事件列表,其中包含一个时间戳列表。这必须以表格形式呈现。当前代码有效,但是具有a)相当多的速成,并且b)非常僵化。我正在寻求重构这一部分,并寻求优化方法的投入。

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)

该表是使用Drupals构建的 theme_table(),我可以从任何数组构建,并为每个行承载数组。然而,Drupal部分对此并不感兴趣:)

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 :)

当前代码(摘要):

<?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)?

示例数据集
$ nodes(删除了不必要的数据)如下:

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"
    }
  }
}


推荐答案

我完全不熟悉Drupal,因此我将根据我自己的方法提出一个建议,以您的要求重构列表的显示电影标题放在一栏中,开始时间在相应的时间栏中。

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.

下面的示例忽略了您正在处理的对象,或者对象包含数组, 仅显示替代模式方法。此模式不是遍历所有格式化和排序操作,而是遍历每部电影,并使用第二个foreach遍历小时列,并测试电影时间是否与小时时间匹配。

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.

<?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实体替换为您更喜欢设置表格。

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.

这篇关于事件列表,带有时间戳列表,在PHP中以表格形式按小时分组。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆