Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F775556
in-portal
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Feb 5, 9:51 AM
Size
26 KB
Mime Type
text/x-diff
Expires
Fri, Feb 7, 9:51 AM (8 h, 27 m)
Engine
blob
Format
Raw Data
Handle
558099
Attached To
rINP In-Portal
in-portal
View Options
Index: branches/5.2.x/core/kernel/managers/request_manager.php
===================================================================
--- branches/5.2.x/core/kernel/managers/request_manager.php (revision 14731)
+++ branches/5.2.x/core/kernel/managers/request_manager.php (revision 14732)
@@ -1,474 +1,485 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2010 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kRequestManager extends kBase {
/**
* Prevents request from being proceeded twice
*
* @var bool
* @access protected
*/
protected $processed = false;
/**
* Processes request
*
* @access public
*/
public function process()
{
if ( $this->processed ) {
return;
}
$this->dumpRequest();
$this->processOpener();
$events = $this->getEvents();
$all_passed = $this->getAllPassed($events);
// set "all_passed" before kApplication::GetTopmostPrefix method call !
$this->Application->SetVar('all_passed', implode(',', $all_passed));
foreach ($events as $prefix_special => $event_name) {
$event =& $this->runEvent($prefix_special, $event_name);
if ( $event->status == kEvent::erSTOP ) {
// event requested to stop processing at this point
kUtil::safeDefine('DBG_SKIP_REPORTING', 1);
$this->Application->Session->SaveData();
exit;
}
if ( $event->status == kEvent::erPERM_FAIL ) {
$this->processPermissionError($event);
}
if ( ($event->status == kEvent::erSUCCESS || $event->status == kEvent::erPERM_FAIL) && $this->canRedirect($event) ) {
$this->performRedirect($event);
}
}
$this->Application->SetVar('events', $events);
$this->Application->SetVar('passed', implode(',', $all_passed));
$this->Application->EventManager->runAgents(reBEFORE);
$this->processed = true;
}
/**
* Dumps user request to debugger (only when enabled)
*
* @return void
* @access protected
*/
protected function dumpRequest()
{
if ( defined('DEBUG_MODE') && $this->Application->isDebugMode() && kUtil::constOn('DBG_SHOW_HTTPQUERY') ) {
$this->Application->Debugger->appendHTML('HTTPQuery:');
$this->Application->Debugger->dumpVars($this->Application->HttpQuery->_Params);
}
}
/**
* Returns event names, given in request (post, get)
*
* @return Array
* @access protected
*/
protected function getEvents()
{
$post_events = $this->getEventsFromPost();
return $post_events ? $post_events : $this->getEventsFromGet();
}
/**
* Get all passed prefixes
*
* @param Array $events
* @return Array
* @access protected
*/
protected function getAllPassed($events)
{
$ret = explode(',', $this->Application->GetVar('passed'));
foreach ($events as $prefix_special => $event_name) {
if (!$event_name) {
continue;
}
if ($this->Application->isAdmin) {
array_push($ret, $prefix_special);
}
else {
// don't add special on Front-end because of category item list special is autogenerated
$prefix_special = explode('.', $prefix_special);
array_push($ret, $prefix_special[0]);
}
}
return $ret;
}
/**
* Creates and runs event. Returns false, when prefix of given event isn't registered
*
* @param string $prefix_special
* @param string $event_name
*
* @return kEvent|false
* @access protected
*/
protected function &runEvent($prefix_special, $event_name)
{
$event = new kEvent($prefix_special . ':' . $event_name);
if ( preg_match('/(.*?)-(.*)/', $event->Prefix, $regs) && $this->Application->prefixRegistred($regs[1]) ) {
// this is event from cloned config -> load parent config to create valid clone
$this->Application->UnitConfigReader->loadConfig($regs[1]);
$this->Application->UnitConfigReader->runAfterConfigRead($regs[1]);
}
if ( !$this->Application->EventManager->verifyEventPrefix($event, true) ) {
$false = false;
return $false;
}
+ $event->SetRedirectParam('opener', 's'); // stay on same page after event is called
$event->setEventParam('top_prefix', $this->Application->GetTopmostPrefix($event->Prefix, true));
$event_handler =& $this->Application->recallObject($event->Prefix . '_EventHandler');
/* @var $event_handler kEventHandler */
if ( ($this->Application->RecallVar('user_id') == USER_ROOT) || $event_handler->CheckPermission($event) ) {
$this->Application->HandleEvent($event);
}
return $event;
}
/**
* Processes case, when event finished with permission error
*
* @param kEvent $event
* @access protected
*/
protected function processPermissionError(&$event)
{
// should do redirect but to no_permissions template
$event->redirect = $this->Application->isAdmin ? 'no_permission' : $this->Application->ConfigValue('NoPermissionTemplate');
$event->SetRedirectParam('pass', 'm');
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$event->SetRedirectParam( 'm_cat_id', $themes_helper->getPageByTemplate($event->redirect) );
// 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);
}
/**
* Performs redirect after event execution
*
* @param kEvent $event
* @access protected
*/
protected function performRedirect(&$event)
{
// we need to pass category if the action was submitted to self-template, with the category passed
// and it has not explicitly set redirect template or pass_category param
if ( $this->samePageRedirect($event) && ($event->getEventParam('pass_category') === false) && $this->Application->GetVar('m_cat_id') ) {
$event->SetRedirectParam('pass_category', 1);
}
$wid = $this->Application->GetVar('m_wid');
$redirect_params = $event->getRedirectParams();
if ( $wid && $event->getRedirectParam('opener') == 'u' ) {
// update last element in current opener stack
unset($redirect_params['opener']);
$redirect_template = is_string($event->redirect) ? $event->redirect : null;
$this->openerStackChange($redirect_template, $redirect_params);
// reset opener, because kApplication::HREF will react differently when 'opener' => 'u'
$event->SetRedirectParam('opener', 's');
$event->redirect = defined('CLOSE_POPUP_TPL') ? CLOSE_POPUP_TPL : 'incs/close_popup';
}
+ if ( $event->getRedirectParam('pass') === false ) {
+ // pass all discovered units to redirected page unless developer decided otherwise
+ $event->SetRedirectParam('pass', 'all');
+ }
+
$this->Application->Redirect($event->redirect, $event->getRedirectParams(), '', $event->redirectScript);
}
/**
* Checks, if redirect can be made
*
* @param kEvent $event
* @return bool
* @access protected
*/
protected function canRedirect(&$event)
{
return $this->samePageRedirect($event) || strlen($event->redirect) > 0;
}
/**
* Checks, that current template will be displayed after redirect
*
* @param kEvent $event
* @return bool
* @access protected
*/
protected function samePageRedirect(&$event)
{
return $event->redirect === true || $event->redirect == $this->Application->GetVar('t');
}
/**
* Returns event names given in GET
*
* @return Array
* @access protected
*/
protected function getEventsFromGet()
{
$events = Array ();
$discovered_units = $this->Application->HttpQuery->getDiscoveredUnits(false);
foreach ($discovered_units as $prefix_special => $query_string) {
$query_string = array_flip($query_string);
if ( !isset($query_string['event']) ) {
continue;
}
$event_name = $this->Application->GetVar($prefix_special . '_event');
// we need to check for pre 5.1.0 url format, because of "PerPage"
// query string part (that was added in place of "event" query
// string part) is available only since 5.1.0 version
if ($event_name && !is_numeric($event_name)) {
$events[$prefix_special] = $event_name;
}
}
return $events;
}
/**
* Returns event names given in POST
*
* @return Array
* @access protected
*/
protected function getEventsFromPost()
{
$ret = Array ();
$events = $this->Application->GetVar('events');
if (!$events) {
return Array ();
}
foreach ($events as $prefix_special => $event_name) {
if (!$event_name) {
continue;
}
if ( is_array($event_name) ) {
// HTML-input names like "events[prefix.special][event_name]", input value don't matter
$event_name = key($event_name);
$this->Application->SetVar($prefix_special . '_event', $event_name);
}
// HTML-input names like "events[prefix.special]", input value is event name
$ret[$prefix_special] = $event_name;
}
return $ret;
}
/**
* Processes window opener stack
*
* @access protected
*/
protected function processOpener()
{
$opener_stack =& $this->Application->makeClass('kOpenerStack');
/* @var $opener_stack kOpenerStack */
switch ( $this->Application->GetVar('m_opener') ) {
case 'r':
$opener_stack->reset();
break;
case 'd':
// "down/push" new template to opener stack, deeplevel++
if ( $this->Application->GetVar('front') ) {
$front_session =& $this->Application->recallObject('Session.front');
/* @var $front_session Session */
$opener_stack->pushRaw( '../' . $front_session->RecallVar('last_template') );
}
else {
$opener_stack->pushRaw( $this->Application->RecallVar('last_template') );
}
break;
case 'u':
// "up/pop" last template from opener stack, deeplevel--
$opener_stack->pop();
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);
$popup_opener_stack =& $this->Application->makeClass('kOpenerStack', Array ($popup_wid));
/* @var $popup_opener_stack kOpenerStack */
$popup_opener_stack->pushRaw( $this->getLastTemplate($parent_wid) );
$popup_opener_stack->save();
$this->Application->SetVar('m_opener', 's');
/*// store window relations
$window_relations = $this->Application->RecallVar('window_relations');
$window_relations = $window_relations ? unserialize($window_relations) : Array ();
$window_relations[$popup_wid] = $parent_wid;
$this->Application->StoreVar('window_relations', serialize($window_relations));*/
return;
break;
default:
// "s/0," stay on same deep level
break;
}
$this->Application->SetVar('m_opener', 's');
$opener_stack->save();
}
/**
* Returns last template from window with given id
*
* @param int $window_id
* @return string
* @access protected
*/
protected function getLastTemplate($window_id)
{
if ( $this->Application->GetVar('front') ) {
$front_session =& $this->Application->recallObject('Session.front');
/* @var $front_session Session */
return '../' . $front_session->RecallVar( rtrim('last_template_popup_' . $window_id, '_') );
}
if ( $this->Application->GetVar('merge_opener_stack') ) {
// get last template from parent (that was closed) window opener stack
$parent_opener_stack =& $this->Application->makeClass('kOpenerStack', Array ($window_id));
/* @var $parent_opener_stack kOpenerStack */
$last_template = $parent_opener_stack->pop(true);
$parent_opener_stack->save(true);
}
else {
$last_template = $this->Application->RecallVar( rtrim('last_template_popup_' . $window_id, '_') );
}
return $last_template;
}
/**
* Allows to add new element to opener stack
*
* @param string $template
* @param Array $params
* @param int $wid
* @access public
*/
public function openerStackPush($template = '', $params = Array (), $wid = null)
{
if ( !isset($params['pass']) ) {
$params['pass'] = 'all';
}
/*// get parent window wid, when this was popup
$window_relations = $this->Application->RecallVar('window_relations');
$window_relations = $window_relations ? unserialize($window_relations) : Array ();
$wid = isset($window_relations[$wid]) ? $window_relations[$wid] : false;*/
$opener_stack =& $this->Application->makeClass('kOpenerStack', Array ($wid));
/* @var $opener_stack kOpenerStack */
// change opener stack
$default_params = Array ('m_opener' => 'u', '__URLENCODE__' => 1);
if ( !$this->Application->ConfigValue('UsePopups') && $opener_stack->getWindowID() ) {
// remove wid to show combined header block in editing window
$default_params['m_wid'] = '';
list ($last_template, $last_params, ) = $opener_stack->get(kOpenerStack::LAST_ELEMENT);
// move last popup's opener stack element to main window's opener stack
if ( $last_params ) {
$last_params = array_merge($last_params, $default_params);
$this->openerStackPush($last_template, $last_params, '');
}
}
$params = array_merge($default_params, $params);
$opener_stack->push($template, $params, 'index.php');
$opener_stack->save();
}
/**
* Allows to change last element in opener stack
*
* @param string $new_template
* @param Array $new_params
* @access protected
*/
protected function openerStackChange($new_template = null, $new_params = null)
{
$opener_stack =& $this->Application->makeClass('kOpenerStack');
/* @var $opener_stack kOpenerStack */
list ($template, $params, $index_file) = $opener_stack->pop();
if ( isset($new_template) ) {
$template = $new_template;
}
if ( isset($new_params) ) {
$params = array_merge($params, $new_params);
}
+ if ( !isset($params['pass_events']) ) {
+ // don't pass events, unless requested
+ $params['pass_events'] = false;
+ }
+
$opener_stack->push($template, $params, $index_file);
$opener_stack->save();
}
}
\ No newline at end of file
Index: branches/5.2.x/core/kernel/utility/event.php
===================================================================
--- branches/5.2.x/core/kernel/utility/event.php (revision 14731)
+++ branches/5.2.x/core/kernel/utility/event.php (revision 14732)
@@ -1,439 +1,436 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
final class kEvent extends kBase {
/**
* Event finished working succsessfully
*
*/
const erSUCCESS = 0;
/**
* Event finished working, but result is unsuccsessfull
*
*/
const erFAIL = -1;
/**
* Event experienced FATAL error - no hooks should continue!
*
*/
const erFATAL = -2;
/**
* Event failed on internal permission checking (user has no permission)
*
*/
const erPERM_FAIL = -3;
/**
* Event requested to stop processing (don't parse templates)
*
*/
const erSTOP = -4;
/**
* Reference to event, that created given event
*
* @var kEvent
* @access public
*/
public $MasterEvent;
/**
* Event name
*
* @var string
* @access public
*/
public $Name;
/**
* Don't execute hooks, before event processing
*
* @var bool
* @access public
*/
public $SkipBeforeHooks = false;
/**
* Don't execute hooks, after event processing
*
* @var bool
* @access public
*/
public $SkipAfterHooks = false;
/**
* Perform redirect after event processing.
* Redirect after event processing allows to prevent same event being present in resulting url.
* Also could contain template name, that needs to be shown after redirect.
*
* @var mixed
* @access public
*/
public $redirect = true;
/**
- * Params, used during redirect url building after event succsessfull processing
+ * Params, used during redirect url building after event successful processing
*
* @var bool
* @access private
*/
- private $redirectParams = Array (
- 'opener' => 's', // redirect to given template
- 'pass' => 'all' // pass all discovered units to redirected page
- );
+ private $redirectParams = Array ();
/**
* PHP file to redirect to. Defaults to "index.php"
*
* @var string
* @access public
*/
public $redirectScript = null;
/**
* Event processing status
*
* @var int
* @access public
*/
public $status = kEvent::erSUCCESS;
/**
* Event parameters
* Usually indicate, how particular event should be processed.
*
* @var Array
* @access private
*/
private $specificParams = Array ();
/**
* Pseudo class used, to create object, based on event contents
*
* @var string
* @access private
*/
private $pseudoClass = '';
/**
* Create event from given prefix, special, name and specific params.
* Parameter $params could be be an an array with following keys: "prefix", "special" (optional), "name".
* Parameter $params could be a string in format: "prefix:name" or "prefix.special:name".
*
* @param mixed $params
* @param Array $specific_params event specific params (none by default)
* @return kEvent
* @access public
*/
public function __construct($params = Array(), $specific_params = null)
{
parent::__construct();
if ($params) {
if ( is_array($params) ) {
$prefix = isset($params['prefix']) ? $params['prefix'] : false;
$special = isset($params['special']) ? $params['special'] : false;
if ($prefix) {
$this->Init($prefix, $special);
}
$this->Name = isset($params['name']) ? $params['name'] : '';
}
elseif ( is_string($params) ) {
if (preg_match('/([^.:]*)[.]{0,1}([^:]*):(.*)/', $params, $regs)) {
$prefix = $regs[1];
$special = $regs[2];
if ($prefix) {
$this->Init($prefix, $special);
}
$this->Name = $regs[3];
}
else {
throw new Exception('Invalid event string: <strong>' . $params . '</strong>. $params should be "prefix[.special]:OnEvent" format');
}
}
}
if ( isset($specific_params) ) {
$this->specificParams = $specific_params;
}
}
/**
* Returns joined prefix and special if any
*
* @param bool $from_submit if true, then joins prefix & special by "_", uses "." otherwise
* @return string
* @access public
*/
public function getPrefixSpecial($from_submit = false)
{
if (!$from_submit) {
return parent::getPrefixSpecial();
}
return rtrim($this->Prefix . '_' . $this->Special, '_');
}
/**
* Sets event parameter
*
* @param string $name
* @param mixed $value
* @access public
*/
public function setEventParam($name,$value)
{
$this->specificParams[$name] = $value;
}
/**
* Returns event parameter by name (supports digging)
*
* @param string $name
* @return mixed
* @access public
*/
public function getEventParam($name)
{
$args = func_get_args();
if (count($args) > 1) {
kUtil::array_unshift_ref($args, $this->specificParams);
return call_user_func_array('getArrayValue', $args); // getArrayValue($this->specificParams, $name);
}
return array_key_exists($name, $this->specificParams) ? $this->specificParams[$name] : false;
}
/**
* Set's pseudo class that differs from
* the one specified in $Prefix
*
* @param string $appendix
* @access public
*/
public function setPseudoClass($appendix)
{
$this->pseudoClass = $this->Prefix . $appendix;
}
/**
* Performs event initialization
* Also sets pseudo class same $prefix
*
* @param string $prefix
* @param string $special
* @access public
*/
public function Init($prefix, $special)
{
$this->pseudoClass = $prefix;
parent::Init($prefix, $special);
}
/**
* Returns object used in event
*
* @param Array $params
* @return kDBBase
* @access public
*/
public function &getObject(array $params = Array())
{
if ( !$this->Application->hasObject($this->prefixSpecial) ) {
$top_event =& $this;
// when OnSave calls OnPreSave in first line, then this would make sure OnSave is used
while ( is_object($top_event->MasterEvent) ) {
$top_event =& $top_event->MasterEvent;
}
$params['parent_event'] =& $top_event;
}
$object =& $this->Application->recallObject($this->prefixSpecial, $this->pseudoClass, $params);
return $object;
}
/**
* Executes given event in context of current event
* Sub-event gets this event in "kEvent::MasterEvent" attribute.
* Sub-event execution results (status and redirect* properties) are copied back to current event.
*
* @param string $name name of callable event (optionally could contain prefix_special as well)
* @see kEvent::MasterEvent
*/
public function CallSubEvent($name)
{
if ( strpos($name, ':') === false ) {
// PrefixSpecial not specified -> use from current event
$name = $this->getPrefixSpecial() . ':' . $name;
}
$child_event = new kEvent($name);
$child_event->copyFrom($this, true);
$this->Application->HandleEvent($child_event);
$this->copyFrom($child_event);
$this->specificParams = $child_event->specificParams;
}
/**
* Allows to copy data between events
*
* @param kEvent $source_event
* @param bool $inherit
* @access public
*/
public function copyFrom(&$source_event, $inherit = false)
{
if ($inherit) {
$this->MasterEvent =& $source_event;
}
else {
$this->status = $source_event->status;
}
$this->redirect = $source_event->redirect;
$this->redirectParams = $source_event->redirectParams;
$this->redirectScript = $source_event->redirectScript;
$this->specificParams = $source_event->specificParams;
}
/**
* Returns all redirect parameters
*
* @return Array
* @access public
*/
public function getRedirectParams()
{
return $this->redirectParams;
}
/**
* Returns redirect parameter
*
* @param string $name
* @return mixed
* @access public
*/
public function getRedirectParam($name)
{
return array_key_exists($name, $this->redirectParams) ? $this->redirectParams[$name] : false;
}
/**
* Set's redirect param for event
*
* @param string $name
* @param string $value
* @access public
*/
public function SetRedirectParam($name, $value)
{
$this->redirectParams[$name] = $value;
}
/**
* Allows to merge passed redirect params hash with existing ones
*
* @param Array $params
* @param bool $overwrite
* @access public
*/
public function setRedirectParams($params, $overwrite = false)
{
if ($overwrite) {
$this->redirectParams = $params;
return ;
}
// append new parameters to parameters set before
$this->redirectParams = kUtil::array_merge_recursive($this->redirectParams, $params);
}
/**
* Allows to tell if this event was called some how (e.g. subevent, hook) from event requested
*
* @param string $event_key event key in format [prefix[.special]:]event_name
* @return bool
* @access public
*/
public function hasAncestor($event_key)
{
if ( strpos($event_key, ':') === false ) {
$event_key = $this->getPrefixSpecial() . ':' . $event_key;
}
return $this->Application->EventManager->eventRunning($event_key);
}
/**
* Returns permission section associated with event
*
* @return string
* @access public
*/
public function getSection()
{
$perm_section = $this->getEventParam('PermSection');
if ($perm_section) {
return $perm_section;
}
// 1. get section by current top_prefix
$top_prefix = $this->getEventParam('top_prefix');
if ($top_prefix == false) {
$top_prefix = $this->Application->GetTopmostPrefix($this->Prefix, true);
$this->setEventParam('top_prefix', $top_prefix);
}
$section = $this->Application->getUnitOption($top_prefix.'.main', 'PermSection');
// 2. check if this section has perm_prefix mapping to other prefix
$sections_helper =& $this->Application->recallObject('SectionsHelper');
/* @var $sections_helper kSectionsHelper */
$section_data =& $sections_helper->getSectionData($section);
if ($section_data && isset($section_data['perm_prefix']) && $section_data['perm_prefix'] != $top_prefix) {
$this->setEventParam('top_prefix', $section_data['perm_prefix']);
$section = $this->Application->getUnitOption($section_data['perm_prefix'].'.main', 'PermSection');
}
if (!$section) {
throw new Exception('Permission <strong>section</strong> not specified for prefix <strong>' . $top_prefix . '</strong>');
}
return $section;
}
public function __toString()
{
return $this->getPrefixSpecial() . ':' . $this->Name;
}
}
\ No newline at end of file
Event Timeline
Log In to Comment