Adding a blog FeedReader
authorSteve Sutton <steve@gaslightmedia.com>
Fri, 14 Jun 2013 18:39:23 +0000 (18:39 +0000)
committerSteve Sutton <steve@gaslightmedia.com>
Fri, 14 Jun 2013 18:39:23 +0000 (18:39 +0000)
Using same feed reader app I made for TCCVB for prWeb.
It will check for blog updates every 5 hours. (as needed)
If the feed fails it wil only update our check date and continue to
function. That way if their feed fails for any reason it won't bring
down the site.

Toolkit/Blogs/Database/application.sql [new file with mode: 0644]
Toolkit/Blogs/Database/tables/blog.sql [new file with mode: 0644]
Toolkit/Blogs/Database/tables/item.sql [new file with mode: 0644]
Toolkit/Blogs/FeedReader.php [new file with mode: 0644]
Toolkit/Blogs/Models/Blog.php [new file with mode: 0644]
Toolkit/Blogs/Models/BlogMapper.php [new file with mode: 0644]
Toolkit/Blogs/Models/Item.php [new file with mode: 0644]
Toolkit/Blogs/Views/feed.html [new file with mode: 0644]
Toolkit/Blogs/application.ini [new file with mode: 0644]
Toolkit/Page.php
templates/template.html

