HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

solution needed - storing data between events in 2.1 (routines work in 2.0.18 but not 2.1)

In 2.0.18 this would work perfectly well caching the info with the first routine in one event and pulling it back in another event with the second routine.

  • Problem 1

    public function CacheUnread($CountUnreadComments){
    $this->CountUnreadComments=$CountUnreadComments;
    }

    public function GetCacheUnread(){
    return $this->CountUnreadComments;
    }

If I get the answer to this I'll fix an existing plugin


  • Problem 2

In 2.0.18 I could also store an array of variables (but not in 2.1)

via the following in an event in a plugin

$Sender->MyData[DataItem1] = "blahblah"

and then using the following in a view and retrieve the variable.

$thedata = $this->MyData[DataItem1]

I'm just curious what would be the correct way to do this in vanilla 2.1.

I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

Comments

  • businessdadbusinessdad Stealth contributor MVP
    edited May 2013

    The commands are out of context, which makes it more difficult to understand the possible issue, but I think that the first one should work correctly, unless the instance of the class changes between the execution of CacheUnread() and GetCacheUnread(). If the instance changes, $this references two difference instances, which would explain why you don't find the property anymore.

    In the second case, it's possible that some settings used by Vanilla 2.1 doesn't allow to add a new array property like you did (although this is just a speculation). You might try the following:

    // In initialisation
    $Sender->MyData = array()
    
    // Set the data
    $Sender->MyData[DataItem1] = "Badababupi";
    
    // In the view
    $DataItem = $this->MyData[DataItem1];
    
  • peregrineperegrine MVP
    edited May 2013

    thanks @businessdad

    I'll play around some more. If I get nowhere I put things in context better for problem1

    In the second case, it's possible that some settings used by Vanilla 2.1 doesn't allow to add a new array property like you did (although this is just a speculation). You might try the following:

    that is what i was wondering too! I'll experiment.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • hgtonighthgtonight ∞ · New Moderator

    If you are using a different instance, make your class members static that should be shared.

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • businessdadbusinessdad Stealth contributor MVP

    @hgtonight said:
    If you are using a different instance, make your class members static that should be shared.

    It's correct, but I would recommend not to abuse of static methods and properties. It would be better to find out why the same come seems to work in 2.0 and not in 2.1, rather than just trying making properties static. I come from years of multithreaded software and I could tell horror stories about static elements. :)

  • peregrineperegrine MVP
    edited May 2013

    thx for the hints:

    Well, the context is the unread icon plugin as far as issue one.

    I had to change the event since BeforeDiscussion_Handler doesn't exist in 2.1

    CHANGE
    // public function DiscussionController_BeforeDiscussion_Handler($Sender) {

    TO THIS
    public function DiscussionController_BeforeRenderAsset_Handler($Sender) {

    it does look like $lid gets stored but it is null by the time I read it in

    public function DiscussionController_BeforeCommentMeta_Handler($Sender) {

    .....

    snippet of code from plugin.
    
    
     protected $CommmentIdArray = Array();
        protected $lid;
    
        public function CacheUnread($CommmentIdArray) {
            $this->CommmentIdArray = $CommmentIdArray;
        }
    
        public function GetCacheUnread() {
            return $this->CommmentIdArray;
        }
    
        public function CacheLastDid($lid) {
            $this->lid = $lid;
        }
    
        public function GetCacheLastDid() {
            return $this->lid;
        }
    
    

    Maybe i'll wait for more developer documentation as far as #2. or come back to the issues in a few weeks, months or years. It's not that critical for #1 and I don't use my plugin - so it doesn't matter to me. :). Number 2 was an issue for future development of a plugin, but that is not critical either, since i don't need the plugin I was developing either.

    Just wondering if anyone ran across the problem and had a better method. BTW I have static variable in one of my plugins and it works fine (can't remeber where I used it though).

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • peregrineperegrine MVP
    edited May 2013

    @businessdad @hgtonight

    thanks for the answers.

    it seems

    the cache example will work between these two events

          DiscussionController_BeforeCommentMeta_Handler($Sender) { 
    
           DiscussionController_BeforeCommentInfo_Handler($Sender) { 
    

    the problem was I assumed - $this would be the same between

       public function DiscussionController_BeforeRenderAsset_Handler($Sender) {
    
       public function DiscussionController_BeforeCommentMeta_Handler($Sender) { 
    

    Still trying to grok how to Store something in $Sender in version 2.1

    e.g.
       public function DiscussionController_BeforeRenderAsset_Handler($Sender) {  
            $Sender->NewData = array();
            $Sender->NewData[0] = "whereami";
    
    }
    
       public function DiscussionController_BeforeCommentMeta_Handler($Sender) { 
               var_dump($Sender->NewData);
    
    }
    
    

    Fatal Error in DiscussionController.__get();

    someday - it may became apparent.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • peregrineperegrine MVP
    edited May 2013

    solved a different way -
    DiscussionController_BeforeDiscussionOptions_Handler instead of

    DiscussionController_BeforeRenderAsset_Handler($Sender

    You guys were right - "this" was "that" when I thought it was "this". I was Confused by the instance.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • businessdadbusinessdad Stealth contributor MVP

    @peregrine said:
    You guys were right - "this" was "that" when I thought it was "this". I was Confused by the instance.

    It's easy to get confused when this is that and that is this. When this is this and that doesn't do that, but it does this and that, then that is the problem. :)

  • peregrineperegrine MVP
    edited May 2013

    part 2 solved with the getview.

    @businessdad - you were correct in suggestion about initializing before using. I finally tested a condensed version of what I was testing and

    $Sender->MyData= array();
    $Sender->MyData['DataItem1'] = "blahblah"

    // initializing array object is mandatory in vanilla 2.1 (so it seems to me), and obviously is the correct practice or you will get fatal error.

    but it took me a while with @shadowdare (thanks) to ask me questions to focus me on dumping variables to focus my test to a workable one to isolate issue.

    exactly what was needed:

    http://vanillaforums.org/discussion/comment/183443/#Comment_183443

    RULE 1 = initialize first. You can see lots of warning messages in many many plugins (including my own) where variables, etc are not initialized first. Vanilla 2.1 is stricter and that is a good thing. and in some case causes fatal errors, not just warnings.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • businessdadbusinessdad Stealth contributor MVP

    @peregrine I'm happy to hear that you fixed the issue. Generally speaking, it's always better to initialise variables before using them. The issue doesn't apply to primitives, since by doing $something = 'xyz' you are effectively initialising it. Arrays, on the other hand, are "containers" and should be initialised as empty before using them.

    Why does it work anyway, sometimes?

    Very simply, because PHP is broken by design (warning, very long post). Depending on the error level set in the configuration, it may go ahead in ambiguous conditions, with all the resulting quirks.

    In my experience, I've seen a large percentage of PHP developers ignoring the above and just "putting things together" as quickly as possible, relying on the fact that PHP is "tolerant". However, as soon as you turn on Notices and Warnings, you see hundreds of messages in websites, which should not be there.

    Dirty approach, which (unfortunately) works anyway
    Disclaimer: I also made this mistake, in the past.

    $MyData = $PDO->exec('SELECT ...', FETCH_ASSOC); // This should return an array, or FALSE if an error occurs
    
    // If $MyData is FALSE, the cycle won't be executed, but a warning is raised. 
    // If E_STRICT error checking is enabled, the execution is halted.
    foreach($MyData as $Row) {
      // Do something
    }
    

    Proper approach

    $MyData = $PDO->exec('SELECT ...', FETCH_ASSOC); // This should return an array, or FALSE if an error occurs
    
    if(is_array($MyData)) { // Check that we actually have some data
      foreach($MyData as $Row) {
        // Do something
      }
    }
    

    My suggestion

    Develop everything in an environment where error level is set to E_ALL. If you want to be picky, also enable E_STRICT (it can be a bit "anal", sometimes). This will throw out all sorts of errors, unless you are absolutely neat while coding. At the beginning it can be a pain to remove all the warnings and notices, but take it as a lesson: you are just cleaning up after yourself. A bit like tidying up the house after ignoring it for a month. Once you are done, you will only have to tackle the odd message here and there.

Sign In or Register to comment.