Как рефакторинг этого условного, чтобы избежать повторения? - PullRequest
0 голосов
/ 10 июня 2009

Это часть страницы событий, которую можно отфильтровать по дате (с использованием предварительно определенных диапазонов дат или средства выбора даты).

Я хочу избежать повторения всего цикла foreach ($days as $day_number)... и т. Д. Для каждого условия.

Я полагаю, что весь цикл можно переместить в функцию, но я не уверен, как это реализовать.

<?php

// open the db connection
$db = new wpdb('user', 'pass', 'db', 'server');


// $today = date('Y-m-d');
$today = '2009-06-21';
$tomorrow  = date( 'Y-m-d', mktime(0, 0, 0, date('m'), date('d')+1, date('Y')) );
$seven_days_ahead = date( 'Y-m-d', mktime(0, 0, 0, date('m'), date('d')+6, date('Y')) );
$thirty_days_ahead = date( 'Y-m-d', mktime(0, 0, 0, date('m'), date('d')+29, date('Y')) );


echo '<div class="column first">';


if ( ! empty($_REQUEST['date_range']) )    
{
    // user has chosen a date/range, show matching events 


    $date_range = mysql_real_escape_string($_REQUEST['date_range']);


    switch( $date_range )
    {
        case 'all':

            // code here

            break;

        case 'next_7_days':

            // code here

            break;

        case 'next_30_days':

            // code here

            break;

        default:

            // code here

    }


}
else
{
    // no date selected, show todays events

    $days = convert_date_to_day_number( $today );

    foreach ( $days as $day_number )
    {
        $where = sprintf( 'WHERE e.day_id = %s', $day_number );

        $events = get_events( $where );

        if ($events)
        {
            echo '<table class="results">';

            render_day( $day_number );

            foreach ($events as $event)
            {
                render_event($event);
            }  

            echo '</table>';
        }
        else
        {
            echo 'No events';                            
        }
    }

}

echo '</div> <!--/column-->';





function convert_date_to_day_number($date)
{
    global $db;

    $sql = "SELECT day_number FROM days WHERE day_date = '$date'";

    $day_numbers = $db->get_results($sql);

    foreach ($day_numbers as $key => $value)
    {
        $day_number[] = $value->day_number;
    }

    return $day_number;
}


function get_events($where)
{
    global $db;

    $sql = "SELECT
                 e.id,
                 TIME_FORMAT(e.start_time, '%H:%i' ) AS start_time,
                 e.x_prod_desc AS title,
                 -- e.title_en AS title,
                 p.name_en AS place,
                 et.name_en AS type,
                 w.week_number,
                 d.day_date AS start_date
             FROM event AS e
             LEFT JOIN place AS p ON p.id = e.place_id
             LEFT JOIN event_type AS et ON et.id = e.event_type_id
             LEFT JOIN days AS d ON d.id = e.day_id
             LEFT JOIN week AS w ON w.id = d.week_id ";   

    $sql .= $where;

    $events = $db->get_results($sql);

    return $events;          
}

function render_event($event)
{
    $request_uri = $_SERVER['REQUEST_URI'];

    $output = <<<EOD

    <tr class="week-$event->week_number">
        <td class="topic"></td>
        <td class="time">$event->start_time</td>
        <td class="summary">
         <a href="$request_uri&amp;event_id=$event->id">$event->title</a>   
        </td>
        <td class="type">$event->type</td>
        <td class="location">
           <span class="addr">$event->place</span>
        </td>
    </tr>

EOD;

    echo $output;
}


