Users running a non-download version of Vanilla (pulled from github), on branch release/2019.016 or master from the last 2 weeks should upgrade to release/2019.017 or latest master for security reasons. Downloaded official open sources releases are not affected.

Ability to show discussion between a certain date?

I want to show a filtered view basically of the discussion page that shows exactly like each discussion does on the discussion page.

So go to the database get all the discussion that fall between this and that date for a certain field. And output them exactly like on the discussion page.

Comments

  • rbrahmsonrbrahmson "You may say I'm a dreamer / But I'm not the only one" NY ✭✭✭

    are you answering your own question?

    Look at the filterdiscussion plugin and the lengthy comment at the top of the source - tells you how to do it with the plugin. Then you can just use the code if you need this inside your own plugin;-)

    MrCaspan
  • phreakphreak Vanilla*APP (White Label) & Vanilla*Skins Shop MVP

    We have a free plugin which separates the list view by dates.

    Would that be a first step to gain a better UX of the discussion view?

    https://vanillaskins.com/plugins.html#dateSeperator

    • VanillaAPP | iOS & Android App for Vanilla - White label app for Vanilla Forums OS
    • VanillaSkins | Plugins, Themes, Graphics and Custom Development for Vanilla
  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    @rbrahmson : clever! I would have mimiced the controller logic and reused only the view, but your approach is much more robust, future proof and requires less code.


    Since @MrCaspan doesn't need a flexible solution as you needed in your plugin, Vanillas "new" filters maybe better suited than hooking into the model:


       public function discussionsController_abracadabra_create($sender, $args) {
           // e.g. 2020-02-28 & 2020-02-21
           $today = DateTimeFormatter::timeStampToDate(time());
           $lastWeek = DateTimeFormatter::timeStampToDate(strtotime("{$today} - 1 week"));
    
           // Define some filters.
           $filter = [
               // yourforum.com/discussions/abracadabra?filter=new-events
               'new-events' => [
                   'name' => Gdn::translate('New Events'),
                   'wheres' => [
                       'd.DateInserted >=' => $lastWeek,
                       'd.DateInserted <=' => $today
                   ]
               ],
               // yourforum.com/discussions/abracadabra?filter=upcoming-events
               'upcoming-events' => [
                   'name' => Gdn::translate('Upcoming Events'),
                   'wheres' => [
                       'd.EventCalendarDate >=' => $lastWeek,
                       'd.EventCalendarDate <=' => $today
                   ]
               ]
           ];
           // Add filters to DiscussionModel.
           $discussionModel = GDN::getContainer()->get(DiscussionModel::class);
           foreach ($filter as $key => $value) {
               $discussionModel->addFilter($key, $value['name'], $value['wheres']);
           }
    
           // Only set individual title if filter applies
           $currentFilter = $sender->Request->get('filter');
           if ($filter[$currentFilter]['name'] ?? false) {
               $sender->title($filter[$currentFilter]['name']);
           }
           // Re-use vanillas default "Recent Discussions" view.
           $sender->View = 'index';
           $sender->index($args);
       }
    


    Maybe naming the method "discussionsController_events_create()" and the filters only "new" and "upcoming" would end up in less surprisingly urls... 😀


    MrCaspanrbrahmson
  • MrCaspanMrCaspan New
    edited February 28

    Yeah basically i want to use the discussion view set by the forum, i just want to filter the dates it shows and show it on my day view of the Events calendar.

    Thanks for all the code and help guys. Ill dig into this today and see what I can do!

    EDIT @R_J This looks like exactly what i am looking for thank you!

  • MrCaspanMrCaspan New
    edited February 28

    So @R_J if I have 3 different views for the EventsPage Year, Month, Day. If the user hits http://forum.com/EventsCalendar/2002 to will go to the year view, http://forum.com/EventsCalendar/2002/02 will go to the month view and http://forum.com/EventsCalendar/2002/02/28 will go to the day view.

    So I don't want to render out the entire view for discussion as I have my own header that I use on the EventsCalender day view but just use the same format that the discussions are formated in but in my day view.. To use literal words

    • Print my control header
    • Take the arguments passed to me on the date to look up IE 2020-02-28 event sin the database that match this
    • Print out using the same format as the discussion page any results found


  • MrCaspanMrCaspan New
    edited March 1

    So i am confused. Should I be calling the discussions view and then filtering it for my Day view. Or should I be doing my own query to the Database and then asking it to use the discussions view to render it.. I am still a bit lost on how I should achieve this. Sorry to bug I'm trying to look at the documentation and other examples but still spinning around my head!

  • This is how I believe it should be done:

    I have a function called  "public function vanillaController_eventCalendar_create($sender, $args = []) {}" this is where I set all my code based on if the user is looking at the Year, Month, Day. If the user is looking at https://forumURL/EventCalendar/2002/02/28 then I render the day.php as they are looking at the day view. So in my vanillaController_eventCalendar_create() function I would need to query the database for the events on the day passed in the argument[2] and then use the discussions view to render out each discussion on that day.

  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    Correct. The method where month or week information is fetched from db should be extended to fetch day information. You have a view for month and week, now you need to add one for day.

    The discussions view that you see in Recent Discussions is made up of several parts. Look at applications\vanilla\views\discussions\index.php

    It includes the "helper_functions.php" from the same folder and in that helper functions are small bits like "writeDiscussion". You can try to read that index.php and fetch only what you need for your day view from the helper functions.

    That might work, but maybe the CSS rules will not apply to your page. You would have to test that.


  • okay thanks!

  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    by the way: the code will become much cleaner if you make vanillaController_eventCalendar_create() a dispatcher and route it to some dedicated calendarDay, calendarMonth, calendarWeek methods.


  • Thanks @R_J I will clean it up once i am done as right now i am doing it all in a case statement in that function. I will break it out after for now I want to just get this code running and also understand it :)

    This is the code i have in the day view

    <?php if (!defined('APPLICATION')) exit();
    
    // This will load in the writeDiscussion helper
    include_once $this->fetchViewLocation('helper_functions', 'discussions', 'vanilla');
    
    // Loop around or data and print out each result
    foreach ($this->DiscussionData->result() as $Discussion) {
      writeDiscussion($Discussion, $this, $Session);
    }
    
    ?>
    
    
    

    It would just seem that I need to populate the DiscussionData object with data from the database? I am not sure how I would do that

  • NM i think i got it I created this function and passed it a date object, and it returned a SQL Result Object

        public function getDay(object $Date) {
    
    
            $sql = Gdn::sql();
            $sql->select('*')
    			->Distinct()
                ->from('Discussion')
                ->where('EventCalendarDate =', $Date->format('Y-m-d'))
                ->orderBy('EventCalendarDate');
    
    
            // add permission restrictions if necessary 
            $perms = DiscussionModel::categoryPermissions();
            if ($perms !== true) {
                $sql->whereIn('CategoryID', $perms);
            }
    
    
            // return $Sql->GetSelect();
            return $sql->get();
       }
    

    I then passed this SQLResult Object to my day.php and looped around it using the writeDiscussion() function.... I just spit out my data :) now i just need to make it look like the rest of the discussion views. I think I just need to load the CSS file

  • MrCaspanMrCaspan New
    edited March 2

    Wow this is so confusing to me.. LOL Okay so I think I got what i need from the database and I apply it against the Discussion view and I spit all my data out... It looks great one problem... all the links are messed up

    If i hover over the links for the forum posts it seems that they all are referencing the page i am on and not the actual pages all the other links are good. If you look at the screenshot all the links in Green work but the main link (in red) just adds #latest to the current page URL! Should I be passing a variable that it is missing to this location?



  • It would seem that this code is it in table_functions();

     $discussionUrl = $discussion->Url;
        if ($session->UserID) {
          $discussionUrl .= '#latest';
        }
    

    After I am doing my SQL query would I have to build this Url parameter for each Discussion?

  • Seems there is a calculate function in class.dicussionmodel.php

    it does some setting of data in there...


        // Fix up output
        $discussion->Name = htmlspecialchars($discussion->Name);
        $discussion->Attributes = dbdecode($discussion->Attributes);
        $discussion->Url = discussionUrl($discussion);
        $discussion->CanonicalUrl = $discussion->Attributes['CanonicalUrl'] ?? $discussion->Url;
        $discussion->Tags = $this->formatTags($discussion->Tags);
    
  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    If you re-use the discussions view, that piece of code should be responsible for the link:


       function writeDiscussion($discussion, $sender, $session) {
           $cssClass = cssClass($discussion);
           $discussionUrl = $discussion->Url;
    ...
               <div class="ItemContent Discussion">
                   <div class="Title" role="heading" aria-level="3">
                       <?php
                       echo adminCheck($discussion, ['', ' ']).anchor($discussionName, $discussionUrl);
                       $sender->fireEvent('AfterDiscussionTitle');
                       ?>
                   </div>
    
    

    You can forget about the "#latest", it just redirects a logged in user to the first unread comment. Not sure about your code, but you might want to check that the object you pass in (the dataset) has a correct Url property.


  • MrCaspanMrCaspan New
    edited March 3

    Yeah I am reusing the discussion view but in Table format and I want the day view to follow that view option. I think I have it now and I can build this URL for it and pass it to the method/function... I am once done I am going to post the Plugin so that people can pull it apart and tell me what I did wrong LOL Or help improve it... that's how I believe the forum works :)

    This is my first venture into Method based programming and object oriented programming in PHP. I can pick stuff up quick and I feel like I am getting the handle of this but the documentation would help a lot to know what methods are exposed or how to load them into your plugin! I love the way Vanilla works!

Sign In or Register to comment.