public function test_relativeTime() { $this->assertEquals("4 seconds ago", ContentUtility::relativeTime(new DateTime("4 seconds ago"), new DateTime())); $this->assertEquals("one minute ago", ContentUtility::relativeTime(strtotime("1 minutes ago"))); $this->assertEquals("4 minutes ago", ContentUtility::relativeTime(strtotime("4 minutes ago"))); $this->assertEquals("4 hours ago", ContentUtility::relativeTime(strtotime("4 hours ago"))); $this->assertEquals("yesterday", ContentUtility::relativeTime(strtotime("24 hours ago"))); $this->assertEquals("2 days ago", ContentUtility::relativeTime(strtotime("2 days ago"))); $this->assertEquals("one week ago", ContentUtility::relativeTime(strtotime("7 days ago"))); $this->assertEquals("2 weeks ago", ContentUtility::relativeTime(strtotime("14 days ago"))); $this->assertEquals("4 weeks ago", ContentUtility::relativeTime(strtotime("1 month ago"))); $this->assertEquals("2 months ago", ContentUtility::relativeTime(strtotime("2 months ago"))); $this->assertEquals("last year", ContentUtility::relativeTime(strtotime("12 months ago"))); $this->assertEquals("10 years ago", ContentUtility::relativeTime(strtotime("10 years ago"))); $this->assertEquals("3 years ago", ContentUtility::relativeTime(strtotime("5 years ago"), new DateTime("2 years ago"))); }
/** * Get this sighting as an associative array * @since Version 3.10.0 * @return array */ public function getArray() { $array = array("id" => $this->id, "lat" => $this->lat, "lon" => $this->lon, "text" => $this->text, "author" => array("id" => $this->user_id, "username" => $this->username), "timezone" => $this->timezone, "date" => array("added" => array("absolute" => $this->date_added->format("Y-m-d H:i:s"), "relative" => ContentUtility::relativeTime($this->date_added)), "seen" => array("absolute" => $this->date->format("Y-m-d H:i:s"), "relative" => ContentUtility::relativeTime($this->date))), "loco_ids" => $this->loco_ids, "meta" => $this->meta, "url" => $this->url->getURLs(), "place" => $this->Place->getArray()); return $array; }
/** * Fetch stories from Sphinx * @since Version 3.9.1 * @return array * @param int $page * @param int $limit * @param boolean $total */ private function fetchStoriesFromSphinx($page = 0, $limit = 25, $total = true) { $Sphinx = $this->getSphinx(); $query = $Sphinx->select("*")->from("idx_news_article")->orderBy("story_time_unix", "DESC")->limit($page * $limit, $limit)->where("topic_id", "=", $this->id)->where("story_active", "=", 1)->option("max_matches", 10000); $matches = $query->execute(); $meta = $Sphinx->query("SHOW META"); $meta = $meta->execute(); if (is_array($matches) && count($matches)) { $return = array("total" => $meta[1]['Value'], "children" => array(), "page" => $page, "perpage" => $limit, "topic_id" => $this->id); foreach ($matches as $id => $row) { $row['time_relative'] = ContentUtility::relativeTime($row['story_time_unix']); $row['time'] = $row['story_time']; $row['title'] = ContentUtility::FormatTitle($row['story_title']); // Match the first sentence $line = explode("\n", !empty($row['story_lead']) ? $row['story_lead'] : $row['story_blurb']); $row['firstline'] = preg_replace('/([^?!.]*.).*/', '\\1', strip_tags($line[0])); if (empty($row['story_slug'])) { $row['slug'] = $this->createSlug($row['story_id']); } $row['url'] = $this->makePermaLink($row['story_slug']); $row['hometext'] = $row['story_blurb']; $row['bodytext'] = $row['story_body']; $row['featured_image'] = $row['story_image']; $row['informant'] = $row['username']; $return['children'][$id] = $row; } return $return; } return false; }
/** * Render the page * @since Version 3.10.0 * @return string */ public function render() { if (!$this->userObject instanceof User) { throw new InvalidArgumentException("No valid user object has been provided"); } #$this->smarty->clearCache($this->template, $this->unique); if ($this->smarty->isCached($this->template, $this->unique)) { Debug::LogCLI("!! Template file " . $this->template . " is already cached for unique ID " . $this->unique); return $this->smarty->fetch($this->template, $this->unique); } Debug::LogCLI("Template file " . $this->template . " is NOT cached for unique ID \"" . $this->unique . "\""); /** * Get user alerts */ if (!$this->userObject->guest) { global $acl; $alerts = $this->userObject->getAlerts($acl); $this->smarty->Assign("alerts", $alerts, true); } /** * Get the latest jobs */ $newjobs = array(); foreach ((new Jobs())->yieldNewJobs(5) as $Job) { $newjobs[] = $Job->getArray(); } $this->smarty->Assign("jobs", $newjobs, true); /** * Upcoming events */ $Memcached = AppCore::GetMemcached(); $cachekey = "railpage.home.upcomingevents"; $upcoming = []; if (!($upcoming = $Memcached->fetch($cachekey))) { $Events = new Events(); $upcoming = []; foreach ($Events->getUpcomingEvents(5) as $row) { //$Event = EventsFactory::CreateEvent($row['event_id']); $EventDate = new EventDate($row['id']); $data = $EventDate->getArray(); $upcoming[] = $data; } $Memcached->save("railpage.home.upcomingevents", $upcoming, strtotime("+5 minutes")); } $this->smarty->Assign("upcomingevents", $upcoming); /** * New photos */ $this->smarty->Assign("newphotos", RecentImages::getNewest(5)); /** * Chronicle */ $Chronicle = new Chronicle(); $this->smarty->Assign("chronicle", $Chronicle->getEntriesForToday(10)); /** * Get the latest railcam photo */ $Camera = new Camera(1); $Photo = $Camera->getLatest(false); $railcam = $Photo->getArray(); $railcam['sizes']['small']['source'] = ImageCache::cache($railcam['sizes']['small']['source']); $this->smarty->Assign("railcam", $railcam); $this->smarty->Assign("railcam_updated", ContentUtility::relativeTime($railcam['dates']['taken'])); /** * First check if this user has a personalised news feed */ if (filter_var($this->userObject->id, FILTER_VALIDATE_INT) && $this->userObject->id > 0) { $Feed = new Feed(); $Feed->setUser($this->userObject)->getFilters(); if (count($Feed->filter_words) || count($Feed->filter_topics)) { $latest = $Feed->findArticles(0, 20); foreach ($latest as $id => $article) { $article['sid'] = $article['story_id']; $article['catid'] = $article['topic_id']; $article['hometext'] = preg_replace("@(\\[b\\]|\\[\\/b\\])@", "", $article['story_blurb']); $article['informant'] = $article['username']; $article['informant_id'] = $article['user_id']; $article['ForumThreadId'] = $article['forum_topic_id']; $article['topictext'] = $article['topic_title']; $article['topic'] = $article['topic_id']; $article['featured_image'] = $article['story_image']; $article['title'] = $article['story_title']; $article['time_relative'] = time2str($article['story_time_unix']); $latest[$id] = $article; } } } $this->smarty->Assign("personalfeed", isset($latest)); /** * No personal news feed - go ahead as normal */ if (!isset($latest)) { /** * Instantiate the base News module */ $News = new Base(); /** * Get the latest 15 news articles */ $latest = $News->latest(20); } /** * Format titles and tags for the latest news articles */ foreach ($latest as $id => $data) { /** * Load the JSON for this article */ if (!isset($data['sid'])) { $data['sid'] = $data['story_id']; } $json = json_decode(News::getArticleJSON($data['sid']), true); $latest[$id]['hometext'] = isset($json['article']['blub']) ? wpautop(process_bbcode($json['article']['blub'])) : wpautop(process_bbcode($json['article']['blurb'])); $latest[$id]['hometext'] = strip_tags($latest[$id]['hometext'], "<a><p><img><br><br /><strong><em>"); $latest[$id]['title'] = format_topictitle($data['title']); $latest[$id]['topic'] = $json['article']['topic']; $latest[$id]['topic_highlight'] = ColourUtility::String2Hex($latest[$id]['topic_title']); $latest[$id]['url'] = $json['article']['url']; $latest[$id]['author'] = $json['article']['author']; $latest[$id]['staff'] = $json['article']['staff']; if (!empty($latest[$id]['featured_image'])) { $latest[$id]['featured_image'] = ImageCache::cache($latest[$id]['featured_image']); } // Get the first paragraph from the home text preg_match("/<p>(.*)<\\/p>/", $latest[$id]['hometext'], $matches); $latest[$id]['hometext'] = strip_tags($matches[1]); if (empty($json['article']['body']) && !empty($json['article']['source'])) { $latest[$id]['url'] = $json['article']['source']; } /** * Pre-rendering */ $this->smarty->addHeadTag(sprintf("<link rel='prerender' href='%s'>", $json['article']['url']['url'])); } /** * Slice the first news article off */ $newsLatest = array_shift($latest); /** * Send them to Smarty */ $this->smarty->assign("newsLatest", $newsLatest); $this->smarty->assign("news", $latest); $this->smarty->assign("pagecontrols", '<p style="background: #333; background: rgba(0, 0, 0, 0.6);margin: -20px;padding: 10px;margin-top: 20px; text-align: center;">Wasting time and bandwidth since 1992</p>'); if ($this->params['handheld']) { $this->smarty->assign("pagecontrols", '<p style="background: #333; background: rgba(0, 0, 0, 0.6);margin: 0px -20px;padding: 0px;margin-top: 40px; text-align: center;font-size:1em;">Wasting time and bandwidth since 1992</p>'); } return $this->smarty->fetch($this->template, $this->unique); }
/** * Extract a user's timeline * @since Version 3.9.1 * @param \DateTime|int $dateFrom * @param \DateTime|int $dateTo * @return array */ public function GenerateTimeline($dateFrom, $dateTo) { $page = false; $items_per_page = false; if (!$this->User instanceof User) { throw new InvalidArgumentException("No user object has been provided (hint: " . __CLASS__ . "::setUser(\$User))"); } if (filter_var($dateFrom, FILTER_VALIDATE_INT)) { $page = $dateFrom; } if (filter_var($dateTo, FILTER_VALIDATE_INT)) { $items_per_page = $dateTo; } /** * Filter out forums this user doesn't have access to */ $forum_post_filter = $this->getFilteredForums(); if ($page && $items_per_page) { $query = "SELECT SQL_CALC_FOUND_ROWS * FROM log_general WHERE user_id = ? " . $forum_post_filter . " ORDER BY timestamp DESC LIMIT ?, ?"; $offset = ($page - 1) * $items_per_page; $params = array($this->User->id, $offset, $items_per_page); } if (!$page || !$items_per_page) { $query = "SELECT SQL_CALC_FOUND_ROWS * FROM log_general WHERE user_id = ? " . $forum_post_filter . " AND timestamp >= ? AND timestamp <= ? ORDER BY timestamp DESC"; $params = array($this->User->id, $dateFrom->format("Y-m-d H:i:s"), $dateTo->format("Y-m-d H:i:s")); } $timeline = array("total" => 0); if ($result = $this->db->fetchAll($query, $params)) { if ($page && $items_per_page) { $timeline['page'] = $page; $timeline['perpage'] = $items_per_page; } if (!$page || !$items_per_page) { $timeline['start'] = $dateFrom->format("Y-m-d H:i:s"); $timeline['end'] = $dateTo->format("Y-m-d H:i:s"); } $timeline['total'] = $this->db->fetchOne("SELECT FOUND_ROWS() AS total"); foreach ($result as $row) { $row['args'] = json_decode($row['args'], true); $row['timestamp'] = new DateTime($row['timestamp']); $timeline['timeline'][$row['id']] = $row; } } /** * Process the timeline data */ if (!isset($timeline['timeline'])) { return $timeline; } foreach ($timeline['timeline'] as $key => $row) { // Set their timezone $row['timestamp']->setTimezone(new DateTimeZone($this->User->timezone)); if (stristr($row['title'], "loco") && empty($row['module'])) { $row['module'] = "locos"; } /** * Check if the meta data array exists */ if (!isset($row['meta'])) { $row['meta'] = array("id" => NULL, "namespace" => NULL); } /** * Format our data for grammatical and sentence structural purposes */ $row = $this->processGrammar($row); /** * Alter the object if needed */ $row = Timeline\Utility\General::formatObject($row); /** * Set the module namespace */ $row['meta']['namespace'] = Timeline\Utility\General::getModuleNamespace($row); /** * Attempt to create a link to this object or action if none exists */ $row['meta']['url'] = Timeline\Utility\Url::createUrl($row); /** * Attempt to create a meta object title for this object or action if none exists */ $row = Timeline\Utility\ObjectTitle::generateTitle($row); /** * Compact it all together and create a succinct message */ $row['action'] = Timeline\Utility\General::compactEvents($row); /** * Create the timestamp */ $row['timestamp_nice'] = ContentUtility::relativeTime($row['timestamp']); /** * Determine the icon */ $row['glyphicon'] = Timeline\Utility\General::getIcon($row); $timeline['timeline'][$key] = $row; } return $timeline; }
/** * Get an array of data * @since Version 3.9.1 * @return array */ public function getArray() { return array("id" => $this->id, "name" => $this->name, "description" => $this->description, "namespace" => $this->namespace, "created" => array("absolute" => $this->DateCreated->format("Y-m-d H:i:s"), "relative" => ContentUtility::relativeTime($this->DateCreated)), "modified" => array("absolute" => $this->DateModified->format("Y-m-d H:i:s"), "relative" => ContentUtility::relativeTime($this->DateModified)), "url" => $this->url->getURLs(), "owner" => $this->Author->getArray()); }