Jump to:

3430 Posts in 1057 Topics by 734 members

Data Model Questions

SilverStripe Forums » Data Model Questions » Selecting One DataObject Every Two Weeks

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

Page: 1
Go to End
Author Topic: 1158 Views
  • taligent
    Avatar
    Community Member
    18 Posts

    Selecting One DataObject Every Two Weeks Link to this post

    I've created a table for Book Excerpts on my site using two classes. BookExcerpt and BookExcerptPage. They are very simple classes. However, now I want to ensure that every 14 days a new excerpt will be listed in the content area of my site. So I added a NextChangeDate field to my page so that every time the page is accessed, the page will check today's date and if it is equal to the NextChangeDate, the next article will be displayed. For this to happen, I need to update the change date field by adding 14 days to it. That shouldn't be a problem. My problem right now is how to query the excerpt table by ID and when there are no further records grab the first record in the table and start the article loop over. Any thoughts on how to do that would be great. I'm a little stumped on that part.

    I've enclosed my BookExcerpt classes in case it is easier to respond by looking at the classes.

    <?php
    class BookExcerpt extends DataObject {
    static $db = array(
    'Sequence' => 'Int',
    'Pages' => 'Text',
    'Title' => 'Text',
    'Quote' => 'Text',
    'Excerpt' => 'Text'
    );

    // Each excerpt exists in one and only one category.
    static $has_one = array(
    'BookExcerptPage' => 'BookExcerptPage'
    );

    static $singular_name = 'Book Excerpt';
    static $plural_name = 'Book Excerpts';

    function getCMSFields() {
    $fields = new FieldSet(
    new NumericField('Sequence', 'Display Sequence'),
    new TextField('Pages', 'Quoted From Page(s)'),
    new TextField('Title', 'Excerpt Title'),
    new TextField('Quote', 'Chapter Quote'),
    new TextareaField('Excerpt', 'Book Excerpt')
    );

    return $fields;
    }
    }
    ?>

    <?php
    class BookExcerptPage extends SendPage {
    //Each BookExcerpt can have multiple excerpts.
    static $has_many = array(
    'BookExcerpt' => 'BookExcerpt'
    );

    static $singular_name = 'Book Excerpt Page';
    static $plural_name = 'Book Excerpt Pages';

    function getCMSFields() {
    $fields = parent::getCMSFields();
    $fields->renameField("Content", "Common Text - Copyright,Order Link, etc...");
    $excerptsTable = new ComplexTableField($this, 'BookExcerpts', 'BookExcerpt', array('Sequence'=>'Display Sequence', 'Title'=>'Title', 'Excerpt'=>'Excerpt'));
    $fields->addFieldToTab('Root.Content.BookExcerpts', $excerptsTable);
    $fields->addFieldToTab('Root.Content.Main', new NumericField('ChangeFrequency', 'Number of Days to Display Article'), 'Content');
    $fields->addFieldToTab('Root.Content.Main', new NumericField('CurrentArticle', 'Article Currently Displayed'), 'Content');
    $fields->addFieldToTab('Root.Content.Main', new CalendarDateField('ChangeDate', 'Next Date to Change the Article'), 'Content');
    return $fields;
    }
    }

    class BookExcerptPage_Controller extends Page_Controller {

    }

  • MarijnKampf
    Avatar
    Community Member
    164 Posts

    Re: Selecting One DataObject Every Two Weeks Link to this post

    I haven't tested this but I would use the MySQL random function to select a random book. You can seed the random function with a number that changes every week. Then get a dataobject for your bookexcerpt.

    class BookExcerptPage_Controller extends Page_Controller {
    function RandomContent() {
    $week = (int)date('YW', $date); // Create seed for rand that changes each week
    return DataObject::get_one("BookExcerpt",null, false, "RAND(" . $week . ")");
    }
    }

    The only drawback is if you add/remove bookexcerpts you'll get a new random number.

  • taligent
    Avatar
    Community Member
    18 Posts

    Re: Selecting One DataObject Every Two Weeks Link to this post

    Thanks for the info, but its not quite what I am looking for. I need a sequential return of an excerpt. I have the following code, but keep getting an error indicating that the function InFuture() does not exist on class date. I don't understand why and my knowledge of php is a bit sketchy, although growing. Here is what I currently have. How would I access the ChangeDate variable from my page as a Date class so that I can check InFuture() on it?

    Here is my BookExcerptPage Class

    <?php
    class BookExcerptPage extends SendPage {
    static $db = array(
    'ChangeFrequency' => 'Int',
    'CurrentArticle' => 'Int',
    'ChangeDate' => 'Date'
    );
    //Each BookExcerpt can have multiple excerpts.
    static $has_many = array(
    'BookExcerpt' => 'BookExcerpt'
    );

    static $singular_name = 'Book Excerpt Page';
    static $plural_name = 'Book Excerpt Pages';

    function getCMSFields() {
    $fields = parent::getCMSFields();
    $fields->renameField("Content", "Common Text - Copyright,Order Link, etc...");
    $excerptsTable = new ComplexTableField($this, 'BookExcerpts', 'BookExcerpt', array('Sequence'=>'Display Sequence', 'Title'=>'Title', 'Excerpt'=>'Excerpt'), "", "", "Sequence ASC");
    $fields->addFieldToTab('Root.Content.BookExcerpts', $excerptsTable);
    $fields->addFieldToTab('Root.Content.Main', new NumericField('ChangeFrequency', 'Number of Days to Display Article'), 'Content');
    $fields->addFieldToTab('Root.Content.Main', new NumericField('CurrentArticle', 'Article Currently Displayed'), 'Content');
    $fields->addFieldToTab('Root.Content.Main', new CalendarDateField('ChangeDate', 'Next Date to Change the Article'), 'Content');
    return $fields;
    }
    }

    class BookExcerptPage_Controller extends Page_Controller {
    public function nextExcerpt() {
    $be = DataObject::get_one("BookExcerpt", "Sequence > $this->CurrentArticle");
    if($be) {
    return $be;
    } else {
    $be = DataObject::get_one("BookExcerpt", "Sequence > 0");
    if($be) {
    return $be;
    } else {
    return false;
    }
    }
    }

    public function currentExcerpt() {
    $curChangeDate = new Date();
    $curChangeDate->setValue($this->ChangeDate);

    if ($curChangeDate->InFuture() == false) {
    return nextExcerpt();
    }

    $be = DataObject::get_one('BookExcerpt', "Sequence = $this->CurrentArticle");
    if($be) {
    return $be;
    } else {
    return false;
    }
    }
    }

    And here is my template code

    <% if currentExcerpt %>
    <p>$currentExcerpt.Title</p>
    <p>$currentExcerpt.Quote</p>
    <p>$currentExcerpt.Excerpt</p>
    <% end_if %>

  • MarijnKampf
    Avatar
    Community Member
    164 Posts

    Re: Selecting One DataObject Every Two Weeks Link to this post

    Why don't you use $this->ChangeDate->InFuture() ?

  • taligent
    Avatar
    Community Member
    18 Posts

    Re: Selecting One DataObject Every Two Weeks Link to this post

    This is where my shaky knowledge of SS and php is not sufficient. I've tried that and get the following error:

    Fatal error: Call to a member function InFuture() on a non-object in C:\Users\dan\Sync\SilverStripe\send\code\BookExcerptPage.php on line 48

    I think I am missing a definition somewhere in my code, but can't find it. To me it appears that it is grabbing the database field rather than wrapping it in an object, but I don't know why...

  • taligent
    Avatar
    Community Member
    18 Posts

    Re: Selecting One DataObject Every Two Weeks Link to this post

    I still don't know why $this-ChangeDate->InFuture() does not work. However I got the code to work with the following exerpt:

    public function currentExcerpt() {
    $curChangeDate = new Date();
    $curChangeDate->setValue($this->ChangeDate);

    if ($curChangeDate->InFuture() == false) {
    return $this->nextExcerpt();
    }

    $be = DataObject::get_one('BookExcerpt', "Sequence = $this->CurrentArticle");
    if($be) {
    return $be;
    } else {
    return false;
    }
    }

    Can someone say why $this-ChangeDate->InFuture() does not work? I am a bit confused on that point.

    1158 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.