Jump to:

1842 Posts in 1600 Topics by 558 members

Blog Module

SilverStripe Forums » Blog Module » [SOLVED] Hiding Future Blog Posts (i.e. Scheduling Entries)

Discuss the Blog Module.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 1444 Views
  • Bstarr
    Avatar
    Community Member
    25 Posts

    [SOLVED] Hiding Future Blog Posts (i.e. Scheduling Entries) Link to this post

    Thanks to everyone who has been helping me through my issues. I have one last problem with my blog. I want to hide posts with publish dates greater than the current date/time. I have looked through tutorials and previous posts and believe somewhere in the BlogTree.php I need to have the $Now listed. Can anyone tell me what I am doing wrong?

    I created a Blogtree.php in the mysite/code folder and used the code I found in a previous thread...

    // only use freshness if no action is present (might be displaying tags or rss)
          if ($this->LandingPageFreshness && !$this->request->param('Action')) {
             $d = new Zend_Date(SS_Datetime::now()->getValue());
             $d->sub($this->LandingPageFreshness);
             $date = $d->toString('YYYY-MM-dd');
              if(defined('DB::USE_ANSI_SQL')) {
             $filter = "\"BlogEntry\".\"Date\" < NOW()";
    } else {
    $filter = "`BlogEntry`.Date < NOW()";
    }

    However, it is still not working I have future posts showing up. Below is the whole page code.

    <?php

    /**
    * @package blog
    */

    /**
    * Blog tree allows a tree of Blog Holders. Viewing branch nodes shows all blog entries from all blog holder children
    */

    class BlogTree extends Page {
       
       // Default number of blog entries to show
       static $default_entries_limit = 10;
       
       static $db = array(
          'Name' => 'Varchar',
          'InheritSideBar' => 'Boolean',
          'LandingPageFreshness' => 'Varchar',
       );
       
       static $defaults = array(
          'InheritSideBar' => True
       );
       
       static $has_one = array(
          "SideBar" => "WidgetArea",
       );
       
       static $allowed_children = array(
          'BlogTree', 'BlogHolder'
       );

       /*
        * Finds the BlogTree object most related to the current page.
        * - If this page is a BlogTree, use that
        * - If this page is a BlogEntry, use the parent Holder
        * - Otherwise, try and find a 'top-level' BlogTree
        *
        * @param $page allows you to force a specific page, otherwise,
        *             uses current
        */
       static function current($page = null) {
          
          if (!$page) {
             $controller = Controller::curr();
             if($controller) $page = $controller->data();
          }
          
          // If we _are_ a BlogTree, use us
          if ($page instanceof BlogTree) return $page;
          
          // Or, if we a a BlogEntry underneath a BlogTree, use our parent
          if($page->is_a("BlogEntry")) {
             $parent = $page->getParent();
             if($parent instanceof BlogTree) return $parent;
          }
          
          // Try to find a top-level BlogTree
          $top = DataObject::get_one('BlogTree', "\"ParentID\" = '0'");
          if($top) return $top;
          
          // Try to find any BlogTree that is not inside another BlogTree
          foreach(DataObject::get('BlogTree') as $tree) {
             if(!($tree->getParent() instanceof BlogTree)) return $tree;
          }
          
          // This shouldn't be possible, but assuming the above fails, just return anything you can get
          return DataObject::get_one('BlogTree');
       }

       /* ----------- ACCESSOR OVERRIDES -------------- */
       
       public function getLandingPageFreshness() {
          $freshness = $this->getField('LandingPageFreshness');
          // If we want to inherit freshness, try that first
          if ($freshness == "INHERIT" && $this->getParent()) $freshness = $this->getParent()->LandingPageFreshness;
          // If we don't have a parent, or the inherited result was still inherit, use default
          if ($freshness == "INHERIT") $freshness = '';
          return $freshness;
       }
       
       function SideBar() {
          if($this->InheritSideBar && $this->getParent()) {
             if (method_exists($this->getParent(), 'SideBar')) return $this->getParent()->SideBar();
          }
          
          if($this->SideBarID){
             return DataObject::get_by_id('WidgetArea', $this->SideBarID);
             // @todo: This segfaults - investigate why then fix: return $this->getComponent('SideBar');
          }
       }
       
       /* ----------- CMS CONTROL -------------- */
       
       function getCMSFields() {
          $fields = parent::getCMSFields();
          $fields->addFieldToTab("Root.Content.Main", new TextField("Name", "Name of blog"));
          $fields->addFieldToTab('Root.Content.Main', new DropdownField('LandingPageFreshness', 'When you first open the blog, how many entries should I show', array(
             "" => "All entries",
             "1 MONTH" => "Last month's entries",
             "2 MONTH" => "Last 2 months' entries",
             "3 MONTH" => "Last 3 months' entries",
             "4 MONTH" => "Last 4 months' entries",
             "5 MONTH" => "Last 5 months' entries",
             "6 MONTH" => "Last 6 months' entries",
             "7 MONTH" => "Last 7 months' entries",
             "8 MONTH" => "Last 8 months' entries",
             "9 MONTH" => "Last 9 months' entries",
             "10 MONTH" => "Last 10 months' entries",
             "11 MONTH" => "Last 11 months' entries",
             "12 MONTH" => "Last year's entries",
             "INHERIT" => "Take value from parent Blog Tree"
          )));
       
          $fields->addFieldToTab("Root.Content.Widgets", new CheckboxField("InheritSideBar", 'Inherit Sidebar From Parent'));
          $fields->addFieldToTab("Root.Content.Widgets", new WidgetAreaEditor("SideBar"));
          
          return $fields;
       }
          
       /* ----------- New accessors -------------- */
       
       public function loadDescendantBlogHolderIDListInto(&$idList) {
          if ($children = $this->AllChildren()) {
             foreach($children as $child) {
                if(in_array($child->ID, $idList)) continue;
                
                if($child instanceof BlogHolder) {
                   $idList[] = $child->ID;
                } elseif($child instanceof BlogTree) {
                   $child->loadDescendantBlogHolderIDListInto($idList);
                }
             }
          }
       }
       
       // Build a list of all IDs for BlogHolders that are children of us
       public function BlogHolderIDs() {
          $holderIDs = array();
          $this->loadDescendantBlogHolderIDListInto($holderIDs);
          return $holderIDs;
       }
          
       /**
        * Get entries in this blog.
        * @param string limit A clause to insert into the limit clause.
        * @param string tag Only get blog entries with this tag
        * @param string date Only get blog entries on this date - either a year, or a year-month eg '2008' or '2008-02'
        * @param callback retrieveCallback A function to call with pagetype, filter and limit for custom blog sorting or filtering
        * @param string $where
        * @return DataObjectSet
        */
       public function Entries($limit = '', $tag = '', $date = '', $retrieveCallback = null, $filter = '') {
          
          $tagCheck = '';
          $dateCheck = '';
          
          if($tag) {
             $SQL_tag = Convert::raw2sql($tag);
             $tagCheck = "AND \"BlogEntry\".\"Tags\" LIKE '%$SQL_tag%'";
          }

          if($date) {
             if(strpos($date, '-')) {
                $year = (int) substr($date, 0, strpos($date, '-'));
                $month = (int) substr($date, strpos($date, '-') + 1);

                if($year && $month) {
                   if(method_exists(DB::getConn(), 'formattedDatetimeClause')) {
                      $db_date=DB::getConn()->formattedDatetimeClause('"BlogEntry"."Date"', '%m');
                      $dateCheck = "AND CAST($db_date AS " . DB::getConn()->dbDataType('unsigned integer') . ") = $month AND " . DB::getConn()->formattedDatetimeClause('"BlogEntry"."Date"', '%Y') . " = '$year'";
                   } else {
                      $dateCheck = "AND MONTH(\"BlogEntry\".\"Date\") = '$month' AND YEAR(\"BlogEntry\".\"Date\") = '$year'";
                   }
                }
             } else {
                $year = (int) $date;
                if($year) {
                   if(method_exists(DB::getConn(), 'formattedDatetimeClause')) {
                      $dateCheck = "AND " . DB::getConn()->formattedDatetimeClause('"BlogEntry"."Date"', '%Y') . " = '$year'";
                   } else {
                      $dateCheck = "AND YEAR(\"BlogEntry\".\"Date\") = '$year'";
                   }
                }
             }
          }

          // Build a list of all IDs for BlogHolders that are children of us
          $holderIDs = $this->BlogHolderIDs();
          
          // If no BlogHolders, no BlogEntries. So return false
          if(empty($holderIDs)) return false;
          
          // Otherwise, do the actual query
          if($filter) $filter .= ' AND ';
          $filter .= '"ParentID" IN (' . implode(',', $holderIDs) . ") $tagCheck $dateCheck";

          $order = '"BlogEntry"."Date" DESC';

          // By specifying a callback, you can alter the SQL, or sort on something other than date.
          if($retrieveCallback) return call_user_func($retrieveCallback, 'BlogEntry', $filter, $limit, $order);
          
          return DataObject::get('BlogEntry', $filter, $order, '', $limit);
       }
    }

    class BlogTree_Controller extends Page_Controller {
       
       static $allowed_actions = array(
          'index',
          'rss',
          'tag'
       );
       
       function init() {
          parent::init();
          
          $this->IncludeBlogRSS();
          
          Requirements::themedCSS("blog");
       }

       function BlogEntries($limit = null) {
          require_once('Zend/Date.php');
          
          if($limit === null) $limit = BlogTree::$default_entries_limit;

          // only use freshness if no action is present (might be displaying tags or rss)
          if ($this->LandingPageFreshness && !$this->request->param('Action')) {
             $d = new Zend_Date(SS_Datetime::now()->getValue());
             $d->sub($this->LandingPageFreshness);
             $date = $d->toString('YYYY-MM-dd');
              if(defined('DB::USE_ANSI_SQL')) {
             $filter = "\"BlogEntry\".\"Date\" < NOW()";
    } else {
    $filter = "`BlogEntry`.Date < NOW()";
    }
          
          // allow filtering by author field and some blogs have an authorID field which
          // may allow filtering by id
          if(isset($_GET['author']) && isset($_GET['authorID'])) {
             $author = Convert::raw2sql($_GET['author']);
             $id = Convert::raw2sql($_GET['authorID']);
             
             $filter .= " \"BlogEntry\".\"Author\" LIKE '". $author . "' OR \"BlogEntry\".\"AuthorID\" = '". $id ."'";
          }
          else if(isset($_GET['author'])) {
             $filter .= " \"BlogEntry\".\"Author\" LIKE '". Convert::raw2sql($_GET['author']) . "'";
          }
          else if(isset($_GET['authorID'])) {
             $filter .= " \"BlogEntry\".\"AuthorID\" = '". Convert::raw2sql($_GET['authorID']). "'";
          }
          
          $start = isset($_GET['start']) ? (int) $_GET['start'] : 0;
          
          $date = $this->SelectedDate();
          
          return $this->Entries("$start,$limit", $this->SelectedTag(), ($date) ? $date->Format('Y-m') : '', null, $filter);
       }

       /**
        * This will create a <link> tag point to the RSS feed
        */
       function IncludeBlogRSS() {
          RSSFeed::linkToFeed($this->Link() . "rss", _t('BlogHolder.RSSFEED',"RSS feed of these blogs"));
       }
       
       /**
        * Get the rss feed for this blog holder's entries
        */
       function rss() {
          global $project_name;

          $blogName = $this->Name;
          $altBlogName = $project_name . ' blog';
          
          $entries = $this->Entries(20);

          if($entries) {
             $rss = new RSSFeed($entries, $this->Link(), ($blogName ? $blogName : $altBlogName), "", "Title", "ParsedContent");
             $rss->outputToBrowser();
          }
       }
       
       /**
        * Protection against infinite loops when an RSS widget pointing to this page is added to this page
        */
       function defaultAction($action) {
          if(stristr($_SERVER['HTTP_USER_AGENT'], 'SimplePie')) return $this->rss();
          
          return parent::defaultAction($action);
       }
       
       /**
        * Return the currently viewing tag used in the template as $Tag
        *
        * @return String
        */
       function SelectedTag() {
          return ($this->request->latestParam('Action') == 'tag') ? Convert::raw2xml($this->request->latestParam('ID')) : '';
       }
       
       /**
        * Return the selected date from the blog tree
        *
        * @return Date
        */
       function SelectedDate() {
          if($this->request->latestParam('Action') == 'date') {
             $year = $this->request->latestParam('ID');
             $month = $this->request->latestParam('OtherID');
       
             if(is_numeric($year) && is_numeric($month) && $month < 13) {
                $date = new Date();
                $date->setValue($year .'-'. $month);
                
                return $date;
             }
          }
             
          return false;
       }
    }

          

  • Invader_Zim
    Avatar
    Community Member
    141 Posts

    Re: [SOLVED] Hiding Future Blog Posts (i.e. Scheduling Entries) Link to this post

    Hi Bstarr.

    I am quite sure i totally miss what you are trying to do...
    but if I hit only "Save" and not "Save and Publish" in my Blog, these entries are hidden from the website visitors
    (even if i set the date to the future)...

  • Bstarr
    Avatar
    Community Member
    25 Posts

    Re: [SOLVED] Hiding Future Blog Posts (i.e. Scheduling Entries) Link to this post

    I essentially want to be able to publish blog entries for future dates and have them show up at the published date/time. The equivalent to scheduling posts in Wordpress or Blogger. When I write posts I usually write 5 or 6 at a time which get published over a few weeks. I also schedule Tweets & facebook posts at specific times to promote my blog entries. Currently I'd have to log into my site and publish each entry and post to social media manually. If published entries don't show up until their published date it is automated as it was when I had a WordPress blog. Sorry I wasn't as clear before.

  • Bstarr
    Avatar
    Community Member
    25 Posts

    Re: [SOLVED] Hiding Future Blog Posts (i.e. Scheduling Entries) Link to this post

    Also, this is the post I originally found. But the code he used isn't working for me.
    http://silverstripe.org/blog-module-forum/show/12304#post304970#post304970

  • Invader_Zim
    Avatar
    Community Member
    141 Posts

    Re: [SOLVED] Hiding Future Blog Posts (i.e. Scheduling Entries) Link to this post

    Ahh, ok I see. Sorry for confusing you

    Sad thing is, I think I can't help you on this then.

    But have you seen this module: CMS-Workflow?
    It has this in it's description: "Set embargo and expiry dates for content"... maybe it helps,
    but I have to step back for someone with deeper knowledge.

    Cheers

  • Bstarr
    Avatar
    Community Member
    25 Posts

    Re: [SOLVED] Hiding Future Blog Posts (i.e. Scheduling Entries) Link to this post

    Thanks Invader_Zim, I was not familiar with the CMS Workflow Module, I just installed it and although it adds an extra step in the process it achieves the desired result of being able to schedule my posts. Thanks!

  • mawk
    Avatar
    Community Member
    4 Posts

    Re: [SOLVED] Hiding Future Blog Posts (i.e. Scheduling Entries) Link to this post

    I had a similar issue and found that the problem was with the SS_DateTime::Now() method being used to create the new Zend_Date object in the BlogEntries method.

    Instead of this:

    $d = new Zend_Date(SS_Datetime::now()->getValue());

    I used this:

    $d = Zend_Date::now();

    on a side note I also found that there was an issue with the limit filtering using the LandingPageFreshness value. This value is a drop field on the blog page but it's storing the values incorrectly and they're not being called correctly. First I changed the field values to two digit values. For example "2 MONTH" became "02". Then you'll want to dev/build. Then change the $this->LandingPageFreshness property references to $this->getLandingPageFreshness() method references. The method, as opposed to the property, deals with the INHERIT values by retrieving from the parent class or setting to empty.

    Also in the BlogEntries method you'll want to change:

    $d->sub($this->LandingPageFreshness);

    to:

    $d->sub($this->getLandingPageFreshness(), Zend_Date::MONTH);

    1444 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.