author = $author; $comment->email = $email; $comment->text = $text; $comment->datetime = $datetime; $comment->item_id = $item_id; return $comment->save(); } static function get_add_form($item_id) { $form = new Forge(url::site("comments"), "", "post"); $group = $form->group(_("Add Comment")); $group->input("author") ->label(_("Author")) ->id("gAuthor"); $group->input("email") ->label(_("Email")) ->id("gEmail"); $group->textarea("text")->label(_("Text")) ->id("gText"); $group->hidden("item_id")->value($item_id); $group->submit(_("Add")); $form->add_rules_from(ORM::factory("comment")); return $form; } static function get_edit_form($comment) { $form = new Forge( url::site("comments/{$comment->id}?_method=put"), "", "post"); $group = $form->group(_("Edit Comment")); $group->input("author") ->label(_("Author")) ->id("gAuthor") ->value($comment->author); $group->input("email") ->label(_("Email")) ->id("gEmail") ->value($comment->email); $group->textarea("text")->label(_("Text")) ->id("gText") ->value($comment->text); $group->submit(_("Edit")); $form->add_rules_from($comment); return $form; } /** * @todo Refactor this into a more generic location */ private static function _add_validation_rules($model_name, $form) { $rules = ORM::factory($model_name)->validation_rules; foreach ($form->inputs as $name => $input) { if (isset($input->inputs)) { comment::_add_validation_rules($model_name, $input); } if (isset($rules[$name])) { $input->rules($rules[$name]); } } } static function block($theme, $show_add_form=true) { $block = new Block; $block->id = "gComments"; $block->title = _("Comments"); $block->content = comment::get_comments($theme->item(), "html"); if ($show_add_form) { $block->content .= comment::get_add_form($theme->item())->render("form.html"); } return $block; } // @todo Set proper Content-Type in a central place (REST_Controller::dispatch?). static function get_comments($item_id) { $comments = ORM::factory('comment')->where('item_id', $item_id) ->orderby('datetime', 'asc') ->find_all(); if (!$comments->count()) { rest::http_status(rest::BAD_REQUEST); return; } switch (rest::output_format()) { case "xml": rest::http_content_type(rest::XML); return xml::to_xml($comments, array("comments", "comment")); break; case "json": rest::http_content_type(rest::JSON); foreach ($comments as $comment) { $data[] = $comment->as_array(); } return json_encode($data); default: foreach ($comments as $comment) { $v = new View("comment.html"); $v->comment = $comment; $html[] = $v; } if (!empty($html)) { return "\n"; } } } /** * Format a human-friendly message showing the amount of time elapsed since the specified * timestamp (e.g. 'said today', 'said yesterday', 'said 13 days ago', 'said 5 months ago'). * * @todo Take into account the viewer's time zone. * @todo Properly pluralize strings. * * @param integer $timestamp Unix format timestamp to compare with * @return string user-friendly string containing the amount of time passed */ static function format_elapsed_time($timestamp) { $now = time(); $time_difference = $now - $timestamp; $date_info_now = getdate($now); /* Calculate the number of days, months and years elapsed since the specified timestamp. */ $elapsed_days = round($time_difference / comment::SECONDS_IN_A_DAY); $elapsed_months = round($time_difference / comment::SECONDS_IN_A_MONTH); $elapsed_years = round($time_difference / comment::SECONDS_IN_A_YEAR); $seconds_since_midnight = $date_info_now['hours'] * comment::SECONDS_IN_AN_HOUR + $date_info_now['minutes'] * comment::SECONDS_IN_A_MINUTE + $date_info_now['seconds']; /* Construct message depending on how much time passed. */ if ($elapsed_years > 0) { $message = sprintf(_('said %d years ago'), $elapsed_years); } else if ($elapsed_months > 0) { $message = sprintf(_('said %d months ago'), $elapsed_months); } else { if ($time_difference < $seconds_since_midnight) { $message = _('said today'); } else if ($time_difference < $seconds_since_midnight + comment::SECONDS_IN_A_DAY) { $message = _('said yesterday'); } else { $message = sprintf(_('said %d days ago'), $elapsed_days); } } return $message; } }