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.

override model method

naquadaqnaquadaq New
edited May 2012 in Vanilla 2.0 - 2.8

Hi,
I want to modify some methods of CategoriesModel in my plugin and I haven't been able to override them. I have override the assocciate caller controller methods but I have seen there are several places where there is a call to the model methods and it is easy to miss any of them. Even to maintain. Is there a way of make this change easy?

Thanks in advance.

Answers

  • very rarely is there cause to do this. I'm naturally a sceptical there is a need. what are you trying to do?

    You could

    • extend the model class and use it appropriately
    • use model hooks
    • query separately
    • request more hooks and state your reasoning

    grep is your friend.

  • I need a modification for my business for the queries to get categories and discussions filter by what we call domainId, which is store in the session. I want to put all this modifications in my new plugin. In fact, I have extended the model with new methods with the modified queries. The problem is that. The controllers that are using this models used the original method name and I want to use the new one. In order to force this I have overriden the controller methods but I'm sure in missing other calls to the model. In addition, there are methods in controllers that cannot be overriden. Let me show you and example:

    method All of CategoriesController call to $CategoryModel->GetFull()
    I want it to call CategoryModel->GetFullByDomain()

    With categories, I want, as well, to update the permission table when a category is created.
    My only solution is to overwrite the save method of the model.

    The same thing with discussions. I have seen that $DiscussionModel->Get() is called from several controllers (p.e I have overriden the DiscussionsController Index method) and places.

    How can achive this from my plugin?

  • Have a look for hooks in the core you should see FireEvent and EventArguments and you can use hooks like so

    public function CategoryModel_AfterGetFullQuery_Handler($Sender){
       if([some condition])
           $Sender->SQL->Where('d.DomainID',$DomainID);
    }
    
    public function CategoryModel_BeforeSaveCategory_Handler($Sender,$Args){
         var_dump($Args['CategoryID']);
    }
    
    public function DiscussionModel_BeforeSaveDiscussion_Handler($Sender){
    
    }
    
    public function DiscussionModel_BeforeGet_Handler($Sender){
    
    }
    

    this is just general pointer in the right direction you need to use your initiative. hope that helps

    grep is your friend.

  • naquadaqnaquadaq New
    edited May 2012

    Thank you very much x00. Now, I'm modifying the CategoryModel_BeforeSaveCategory_Handler. The thing is that I have added a new column in the category table within the plugin like this:

      public function Setup() {
           Gdn::Structure()
            ->Table('Category')
            ->Column('DomainID','int(11)',NULL)
            ->Set();
      }
    

    Now I'm hooking to the BeforeSaveCategory_Handler to add this new field informed as well.

         $myprefs=Gdn::Session()->GetPreference('prefs');
         $argsByRef=$sender->EventArguments['FormPostValues'];
    
         $argsByRef=array_merge($argsByRef, array('DomainId'=>$myprefs['DomainId']));
         $sender->EventArguments['FormPostValues']=&$argsByRef;
    

    trying to add the new field to the FormPostValues array to save it as well but when I check the array in the CategoryModel after:

    $this->FireEvent('BeforeSaveCategory');

    The array does not contain the new element. Do you now if it is possible to do it? how?

  • naquadaqnaquadaq New
    edited May 2012

    For the moment, I have solved the problem by hooking to the controller:

       public function SettingsController_AddEditCategory_Handler($sender)
       {
        $myprefs=Gdn::Session()->GetPreference('prefs');
        $sender->Form->AddHidden('DomainID', $myprefs['DomainID']);
       }
    

    But I still have the necessity to do it with the model for the case of discussions due to I call the save method in my own plugin code and I would like to intercept the discussion save at the point of:

            $this->EventArguments['FormPostValues'] = &$FormPostValues;
            $this->EventArguments['DiscussionID'] = $DiscussionID;
            $this->FireEvent('BeforeSaveDiscussion');
    
  • Ah ok this is simple

    public function CategoryModel_BeforeSaveCategory_Handler($Sender,&$Args){
        $Post=&$Args['FormPostValues'];
        .....
        $Post['DomainID']=$myprefs['DomainID'];
    }

    grep is your friend.

  • If you think of event argument as supplying the hook with object data. They are one way, but if you pass by reference you can affect the underling objects. Arrays are not passed by reference unless you use &

    grep is your friend.

  • Thanks x00. It did the trick.

Sign In or Register to comment.