PHP Classes

File: src/Webfan/Homepagesystem/EventFlow/StateVM.php

Recommend this page to a friend!
  Classes of Till Wehowski   Lazy PHP Event Handler   src/Webfan/Homepagesystem/EventFlow/StateVM.php   Download  
File: src/Webfan/Homepagesystem/EventFlow/StateVM.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Lazy PHP Event Handler
Register event handlers to be loaded dynamically
Author: By
Last change:
Date: 2 years ago
Size: 10,007 bytes
 

Contents

Class file image Download
<?php
/**
 *
 * Copyright (c) 2017, Till Wehowski
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 * must display the following acknowledgement:
 * This product includes software developed by the frdl/webfan.
 * 4. Neither the name of frdl/webfan nor the
 * names of its contributors may be used to endorse or promote products
 * derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY frdl/webfan ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL frdl/webfan BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
 /**
 * EventEmitter javascript like event based final state object :
 * https://github.com/frdl/-Flow/blob/master/api-d/4/js-api/library.js/core/plugin.core.js#L4501
 */
namespace Webfan\Homepagesystem\EventFlow;


use
webfan\hps\Event as Event;



class
StateVM extends State implements \Serializable
{
   
  const
K = '^';
   
  protected
$SecretSigningKey = null;
  public
$serializeClosures = true;
// protected $tagName = __CLASS__;
   
   
   
 
public function on($event, $callback, $obj = null, &$index = null) {
    if (!isset(
$this->events[$event])) {
     
$this->events[$event] = [];
    }
     
     
     if(
null===$index){
   
// $bin = new \frdl\webfan\Serialize\Binary\bin;
        //$index = $bin->serialize($cb);
       
$index = $this->_genKey($callback);
    }
     
     
      if(
$obj === null){
          if(
true===$this->serializeClosures){
          
$serializer = (null=== $this->SecretSigningKey) ? new \SuperClosure\Serializer() : new \SuperClosure\Serializer(null, $this->SecretSigningKey);
          
$cb = $serializer->serialize($callback);
          }else{
              
$cb = $callback;
          }
       
      }else{
       
$cb = [$obj, $callback];
      }
   

  
$this->events[$event][$index] = $cb;
    
// $this->events[$event][] = $cb;
   
return $this;
  }
     

 public function
trigger($eventName, $data = [], Event &$event = null) {
     if (!isset(
$this->events[$eventName])) return $this;
  
 
   
$indexOf=0;
    foreach (
$this->Iterator('Array', $this->events[$eventName]) as $callback) {
         
$payload = array();
     
         
$target = &$this;
         
$evData = &$data;
          
array_push($payload, $eventName);
          
array_push($payload, $target);
        
array_push($payload, $evData);
       
    if(
null===$event){
        if(!
is_object($data) || true !== $data instanceof Event){
         
$event = new Event($eventName);
        }elseif(
true === $data instanceof Event){
          
$event = &$data;
        }
    }
       
       
    if(!
is_object($data) || true !== $data instanceof Event){
        
$payload[] = &$event;
    }
       
       
        if(
is_string($callback)){
            
$serializer = (null=== $this->SecretSigningKey) ? new \SuperClosure\Serializer() : new \SuperClosure\Serializer(null, $this->SecretSigningKey);
            
$callback = $serializer->unserialize($callback);
        }
       
         if(!
is_callable($callback)){
           
trigger_error('Cannot trigger Event '.$eventName.' on Listener #'.$indexOf, E_USER_WARNING);
            continue;
        }
   
// if(frdl\run($callback, $payload) === false) break;
     
if(false === call_user_func_array($callback, $payload))break;
               
        if(
$event->isDefaultPrevented()){
           
$event->setResult(null);
            break;
        }
       
           
        if(
$event->isPropagationStopped()){
            break;
        }
       
     
$indexOf++;
    }
    return
$this;
 }
   
   
   
     public function
once($event, $callback, $obj = null) {
        
$THAT = $this;
     
$k = $this->_genKey($callback);
        
$callback= ($obj === null) ? $callback : [$obj, $callback];
        
     
$serializer = (null=== $this->SecretSigningKey) ? new \SuperClosure\Serializer() : new \SuperClosure\Serializer(null, $this->SecretSigningKey);
     
$cb = (is_callable($callback)) ? $serializer->serialize($callback) : $callback;
    
   
// $bin = new \frdl\webfan\Serialize\Binary\bin;
   
    // $k = $bin->serialize( $cb );
   
        
        
      
$func =function($event, $THAT, $data) use($cb, $k){
           
$callback = unserialize($cb);
             
         
// $THAT->removeEventListener($event, $fn);
            // unset($THAT->events[$event][$k]);
          // $THAT->removeEventListener($event, $k);
           
$events = $THAT->getEvents();
             unset(
$events[$event][$k]);
          
$THAT->setEvents($events);
          
                      
           
$res = call_user_func_array($callback, func_get_args());
       
          return
$res;
         };
        
      
$this->on($event, $func, null, $k);
             
    return
$this;
  }
 
   
   
  protected function
_genKey($cb){
     
$serializer = (null=== $this->SecretSigningKey) ? new \SuperClosure\Serializer() : new \SuperClosure\Serializer(null, $this->SecretSigningKey);
     
$cb = (is_callable($cb)) ? $serializer->serialize($cb) : $cb;
     
     
$bin = new \frdl\webfan\Serialize\Binary\bin;
     
$d = $bin->serialize( $cb );
     
$k = sha1($d).strlen($d);
     
      return
$k;
  }
   
   
  public function
removeEventListener($event, $callback, $obj = null){
     if (!isset(
$this->events[$event])) return $this;
     
     
$events = $this->events;
     
      
$listener = ($obj === null) ? $callback : array($obj, $callback);
     
     
$serializer = (null=== $this->SecretSigningKey) ? new \SuperClosure\Serializer() : new \SuperClosure\Serializer(null, $this->SecretSigningKey);
     
$bin = new \frdl\webfan\Serialize\Binary\bin;
     
// $sl =(is_callable( $listener )) ? $bin->serialize($serializer->serialize($listener)) : $bin->serialize($listener);
     
$sl =(is_callable( $listener )) ? $serializer->serialize($listener) : $listener;
     

 
// $indexOf = 0;
   
     
 // foreach ($this->Iterator('Array', $events[$event]) as $indexOf => $EventListener) {
     
foreach ($events[$event] as $indexOf => $EventListener) {
       
/*
        if(is_string($listener)&& !is_array($EventListener) && !is_string($EventListener) ){
           
             $EventListener = $serializer->serialize($EventListener);
        }
        */
           
      
if($EventListener ===$sl || $EventListener === $bin->serialize($sl) || $EventListener === $listener
          
|| $indexOf === $listener
          
|| $indexOf === $sl
          
|| $indexOf === $this->_genKey($callback)
         ) {
      
// array_splice($this->events[$event], $indexOf, 0);
          
unset($events[$event][$indexOf]);
        
           
          
           if(
0===count($events[$event]))unset($events[$event]);
      
        
// $indexOf--;
      
}
       
// $indexOf++;
   
}
 
      
$this->events=$events;

    return
$this;
  }
   
   
   
    public function
setSecretSigningKey($key){
        
$this->SecretSigningKey = $key;
        return
$this;
    }
   
    public function
getEvents(){
            return
$this->events;
    }
   
    public function
test(){
           echo
'<pre>test; '.__METHOD__.'</pre>';
        return
$this;
    }
   
    public function
setEvents($events){
           
$this->events = $events;
        return
$this;
    }
   
   
   

    public function
serialize() {
 
// echo "Serializing MyClass...\n";
    // return serialize($this->data);
       
$events = $this->events;
        foreach(
$events as $name => $listeners){
           foreach(
$listeners as $index => $listener){
               if(
is_array($listener) ){
                  
$list=$listener;
                  
$l = function() use($list){
                     return
call_user_func_array($list, func_get_args());
                   };
                  
                  
$serializer = (null=== $this->SecretSigningKey) ? new \SuperClosure\Serializer() : new \SuperClosure\Serializer(null, $this->SecretSigningKey);
                  
$events[$name][$index] = $serializer->serialize($l);
               } elseif( !
is_string($listener) ){
                  
$serializer = (null=== $this->SecretSigningKey) ? new \SuperClosure\Serializer() : new \SuperClosure\Serializer(null, $this->SecretSigningKey);
                  
$events[$name][$index] = $serializer->serialize($listener);
              } else {
                  
                   
$events[$name][$index] = $listener;
               }
           }
        }
       
       
$context = $this->_context;
       
       
$context = serialize($context);
       
       
       
$data = array(
           
'events' => $this->events,
           
//'tagName' => $this->tagName,
           
'name' => $this->name,
           
'context' => $context
       
);
       
       
$bin = new \frdl\webfan\Serialize\Binary\bin;
        return
$bin->serialize($data);
    }
  
   
    public function
unserialize($data) {
    
// echo "Unserializing MyClass...\n";
     // $this->data = unserialize($data);
       
$bin = new \frdl\webfan\Serialize\Binary\bin;
       
$data = $bin->unserialize($data);
       
       
$data['context'] = unserialize($data['context']);
       
       
$this->_context=$data['context'];
       
       
$this->name = $data['name'];
       
       
       
//print_r($data['events']);die();
       
       
foreach($data['events'] as $name => $listeners){
           foreach(
$listeners as $index => $listener){
               if( !
is_string($listener) && !is_array($listener) ){
                  
$serializer = (null=== $this->SecretSigningKey) ? new \SuperClosure\Serializer() : new \SuperClosure\Serializer(null, $this->SecretSigningKey);
                  
$data['events'][$name][$index] = $serializer->unserialize($listener);
                  
              }
           }
        }
       
       
$this->setEvents($data['events']);
       
         
//if( $this->tagName !== $data['tagName']){
           //warning ???
          //}
       
       
       
   
}
   

}