PHP Classes

File: src/Webfan/App/EventModule.php

Recommend this page to a friend!
  Classes of Till Wehowski   Lazy PHP Event Handler   src/Webfan/App/EventModule.php   Download  
File: src/Webfan/App/EventModule.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: 5,523 bytes
 

Contents

Class file image Download
<?php
/*
 Copyright (c) 2019 Webfan Homepagesystem MIT License
 https://raw.githubusercontent.com/webfan3/hps/master/LICENSE
*/
namespace Webfan\App;
use
webfan\hps\Event;
use
Webfan\Homepagesystem\EventFlow\StateVM;
class
EventModule
{

   
    const
MODEL = StateVM::class;
    protected
$action;
    protected static
$emitters = [];
    protected
$emitter = null;
    protected
$mark;
   
    protected
$dirCompiled;
    protected static
$dirBase = 'compiled.events';
   
    public static function
setBaseDir($dirBase){
        if(!
is_dir($dirBase) || !is_writable($dirBase)){
          throw new \
Exception('Cannot apply baseDir in '.__METHOD__);
        }
       
self::$dirBase = $dirBase;
    }
   
    public static function
action($action, $reload = false, $dirBase = null){
        return new
self($action, $reload, $dirBase);
    }
   
    public function
__construct( $action, $reload = false, $dirBase = null){
        if(
is_string($dirBase) && is_dir($dirBase)){
          
self::setBaseDir($dirBase);
        }
       
       
$action = trim($action, '\\/ ');
   
// $pathes = explode('\\', $action);
       
$pathes = preg_split("/[\\\@\:\s\.\/]/", $action);
       
$ft = str_replace('\\', '_', substr($action, 0,1));
        if(
strlen($action) > 4){
           
$ft.= \DIRECTORY_SEPARATOR. substr($action, 0,5);
        }
       
$ft.= \DIRECTORY_SEPARATOR;
       
$path = $ft . implode(\DIRECTORY_SEPARATOR, $pathes).\DIRECTORY_SEPARATOR;
       
       
$path = str_replace('\\', \DIRECTORY_SEPARATOR, $path);
       
       
       
$this->dirCompiled = rtrim(self::$dirBase, \DIRECTORY_SEPARATOR.'/ ') .\DIRECTORY_SEPARATOR .$path;
       
   
           
       
        if(empty(
$action)){
            throw new \
Exception('No action/EventModule given in '.__METHOD__.' '.__LINE__);
        }
       
       
$this->action=$action;
       
        if(!isset(
self::$emitters[$this->action]) || true ===$reload){
          
$this->_loadEmitter($this->emitter);
          
self::$emitters[$this->action] = $this->emitter;
        }elseif( isset(
self::$emitters[$this->action]) ){
           
$this->emitter = self::$emitters[$this->action];
        }else{
           
$classname = self::MODEL;
           
$this->emitter = new $classname();
           
self::$emitters[$this->action] = $this->emitter;
        }
       
       
       
    }
   
   
    public function
__call($name, $params){
            if(
null!==$this->emitter && is_callable([$this->emitter, $name])){
               return
call_user_func_array([$this->emitter, $name], $params);
            }
    }
   
   
    protected function
_loadEmitter(&$emitter = null){
       
        if(
file_exists($this->filepath() ) ){
           
           
$emitter = require $this->filepath();
           
        }else{
           
$classname = self::MODEL;
           
$emitter =new $classname();
        }
    }
   
   
   
    public function
filepath($action = null){
        if(
null===$action)$action=$this->action;
       
$a = preg_replace("/[^A-Za-z0-9\_\-]/", '_', $action);
        return
$this->dirCompiled.'on'.ucfirst($a).'.'.strlen($action).'.'.sha1($action).'.php';
    }
   
   
    public function
wrap($listener, $obj = null){
       
                if(
null !== $obj && is_object($obj) && is_string($listener) ){
                 
$callback = [$obj, $listener];
                }else{
                  
$callback = $listener;
                }
       
        return (static function(
$eventName, $Emitter, $event) use ($callback){
           
            
$args = func_get_args();
            
$event = array_pop($args);
              if(
is_object($event) && true === $event instanceof Event){
                   if(
$event->isPropagationStopped() || $event->isDefaultPrevented() ){
                        return
false;
                   }
                 
               
              }
           
$args[]=$event;
            try{
                 return
call_user_func_array($callback, $args);
            }catch(\
Exception $e){
                throw
$e;
            }
        });
    }
   
   
    public static function
register($action, $eventName, $listener, $obj = null, $once = false, $save = true){
       
$E = new self($action);
       
self::unregister($action, $eventName, $listener, $obj, false);
       
$method = (true===$once) ? 'once' : 'on';
       
$E->{$method}($eventName, $E->wrap($listener, $obj), $obj);
             if(
true===$save){
                
$E->save(true);
             }
        return
$E;
    }
   
    public static function
unregister($action, $eventName = null, $listener = null, $obj = null, $save = true){
       
$E = new self($action);
       
$method = 'removeEventListener';
       
        if(
null !== $eventName){
            
$E->{$method}($eventName, $E->wrap($listener, $obj), $obj);
             if(
true===$save){
                
$E->save(true);
             }
        }
       
        if(
null === $eventName || 0 === count($E->getEvents() ) ){
            if(
file_exists( $E->filepath() ) ){
               
unlink( $E->filepath() ) ;
            }
        }
       
       
        return
$E;
    }
   
   
   
    public function
save($reload = true){
        if(!
is_dir($this->dirCompiled)){
        
// $this->fs()->createDir($this->dirCompiled, 0775, true);
            
mkdir($this->dirCompiled, 0775, true);
        }
         
chmod($this->dirCompiled, 0775);
         
         
//$cont = $this->mark . serialize($this->emitter);
   
$t = time();
       
$emitterStr = addslashes(serialize($this->emitter));
       
       
$num = count($this->getEvents() );
       
$action = $this->action;
       
$banner = <<<BANNER
/*
* This file was generated by Webfan Php-Installer/Frdlweb CMS, you SHOULD not edit this file manually! (created:
$t)
* It contains
$num EventHandlers of the action/group `$action`
*/
BANNER;
       
/*
$cont =<<<EMITTERPHP
<?php
$banner
return unserialize(<<<PHPCODEEMITTERSTRING
$emitterStr
PHPCODEEMITTERSTRING
);
   
EMITTERPHP;
*/
       
$cont =<<<EMITTERPHP
<?php
$banner
return unserialize('
$emitterStr');
   
EMITTERPHP;
       
       
        if(!
is_dir(dirname($this->filepath()))){
        
           
mkdir(dirname($this->filepath()), 0775, true);
        }
         
chmod(dirname($this->filepath()), 0775);
       
         
file_put_contents($this->filepath(), $cont);
       
         
chmod($this->filepath(), 0775);
       
        if(
true === $reload){
           
self::$emitters[$this->action] = $this->emitter;
        }
    }
}