Please upgrade here. These earlier versions are no longer being updated and have security issues.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

DBA Counts, where's the file located?

I'm wondering where I can find the file that stores all of the info for dba counts. I'm wanting to add a new field for it to check and think I can figure it out by looking at the code. I've looked all through the different vanilla folders and can't seem to find it. Can someone point me to where I can find this?

Comments

  • vrijvlindervrijvlinder Papillon-Sauvage MVP

    DBA= database

    That means go into mySQL and search for counts.

  • BleistivtBleistivt Moderator

    https://github.com/vanilla/vanilla/blob/master/applications/dashboard/controllers/class.dbacontroller.php

    But you don't add to it by editing that file. All applications and plugins use event hooks to register their recalculation jobs.

    Usually you would create a method "Counts" on the corresponding model, but you don't need to create one:

    public function dbacontroller_countJobs_handler($sender) {
        $sender->Data['Jobs']['Recalculate MyPluginCounts'] = '/plugin/myplugincounts.json';
    }
    
    public function plugincontroller_myPluginCounts_create($sender) {
        $sender->permission('Garden.Settings.Manage');
    
        // Do the recalculation here
        // Search DBAModel::GetCountSQL for good examples.
    
        $sender->setData('Result', array('Complete' => true));
        $sender->renderData();
    }
    
  • @Bleistivt I searched "DBAModel::GetCountSQL" and found one of my older discussions where you and hgtonight were helping me with the "DiscountDiscussions" plugin. I noticed this post: http://vanillaforums.org/discussion/comment/223611/#Comment_223611

    In this post, hgtonight is giving the structure for what I needed at the time, in 3 parts. It seems that part 3 would be valuable to be here because in this part he is "registering the counts handler on the DBA controller".

    I should mention that the field has already been created and is working, I just need to add it dba/counts. The field is CustomCount, something you've helped me create yourself actually :)

  • R_JR_J Ex-Fanboy Munich Admin

    It doesn't work by adding your field somewhere and it is recreated automatically.
    When /dba/counts is called, it looks for every plugin that hooks into CountJobs and calls that function.

    You have to implement the code bleistivt gave you and create a "count your field and update it in the appropriate tables"-function all by yourself

    "Search DBAModel::GetCountSQL for good examples." meant to look at Vanillas function GetCountSQL in the dbamodel: https://github.com/vanilla/vanilla/blob/2.1/applications/dashboard/models/class.dbamodel.php#L42-96 on how something like that can be done.

  • Oh ok thanks, I got confused there and thought he meant to search here for that.

  • I've been trying to figure this out on my own, but I'm stumped again. I've looked over the GetCountSQL function for examples, but realized I had a great example from the DiscountDiscussions plugin that Bleistivt & hgtonight helped me with. In this plugin I have a model called DiscountDiscussionsModel that recalculates the field "CountComments". The plugin itself also calls the function DBAController_CountJobs_Handler, which is what you referred to here:

    @R_J said:
    When /dba/counts is called, it looks for every plugin that hooks into CountJobs and calls that function.

    Ideally, since it's working here, shouldn't I be able to mimic this by using the same code and modifying it to reflect my DisablePostCount plugin?

    Here's the part of within /plugins/DiscountDiscussions/class.discountdiscussions.plugin.php that has what I need:

     public function PluginController_DiscountDiscussions_Create($Sender, $Column, $UserID) {
            $Count = DiscountDiscussionModel::UserCount($UserID);
    
            $Sender->SetData($Column, $Count);
            $Sender->SetData('_Value', $Count);
            $Sender->SetData('_CssClass', 'Count');
            $Sender->Render('Value', 'Utility', 'Dashboard');
        }
    
        public function DBAController_CountJobs_Handler($Sender) {
            $Sender->Data['Jobs']['Reduce Post Count'] = "/dba/counts.json?"
                .http_build_query(array('table' => 'DiscountDiscussion', 'column' => 'CountComments'));
        }
    

    And here is what is within /plugins/DiscountDiscussions/models/class.discountdiscussionmodel.php:

    <?php if (!defined('APPLICATION')) exit();
    
    class DiscountDiscussionModel extends Gdn_Model {
    
        public function Counts($Column, $From, $To) {
            $ExcludeIDs = explode(',', C('DiscountDiscussions.IDs'));
            $ExcludeIDs = array_filter($ExcludeIDs, 'ctype_digit');
    
            $CountQuery = DBAModel::GetCountSQL('count', 'User', 'Comment', 'CountComments', 'CommentID', 'UserID', 'InsertUserID');
            $AndNotIn = ' and c.DiscussionID not in ('.implode(', ', $ExcludeIDs).')';
            Gdn::Database()->Query(substr($CountQuery, 0, -1) . $AndNotIn . ')');
    
            return array('Complete' => TRUE);
        }
    
        public static function UserCount($UserID) {
            $ExcludeIDs = explode(',', C('DiscountDiscussions.IDs'));
            $ExcludeIDs = array_filter($ExcludeIDs, 'ctype_digit');
    
            $Count = Gdn::SQL()
                ->From('Comment')
                ->Where('InsertUserID', $UserID)
                ->WhereNotIn('DiscussionID', $ExcludeIDs)
                ->GetCount();
    
            Gdn::UserModel()->SetField($UserID, 'CountComments', $Count);
    
            return $Count;
        }
    
    }
    
  • BleistivtBleistivt Moderator

    Ideally, since it's working here, shouldn't I be able to mimic this by using the same code and modifying it to reflect my DisablePostCount plugin?

    What are you trying to do? DisablePostCount sound like it just... disables the post count. So I'm assuming you want to do that.

    In your counts function you would then just set the whole column to zero like that:

    Gdn::sql()->update('User')->set('CountDiscussions', 0)->put();
    
  • @Bleistivt DisablePostCount is the plugin you practically made for me. I named it this at the time because I didn't fully understand what the plugin was actually doing. It is a plugin that creates and manages another field in GDN_User called "CustomCount". Perhaps a better name would be DiscountCustomCount. Anyways, I'm needing to add the ability to update this field by running dba/counts, and since this is already happening in the very similar plugin (also practically made by you), DiscountDiscussions, I thought I could mimic what is happening in there and achieve what I need.

  • SkismaSkisma New
    edited June 2015

    Let me add the code to clarify.

    DiscountDiscussions:

    <?php if (!defined('APPLICATION')) exit();
    
    $PluginInfo['DiscountDiscussions'] = array(
        'Name' => 'DiscountDiscussions',
        'Description' => 'Do not count comments in specified discussions.',
        'Version' => '1.0',
        'Author' => "hgtonight, Skisma, Bleistivt",
        'MobileFriendly' => TRUE,
        'SettingsUrl' => '/settings/discountdiscussions',
        'SettingsPermission' => 'Garden.Settings.Manage'
    );
    
    class DiscountDiscussionsPlugin extends Gdn_Plugin {
    
        public function SettingsController_DiscountDiscussions_Create($Sender) {
            $Sender->Permission('Garden.Settings.Manage');
            $Sender->AddSideMenu('/settings/discountdiscussions');
            $Sender->SetData('Title', 'DiscountDiscussions'.' '.T('Settings'));
    
            $Conf = new ConfigurationModule($Sender);
            $Conf->Initialize(array(
                'DiscountDiscussions.IDs' => array(
                    'Control' => 'textbox',
                    'LabelCode' => 'DiscussionIDs where no comments are counted, comma separated.',
                ))
            );
            $Conf->RenderAll();
        }
    
        public function CommentModel_BeforeNotification_Handler($Sender, $Args) {
            Gdn::UserModel()->SetField($Args['Comment']->InsertUserID, 'CountComments', null);
            DiscountDiscussionModel::UserCount($Sender->EventArguments['Comment']['InsertUserID']);
        }
    
        public function PluginController_DiscountDiscussions_Create($Sender, $Column, $UserID) {
            $Count = DiscountDiscussionModel::UserCount($UserID);
    
            $Sender->SetData($Column, $Count);
            $Sender->SetData('_Value', $Count);
            $Sender->SetData('_CssClass', 'Count');
            $Sender->Render('Value', 'Utility', 'Dashboard');
        }
    
        public function DBAController_CountJobs_Handler($Sender) {
            $Sender->Data['Jobs']['Reduce Post Count'] = "/dba/counts.json?"
                .http_build_query(array('table' => 'DiscountDiscussion', 'column' => 'CountComments'));
        }
    
    }
    
    if (!function_exists('CountString')) {
        function CountString($Number, $Url = '', $Options = array()) {
            $Url = str_replace('/profile/count/comments', '/plugin/discountdiscussions/comment', $Url);
            if (is_string($Options))
                $Options = array('cssclass' => $Options);
            $Options = array_change_key_case($Options);
            $CssClass = GetValue('cssclass', $Options, '');
            if ($Number === NULL && $Url) {
                $CssClass = ConcatSep(' ', $CssClass, 'Popin TinyProgress');
                $Url = htmlspecialchars($Url);
                $Result = "<span class=\"$CssClass\" rel=\"$Url\"></span>";
            } elseif ($Number) {
                $Result = " <span class=\"Count\">$Number</span>";
            } else {
                $Result = '';
            }
            return $Result;
        }
    
    }
    

    DiscountDiscussionModel:

    <?php if (!defined('APPLICATION')) exit();
    
    class DiscountDiscussionModel extends Gdn_Model {
    
        public function Counts($Column, $From, $To) {
            $ExcludeIDs = explode(',', C('DiscountDiscussions.IDs'));
            $ExcludeIDs = array_filter($ExcludeIDs, 'ctype_digit');
    
            $CountQuery = DBAModel::GetCountSQL('count', 'User', 'Comment', 'CountComments', 'CommentID', 'UserID', 'InsertUserID');
            $AndNotIn = ' and c.DiscussionID not in ('.implode(', ', $ExcludeIDs).')';
            Gdn::Database()->Query(substr($CountQuery, 0, -1) . $AndNotIn . ')');
    
            return array('Complete' => TRUE);
        }
    
        public static function UserCount($UserID) {
            $ExcludeIDs = explode(',', C('DiscountDiscussions.IDs'));
            $ExcludeIDs = array_filter($ExcludeIDs, 'ctype_digit');
    
            $Count = Gdn::SQL()
                ->From('Comment')
                ->Where('InsertUserID', $UserID)
                ->WhereNotIn('DiscussionID', $ExcludeIDs)
                ->GetCount();
    
            Gdn::UserModel()->SetField($UserID, 'CountComments', $Count);
    
            return $Count;
        }
    
    }
    

    DisablePostCount:

    <?php if (!defined('APPLICATION')) exit();
    
    $PluginInfo['DisablePostCount'] = array(
        'Name' => 'DisablePostCount',
        'Description' => 'Disables post count in specified discussions.',
        'Version' => '1.0',
        'Author' => "Skisma, Bleistivt",
        'MobileFriendly' => TRUE,
        'SettingsUrl' => '/settings/disablepostcount',
        'SettingsPermission' => 'Garden.Settings.Manage'
    );
    
    class DisablePostCountPlugin extends Gdn_Plugin {
    
        public function SettingsController_DisablePostCount_Create($Sender) {
            $Sender->Permission('Garden.Settings.Manage');
            $Sender->AddSideMenu('/settings/disablepostcount');
            $Sender->SetData('Title', 'DisablePostCount'.' '.T('Settings'));
    
            $Conf = new ConfigurationModule($Sender);
            $Conf->Initialize(array(
                'DisablePostCount.IDs' => array(
                    'Control' => 'textbox',
                    'LabelCode' => 'List the DiscussionIDs you wish to disable post count in, comma separated.',
                ))
            );
            $Conf->RenderAll();
        }
    
        public function Setup() {
            $this->Structure();
        }
    
        public function Structure() {
            GDN::Structure()->Table('User')
            ->Column('CustomCount', 'int(11)', 0)
            ->Set();
        }  
    
         public function PluginController_DisablePostCount_Create($Sender, $Column, $UserID) { //I added this piece in attempt to mimic DiscountDiscussions
            $Count = DisablePostCountsModel::UserCount($UserID);
    
            $Sender->SetData($Column, $Count);
            $Sender->SetData('_Value', $Count);
            $Sender->SetData('_CssClass', 'Count');
            $Sender->Render('Value', 'Utility', 'Dashboard');
        }
    
        public function DBAController_CountJobs_Handler($Sender) {  //I added this piece in attempt to mimic DiscountDiscussions
            $Sender->Data['Jobs']['Reduce CustomCount'] = "/dba/counts.json?"
                .http_build_query(array('table' => 'DisablePostCounts', 'column' => 'CustomCount'));
        } 
    
        public function CommentModel_BeforeNotification_Handler($Sender, $Args) {
    
            Gdn::UserModel()->SetField($Args['Comment']->InsertUserID, 'CustomCount', null); //I added this piece in attempt to mimic DiscountDiscussions
            DisablePostCountsModel::UserCount($Sender->EventArguments['Comment']['InsertUserID']); //I added this piece in attempt to mimic DiscountDiscussions
    
        $ExcludeIDs = array_map('trim', explode(',', C('DisablePostCount.IDs')));
    
    if (!in_array(val('DiscussionID', $Args['Comment']), $ExcludeIDs)) {
    $UserID = val('InsertUserID', $Args['Comment']);
    $Count = Gdn::UserModel()->GetID($UserID)->CustomCount;
    Gdn::UserModel()->SetField($UserID, 'CustomCount', $Count + 1);
    
            }
        }
    
      public function CommentModel_DeleteComment_Handler($Sender, $Args) {
    
        $ExcludeIDs = array_map('trim', explode(',', C('DisablePostCount.IDs')));
    
    if (!in_array(val('DiscussionID', $Args['Comment']), $ExcludeIDs)) {
    $UserID = val('InsertUserID', $Args['Comment']);
    $Count = Gdn::UserModel()->GetID($UserID)->CustomCount;
    Gdn::UserModel()->SetField($UserID, 'CustomCount', $Count - 1);
    
            }
        }
    }
    

    DisablePostCountsModel:

    <?php if (!defined('APPLICATION')) exit(); //I created this entire model in attempt to mimic DiscountDiscussions
    
    class DisablePostCountsModel extends Gdn_Model {
    
        public function Counts($Column, $From, $To) {
            $ExcludeIDs = explode(',', C('DisablePostCount.IDs'));
            $ExcludeIDs = array_filter($ExcludeIDs, 'ctype_digit');
    
            $CountQuery = DBAModel::GetCountSQL('count', 'User', 'Comment', 'CountComments', 'CustomCount', 'CommentID', 'UserID', 'InsertUserID');
            $AndNotIn = ' and c.DiscussionID not in ('.implode(', ', $ExcludeIDs).')';
            Gdn::Database()->Query(substr($CountQuery, 0, -1) . $AndNotIn . ')');
    
            return array('Complete' => TRUE);
        }
    
        public static function UserCount($UserID) {
            $ExcludeIDs = explode(',', C('DisablePostCount.IDs'));
            $ExcludeIDs = array_filter($ExcludeIDs, 'ctype_digit');
    
            $Count = Gdn::SQL()
                ->From('Comment')
                ->Where('InsertUserID', $UserID)
                ->WhereNotIn('DiscussionID', $ExcludeIDs)
                ->GetCount();
    
            Gdn::UserModel()->SetField($UserID, 'CountComments', $Count);
    
            return $Count;
        }
    
    }
    

    I've attempted to run and get this error:

  • BleistivtBleistivt Moderator

    You have too many arguments on line 9, remove the 'CountComments'

  • Wow, this fixed it! Glad I was able to get 99% of this done by simply referencing another plugin, hopefully next time I can get to 100%. Thanks!

Sign In or Register to comment.