Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Tue, Jun 17, 3:36 PM

in-portal

Index: branches/unlabeled/unlabeled-1.44.2/core/kernel/event_manager.php
===================================================================
--- branches/unlabeled/unlabeled-1.44.2/core/kernel/event_manager.php (nonexistent)
+++ branches/unlabeled/unlabeled-1.44.2/core/kernel/event_manager.php (revision 8003)
@@ -0,0 +1,556 @@
+<?php
+
+ define('hBEFORE', 1);
+ define('hAFTER', 2);
+
+ define('reBEFORE', 1);
+ define('reAFTER', 2);
+
+ class kEventManager extends kBase {
+
+ /**
+ * Connection to database
+ *
+ * @var kDBConnection
+ * @access public
+ */
+ var $Conn;
+
+ /**
+ * Cache of QueryString parameters
+ * from config, that are represented
+ * in enviroment variable
+ *
+ * @var Array
+ */
+ var $queryMaps = Array();
+
+ /**
+ * Build events registred for
+ * pseudo classes. key - pseudo class
+ * value - event name
+ *
+ * @var Array
+ * @access private
+ */
+ var $buildEvents=Array();
+
+
+ /**
+ * Events, that should be run before parser initialization
+ *
+ * @var Array
+ */
+ var $beforeRegularEvents = Array();
+
+ /**
+ * Events, that should be run after parser initialization
+ *
+ * @var Array
+ */
+ var $afterRegularEvents = Array();
+
+ /**
+ * Holds before hooks
+ * key - prefix.event (to link to)
+ * value - hooked event info
+ *
+ * @var Array
+ * @access private
+ */
+ var $beforeHooks=Array();
+
+ /**
+ * Holds after hooks
+ * key - prefix.event (to link to)
+ * value - hooked event info
+ *
+ * @var Array
+ * @access private
+ */
+ var $afterHooks = Array();
+
+
+ var $recursionStack = Array();
+
+ function kEventManager()
+ {
+ parent::kBase();
+ $this->Conn =& $this->Application->GetADODBConnection();
+ }
+
+ /**
+ * Set's new enviroment parameter mappings
+ * between their names as application vars
+ *
+ * @param Array $new_query_maps
+ * @access public
+ */
+ /*function setQueryMaps($new_query_maps)
+ {
+ $this->queryMaps = $new_query_maps;
+ }*/
+
+ /**
+ * Adds new query map to already parsed query maps
+ *
+ * @param string $prefix
+ */
+ function setQueryMap($prefix_special)
+ {
+ list($prefix) = explode('.', $prefix_special);
+ $query_map = $this->Application->getUnitOption($prefix, 'QueryString');
+ if ($query_map) {
+ $this->queryMaps[$prefix_special] = $query_map;
+ }
+ else {
+ unset($this->queryMaps[$prefix]);
+ }
+
+// 'passed' is set later in ProcessRequest - do we really need it here? (it breakes HTTPQuery initialization...)
+// $this->Application->SetVar('passed', implode(',', array_keys($this->queryMaps)) );
+ return $query_map;
+ }
+
+ /**
+ * Registers new regular event
+ *
+ * @param string $short_name name to be used to store last maintenace run info
+ * @param string $event_name
+ * @param int $run_interval run interval in seconds
+ * @param int $type before or after regular event
+ */
+ function registerRegularEvent($short_name, $event_name, $run_interval, $type = reBEFORE)
+ {
+ if($type == reBEFORE)
+ {
+ $this->beforeRegularEvents[$short_name] = Array('EventName' => $event_name, 'RunInterval' => $run_interval);
+ }
+ else
+ {
+ $this->afterRegularEvents[$short_name] = Array('EventName' => $event_name, 'RunInterval' => $run_interval);
+ }
+ }
+
+ function registerBuildEvent($pseudo_class,$build_event_name)
+ {
+ $this->buildEvents[$pseudo_class]=$build_event_name;
+ }
+
+ /**
+ * Returns build event by pseudo class
+ * name if any defined in config
+ *
+ * @param string $pseudo_class
+ * @return kEvent
+ * @access public
+ */
+ function &getBuildEvent($pseudo_class)
+ {
+ $false = false;
+ if( !isset($this->buildEvents[$pseudo_class]) ) return $false;
+
+ $event = new kEvent();
+ $event->Name=$this->buildEvents[$pseudo_class];
+ $event->MasterEvent=null;
+ return $event;
+ }
+
+ /**
+ * Check if event is called twice, that causes recursion
+ *
+ * @param kEvent $event
+ */
+ function isRecursion(&$event)
+ {
+ $event_key = $event->getPrefixSpecial().':'.$event->Name;
+ return in_array($event_key, $this->recursionStack) ? true : false;
+ }
+
+ function pushEvent(&$event)
+ {
+ $event_key = $event->getPrefixSpecial().':'.$event->Name;
+ array_push($this->recursionStack, $event_key);
+ }
+
+ function popEvent()
+ {
+ array_pop($this->recursionStack);
+ }
+
+ /**
+ * Allows to process any type of event
+ *
+ * @param kEvent $event
+ * @access public
+ */
+ function HandleEvent(&$event)
+ {
+ if ($this->isRecursion($event)) {
+ return true;
+ }
+
+ $this->pushEvent($event);
+
+ if( !$this->Application->prefixRegistred($event->Prefix) )
+ {
+ $unit_config_reader =& $this->Application->recallObject('kUnitConfigReader');
+ $unit_config_reader->loadConfig($event->Prefix);
+ if( !$this->Application->prefixRegistred($event->Prefix) )
+ {
+ trigger_error('Prefix <b>'.$event->Prefix.'</b> not registred (requested event <b>'.$event->Name.'</b>)', E_USER_NOTICE);
+ return false;
+ }
+ }
+
+ if (!$event->SkipBeforeHooks) {
+ $this->processHooks($event, hBEFORE);
+ if ($event->status == erFATAL) return true;
+ }
+
+ $event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
+ /* @var $event_handler kEventHandler */
+ $event_handler->processEvent($event);
+
+ if ($event->status == erFATAL) return true;
+ if (!$event->SkipAfterHooks) {
+ $this->processHooks($event, hAFTER);
+ }
+
+ $this->popEvent();
+ return true;
+ }
+
+ function ProcessRequest()
+ {
+ $this->processOpener();
+
+ // 1. get events from $_POST
+ $events = $this->Application->GetVar('events');
+ if ($events === false) $events = Array();
+ // 2. if nothing there, then try to find them in $_GET
+ if ($this->queryMaps && !$events) {
+ // if we got $_GET type submit (links, not javascript)
+ foreach ($this->queryMaps as $prefix_special => $query_map) {
+ $query_map = array_flip($query_map);
+ if (isset($query_map['event'])) {
+ $event_name = $this->Application->GetVar($prefix_special.'_event');
+ if ($event_name) {
+ $events[$prefix_special] = $event_name;
+ }
+ }
+ }
+ $actions = $this->Application->GetVar('do');
+ if ($actions) {
+ list($prefix, $event_name) = explode('_', $actions);
+ $events[$prefix] = $event_name;
+ }
+ }
+
+ // 3. store all prefixes passed before event processing, because they are used by GetTopmostPrefix
+ $all_passed = explode(',', $this->Application->GetVar('passed'));
+ foreach ($events as $prefix_special => $event_name) {
+ if (!$event_name) continue;
+ $prefix_special = explode('.',$prefix_special);
+ array_push($all_passed, $prefix_special[0]);
+ }
+ $this->Application->SetVar('all_passed', implode(',', $all_passed));
+
+ foreach ($events as $prefix_special => $event_name) {
+ if (!$event_name) continue;
+ if (is_array($event_name)) {
+ $event_name = key($event_name);
+ $events[$prefix_special] = $event_name;
+ $this->Application->SetVar($prefix_special.'_event', $event_name);
+ }
+
+ $event = new kEvent();
+ $event->Name = $event_name;
+ $event->Prefix_Special = $prefix_special;
+
+ $prefix_special = explode('.',$prefix_special);
+ $event->Prefix = $prefix_special[0];
+// array_push($passed, $prefix_special[0]);
+ $event->Special = isset($prefix_special[1]) ? $prefix_special[1] : '';
+
+ $event->redirect_params = Array('opener' => 's', 'pass' => 'all');
+ $event->redirect = true;
+
+ $event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
+ /* @var $event_handler kEventHandler */
+ $event->setEventParam('top_prefix', $this->Application->GetTopmostPrefix($event->Prefix, true));
+ if (($this->Application->RecallVar('user_id') == -1) || $event_handler->CheckPermission($event)) {
+ $this->HandleEvent($event);
+ }
+
+ if ($event->status == erSTOP) {
+ // event requested to stop processing at this point
+ safeDefine('DBG_SKIP_REPORTING', 1);
+ $this->Application->Session->SaveData();
+ exit;
+ }
+
+ if ($event->status == erPERM_FAIL) {
+ // should do redirect but to no_permissions template
+ $event->redirect = $this->Application->IsAdmin() ? 'no_permission' : $this->Application->ConfigValue('NoPermissionTemplate');
+ $event->redirect_params['pass'] = 'm';
+ $event->redirect_params['m_cat_id'] = 0;
+
+ // restore stuff, that processOpener() changed
+ $wid = $this->Application->GetVar('m_wid');
+ $this->Application->RestoreVar(rtrim('opener_stack_'.$wid, '_'));
+ // don't save last_template, because no_permission template does js history.back and could cause invalid opener_stack content
+ $this->Application->SetVar('skip_last_template', 1);
+ }
+
+ if ( ($event->status == erSUCCESS || $event->status == erPERM_FAIL) && ($event->redirect === true || strlen($event->redirect) > 0)) {
+ // we need to pass category if the action was submitted to self-template, with the category passed
+ // and it has not explicly set redirect template or pass_cateogry param
+ if ($event->redirect === true && !isset($event->redirect_params['pass_category']) && $this->Application->GetVar('m_cat_id')) {
+ $event->redirect_params['pass_category'] = 1;
+ }
+
+ $wid = $this->Application->GetVar('m_wid');
+ if ($wid && $event->redirect_params['opener'] == 'u') {
+ $event->redirect_params['opener'] = 's'; // because Application->HREF will react differently when 'opener' = 'u'
+ $event->redirect = defined('CLOSE_POPUP_TPL') ? CLOSE_POPUP_TPL : 'incs/close_popup';
+ }
+
+ $this->Application->Redirect($event->redirect, $event->redirect_params, null, $event->redirect_script);
+ }
+ }
+
+ $this->Application->SetVar('events', $events);
+ $this->Application->SetVar('passed', implode(',', $all_passed));
+ }
+
+ function processOpener()
+ {
+ $wid = $this->Application->GetVar('m_wid');
+
+ $opener_stack = $this->Application->RecallVar(rtrim('opener_stack_'.$wid, '_'));
+ $opener_stack = $opener_stack ? unserialize($opener_stack) : Array();
+
+ $opener_action = $this->Application->GetVar('m_opener');
+ switch ($opener_action) {
+ case 'r': // "reset" opener stack
+ $opener_stack = Array();
+ break;
+
+ case 'd': // "down/push" new template to opener stack, deeplevel++
+ if ($this->Application->GetVar('front')) {
+ $front_session =& $this->Application->recallObject('Session.front');
+ array_push($opener_stack, '../'.$front_session->RecallVar('last_template') );
+ }
+ else {
+ array_push($opener_stack, $this->Application->RecallVar('last_template') );
+ }
+ break;
+
+ case 'u': // "up/pop" last template from opener stack, deeplevel--
+ array_pop($opener_stack);
+ break;
+
+ case 'p': // pop-up - generate new wid
+ $parent_wid = $this->Application->GetVar('m_wid'); // window_id of popup's parent window
+ $popup_wid = (int)$this->Application->RecallVar('last_wid') + 1;
+ $this->Application->StoreVar('last_wid', $popup_wid);
+ $this->Application->SetVar('m_wid', $popup_wid);
+
+ if ($this->Application->GetVar('front')) {
+ $front_session =& $this->Application->recallObject('Session.front');
+
+ $last_template = $front_session->RecallVar(rtrim('last_template_popup_'.$parent_wid, '_'));
+ $last_template = '../'.$last_template;
+ }
+ else {
+ $last_template = $this->Application->RecallVar(rtrim('last_template_popup_'.$parent_wid, '_'));
+ }
+
+ $opener_stack = Array ( $last_template );
+ $this->Application->SetVar('m_opener', 's');
+ $wid = $popup_wid;
+ break;
+
+ default: // "s/0," stay on same deep level
+ break;
+ }
+
+
+ $this->Application->SetVar('m_opener', 's');
+ $this->Application->StoreVar(rtrim('opener_stack_'.$wid, '_'), serialize($opener_stack));
+ }
+
+ /**
+ * Used from relationship event handler
+ *
+ * @param string $t
+ * @param Array $params
+ * @param string $pass
+ */
+ function openerStackPush($t, $params, $pass = 'all', $wid=null)
+ {
+ if (!isset($wid)) $wid = $this->Application->GetVar('m_wid');
+ $stack_name = rtrim('opener_stack_'.$wid, '_');
+
+ $opener_stack = $this->Application->RecallVar($stack_name);
+ $opener_stack = $opener_stack ? unserialize($opener_stack) : Array();
+
+ $redirect_params = array_merge_recursive2(Array('m_opener' => 'u', '__URLENCODE__' => 1), $params);
+ $new_level = $this->Application->BuildEnv($t, $redirect_params, $pass, true);
+ array_push($opener_stack, 'index.php|'.ltrim($new_level, ENV_VAR_NAME.'=') );
+ $this->Application->StoreVar($stack_name, serialize($opener_stack));
+ }
+
+ function registerHook($hookto_prefix, $hookto_special, $hookto_event, $mode, $do_prefix, $do_special, $do_event, $conditional)
+ {
+ if( !$this->Application->prefixRegistred($hookto_prefix) )
+ {
+ if ($this->Application->isDebugMode()) {
+ trigger_error('Prefix <b>'.$hookto_prefix.'</b> doesn\'t exist when trying to hook from <b>'.$do_prefix.':'.$do_event.'</b>', E_USER_WARNING);
+ }
+ return;
+ }
+ $hookto_prefix_special = rtrim($hookto_prefix.'.'.$hookto_special, '.');
+ if ($mode == hBEFORE) {
+ $this->beforeHooks[strtolower($hookto_prefix_special.'.'.$hookto_event)][] = Array(
+ 'DoPrefix' => $do_prefix,
+ 'DoSpecial' => $do_special,
+ 'DoEvent' => $do_event,
+ 'Conditional' => $conditional,
+ );
+ }
+ elseif ($mode == hAFTER) {
+ $this->afterHooks[strtolower($hookto_prefix_special.'.'.$hookto_event)][] = Array(
+ 'DoPrefix' => $do_prefix,
+ 'DoSpecial' => $do_special,
+ 'DoEvent' => $do_event,
+ 'Conditional' => $conditional,
+ );
+ }
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param kEvent $event
+ * @param int $mode hBEFORE or hAFTER
+ * @return Array
+ */
+ function &getHooks(&$event, $mode, $special = null)
+ {
+ $event_key = !isset($special) ? $event->Prefix_Special : $event->Prefix.'.'.$special;
+
+ if ($mode == hBEFORE) {
+ $mode_hooks =& $this->beforeHooks;
+ }
+ else {
+ $mode_hooks =& $this->afterHooks;
+ }
+
+ if (!isset($mode_hooks[strtolower($event_key.'.'.$event->Name)])) {
+ $hooks = array();
+ return $hooks;
+ }
+ return $mode_hooks[strtolower($event_key.'.'.$event->Name)];
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param kEvent $event
+ * @param int $mode hBEFORE or hAFTER
+ */
+ function processHooks(&$event, $mode)
+ {
+ // * - get hooks that are valid with any special of given prefix
+ $hooks = array_merge($this->getHooks($event, $mode, '*'), $this->getHooks($event, $mode));
+
+ if ($hooks) {
+ foreach ($hooks as $hook) {
+ if ($hook['DoSpecial'] == '*') {
+ // use same special as master event
+ $hook['DoSpecial'] = $event->Special;
+ }
+
+ $prefix_special = rtrim($hook['DoPrefix'].'_'.$hook['DoSpecial'], '_');
+ if ( $hook['Conditional'] && !$this->Application->GetVar($prefix_special) ) {
+ continue;
+ }
+
+ $hook_event = new kEvent( Array('name'=>$hook['DoEvent'],'prefix'=>$hook['DoPrefix'],'special'=>$hook['DoSpecial']) );
+ $hook_event->MasterEvent =& $event;
+ $this->HandleEvent($hook_event);
+ }
+ }
+ }
+
+ /**
+ * Set's new event for $prefix_special
+ * passed
+ *
+ * @param string $prefix_special
+ * @param string $event_name
+ * @access public
+ */
+ function setEvent($prefix_special,$event_name)
+ {
+ $actions =& $this->Application->recallObject('kActions');
+ $actions->Set('events['.$prefix_special.']',$event_name);
+ }
+
+ /**
+ * Run registred regular events with specified event type
+ *
+ * @param int $event_type
+ */
+ function RunRegularEvents($event_type = reBEFORE, $from_cron=false)
+ {
+ if (defined('IS_INSTALL')) return ;
+ // if RegularEvents are set to run from cron
+ if (!$from_cron && $this->Application->ConfigValue('UseCronForRegularEvent')) return ;
+ $events_source = ($event_type == reBEFORE) ? $this->beforeRegularEvents : $this->afterRegularEvents;
+
+ /*if(rand(0, 100) < 90)
+ {
+ return;
+ }*/
+
+ $sql = 'SELECT Data FROM '.TABLE_PREFIX.'Cache WHERE VarName = %s';
+ $event_last_runs = $this->Conn->GetOne( sprintf($sql, $this->Conn->qstr('RegularEventRuns') ) );
+ $event_last_runs = $event_last_runs ? unserialize($event_last_runs) : Array();
+
+ foreach($events_source as $short_name => $event_data)
+ {
+ $event_last_run = getArrayValue($event_last_runs, $short_name);
+ if($event_last_run && $event_last_run > adodb_mktime() - $event_data['RunInterval'])
+ {
+ continue;
+ }
+ else
+ {
+ $event = new kEvent($event_data['EventName']);
+ $event->redirect = false;
+ $this->Application->HandleEvent($event);
+ $event_last_runs[$short_name] = adodb_mktime();
+ }
+ }
+
+ $sql = 'REPLACE INTO '.TABLE_PREFIX.'Cache (VarName,Data,Cached) VALUES (%s,%s,%s)';
+ $this->Conn->Query( sprintf($sql, $this->Conn->qstr('RegularEventRuns'), $this->Conn->qstr(serialize($event_last_runs)), adodb_mktime() ) );
+ }
+
+ /**
+ * Allows to determine, that required event is beeing processed right now
+ *
+ * @param string $event_key Event name in format prefix[.special]:event_name
+ * @return bool
+ */
+ function eventRunning($event_key)
+ {
+ return array_search($event_key, $this->recursionStack) !== false;
+ }
+ }
+
+
+?>
\ No newline at end of file
Property changes on: branches/unlabeled/unlabeled-1.44.2/core/kernel/event_manager.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.44
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property

Event Timeline