/** * Create a URL object from a provided Article * @since Version 3.10.0 * @param \Railpage\News\Article * @return \Railpage\Url */ public static function CreateArticleUrl(Article $Article) { $Url = new Url($Article->makePermaLink($Article->slug)); $Url->source = $Article->source; $Url->reject = sprintf("/news/pending?task=reject&id=%d&queue=newqueue", $Article->id); $Url->edit = sprintf("/news?mode=article.edit&id=%d", $Article->id); /** * Alter the URL */ if (empty($Article->getParagraphs()) && !empty($Article->source)) { $Url->url = $Article->source; $Url->canonical = $Article->source; } return $Url; }
/** * Constructor * @param string $slug */ public function __construct($slug) { $Database = AppCore::GetDatabase(); $Cache = AppCore::GetMemcached(); $mckey = "railpage:news.article_slug=" . $slug; $loaded = false; if ($story_id = $Cache->fetch($mckey)) { try { parent::__construct($story_id); $loaded = true; } catch (Exception $e) { } } /** * Fall back to a database query if we can't load the news article from Memcached */ if (!$loaded) { $story_id = $Database->fetchOne("SELECT sid FROM nuke_stories WHERE slug = ?", $slug); if (filter_var($story_id, FILTER_VALIDATE_INT)) { $Cache->save($mckey, $story_id, strtotime("+6 months")); parent::__construct($story_id); } else { throw new Exception("Could not find a story matching URL slug " . $slug); return false; } } }
/** * Get the formatted lead text for this article * @since Version 3.10.0 * @param \Railpage\News\Article $Article * @param string $section The section of the article (lead or paragraphs) to format * @return string */ public static function FormatArticleText($Article, $section = "lead") { $Memcached = AppCore::GetMemcached(); $cachekey = $section == "lead" ? Article::CACHE_KEY_FORMAT_LEAD : Article::CACHE_KEY_FORMAT_PARAGRAPHS; $cachekey = sprintf($cachekey, $Article->id); $whitespace_find = array("<p> </p>", "<p></p>", "<p> </p>"); $whitespace_replace = array("", "", ""); #$Memcached->delete($cachekey); if (!($text = $Memcached->Fetch($cachekey))) { $text = $section == "lead" ? $Article->getLead() : $Article->getParagraphs(); if (function_exists("format_post")) { $text = str_replace($whitespace_find, $whitespace_replace, $text); $text = format_post($text); if (is_object($text)) { $text = $text->__toString(); } $Memcached->save($cachekey, $text, 0); } } return $text; }
/** * Constructor * @param string $slug */ public function __construct($slug) { global $ZendDB, $ZendDB_ReadOnly; $mckey = "railpage:news.article_slug=" . $slug; if ($story_id = getMemcacheObject($mckey)) { parent::__construct($story_id); } else { $story_id = $ZendDB_ReadOnly->fetchOne("SELECT sid FROM nuke_stories WHERE slug = ?", $slug); if (filter_var($story_id, FILTER_VALIDATE_INT)) { setMemcacheObject($mckey, $story_id, strtotime("+6 months")); parent::__construct($story_id); } else { throw new \Exception("Could not find a story matching URL slug " . $slug); return false; } } }
/** * Create a news article announcing the end of the competition * @since Version 3.10.0 * @param \Railpage\Images\Competition $photoComp * @return void */ public static function createNewsArticle_Winner(Competition $photoComp) { /** * Get the winning photo */ $Photo = $photoComp->getWinningPhoto(); /** * Get all photos by vote count */ $photos = $photoComp->getPhotosAsArrayByVotes(); /** * Get the next competition */ $Competitions = new Competitions(); $NextComp = $Competitions->getNextCompetition($photoComp); /** * Curate the news article */ $Topic = new NewsTopic(5); // Topic in the Railpage category $Article = new NewsArticle(); $Article->title = $photoComp->title . " photo comp"; $Article->lead = sprintf("Congratulations to [url=%s]%s[/url] who has won the [url=%s]%s[/url] photo competition with %d votes. ", $Photo->Author->url->url, $Photo->Author->username, $photoComp->url->url, $photoComp->title, count($photos[0]['votes'])); $Article->firstline = $Article->lead; $Article->featured_image = $Photo->Image->sizes['medium']['source']; //$Article->paragraphs = $Article->lead . "\n\n" . sprintf("In second place was [url=%s]%s[/url] with %d votes, and in third place was [url=%s]%s[/url] with %d votes. \n\n", $photos[1]['author']['url']['url'], $photos[1]['author']['username'], count($photos[1]['votes']), $photos[2]['author']['url']['url'], $photos[2]['author']['username'], count($photos[2]['votes'])); $Article->paragraphs = vsprintf("%s\n\nIn second place was [url=%s]%s[/url] with %d votes, and in third place was [url=%s]%s[/url] with %d votes. \n\n", [$Article->lead, $photos[1]['author']['url']['url'], $photos[1]['author']['username'], count($photos[1]['votes']), $photos[2]['author']['url']['url'], $photos[2]['author']['username'], count($photos[2]['votes'])]); if (self::isSubmissionWindowOpen($NextComp) && !self::isVotingWindowOpen($NextComp)) { $Article->paragraphs .= sprintf("Submissions for our next competition, [url=%s]%s[/url], are open until %s. ", $NextComp->url->url, $NextComp->title, $NextComp->SubmissionsDateClose->Format("F jS")); } elseif (!self::isSubmissionWindowOpen($NextComp) && !self::isVotingWindowOpen($NextComp)) { $Article->paragraphs .= sprintf("Submissions for our next competition, [url=%s]%s[/url], are open from %s until %s. ", $NextComp->url->url, $NextComp->title, $NextComp->SubmissionsDateOpen->Format("F jS"), $NextComp->SubmissionsDateClose->Format("F jS")); } if ($NextComp->VotingDateOpen > new DateTime()) { if (!preg_match('/[\\p{P}]$/u', $NextComp->theme)) { $NextComp->theme .= "."; } $Article->paragraphs .= sprintf("Entry to the competition is open to all registered users. If you're not a registered user, you can [url=/registration]sign up now[/url]!\n\nThe next theme is: [i]%s[/i] \n\n", $NextComp->theme); } $Article->setAuthor(UserFactory::CreateUser(User::SYSTEM_USER_ID))->setStaff(UserFactory::CreateUser(User::SYSTEM_USER_ID))->setTopic($Topic); $Article->commit(); $Article->Approve(User::SYSTEM_USER_ID); }
/** * Get JSON object for a news article * @since Version 3.8.7 * @param int $article_id * @return string */ public static function getArticleJSON($article_id) { $key = sprintf("json:railpage.news.article=%d", $article_id); #deleteMemcacheObject($key); if (!($json = getMemcacheObject($key))) { $Article = new Article($article_id); $json = $Article->makeJSON(); } return $json; }
/** * Store jobs in the database * @since Version 3.9 * @return \Railpage\News\Scraper * @param boolean $logging Enable verbose logging of this feature */ public function store($logging = false) { /** * Get Sphinx so we can lookup similar articles to prevent duplicates */ $Sphinx = $this->getSphinx(); foreach ($this->articles as $article) { /** * Look through our approved news articles for a possible duplication */ $query = $Sphinx->select("*")->from("idx_news_article")->orderBy("story_time_unix", "DESC")->where("story_time_unix", ">=", $article['date']->sub(new DateInterval("P7D"))->getTimestamp())->match("story_title", $article['title']); $matches = $query->execute(); /** * Look through our rejected titles to see if we've already rejected this */ $query = $Sphinx->select("*")->from("idx_news_articles_rejected")->match("title", $article['title']); $rejected = $query->execute(); /** * If no matches are found we'll add in the article */ if (!count($matches) && !count($rejected)) { $Article = new Article(); $Article->title = $article['title']; $Article->blurb = $article['blurb']; $Article->source = $article['source']; $Article->body = $article['body']; $Article->setTopic($article['topic'])->setAuthor(new User(User::SYSTEM_USER_ID))->commit(true); if ($logging) { printf("Added news article \"%s\" (ID %d) in topic %s\n", $Article->title, $Article->id, $Article->Topic->name); } } } return $this; }