Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Thu, Sep 18, 4:10 PM

in-portal

Index: trunk/core/kernel/event_manager.php
===================================================================
--- trunk/core/kernel/event_manager.php (revision 4621)
+++ trunk/core/kernel/event_manager.php (revision 4622)
@@ -1,466 +1,470 @@
<?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]);
}
$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) )
{
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');
$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;
}
}
$passed = explode(',', $this->Application->GetVar('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;
- $this->HandleEvent($event);
-
+
+ $event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
+ if ($event_handler->checkPermissions($event)) {
+ $this->HandleEvent($event);
+ }
+
if($event->status==erSUCCESS && ($event->redirect === true || strlen($event->redirect) > 0) )
{
$this->Application->Redirect($event->redirect, $event->redirect_params, null, $event->redirect_script);
}
}
$this->Application->SetVar('events', $events);
$this->Application->SetVar('passed', implode(',', $passed));
}
function processOpener()
{
$opener_action=$this->Application->GetVar('m_opener');
$opener_stack=$this->Application->RecallVar('opener_stack');
$opener_stack=$opener_stack?unserialize($opener_stack):Array();
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')) {
array_push($opener_stack, '../'.$this->Application->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 - do not store last template
$this->Application->SetVar('skip_last_template', 1);
break;
default: // "s/0," stay on same deep level
break;
}
if ( !$this->Application->GetVar('skip_last_template') ) {
$this->Application->SetVar('m_opener','s');
}
$this->Application->StoreVar('opener_stack',serialize($opener_stack));
}
function registerHook($hookto_prefix, $hookto_special, $hookto_event, $mode, $do_prefix, $do_special, $do_event, $conditional)
{
if( !$this->Application->getUnitOptions($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;
}
$hooks = getArrayValue($mode_hooks, strtolower($event_key.'.'.$event->Name));
if (!$hooks) {
$hooks = Array();
}
return $hooks;
}
/**
* 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 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: trunk/core/kernel/event_manager.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.22
\ No newline at end of property
+1.23
\ No newline at end of property
Index: trunk/core/kernel/event_handler.php
===================================================================
--- trunk/core/kernel/event_handler.php (revision 4621)
+++ trunk/core/kernel/event_handler.php (revision 4622)
@@ -1,289 +1,304 @@
<?php
/**
* Note:
* 1. When adressing variables from submit containing
* Prefix_Special as part of their name use
* $event->getPrefixSpecial(true) instead of
* $event->Prefix_Special as usual. This is due PHP
* is converting "." symbols in variable names during
* submit info "_". $event->getPrefixSpecial optional
* 1st parameter returns correct corrent Prefix_Special
* for variables beeing submitted such way (e.g. variable
* name that will be converted by PHP: "users.read_only_id"
* will be submitted as "users_read_only_id".
*
* 2. When using $this->Application-LinkVar on variables submitted
* from form which contain $Prefix_Special then note 1st item. Example:
* LinkVar($event->getPrefixSpecial(true).'_varname',$event->Prefix_Special.'_varname')
*
*/
/**
* Default event handler. Mostly abstract class
*
*/
class kEventHandler extends kBase {
/**
* In case if event should be handled with mehod,
* which name differs from event name, then it
* should be specified here.
* key - event name, value - event method
*
* @var Array
* @access protected
*/
var $eventMethods=Array();
/**
* Define alternative event processing method names
*
* @see $eventMethods
* @access protected
*/
function mapEvents()
{
}
function getPrefixSpecial()
{
trigger_error('Usage of getPrefixSpecial() this method is forbidden in kEventHandler class children. Use $event->getPrefixSpecial(true); instead', E_USER_ERROR);
}
/**
* Set's prefix and special
*
* @param string $prefix
* @param string $special
* @access public
*/
function Init($prefix,$special)
{
parent::Init($prefix,$special);
$this->mapEvents();
}
/**
* Process Event
*
* @param kEvent $event
* @access public
*/
function processEvent(&$event)
{
$event_name=$event->Name;
if( isset($this->eventMethods[$event_name]) ) $event_name=$this->eventMethods[$event_name];
if( method_exists($this,$event_name) )
{
$this->$event_name($event);
}
else
{
trigger_error('event <b>'.$event->Name.'</b> not implemented in class <b>'.get_class($this).'</b>', E_USER_ERROR);
}
}
/**
* Sample dummy event
*
* @param kEvent $event
* @access protected
*/
function OnBuild(&$event)
{
/*echo 'building: <br>';
print_pre($event);*/
}
/**
* Returns to previous template in opener stack
*
* @param kEvent $event
*/
function OnGoBack(&$event)
{
$event->SetRedirectParam('opener', 'u');
}
/**
* Apply some special processing to
* object beeing recalled before using
* it in other events that call prepareObject
*
* @param Object $object
* @param kEvent $event
* @access protected
*/
function prepareObject(&$object, &$event)
{
// processing here
}
/**
* Creates new event as child of
* event passed as $event param
*
* @param kEvent $event
* @access protected
*/
function &inheritEvent(&$event, $name=null)
{
$child_event = new kEvent();
$child_event->MasterEvent =& $event;
$child_event->Prefix=$event->Prefix;
$child_event->Special=$event->Special;
$child_event->Prefix_Special=$event->Prefix_Special;
$child_event->Name = $name;
return $child_event;
}
/**
* Created url part for this module
*
* @param kEvent $event
*/
function BuildEnv(&$event)
{
$prefix_special = $event->getPrefixSpecial();
$url_params = $event->getEventParam('url_params');
$pass_events = $event->getEventParam('pass_events');
$query_vars = $this->Application->getUnitOption($event->Prefix, 'QueryString');
$event_key = array_search('event', $query_vars);
if ($event_key) {
// pass through event of this prefix
unset($query_vars[$event_key]);
}
if (!getArrayValue($url_params, $prefix_special.'_event')) {
// if empty event, then remove it from url
unset( $url_params[$prefix_special.'_event'] );
}
//if pass events is off and event is not implicity passed
if ( !$pass_events && !isset($url_params[$prefix_special.'_event']) )
{
unset($url_params[$prefix_special.'_event']); // remove event from url if requested
//otherwise it will use value from get_var
}
if(!$query_vars) return true;
$processed_params = Array();
foreach($query_vars as $index => $var_name)
{
//if value passed in params use it, otherwise use current from application
$var_name = $prefix_special.'_'.$var_name;
$processed_params[$var_name] = isset( $url_params[$var_name] ) ? $url_params[$var_name] : $this->Application->GetVar($var_name);
if ( isset($url_params[$var_name]) ) unset( $url_params[$var_name] );
}
$ret = '';
if($processed_params[$prefix_special.'_Page'] > 1)
{
$ret .= $processed_params[$prefix_special.'_Page'].'/';
}
if ($processed_params[$prefix_special.'_id']) {
// this allows to fill 3 cache records with one query (see this method for details)
$category_id = isset($url_params['m_cat_id']) ? $url_params['m_cat_id'] : $this->Application->GetVar('m_cat_id');
$category_filename = $this->Application->getFilename('c', $category_id);
// if template is also item template of category, then remove template
$template = getArrayValue($url_params, 't');
$item_template = $this->Application->getCache('item_templates', $category_id);
if ($template == $item_template || strtolower($template) == '__default__') {
unset($url_params['t']);
}
// get item's filename
$filename = $this->Application->getFilename($event->Prefix, $processed_params[$prefix_special.'_id'] );
if($filename !== false) $ret .= $filename.'/';
}
if( getArrayValue($processed_params, $prefix_special.'_Reviews_Page') > 1)
{
if($processed_params[$prefix_special.'_id']) $ret = rtrim($ret, '/');
$ret .= '_'.$processed_params[$prefix_special.'_Reviews_Page'].'/';
}
$event->setEventParam('url_params', $url_params);
$event->setEventParam('env_string', strtolower($ret) );
}
/**
* Process mod_rewrite url part left after previous parser
*
* @param kEvent $event
*/
function ParseEnv(&$event)
{
// <module_page>/<item_filename>_<reviews_page>
$url_parts = $event->getEventParam('url_parts');
$defaults = Array('id' => 0, 'Page' => 1, 'Reviews_Page' => 1);
foreach ($defaults as $var_name => $var_value)
{
$this->Application->SetVar($event->getPrefixSpecial().'_'.$var_name, $var_value);
}
if (!$url_parts) {
// $event->status = erFAIL;
return false;
}
$ret = '';
$url_part = array_shift($url_parts);
// match module page
if( is_numeric($url_part) )
{
$this->Application->SetVar( $event->getPrefixSpecial().'_Page', $url_part);
$url_part = $url_parts ? array_shift($url_parts) : '';
}
if (!$url_part) {
$event->setEventParam('url_parts', $url_parts);
// $event->status = erFAIL;
return true;
}
// match module reviews page
if( preg_match('/(.*)_([\d]+)$/', $url_part, $rets) )
{
$url_part = $rets[1];
$this->Application->SetVar( $event->getPrefixSpecial().'_Reviews_Page', $rets[2]);
}
// match item's filename
$db =& $this->Application->GetADODBConnection();
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$table = $this->Application->getUnitOption($event->Prefix, 'TableName');
$sql = 'SELECT item_table.'.$id_field.'
FROM '.$table.' item_table
LEFT JOIN '.TABLE_PREFIX.'CategoryItems cat_items ON item_table.ResourceId = cat_items.ItemResourceId
WHERE (item_table.Filename = '.$db->qstr($url_part).') AND (cat_items.CategoryId = '.$this->Application->GetVar('m_cat_id').')';
$item_id = $db->GetOne($sql);
if($item_id !== false)
{
$this->Application->SetVar($event->getPrefixSpecial().'_id', $item_id);
}
else
{
array_unshift($url_parts, $url_part);
$event->status = erFAIL;
}
$event->setEventParam('url_parts', $url_parts);
}
+
+ /**
+ * Checks permissions of user
+ *
+ * @param kEvent $event
+ */
+ function checkPermissions(&$event)
+ {
+ if ($this->Application->GetVar('u_id') == -1) {
+ // "root" has all permissions
+ return true;
+ }
+
+ return true;
+ }
}
?>
\ No newline at end of file
Property changes on: trunk/core/kernel/event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.23
\ No newline at end of property
+1.24
\ No newline at end of property

Event Timeline