Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Sat, Feb 22, 12:07 AM

in-portal

Index: branches/5.2.x/core/kernel/managers/request_manager.php
===================================================================
--- branches/5.2.x/core/kernel/managers/request_manager.php (revision 16701)
+++ branches/5.2.x/core/kernel/managers/request_manager.php (revision 16702)
@@ -1,484 +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->HandleEvent(new kEvent('adm:OnBeforeShutdown'));
$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->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));
/** @var kEventHandler $event_handler */
$event_handler = $this->Application->recallObject($event->Prefix . '_EventHandler');
if ( $this->Application->permissionCheckingDisabled() || $event_handler->CheckPermission($event) ) {
$this->Application->HandleEvent($event);
$this->Application->notifyEventSubscribers($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');
/** @var kThemesHelper $themes_helper */
$themes_helper = $this->Application->recallObject('ThemesHelper');
$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()
{
/** @var kOpenerStack $opener_stack */
$opener_stack = $this->Application->makeClass('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') ) {
/** @var Session $front_session */
$front_session = $this->Application->recallObject('Session.front');
$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);
/** @var kOpenerStack $popup_opener_stack */
$popup_opener_stack = $this->Application->makeClass('kOpenerStack', Array ($popup_wid));
$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') ) {
/** @var Session $front_session */
$front_session = $this->Application->recallObject('Session.front');
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
/** @var kOpenerStack $parent_opener_stack */
$parent_opener_stack = $this->Application->makeClass('kOpenerStack', Array ($window_id));
$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;*/
/** @var kOpenerStack $opener_stack */
$opener_stack = $this->Application->makeClass('kOpenerStack', Array ($wid));
// change opener stack
$default_params = Array ('m_opener' => 'u');
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)
{
/** @var kOpenerStack $opener_stack */
$opener_stack = $this->Application->makeClass('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();
}
}

Event Timeline