diff --git a/Toolkit/Blogs/Database/application.sql b/Toolkit/Blogs/Database/application.sql
new file mode 100644 (file)
index 0000000..8e0f8d7
--- /dev/null
@@ -0,0 +1,7 @@
+CREATE SCHEMA blogs;
+
+GRANT ALL ON SCHEMA blogs TO nobody;
+
+\i ./tables/blog.sql
+\i ./tables/item.sql
+
diff --git a/Toolkit/Blogs/Database/tables/blog.sql b/Toolkit/Blogs/Database/tables/blog.sql
new file mode 100644 (file)
index 0000000..10d64da
--- /dev/null
@@ -0,0 +1,14 @@
+DROP TABLE IF EXISTS blogs.blog;
+
+CREATE TABLE blogs.blog (
+    id SERIAL,
+    title TEXT,
+    url TEXT,
+    description TEXT,
+    build TIMESTAMP with time zone,
+    checkdate TIMESTAMP with time zone,
+    PRIMARY KEY (id)
+);
+
+GRANT ALL ON blogs.blog TO nobody;
+GRANT ALL ON blogs.blog_id_seq TO nobody;
diff --git a/Toolkit/Blogs/Database/tables/item.sql b/Toolkit/Blogs/Database/tables/item.sql
new file mode 100644 (file)
index 0000000..09133f4
--- /dev/null
@@ -0,0 +1,14 @@
+DROP TABLE IF EXISTS blogs.item;
+
+CREATE TABLE blogs.item (
+    id SERIAL,
+    title TEXT,
+    url TEXT,
+    guid TEXT,
+    description TEXT,
+    pubdate TIMESTAMP with time zone,
+    PRIMARY KEY (id)
+);
+
+GRANT ALL ON blogs.item TO nobody;
+GRANT ALL ON blogs.item_id_seq TO nobody;
diff --git a/Toolkit/Blogs/FeedReader.php b/Toolkit/Blogs/FeedReader.php
new file mode 100644 (file)
index 0000000..e9e3904
--- /dev/null
@@ -0,0 +1,194 @@
+<?php
+
+/**
+ * FeedReader.php
+ *
+ * PHP version 5.3
+ *
+ * @category  Toolkit
+ * @package   PrWeb
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_PrWeb_FeedReader
+ *
+ * Check the RSS feed on a regular bases to see if there's updates.
+ * If an update is found it removes all items adn creates new ones from the
+ * Feed.
+ *
+ * @category  Toolkit
+ * @package   PrWeb
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_Blogs_FeedReader
+{
+
+    /**
+     * PDO Connection to database
+     *
+     * @var PDO
+     */
+    private $_dbh;
+
+    /**
+     *
+     * @var Toolkit_Blogs_Models_BlogMapper
+     */
+    private $_blogMapper;
+
+    /**
+     * PrWeb Record
+     *
+     * @var Toolkit_Blogs_Models_Blog
+     */
+    private $_blog;
+
+    /**
+     * Items from the PrWeb Feed Rss
+     *
+     * @var ArrayObject
+     */
+    private $_items;
+
+
+    /**
+     * time interval to check for new updates from feed
+     * time is in minutes.
+     */
+    const FEED_CHECK_INTERVAL = 5;
+    const FEED_CHECK_PART     = 'hours';
+    const FEED_RSS_URL        = 'http://michigantrailmaps.com/blog/?feed=rss2';
+    const HTML_TPL            = 'feed.html';
+
+
+    /**
+     * Creates Object of FeedReader for PrWeb
+     *
+     * @param PDO                              $pdo         Database Connection
+     * @param Toolkit_Blogs_Models_BlogMapper $blogMapper Mapper Object for prWeb
+     */
+    public function __construct(
+        PDO $pdo,
+        Toolkit_Blogs_Models_BlogMapper $blogMapper
+    ) {
+        $this->_dbh        = $pdo;
+        $this->_blogMapper = $blogMapper;
+        $this->_blog       = $this->_blogMapper->fetchBlog();
+        $this->_items      = $this->_blogMapper->fetchAllItems();
+        $this->checkForUpdates();
+    }
+
+    /**
+     * Checks the last build date for prWeb record
+     *
+     * @return boolean
+     */
+    public function checkForUpdates()
+    {
+        if (!$this->_blog) {
+            $prWebRss = $this->fetchRssFeed();
+            if ($prWebRss) {
+                $this->updateFeedData($prWebRss);
+                // if the items are updated then refetch them
+                $this->_blog = $this->_blogMapper->fetchBlog();
+                $this->_items = $this->_blogMapper->fetchAllItems();
+            }
+            return true;
+        }
+        $currentTime = new DateTime();
+        $buildDate = new DateTime($this->_blog->getCheckdate());
+        $buildDate->modify('+' . self::FEED_CHECK_INTERVAL . ' ' . self::FEED_CHECK_PART);
+        if ($currentTime > $buildDate) {
+            $prWebRss = $this->fetchRssFeed();
+            if ($prWebRss) {
+                $this->updateFeedData($prWebRss);
+                // if the items are updated then refetch them
+                $this->_blog = $this->_blogMapper->fetchBlog();
+                $this->_items = $this->_blogMapper->fetchAllItems();
+            } else {
+                // update the check date
+                $this->_blog->setCheckdate(date('Y-m-d H:i:s'));
+                $this->_blogMapper->savePrWeb($this->_blog);
+            }
+        }
+    }
+
+    public function fetchRssFeed()
+    {
+        try {
+            $blogRss = Zend_Feed::import(self::FEED_RSS_URL);
+        } catch (Zend_Feed_Exception $e) {
+            Toolkit_Common::handleError($e);
+            return false;
+        }
+        return $blogRss;
+    }
+
+    public function updateFeedData($blogRss)
+    {
+        if (!$this->_blog) {
+            $this->_blog = Toolkit_Blogs_Models_Blog::createByValues(
+                array(
+                    'title'       => trim($blogRss->title()),
+                    'url'         => trim($blogRss->link()),
+                    'description' => trim($blogRss->description()),
+                    'build'       => trim($blogRss->lastBuildDate()),
+                    'checkdate'   => date('Y-m-d H:i:s')
+                )
+            );
+        } else {
+            $this->_blog->setBuild(trim($blogRss->lastBuildDate()));
+            $this->_blog->setCheckdate(date('Y-m-d H:i:s'));
+            $this->_blog->setDescription(trim($blogRss->description()));
+            $this->_blog->setTitle(trim($blogRss->title()));
+            $this->_blog->setUrl(trim($blogRss->link()));
+        }
+        $this->_blogMapper->savePrWeb($this->_blog);
+        $items = new ArrayObject();
+        // Loop over each channel item and store relevant data
+        $index = 0;
+        foreach ($blogRss as $item) {
+            $items->offsetSet($index, array(
+                'title'       => $item->title(),
+                'link'        => $item->link(),
+                'guid'        => $item->guid(),
+                'pubdate'     => $item->pubDate(),
+                'description' => $item->description()
+            ));
+            ++$index;
+        }
+        $this->_blogMapper->saveAllItems($items);
+    }
+
+    public function toHtml(HTML_Template_Flexy $tpl)
+    {
+        $glmBaseUrl = ($_SERVER['HTTPS'] == 'on')
+            ? GLM_APP_BASE_SECURE_URL
+            : GLM_APP_BASE_URL;
+        $GLOBALS['bottomScripts'][] = $glmBaseUrl . 'libjs/external.js';
+        $tpl->compile(self::HTML_TPL);
+        $page        = new stdClass();
+        $page->items = $this->_items;
+        $page->prWeb = $this->_blog;
+        return $tpl->bufferedOutputObject($page);
+    }
+
+    public function fetchMostRecent()
+    {
+        return array(
+            'blog'  => $this->_blog,
+            'items' => $this->_items
+        );
+    }
+
+
+}
diff --git a/Toolkit/Blogs/Models/Blog.php b/Toolkit/Blogs/Models/Blog.php
new file mode 100644 (file)
index 0000000..04c92ef
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+
+/**
+ * PrWeb.php
+ *
+ * PHP version 5.3
+ *
+ * @category  Toolkit
+ * @package   PrWeb
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Blogs_Models_Blog
+ *
+ * Representation of the PrWeb table
+ *
+ * @category  Toolkit
+ * @package   PrWeb
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_Blogs_Models_Blog
+{
+    private $_id;
+    private $_title;
+    private $_url;
+    private $_description;
+    private $_build;
+    private $_checkdate;
+
+
+    const TABLE_NAME = 'blogs.blog';
+    const PRI_KEY    = 'id';
+
+
+    private function __construct($values)
+    {
+        extract($values);
+        $this->setBuild($build)
+            ->setCheckdate($checkdate)
+            ->setDescription($description)
+            ->setTitle($title)
+            ->setUrl($url);
+        if ($id = filter_var($id, FILTER_VALIDATE_INT)) {
+            $this->setId($id);
+        }
+    }
+
+    static public function createByValues($values)
+    {
+        if (is_array($values) && !empty($values)) {
+            return new Toolkit_Blogs_Models_Blog($values);
+        } else {
+            return false;
+        }
+    }
+
+    public function getId()
+    {
+        return $this->_id;
+    }
+
+    public function setId($id)
+    {
+        $this->_id = $id;
+        return $this;
+    }
+
+    public function getTitle()
+    {
+        return $this->_title;
+    }
+
+    public function setTitle($title)
+    {
+        $this->_title = $title;
+        return $this;
+    }
+
+    public function getUrl()
+    {
+        return $this->_url;
+    }
+
+    public function setUrl($url)
+    {
+        $this->_url = $url;
+        return $this;
+    }
+
+    public function getDescription()
+    {
+        return $this->_description;
+    }
+
+    public function setDescription($description)
+    {
+        $this->_description = $description;
+        return $this;
+    }
+
+    public function getBuild()
+    {
+        return $this->_build;
+    }
+
+    public function setBuild($build)
+    {
+        $this->_build = $build;
+        return $this;
+    }
+
+    public function getCheckdate()
+    {
+        return $this->_checkdate;
+    }
+
+    public function setCheckdate($checkdate)
+    {
+        $this->_checkdate = $checkdate;
+        return $this;
+    }
+
+
+}
diff --git a/Toolkit/Blogs/Models/BlogMapper.php b/Toolkit/Blogs/Models/BlogMapper.php
new file mode 100644 (file)
index 0000000..f196cef
--- /dev/null
@@ -0,0 +1,206 @@
+<?php
+
+/**
+ * PrWebMapper.php
+ *
+ * PHP version 5.3
+ *
+ * @category  Toolkit
+ * @package   PrWeb
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Blogs_Models_BlogMapper
+ *
+ * Mapper Object for dealing with all database queries for generating
+ * the object for prweb and items.
+ *
+ * @category  Toolkit
+ * @package   PrWeb
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_Blogs_Models_BlogMapper
+{
+    /**
+     * PDO Connection to database
+     *
+     * @var PDO
+     */
+    private $_dbh;
+
+    /**
+     * There's only one prWeb record
+     */
+    const PRWEB_ID = 1;
+
+    /**
+     * Creates an object of type PrWebMapper
+     *
+     * @param PDO $pdo Database Connection
+     */
+    public function __construct(PDO $pdo)
+    {
+        $this->_dbh = $pdo;
+    }
+
+    /**
+     * Return the prweb record or false if none exists
+     *
+     * @return boolean | Toolkit_Blogs_Models_Blog
+     */
+    public function fetchBlog()
+    {
+        try {
+            $sql = "
+            SELECT *
+              FROM " . Toolkit_Blogs_Models_Blog::TABLE_NAME ."
+             WHERE " . Toolkit_Blogs_Models_Blog::PRI_KEY . " = "
+                . self::PRWEB_ID;
+            $stmt = $this->_dbh->query($sql);
+            if ($stmt->rowCount() > 0) {
+                return Toolkit_Blogs_Models_Blog::createByValues(
+                    $stmt->fetch(PDO::FETCH_ASSOC)
+                );
+            } else {
+                return false;
+            }
+
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+
+    }
+
+    /**
+     * Return the items record or false if none exists
+     *
+     * @return boolean | Toolkit_Blogs_Models_Blog
+     */
+    public function fetchAllItems()
+    {
+        $items = new ArrayObject();
+        try {
+            $sql = "
+              SELECT *
+                FROM " . Toolkit_Blogs_Models_Item::TABLE_NAME ."
+            ORDER BY " . Toolkit_Blogs_Models_Item::SORT;
+            $stmt = $this->_dbh->query($sql);
+            if ($stmt->rowCount() > 0) {
+                $index = 0;
+                while ($values = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                    $items->offsetSet(
+                        $index,
+                        Toolkit_Blogs_Models_Item::createByValues(
+                            $stmt->fetch(PDO::FETCH_ASSOC)
+                        )
+                    );
+                    ++$index;
+                }
+                return $items;
+            } else {
+                return false;
+            }
+
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+
+    }
+
+    public function savePrWeb(
+        Toolkit_Blogs_Models_Blog $prWeb
+    ) {
+        if ($prWeb->getId()) {
+            $sql = "
+            UPDATE " . Toolkit_Blogs_Models_Blog::TABLE_NAME . "
+               SET title = :title,
+                   url = :url,
+                   description = :description,
+                   build = :build,
+                   checkdate = :checkdate
+             WHERE " . Toolkit_Blogs_Models_Blog::PRI_KEY . " = :id";
+        } else {
+            $sql = "
+            INSERT INTO " . Toolkit_Blogs_Models_Blog::TABLE_NAME . "
+            (id, title, url, description, build, checkdate)
+            VALUES
+            (" . self::PRWEB_ID . ", :title, :url, :description, :build, :checkdate)
+            RETURNING " . Toolkit_Blogs_Models_Blog::PRI_KEY;
+        }
+        $stmt = $this->_dbh->prepare($sql);
+        $stmt->bindParam(':title', $prWeb->getTitle());
+        $stmt->bindParam(':url', $prWeb->getUrl());
+        $stmt->bindParam(':description', $prWeb->getDescription());
+        $stmt->bindParam(':build', $prWeb->getBuild());
+        $stmt->bindParam(':checkdate', $prWeb->getCheckdate());
+        if ($prWeb->getId()) {
+            $stmt->bindParam(':id', $prWeb->getId(), PDO::PARAM_INT);
+        }
+        $stmt->execute();
+        if (!$prWeb->getId()) {
+            $prWeb->setId($stmt->fetchColumn());
+        }
+        return $prWeb;
+    }
+
+    public function saveAllItems(ArrayObject $items)
+    {
+        $this->_dbh->beginTransaction();
+        $this->_dbh->query(
+            "DELETE FROM " . Toolkit_Blogs_Models_Item::TABLE_NAME
+        );
+        foreach ($items as $item) {
+            $this->saveItem(
+                Toolkit_Blogs_Models_Item::createByValues($item)
+            );
+        }
+        $this->_dbh->commit();
+    }
+
+    public function saveItem(
+        Toolkit_Blogs_Models_Item $item
+    ) {
+         if ($item->getId()) {
+            $sql = "
+            UPDATE " . Toolkit_Blogs_Models_Item::TABLE_NAME . "
+               SET title = :title,
+                   url = :url,
+                   guid = :guid,
+                   description = :description,
+                   pubdate = :pubdate
+             WHERE " . Toolkit_Blogs_Models_Item::PRI_KEY . " = :id";
+        } else {
+            $sql = "
+            INSERT INTO " . Toolkit_Blogs_Models_Item::TABLE_NAME . "
+            (title, url, guid, description, pubdate)
+            VALUES
+            (:title, :url, :guid, :description, :pubdate)
+            RETURNING " . Toolkit_Blogs_Models_Item::PRI_KEY;
+        }
+        $stmt = $this->_dbh->prepare($sql);
+        $stmt->bindParam(':title', $item->getTitle());
+        $stmt->bindParam(':url', $item->getUrl());
+        $stmt->bindParam(':guid', $item->getGuid());
+        $stmt->bindParam(':description', $item->getDescription());
+        $stmt->bindParam(':pubdate', $item->getPubdate());
+        if ($item->getId()) {
+            $stmt->bindParam(':id', $item->getId(), PDO::PARAM_INT);
+        }
+        $stmt->execute();
+        if (!$item->getId()) {
+            $item->setId($stmt->fetchColumn());
+        }
+        return $item;
+    }
+
+
+}
diff --git a/Toolkit/Blogs/Models/Item.php b/Toolkit/Blogs/Models/Item.php
new file mode 100644 (file)
index 0000000..db8a4e2
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+
+/**
+ * Item.php
+ *
+ * PHP version 5.3
+ *
+ * @category  Toolkit
+ * @package   PrWeb
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Blogs_Models_Item
+ *
+ * Representation of the Item table
+ *
+ * @category  Toolkit
+ * @package   PrWeb
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_Blogs_Models_Item
+{
+    private $_id;
+    private $_title;
+    private $_url;
+    private $_guid;
+    private $_description;
+    private $_pubdate;
+
+    const TABLE_NAME = 'blogs.item';
+    const PRI_KEY    = 'id';
+    const SORT       = 'pubdate desc';
+
+    private function __construct($values)
+    {
+        extract($values);
+        $this->setPubdate($pubdate)
+            ->setDescription($description)
+            ->setTitle($title)
+            ->setUrl($url)
+            ->setGuid($guid);
+        if ($id = filter_var($id, FILTER_VALIDATE_INT)) {
+            $this->setId($id);
+        }
+    }
+
+    static public function createByValues($values)
+    {
+        if (is_array($values) && !empty($values)) {
+            return new Toolkit_Blogs_Models_Item($values);
+        } else {
+            return false;
+        }
+    }
+
+    public function getId()
+    {
+        return $this->_id;
+    }
+
+    public function setId($id)
+    {
+        $this->_id = $id;
+        return $this;
+    }
+
+    public function getTitle()
+    {
+        return $this->_title;
+    }
+
+    public function setTitle($title)
+    {
+        $this->_title = $title;
+        return $this;
+    }
+
+    public function getUrl()
+    {
+        return $this->_url;
+    }
+
+    public function setUrl($url)
+    {
+        $this->_url = $url;
+        return $this;
+    }
+
+    public function getGuid()
+    {
+        return $this->_guid;
+    }
+
+    public function setGuid($guid)
+    {
+        $this->_guid = $guid;
+        return $this;
+    }
+
+    public function getDescription()
+    {
+        return $this->_description;
+    }
+
+    public function setDescription($description)
+    {
+        $this->_description = $description;
+        return $this;
+    }
+
+    public function getPubdate()
+    {
+        return $this->_pubdate;
+    }
+
+    public function setPubdate($pubdate)
+    {
+        $this->_pubdate = $pubdate;
+        return $this;
+    }
+
+    public function getPubdateFormated($format)
+    {
+        $time = strtotime($this->getPubdate());
+        return date($format, $time);
+    }
+
+
+}
diff --git a/Toolkit/Blogs/Views/feed.html b/Toolkit/Blogs/Views/feed.html
new file mode 100644 (file)
index 0000000..df3bb30
--- /dev/null
@@ -0,0 +1,52 @@
+<style>
+    #prWeb-feed-rss {
+        width: 600px;
+    }
+    #prWeb-feed-rss header {
+        position: relative;
+        margin: 5 0;
+        height: auto;
+        margin-bottom: 5px;
+    }
+    #prWeb-feed-rss h1 {
+        margin: 1em 0 0.4em;
+        color: black;
+        font-size: 2.0rem;
+        font-weight: normal;
+    }
+    #prWeb-feed-rss h2 {
+        font-size: smaller;
+        font-weight: normal;
+    }
+    #prWeb-feed-rss article {
+        width: 100%;
+    }
+    #prWeb-feed-rss article h1 {
+        font-size: medium;
+        font-weight: normal;
+        color: #00456C;
+    }
+
+</style>
+<section id="prWeb-feed-rss">
+    <header>
+        <hgroup>
+            <h1>{prWeb.getTitle()}</h1>
+            <h2>{prWeb.getDescription()}</h2>
+        </hgroup>
+    </header>
+
+    <article class="prWeb-item" flexy:foreach="items,item">
+        <header>
+            <hgroup>
+                <h1>{item.getTitle()}</h1>
+            </hgroup>
+        </header>
+        <time datetime="{item.getpubDate()}" pubdate>
+            {item.getPubdateFormated(#F j, Y#)}
+        </time>
+        <div>
+            {item.getDescription():h}
+        </div>
+    </article>
+</section>
diff --git a/Toolkit/Blogs/application.ini b/Toolkit/Blogs/application.ini
new file mode 100644 (file)
index 0000000..c053332
--- /dev/null
@@ -0,0 +1,28 @@
+; production server configuration for application
+[production]
+flexyOptions.templateDir     = BASE "Toolkit/Blogs/Views"
+flexyOptions.compileDir      = BASE "Toolkit/Blogs/Views/compiled"
+flexyOptions.url_rewrite     = "baseurl/::" BASE_URL ",basesecureurl/::" BASE_SECURE_URL
+flexyOptions.forceCompile    = Off
+flexyOptions.locale          = "en"
+flexyOptions.debug           = Off
+flexyOptions.allowPHP        = On
+flexyOptions.flexyIgnore     = On
+flexyOptions.globals         = On
+flexyOptions.globalfunctions = On
+flexyOptions.privates        = On
+flexyOptions.compiler        = "Flexy"
+
+; development server configuration inherits from production and
+; overrides values as needed
+[development : production]
+
+; Chuck's server configuration inherits from development and
+; overrides values as needed
+[chuck : development]
+
+; Steve's server configuration inherits from development and
+; overrides values as needed
+[steve : development]
+;flexyOptions.forceCompile = On
+;flexyOptions.strict = On
\ No newline at end of file
index 401360e..ede62cb 100755 (executable)
@@ -402,6 +402,10 @@ class Toolkit_Page
             $this->_events($this->_toolboxPage, $this->_pageGateway);
         }
 
+        if ($this->_catid == HOME_ID) {
+            $this->_blogReeder();
+        }
+
         if (   defined("GLM_BLOCKS")
             && GLM_BLOCKS
             && !filter_input(INPUT_GET, 'sitemap')
@@ -756,6 +760,16 @@ class Toolkit_Page
         $this->rotatingImages = $decorator->toHtml($is);
     }
 
+    private function _blogReeder()
+    {
+        $dbh        = Toolkit_Database::getInstance();
+        $blogMapper = new Toolkit_Blogs_Models_BlogMapper($dbh);
+        $feedReader = new Toolkit_Blogs_FeedReader($dbh, $blogMapper);
+
+        $feed = $feedReader->fetchMostRecent();
+        $this->feed = $feed['items'];
+    }
+
     /**
      * Add Weather module
      *
index 74d7625..aef9625 100755 (executable)
                                        <a id="enews" href="baseurl/newsletter-7/">Sign Up For Our Enewsletter</a>
                                        <a id="tripplanner" href="baseurl/trip-planner-6/">Trip And Trail Planner (<span class="trip-list-count">{tripPlannerCount:h}</span>)</a>
                                </div>
-                               
+
                                <div id="toolbox">
                                        <div id="addthis_wrapper">
                                                <!-- AddThis Button BEGIN -->
                                                <script type="text/javascript">var addthis_config = {"data_track_addressbar":false};</script>
                                                <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5135fe4558d287a9"></script>
                                                <!-- AddThis Button END -->
-                                       </div><!--/#addthis_wrapper--> 
+                                       </div><!--/#addthis_wrapper-->
                                        {toolboxContent:h}
                                </div><!--/#toolbox-->
                                <div id="hHlines_wrapper">
                                                </div><!--/#trailshop_wrapper-->
                                                <div id="blog_wrapper">
                                                        <h2>Trail Talk Blog</h2>
-                                                       <p class="blog_date">Wed, March 6, 2013 - 5:16PM</p>
-                                                       <a class="blog_link" href="#">Sally Jewel: She's No James Watt</a>
-                                                       <p class="blog_desc">Sally Jewell, the CEO of REI, has been nominated to the the next Secretary of the Interior and that's great because she's one of us, somebody who maintains their sanity by escaping outdoors.</p>
+                            <article flexy:foreach="feed,item">
+                                <p class="blog_date">{item.getPubdateFormated(#D, F j, Y g:iA#)}</p>
+                                <a class="blog_link" href="{item.getGuid():h}">{item.getTitle()}</a>
+                                <p class="blog_desc">{item.getDescription():h}</p>
+                            </article>
                                                </div><!--/#blog_wrapper-->
                                        </div><!--/#action2-->
                                </div><!--/hHlines_wrapper-->