function render_day( $day_number )
{
    global $db;

    $sql = "SELECT
                d.day_number,
                DATE_FORMAT( d.day_date, '%W %e %M %Y' ) AS date,
                DATE_FORMAT( d.day_date, '%b' ) AS month,
                DATE_FORMAT( d.day_date, '%e' ) AS day
            FROM days AS d
            WHERE day_number = " . $day_number;

    $day = $db->get_results($sql);

    $day = $day[0];

    $output = <<<EOD

    <tr class="day">
        <th colspan="5">
            <em class="date">
                <abbr class="dtstart" title="20090605T1806Z">
                    <span title="$day->date">
                        <span class="month">$day->month</span>
                        <span class="day">$day->day</span>
                </span>
                </abbr>
            </em>
            $day->date
            <span class="event-day">Day $day->day_number</span>
        </th>
    </tr>

EOD;

    echo $output;
}
?>

Ответы [ 4 ]

3 голосов
/ 10 июня 2009

Во-первых, вы можете использовать strtotime для относительных дат:

$today = '2009-06-21';
$tomorrow  = date( 'Y-m-d', strtotime('+1 day') );
$seven_days_ahead = date( 'Y-m-d', strtotime('+7 days') );
$thirty_days_ahead = date( 'Y-m-d', strtotime('+30 day') );
    // or +1 month (=> calendar month)

Во-вторых, вы можете установить две переменные с датами начала и окончания, затем:

$date = $start_date; // 'Y-m-d' format
while( $date <= $end_date ) {
    //code here or fill up a table with your days
    // using $date
    $date = date( 'Y-m-d', strtotime( '+1day', strtotime($date) ) );
}

Всякий раз, когда вы работаете с датами в PHP, вы должны проверить strtotime.

2 голосов
/ 10 июня 2009

Вместо того, чтобы запрашивать базу данных по одному разу на каждый день, я бы сделал оператор WHERE, который извлек все события для желаемого диапазона дат, а затем отправил бы это в функцию рендеринга, которая просматривает каждую строку в наборе результатов, и если день отличается от предыдущего, звонит render_day() до звонка render_event().

switch (/* input from user */) {
    // Build a date range here.
    // Resulting statement would be something like:
    // WHERE event_date >= '2009-06-10' AND event_date < '2009-06-17'
}

$events = get_events($filter);
$prev_date = null;
foreach ($events as $event) {
    if ($event->date != $prev_date) render_day($event->date);
    render_event($event);
    $prev_date = $event->date;
}
0 голосов
/ 10 июня 2009
function generateEventsTable($dateStr)
{
    $days = convert_date_to_day_number( $today );
    foreach ( $days as $day_number )
    {
        $where = sprintf( 'WHERE e.day_id = %s', $day_number );
        $events = get_events( $where );
        if ($events)
        {
            echo '<table class="results">';
            render_day( $day_number );
            foreach ($events as $event)
            {
                render_event($event);
            }  
            echo '</table>';
        }
        else
        {
            echo 'No events';                            
        }
    }
}

Назовите это так:

generateEventsTable($today);
0 голосов
/ 10 июня 2009

Вау! Я прочитал это!

Прежде всего используйте шаблонизатор (например, smarty ) или любой другой способ разделения вашего кода и HTML. Это плохая идея выводить HTML изнутри функций.

Я не уверен, но думаю, что использование меток времени unix в БД может упростить вашу структуру данных. То же самое касается php-кода. Внимательно прочитайте о функциях даты / времени в руководстве по php, я думаю, вы найдете много интересного ...

На самом деле, как я вижу из вашего кода, использование временных меток и шаблонов сократит ваш код до некоторой строки для извлечения данных и назначения их для механизма шаблонов. Функция PHP "date ()" уже имеет возможность возвращать номер недели, номер дня через неделю или год и т. Д. *

Это фиктивный пример того, как может выглядеть ваш код:

$begin = mktime(...);
$end = mktime(...);
$query = "
    SELECT a,b,c 
    FROM events 
    WHERE ctime >= $begin AND ctime <= $end AND ...
";
$events = array();
while ($fetch = fetch_here(...))
{
    $event = new MyEvent();
    $event->loadDBFetch($fetch);
    array_push($events, $event);
}
$tplEngine->assign('events', $events);

Конечно, это не готовое решение, но мне кажется, что ваш код может быть похож на это.

...