Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F727163
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
Mon, Jan 6, 8:12 AM
Size
51 KB
Mime Type
text/x-diff
Expires
Wed, Jan 8, 8:12 AM (2 d, 2 h ago)
Engine
blob
Format
Raw Data
Handle
537214
Attached To
rINP In-Portal
in-portal
View Options
Index: branches/5.2.x/core/kernel/managers/rewrite_url_processor.php
===================================================================
--- branches/5.2.x/core/kernel/managers/rewrite_url_processor.php (revision 16801)
+++ branches/5.2.x/core/kernel/managers/rewrite_url_processor.php (revision 16802)
@@ -1,1097 +1,1101 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2011 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 kRewriteUrlProcessor extends kUrlProcessor {
/**
* Holds a reference to httpquery
*
* @var kHttpQuery
* @access protected
*/
protected $HTTPQuery = null;
/**
* Urls parts, that needs to be matched by rewrite listeners
*
* @var Array
* @access protected
*/
protected $_partsToParse = Array ();
/**
* Category item prefix, that was found
*
* @var string|boolean
* @access protected
*/
protected $modulePrefix = false;
/**
* Template aliases for current theme
*
* @var Array
* @access protected
*/
protected $_templateAliases = null;
/**
* Domain-based primary language id
*
* @var int
* @access public
*/
public $primaryLanguageId = false;
/**
* Domain-based primary theme id
*
* @var int
* @access public
*/
public $primaryThemeId = false;
/**
* Possible url endings from ModRewriteUrlEnding configuration variable
*
* @var Array
* @access protected
*/
protected $_urlEndings = Array ('.html', '/', '');
/**
* Factory storage sub-set, containing mod-rewrite listeners, used during url building and parsing
*
* @var Array
* @access protected
*/
protected $rewriteListeners = Array ();
/**
* Constructor of kRewriteUrlProcessor class
*
* @param $manager
* @return kRewriteUrlProcessor
*/
public function __construct(&$manager)
{
parent::__construct($manager);
$this->HTTPQuery = $this->Application->recallObject('HTTPQuery');
// domain based primary language
$this->primaryLanguageId = $this->Application->siteDomainField('PrimaryLanguageId');
if (!$this->primaryLanguageId) {
// when domain-based language not found -> use site-wide language
$this->primaryLanguageId = $this->Application->GetDefaultLanguageId();
}
// domain based primary theme
$this->primaryThemeId = $this->Application->siteDomainField('PrimaryThemeId');
if (!$this->primaryThemeId) {
// when domain-based theme not found -> use site-wide theme
$this->primaryThemeId = $this->Application->GetDefaultThemeId(true);
}
$this->_initRewriteListeners();
}
/**
* Sets module prefix.
*
* @param string $prefix Unit config prefix.
*
* @return void
*/
public function setModulePrefix($prefix)
{
$this->modulePrefix = $prefix;
}
/**
* Parses url
*
* @return void
*/
public function parseRewriteURL()
{
$url = $this->Application->GetVar('_mod_rw_url_');
+ if ( !is_string($url) ) {
+ $url = '';
+ }
+
if ( $url ) {
$this->_redirectToDefaultUrlEnding($url);
$url = $this->_removeUrlEnding($url);
}
$cached = $this->_getCachedUrl($url);
if ( $cached !== false ) {
$vars = $cached['vars'];
$passed = $cached['passed'];
}
else {
$vars = $this->parse($url);
$passed = $vars['pass']; // also used in bottom of this method
unset($vars['pass']);
if ( !$this->_partsToParse ) {
// don't cache 404 Not Found
$this->_setCachedUrl($url, Array ('vars' => $vars, 'passed' => $passed));
}
else {
header('HTTP/1.0 404 Not Found');
}
if ( $this->Application->GetVarDirect('t', 'Post') ) {
// template from POST overrides template from URL.
$vars['t'] = $this->Application->GetVarDirect('t', 'Post');
if ( isset($vars['is_virtual']) && $vars['is_virtual'] ) {
$vars['m_cat_id'] = 0; // this is virtual template category (for Proj-CMS)
}
}
unset($vars['is_virtual']);
}
foreach ($vars as $name => $value) {
$this->HTTPQuery->Set($name, $value);
}
$this->_initAll(); // also will use parsed language to load phrases from it
$this->HTTPQuery->finalizeParsing($passed);
}
/**
* Detects url ending of given url
*
* @param string $url
* @return string
* @access protected
*/
protected function _findUrlEnding($url)
{
if ( !$url ) {
return '';
}
foreach ($this->_urlEndings as $url_ending) {
if ( mb_substr($url, mb_strlen($url) - mb_strlen($url_ending)) == $url_ending ) {
return $url_ending;
}
}
return '';
}
/**
* Removes url ending from url
*
* @param string $url
* @return string
* @access protected
*/
protected function _removeUrlEnding($url)
{
$url_ending = $this->_findUrlEnding($url);
if ( !$url_ending ) {
return $url;
}
return mb_substr($url, 0, mb_strlen($url) - mb_strlen($url_ending));
}
/**
* Redirects user to page with default url ending, where needed
*
* @param string $url
* @return void
* @access protected
*/
protected function _redirectToDefaultUrlEnding($url)
{
$default_ending = $this->Application->ConfigValue('ModRewriteUrlEnding');
if ( $this->_findUrlEnding($url) == $default_ending || !$this->Application->ConfigValue('ForceModRewriteUrlEnding') ) {
return;
}
// user manually typed url with different url ending -> redirect to same url with default url ending
$target_url = $this->Application->BaseURL() . $this->_removeUrlEnding($url) . $default_ending;
trigger_error('Mod-rewrite url "<strong>' . $_SERVER['REQUEST_URI'] . '</strong>" without "<strong>' . $default_ending . '</strong>" line ending used', E_USER_NOTICE);
$this->Application->Redirect('external:' . $target_url, Array ('response_code' => 301));
}
/**
* Returns url parsing result from cache or false, when not yet parsed
*
* @param $url
* @return Array|bool
* @access protected
*/
protected function _getCachedUrl($url)
{
if ( !$url || (defined('DBG_CACHE_URLS') && !DBG_CACHE_URLS) ) {
return false;
}
$sql = 'SELECT *
FROM ' . TABLE_PREFIX . 'CachedUrls
WHERE Hash = ' . kUtil::crc32($url) . ' AND DomainId = ' . (int)$this->Application->siteDomainField('DomainId');
$data = $this->Conn->GetRow($sql);
if ( $data ) {
$lifetime = (int)$data['LifeTime']; // in seconds
if ( ($lifetime > 0) && ($data['Cached'] + $lifetime < TIMENOW) ) {
// delete expired
$sql = 'DELETE FROM ' . TABLE_PREFIX . 'CachedUrls
WHERE UrlId = ' . $data['UrlId'];
$this->Conn->Query($sql);
return false;
}
return unserialize($data['ParsedVars']);
}
return false;
}
/**
* Caches url
*
* @param string $url
* @param Array $data
* @return void
* @access protected
*/
protected function _setCachedUrl($url, $data)
{
if ( !$url || (defined('DBG_CACHE_URLS') && !DBG_CACHE_URLS) ) {
return;
}
$vars = $data['vars'];
$passed = $data['passed'];
sort($passed);
// get expiration
if ( $vars['m_cat_id'] > 0 ) {
$sql = 'SELECT PageExpiration
FROM ' . TABLE_PREFIX . 'Categories
WHERE CategoryId = ' . $vars['m_cat_id'];
$expiration = $this->Conn->GetOne($sql);
}
// get prefixes
$prefixes = Array ();
$m_index = array_search('m', $passed);
if ( $m_index !== false ) {
unset($passed[$m_index]);
if ( $vars['m_cat_id'] > 0 ) {
$prefixes[] = 'c:' . $vars['m_cat_id'];
}
$prefixes[] = 'lang:' . $vars['m_lang'];
$prefixes[] = 'theme:' . $vars['m_theme'];
}
foreach ($passed as $prefix) {
if ( array_key_exists($prefix . '_id', $vars) && is_numeric($vars[$prefix . '_id']) ) {
$prefixes[] = $prefix . ':' . $vars[$prefix . '_id'];
}
else {
$prefixes[] = $prefix;
}
}
$fields_hash = Array (
'Url' => $url,
'Hash' => kUtil::crc32($url),
'DomainId' => (int)$this->Application->siteDomainField('DomainId'),
'Prefixes' => $prefixes ? '|' . implode('|', $prefixes) . '|' : '',
'ParsedVars' => serialize($data),
'Cached' => adodb_mktime(),
'LifeTime' => isset($expiration) && is_numeric($expiration) ? $expiration : -1
);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'CachedUrls');
}
/**
* Loads all registered rewrite listeners, so they could be quickly accessed later
*
* @access protected
*/
protected function _initRewriteListeners()
{
static $init_done = false;
if ($init_done || count($this->Application->RewriteListeners) == 0) {
// not initialized OR mod-rewrite url with missing config cache
return ;
}
foreach ($this->Application->RewriteListeners as $prefix => $listener_data) {
foreach ($listener_data['listener'] as $index => $rewrite_listener) {
list ($listener_prefix, $listener_method) = explode(':', $rewrite_listener);
// don't use temp variable, since it will swap objects in Factory in PHP5
$this->rewriteListeners[$prefix][$index] = Array ();
$this->rewriteListeners[$prefix][$index][0] = $this->Application->recallObject($listener_prefix);
$this->rewriteListeners[$prefix][$index][1] = $listener_method;
}
}
define('MOD_REWRITE_URL_ENDING', $this->Application->ConfigValue('ModRewriteUrlEnding'));
$init_done = true;
}
/**
* Parses given string into a set of variables (url in this case)
*
* @param string $string
* @param string $pass_name
* @return Array
* @access public
*/
public function parse($string, $pass_name = 'pass')
{
// external url (could be back this website as well)
if ( preg_match('/external:(.*)/', $string, $regs) ) {
$string = $regs[1];
}
$vars = Array ();
$url_components = parse_url($string);
if ( isset($url_components['query']) ) {
parse_str(html_entity_decode($url_components['query']), $url_params);
if ( isset($url_params[ENV_VAR_NAME]) ) {
$url_params = array_merge($url_params, $this->manager->plain->parse($url_params[ENV_VAR_NAME], $pass_name));
unset($url_params[ENV_VAR_NAME]);
}
$vars = array_merge($vars, $url_params);
}
$this->_fixPass($vars, $pass_name);
if ( isset($url_components['path']) ) {
if ( BASE_PATH ) {
$string = preg_replace('/^' . preg_quote(BASE_PATH, '/') . '/', '', $url_components['path'], 1);
}
else {
$string = $url_components['path'];
}
$string = $this->_removeUrlEnding(trim($string, '/'));
}
else {
$string = '';
}
$url_parts = $string ? explode('/', mb_strtolower($string)) : Array ();
$this->setModulePrefix(false);
$this->_partsToParse = $url_parts;
if ( ($this->HTTPQuery->Get('rewrite') == 'on') || !$url_parts ) {
$this->_setDefaultValues($vars);
}
if ( !$url_parts ) {
$this->_initAll();
$vars['t'] = $this->Application->UrlManager->getTemplateName();
return $vars;
}
$this->_parseLanguage($url_parts, $vars);
$this->_parseTheme($url_parts, $vars);
// http://site-url/<language>/<theme>/<category>[_<category_page>]/<template>/<module_page>
// http://site-url/<language>/<theme>/<category>[_<category_page>]/<module_page> (category-based section template)
// http://site-url/<language>/<theme>/<category>[_<category_page>]/<template>/<module_item>
// http://site-url/<language>/<theme>/<category>[_<category_page>]/<module_item> (category-based detail template)
// http://site-url/<language>/<theme>/<rl_injections>/<category>[_<category_page>]/<rl_part> (customized url)
if ( !$this->_processRewriteListeners($url_parts, $vars) ) {
// rewrite listener wasn't able to determine template
$this->_parsePhysicalTemplate($url_parts, $vars);
if ( ($this->modulePrefix === false) && $vars['m_cat_id'] && !$this->_partsToParse ) {
// no category item found, but category found and all url matched -> module index page
return $vars;
}
}
if ( $this->_partsToParse ) {
/** @var kThemesHelper $themes_helper */
$themes_helper = $this->Application->recallObject('ThemesHelper');
$not_found = $this->Application->ConfigValue('ErrorTemplate');
$vars['t'] = $not_found ? $not_found : 'error_notfound';
$vars['m_cat_id'] = $themes_helper->getPageByTemplate($vars['t'], $vars['m_theme']);
$vars['pass'] = array('m');
}
return $vars;
}
/**
* Ensures, that "m" is always in "pass" variable
*
* @param Array $vars
* @param string $pass_name
* @return void
* @access protected
*/
protected function _fixPass(&$vars, $pass_name)
{
if ( isset($vars[$pass_name]) ) {
$vars[$pass_name] = array_unique(explode(',', 'm,' . $vars[$pass_name]));
}
else {
$vars[$pass_name] = Array ('m');
}
}
/**
* Initializes theme & language based on parse results
*
* @return void
* @access protected
*/
protected function _initAll()
{
$this->Application->VerifyThemeId();
$this->Application->VerifyLanguageId();
// no need, since we don't have any cached phrase IDs + nobody will use PhrasesCache::LanguageId soon
// $this->Application->Phrases->Init('phrases');
}
/**
* Sets default parsed values before actual url parsing (only, for empty url)
*
* @param Array $vars
* @access protected
*/
protected function _setDefaultValues(&$vars)
{
$defaults = Array (
'm_cat_id' => 0, // no category
'm_cat_page' => 1, // first category page
'm_opener' => 's', // stay on same page
't' => 'index' // main site page
);
if ($this->primaryLanguageId) {
// domain-based primary language
$defaults['m_lang'] = $this->primaryLanguageId;
}
if ($this->primaryThemeId) {
// domain-based primary theme
$defaults['m_theme'] = $this->primaryThemeId;
}
foreach ($defaults as $default_key => $default_value) {
if ($this->HTTPQuery->Get($default_key) === false) {
$vars[$default_key] = $default_value;
}
}
}
/**
* Processes url using rewrite listeners
*
* Pattern: Chain of Command
*
* @param Array $url_parts
* @param Array $vars
* @return bool
* @access protected
*/
protected function _processRewriteListeners(&$url_parts, &$vars)
{
$this->_initRewriteListeners();
$page_number = $this->_parsePage($url_parts, $vars);
foreach ($this->rewriteListeners as $prefix => $listeners) {
// set default page
// $vars[$prefix . '_Page'] = 1; // will override page in session in case, when none is given in url
if ($page_number) {
// page given in url - use it
$vars[$prefix . '_id'] = 0;
$vars[$prefix . '_Page'] = $page_number;
}
// $listeners[1] - listener, used for parsing
$listener_result = call_user_func_array(
$listeners[1],
array(REWRITE_MODE_PARSE, $prefix, &$vars, &$url_parts)
);
if ($listener_result === false) {
// will not proceed to other methods
return true;
}
}
// will proceed to other methods
return false;
}
/**
* Set's page (when found) to all modules
*
* @param Array $url_parts
* @param Array $vars
* @return string
* @access protected
*
* @todo Should find a way, how to determine what rewrite listener page is it
*/
protected function _parsePage(&$url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$page_number = end($url_parts);
if (!is_numeric($page_number)) {
return false;
}
array_pop($url_parts);
$this->partParsed($page_number, 'rtl');
return $page_number;
}
/**
* Gets language part from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
* @access protected
*/
protected function _parseLanguage(&$url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$url_part = reset($url_parts);
$sql = 'SELECT LanguageId, IF(LOWER(PackName) = ' . $this->Conn->qstr($url_part) . ', 2, PrimaryLang) AS SortKey
FROM ' . TABLE_PREFIX . 'Languages
WHERE Enabled = 1
ORDER BY SortKey DESC';
$language_info = $this->Conn->GetRow($sql);
if ($language_info && $language_info['LanguageId'] && $language_info['SortKey']) {
// primary language will be selected in case, when $url_part doesn't match to other's language pack name
// don't use next enabled language, when primary language is disabled
$vars['m_lang'] = $language_info['LanguageId'];
if ($language_info['SortKey'] == 2) {
// language was found by pack name
array_shift($url_parts);
$this->partParsed($url_part);
}
elseif ($this->primaryLanguageId) {
// use domain-based primary language instead of site-wide primary language
$vars['m_lang'] = $this->primaryLanguageId;
}
return true;
}
return false;
}
/**
* Gets theme part from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
*/
protected function _parseTheme(&$url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$url_part = reset($url_parts);
$sql = 'SELECT ThemeId, IF(LOWER(Name) = ' . $this->Conn->qstr($url_part) . ', 2, PrimaryTheme) AS SortKey, TemplateAliases
FROM ' . TABLE_PREFIX . 'Themes
WHERE Enabled = 1
ORDER BY SortKey DESC';
$theme_info = $this->Conn->GetRow($sql);
if ($theme_info && $theme_info['ThemeId'] && $theme_info['SortKey']) {
// primary theme will be selected in case, when $url_part doesn't match to other's theme name
// don't use next enabled theme, when primary theme is disabled
$vars['m_theme'] = $theme_info['ThemeId'];
if ($theme_info['TemplateAliases']) {
$this->_templateAliases = unserialize($theme_info['TemplateAliases']);
}
else {
$this->_templateAliases = Array ();
}
if ($theme_info['SortKey'] == 2) {
// theme was found by name
array_shift($url_parts);
$this->partParsed($url_part);
}
elseif ($this->primaryThemeId) {
// use domain-based primary theme instead of site-wide primary theme
$vars['m_theme'] = $this->primaryThemeId;
}
return true;
}
$vars['m_theme'] = 0; // required, because used later for category/template detection
return false;
}
/**
* Parses real template name from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
*/
protected function _parsePhysicalTemplate($url_parts, &$vars)
{
if ( !$url_parts ) {
return false;
}
/** @var kThemesHelper $themes_helper */
$themes_helper = $this->Application->recallObject('ThemesHelper');
do {
$index_added = false;
$template_path = implode('/', $url_parts);
$template_found = $themes_helper->getTemplateId($template_path, $vars['m_theme']);
if ( !$template_found ) {
$index_added = true;
$template_found = $themes_helper->getTemplateId($template_path . '/index', $vars['m_theme']);
}
if ( !$template_found ) {
array_shift($url_parts);
}
} while ( !$template_found && $url_parts );
if ( $template_found ) {
$template_parts = explode('/', $template_path);
$vars['t'] = $template_path . ($index_added ? '/index' : '');
while ( $template_parts ) {
$this->partParsed(array_pop($template_parts), 'rtl');
}
// 1. will damage actual category during category item review add process
// 2. will use "use_section" parameter of "m_Link" tag to gain same effect
// $vars['m_cat_id'] = $themes_helper->getPageByTemplate($template_path, $vars['m_theme']);
return true;
}
return false;
}
/**
* Returns environment variable values for given prefix (uses directly given params, when available)
*
* @param string $prefix_special
* @param Array $params
* @param bool $keep_events
* @return Array
* @access public
*/
public function getProcessedParams($prefix_special, &$params, $keep_events)
{
list ($prefix) = explode('.', $prefix_special);
/** @var Array $query_vars */
$query_vars = $this->Application->getUnitOption($prefix, 'QueryString', Array ());
if ( !$query_vars ) {
// given prefix doesn't use "env" variable to pass it's data
return false;
}
$event_key = array_search('event', $query_vars);
if ( $event_key ) {
// pass through event of this prefix
unset($query_vars[$event_key]);
}
if ( array_key_exists($prefix_special . '_event', $params) && !$params[$prefix_special . '_event'] ) {
// if empty event, then remove it from url
unset($params[$prefix_special . '_event']);
}
// if pass events is off and event is not implicity passed
if ( !$keep_events && !array_key_exists($prefix_special . '_event', $params) ) {
unset($params[$prefix_special . '_event']); // remove event from url if requested
//otherwise it will use value from get_var
}
$processed_params = Array ();
foreach ($query_vars as $var_name) {
// if value passed in params use it, otherwise use current from application
$var_name = $prefix_special . '_' . $var_name;
$processed_params[$var_name] = array_key_exists($var_name, $params) ? $params[$var_name] : $this->Application->GetVar($var_name);
if ( array_key_exists($var_name, $params) ) {
unset($params[$var_name]);
}
}
return $processed_params;
}
/**
* Returns module item details template specified in given category custom field for given module prefix
*
* @param int|Array $category
* @param string $module_prefix
* @param int $theme_id
* @return string
* @access public
* @todo Move to kPlainUrlProcessor
*/
public function GetItemTemplate($category, $module_prefix, $theme_id = null)
{
if ( !isset($theme_id) ) {
$theme_id = $this->Application->GetVar('m_theme');
}
$category_id = is_array($category) ? $category['CategoryId'] : $category;
$cache_key = __CLASS__ . '::' . __FUNCTION__ . '[%CIDSerial:' . $category_id . '%][%ThemeIDSerial:' . $theme_id . '%]' . $module_prefix;
$cached_value = $this->Application->getCache($cache_key);
if ( $cached_value !== false ) {
return $cached_value;
}
if ( !is_array($category) ) {
if ( $category == 0 ) {
$category = $this->Application->findModule('Var', $module_prefix, 'RootCat');
}
$sql = 'SELECT c.ParentPath, c.CategoryId
FROM ' . TABLE_PREFIX . 'Categories AS c
WHERE c.CategoryId = ' . $category;
$category = $this->Conn->GetRow($sql);
}
$parent_path = implode(',', explode('|', substr($category['ParentPath'], 1, -1)));
// item template is stored in module' system custom field - need to get that field Id
$primary_lang = $this->Application->GetDefaultLanguageId();
$item_template_field_id = $this->getItemTemplateCustomField($module_prefix);
// looking for item template through cats hierarchy sorted by parent path
$query = ' SELECT ccd.l' . $primary_lang . '_cust_' . $item_template_field_id . ',
FIND_IN_SET(c.CategoryId, ' . $this->Conn->qstr($parent_path) . ') AS Ord1,
c.CategoryId, c.Name, ccd.l' . $primary_lang . '_cust_' . $item_template_field_id . '
FROM ' . TABLE_PREFIX . 'Categories AS c
LEFT JOIN ' . TABLE_PREFIX . 'CategoryCustomData AS ccd
ON ccd.ResourceId = c.ResourceId
WHERE c.CategoryId IN (' . $parent_path . ') AND ccd.l' . $primary_lang . '_cust_' . $item_template_field_id . ' != \'\'
ORDER BY FIND_IN_SET(c.CategoryId, ' . $this->Conn->qstr($parent_path) . ') DESC';
$item_template = $this->Conn->GetOne($query);
if ( !isset($this->_templateAliases) ) {
// when empty url OR mod-rewrite disabled
/** @var kThemesHelper $themes_helper */
$themes_helper = $this->Application->recallObject('ThemesHelper');
$sql = 'SELECT TemplateAliases
FROM ' . TABLE_PREFIX . 'Themes
WHERE ThemeId = ' . (int)$themes_helper->getCurrentThemeId();
$template_aliases = $this->Conn->GetOne($sql);
$this->_templateAliases = $template_aliases ? unserialize($template_aliases) : Array ();
}
if ( substr($item_template, 0, 1) == '#' ) {
// it's template alias + "#" isn't allowed in filenames
$item_template = (string)getArrayValue($this->_templateAliases, $item_template);
}
$this->Application->setCache($cache_key, $item_template);
return $item_template;
}
/**
* Returns category custom field id, where given module prefix item template name is stored
*
* @param string $module_prefix
* @return int
* @access public
* @todo Move to kPlainUrlProcessor; decrease visibility, since used only during upgrade
*/
public function getItemTemplateCustomField($module_prefix)
{
$cache_key = __CLASS__ . '::' . __FUNCTION__ . '[%CfSerial%]:' . $module_prefix;
$cached_value = $this->Application->getCache($cache_key);
if ($cached_value !== false) {
return $cached_value;
}
$sql = 'SELECT CustomFieldId
FROM ' . TABLE_PREFIX . 'CustomFields
WHERE FieldName = ' . $this->Conn->qstr($module_prefix . '_ItemTemplate');
$item_template_field_id = $this->Conn->GetOne($sql);
$this->Application->setCache($cache_key, $item_template_field_id);
return $item_template_field_id;
}
/**
* Marks url part as parsed
*
* @param string $url_part
* @param string $parse_direction
* @access public
*/
public function partParsed($url_part, $parse_direction = 'ltr')
{
if ( !$this->_partsToParse ) {
return ;
}
if ( $parse_direction == 'ltr' ) {
$expected_url_part = reset($this->_partsToParse);
if ( $url_part == $expected_url_part ) {
array_shift($this->_partsToParse);
}
}
else {
$expected_url_part = end($this->_partsToParse);
if ( $url_part == $expected_url_part ) {
array_pop($this->_partsToParse);
}
}
if ( $url_part != $expected_url_part ) {
trigger_error('partParsed: expected URL part "<strong>' . $expected_url_part . '</strong>", received URL part "<strong>' . $url_part . '</strong>"', E_USER_NOTICE);
}
}
/**
* Determines if there is more to parse in url
*
* @return bool
* @access public
*/
public function moreToParse()
{
return count($this->_partsToParse) > 0;
}
/**
* Builds url
*
* @param string $t
* @param Array $params
* @param string $pass
* @param bool $pass_events
* @param bool $env_var
* @return string
* @access public
*/
public function build($t, $params, $pass = 'all', $pass_events = false, $env_var = false)
{
if ( $this->Application->GetVar('admin') || (array_key_exists('admin', $params) && $params['admin']) ) {
$params['admin'] = 1;
if ( !array_key_exists('editing_mode', $params) ) {
$params['editing_mode'] = EDITING_MODE;
}
}
$ret = '';
$env = '';
if ( isset($params['__SSL__']) ) {
unset($params['__SSL__']);
}
$catalog_item_found = false;
$pass_info = $this->getPassInfo($pass);
if ( $pass_info ) {
if ( $pass_info[0] == 'm' ) {
array_shift($pass_info);
}
$inject_parts = Array (); // url parts for beginning of url
$params['t'] = $t; // make template available for rewrite listeners
$params['pass_template'] = true; // by default we keep given template in resulting url
if ( !array_key_exists('pass_category', $params) ) {
$params['pass_category'] = false; // by default we don't keep categories in url
}
foreach ($pass_info as $pass_index => $pass_element) {
list ($prefix) = explode('.', $pass_element);
$catalog_item = $this->Application->findModule('Var', $prefix) && $this->Application->getUnitOption($prefix, 'CatalogItem');
if ( array_key_exists($prefix, $this->rewriteListeners) ) {
// if next prefix is same as current, but with special => exclude current prefix from url
$next_prefix = array_key_exists($pass_index + 1, $pass_info) ? $pass_info[$pass_index + 1] : false;
if ( $next_prefix ) {
$next_prefix = substr($next_prefix, 0, strlen($prefix) + 1);
if ( $prefix . '.' == $next_prefix ) {
continue;
}
}
// rewritten url part
$url_part = $this->BuildModuleEnv($pass_element, $params, $pass_events);
if ( is_string($url_part) && $url_part ) {
$ret .= $url_part . '/';
if ( $catalog_item ) {
// pass category later only for catalog items
$catalog_item_found = true;
}
}
elseif ( is_array($url_part) ) {
// rewrite listener want to insert something at the beginning of url too
if ( $url_part[0] ) {
$inject_parts[] = $url_part[0];
}
if ( $url_part[1] ) {
$ret .= $url_part[1] . '/';
}
if ( $catalog_item ) {
// pass category later only for catalog items
$catalog_item_found = true;
}
}
elseif ( $url_part === false ) {
// rewrite listener decided not to rewrite given $pass_element
$env .= ':' . $this->manager->plain->BuildModuleEnv($pass_element, $params, $pass_events);
}
}
else {
$env .= ':' . $this->manager->plain->BuildModuleEnv($pass_element, $params, $pass_events);
}
}
if ( $catalog_item_found || preg_match('/c\.[-\d]*/', implode(',', $pass_info)) ) {
// "c" prefix is present -> keep category
$params['pass_category'] = true;
}
$params['inject_parts'] = $inject_parts;
$ret = $this->BuildModuleEnv('m', $params, $pass_events) . '/' . $ret;
$cat_processed = array_key_exists('category_processed', $params) && $params['category_processed'];
// remove temporary parameters used by listeners
unset($params['t'], $params['inject_parts'], $params['pass_template'], $params['pass_category'], $params['category_processed']);
$ret = trim($ret, '/');
if ( isset($params['url_ending']) ) {
if ( $ret ) {
$ret .= $params['url_ending'];
}
unset($params['url_ending']);
}
elseif ( $ret ) {
$ret .= MOD_REWRITE_URL_ENDING;
}
if ( $env ) {
$params[ENV_VAR_NAME] = ltrim($env, ':');
}
}
unset($params['pass'], $params['opener'], $params['m_event']);
// TODO: why?
// $ret = str_replace('%2F', '/', urlencode($ret));
if ( $params ) {
$params_str = http_build_query($params);
$ret .= '?' . str_replace('%23', '#', $params_str);
}
return $ret;
}
/**
* Builds env part that corresponds prefix passed
*
* @param string $prefix_special item's prefix & [special]
* @param Array $params url params
* @param bool $pass_events
* @return string
* @access protected
*/
protected function BuildModuleEnv($prefix_special, &$params, $pass_events = false)
{
list ($prefix) = explode('.', $prefix_special);
$url_parts = Array ();
$listener = $this->rewriteListeners[$prefix][0];
$ret = call_user_func_array(
$listener,
array(REWRITE_MODE_BUILD, $prefix_special, &$params, &$url_parts, $pass_events)
);
return $ret;
}
}
Index: branches/5.2.x/core/kernel/utility/http_query.php
===================================================================
--- branches/5.2.x/core/kernel/utility/http_query.php (revision 16801)
+++ branches/5.2.x/core/kernel/utility/http_query.php (revision 16802)
@@ -1,817 +1,823 @@
<?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!');
class kHTTPQuery extends Params {
/**
* Cache of QueryString parameters
* from config, that are represented
* in environment variable
*
* @var Array
*/
protected $discoveredUnits = Array ();
/**
* $_POST vars
*
* @var Array
* @access private
*/
var $Post;
/**
* $_GET vars
*
* @var Array
* @access private
*/
var $Get;
/**
* $_COOKIE vars
*
* @var Array
* @access private
*/
var $Cookie = array();
/**
* $_SERVER vars
*
* @var Array
* @access private
*/
var $Server;
/**
* $_ENV vars
*
* @var Array
* @access private
*/
var $Env;
/**
* Order in what write
* all vars together in
* the same array
*
* @var string
*/
var $Order;
/**
* Uploaded files info
*
* @var Array
* @access private
*/
var $Files;
var $specialsToRemove = Array();
/**
* SessionID is given via "sid" variable in query string
*
* @var bool
*/
var $_sidInQueryString = false;
/**
* Trust information, provided by proxy
*
* @var bool
*/
protected $_trustProxy = false;
/**
* Loads info from $_POST, $_GET and related arrays into common place.
*
* @param string $order Order.
*
* @throws RuntimeException When "Proxy" header is present in Web Request.
*/
public function __construct($order = 'CGPF')
{
parent::__construct();
// Don't process cookies from CLI.
if ( PHP_SAPI === 'cli' ) {
$order = str_replace('C', '', $order);
}
$this->Order = $order;
if ( isset($_SERVER['HTTP_PROXY']) && PHP_SAPI !== 'cli' ) {
throw new RuntimeException('Web Requests with "Proxy" header are forbidden.');
}
if ( isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) {
// When AJAX request is made from jQuery, then create ajax variable,
// so any logic based in it (like redirects) will not break down.
$_GET['ajax'] = 'yes';
}
$this->_trustProxy = kUtil::getSystemConfig()->get('TrustProxy');
}
/**
* Discovers unit form request and returns it's QueryString option on success
*
* @param string $prefix_special
*
* @return Array|bool
* @access public
*/
public function discoverUnit($prefix_special)
{
list($prefix) = explode('.', $prefix_special);
$query_string = $this->getQueryString($prefix);
if ($query_string) {
// only units with QueryString option can be discovered
$this->discoveredUnits[$prefix_special] = $query_string;
return $query_string;
}
unset( $this->discoveredUnits[$prefix] );
return false;
}
/**
* Returns units, passed in request
*
* @param bool $prefix_special_only
* @return Array
* @access protected
*/
public function getDiscoveredUnits($prefix_special_only = true)
{
return $prefix_special_only ? array_keys( $this->discoveredUnits ) : $this->discoveredUnits;
}
/**
* Returns QueryMap for requested unit config.
* In case if unit config is a clone, then get parent item's (from prefix) config to create clone
*
* @param string $prefix
* @return Array
* @access protected
*/
protected function getQueryString($prefix)
{
$ret = $this->Application->getUnitOption($prefix, 'QueryString', Array ());
if ( !$ret && preg_match('/(.*?)-(.*)/', $prefix, $regs) ) {
// "#prefix" (new format), "prefix" (old format)
return $this->_getQueryString('#' . $regs[2]);
}
return $ret;
}
/**
* Returns query string (with safety check against missing prefixes)
*
* @param string $prefix
* @return Array
*/
private function _getQueryString($prefix)
{
if ( $this->Application->prefixRegistred($prefix) ) {
return $this->Application->getUnitOption($prefix, 'QueryString');
}
return substr($prefix, 0, 1) == '#' ? $this->_getQueryString( substr($prefix, 1) ) : Array ();
}
/**
* Removes specials from request
*
* @param Array $array
* @return Array
* @access protected
*/
protected function _removeSpecials($array)
{
$ret = Array ();
$removed = false;
foreach ($this->specialsToRemove as $prefix_special => $flag) {
if ( $flag ) {
$removed = true;
list ($prefix, $special) = explode('.', $prefix_special, 2);
foreach ($array as $key => $val) {
$new_key = preg_match("/^" . $prefix . "[._]{1}" . $special . "(.*)/", $key, $regs) ? $prefix . $regs[1] : $key;
$ret[$new_key] = is_array($val) ? $this->_removeSpecials($val) : $val;
}
}
}
return $removed ? $ret : $array;
}
public function process()
{
$this->AddAllVars();
$this->removeSpecials();
ini_set('magic_quotes_gpc', 0);
$this->Application->UrlManager->LoadStructureTemplateMapping();
$this->AfterInit();
}
/**
* All all requested vars to
* common storage place
*
* @return void
* @access protected
*/
protected function AddAllVars()
{
for ($i = 0; $i < strlen($this->Order); $i++) {
switch ($this->Order[$i]) {
case 'G':
$this->Get = $this->AddVars($_GET);
if ( array_key_exists('sid', $_GET) ) {
$this->_sidInQueryString = true;
}
$vars = $this->Application->processQueryString($this->Get(ENV_VAR_NAME));
if ( array_key_exists('sid', $vars) ) {
// used by Session::GetPassedSIDValue
$this->Get['sid'] = $vars['sid'];
}
$this->AddParams($vars);
break;
case 'P':
$this->Post = $this->AddVars($_POST);
$this->convertPostEvents();
$this->_processPostEnvVariables();
break;
case 'C':
$this->Cookie = $this->AddVars($_COOKIE);
break;
/*case 'E';
$this->Env = $this->AddVars($_ENV, false); //do not strip slashes!
break;
case 'S';
$this->Server = $this->AddVars($_SERVER, false); //do not strip slashes!
break;*/
case 'F';
$this->convertFiles();
$this->Files = $this->MergeVars($_FILES); // , false); //do not strip slashes!
break;
}
}
}
/**
* Allow POST variables, that names were transformed by PHP ("." replaced with "_") to
* override variables, that were virtually created through environment variable parsing
*
*/
function _processPostEnvVariables()
{
$passed = $this->Get('passed');
if ( !$passed ) {
return;
}
$passed = explode(',', $passed);
foreach ($passed as $prefix_special) {
if ( strpos($prefix_special, '.') === false ) {
continue;
}
list ($prefix, $special) = explode('.', $prefix_special);
$query_map = $this->getQueryString($prefix);
$post_prefix_special = $prefix . '_' . $special;
foreach ($query_map as $var_name) {
if ( array_key_exists($post_prefix_special . '_' . $var_name, $this->Post) ) {
$this->Set($prefix_special . '_' . $var_name, $this->Post[$post_prefix_special . '_' . $var_name]);
}
}
}
}
/**
* Removes requested specials from all request variables
*
* @return void
* @access protected
*/
protected function removeSpecials()
{
$this->specialsToRemove = $this->Get('remove_specials');
if ( $this->specialsToRemove ) {
foreach ($this->specialsToRemove as $prefix_special => $flag) {
if ( $flag && strpos($prefix_special, '.') === false ) {
unset($this->specialsToRemove[$prefix_special]);
trigger_error('Incorrect usage of "<strong>remove_specials[' . $prefix_special . ']</strong>" field (no special found)', E_USER_NOTICE);
}
}
$this->_Params = $this->_removeSpecials($this->_Params);
}
}
/**
* Finishes initialization of kHTTPQuery class
*
* @return void
* @access protected
* @todo: only uses build-in rewrite listeners, when cache is build for the first time
*/
protected function AfterInit()
{
$rewrite_url = $this->Get('_mod_rw_url_');
+ if ( !is_string($rewrite_url) ) {
+ $rewrite_url = '';
+ }
+
if ( $this->Application->RewriteURLs() || $rewrite_url ) {
// maybe call onafterconfigread here
$this->Application->UrlManager->initRewrite();
if ( defined('DEBUG_MODE') && $this->Application->isDebugMode() ) {
$this->Application->Debugger->profileStart('url_parsing', 'Parsing <b>MOD_REWRITE</b> url');
$this->Application->UrlManager->rewrite->parseRewriteURL();
$description = 'Parsing <b>MOD_REWRITE</b> url (template: <b>' . $this->Get('t') . '</b>)';
$this->Application->Debugger->profileFinish('url_parsing', $description);
}
else {
$this->Application->UrlManager->rewrite->parseRewriteURL();
}
if ( !$rewrite_url && $this->rewriteRedirectRequired() ) {
// rewrite url is missing (e.g. not a script from tools folder)
$url_params = $this->getRedirectParams();
// no idea about how to check, that given template require category to be passed with it, so pass anyway
$url_params['pass_category'] = 1;
$url_params['response_code'] = 301; // Moved Permanently
trigger_error('Non mod-rewrite url "<strong>' . $_SERVER['REQUEST_URI'] . '</strong>" used', E_USER_NOTICE);
$this->Application->Redirect('', $url_params);
}
if ( $this->Application->GetVar('is_friendly_url') ) {
$url_params = $this->getRedirectParams();
// No idea about how to check, that given template
// require category to be passed with it, so pass anyway.
$url_params['pass_category'] = 1;
$this->Application->Redirect('', $url_params);
}
}
else {
$this->Application->VerifyThemeId();
$this->Application->VerifyLanguageId();
}
$virtual_template = $this->Application->getVirtualPageTemplate($this->Get('m_cat_id'));
if ( ($virtual_template !== false) && preg_match('/external:(.*)/', $virtual_template) ) {
trigger_error('URL of page, that has "External URL" set was accessed: "<strong>' . $_SERVER['REQUEST_URI'] . '</strong>"', E_USER_NOTICE);
$this->Application->Redirect($virtual_template);
}
}
/**
* Checks, that non-rewrite url was visited and it's automatic rewrite is required
*
* @return bool
*/
function rewriteRedirectRequired()
{
$redirect_conditions = Array (
!$this->IsHTTPSRedirect(), // not https <-> http redirect
!$this->refererIsOurSite(), // referer doesn't match ssl path or non-ssl domain (same for site domains)
!defined('GW_NOTIFY'), // not in payment gateway notification script
preg_match('/[\/]{0,1}index.php[\/]{0,1}/', $_SERVER['PHP_SELF']), // "index.php" was visited
$this->Get('t') != 'index', // not on index page
);
$perform_redirect = true;
foreach ($redirect_conditions as $redirect_condition) {
$perform_redirect = $perform_redirect && $redirect_condition;
if (!$perform_redirect) {
return false;
}
}
return true;
}
/**
* This is redirect from https to http or via versa
*
* @return bool
*/
function IsHTTPSRedirect()
{
$http_referer = array_key_exists('HTTP_REFERER', $_SERVER) ? $_SERVER['HTTP_REFERER'] : false;
return (
( PROTOCOL == 'https://' && preg_match('#http:\/\/#', $http_referer) )
||
( PROTOCOL == 'http://' && preg_match('#https:\/\/#', $http_referer) )
);
}
/**
* Checks, that referer is out site
*
* @return bool
*/
function refererIsOurSite()
{
if ( !array_key_exists('HTTP_REFERER', $_SERVER) ) {
// no referer -> don't care what happens
return false;
}
/** @var SiteHelper $site_helper */
$site_helper = $this->Application->recallObject('SiteHelper');
$found = false;
$http_referer = $_SERVER['HTTP_REFERER'];
preg_match('/^(.*?):\/\/(.*?)(\/|$)/', $http_referer, $regs); // 1 - protocol, 2 - domain
if ($regs[1] == 'https') {
$found = $site_helper->getDomainByName('SSLUrl', $http_referer) > 0;
if (!$found) {
// check if referer starts with our ssl url
$ssl_url = $this->Application->ConfigValue('SSL_URL');
$found = $ssl_url && preg_match('/^' . preg_quote($ssl_url, '/') . '/', $http_referer);
}
}
else {
$found = $site_helper->getDomainByName('DomainName', $regs[2]) > 0;
if (!$found) {
$found = $regs[2] == DOMAIN;
}
}
return $found;
}
function convertFiles()
{
if ( !$_FILES ) {
return ;
}
$tmp = Array ();
$file_keys = Array ('error', 'name', 'size', 'tmp_name', 'type');
foreach ($_FILES as $file_name => $file_info) {
if ( is_array($file_info['error']) ) {
$tmp[$file_name] = $this->getArrayLevel($file_info['error'], $file_name);
}
else {
$normal_files[$file_name] = $file_info;
}
}
if ( !$tmp ) {
return ;
}
$files = $_FILES;
$_FILES = Array ();
foreach ($tmp as $prefix => $prefix_files) {
$anchor =& $_FILES;
foreach ($prefix_files['keys'] as $key) {
$anchor =& $anchor[$key];
}
foreach ($prefix_files['value'] as $field_name) {
unset($inner_anchor, $copy);
$work_copy = $prefix_files['keys'];
foreach ($file_keys as $file_key) {
$inner_anchor =& $files[$prefix][$file_key];
if ( isset($copy) ) {
$work_copy = $copy;
}
else {
$copy = $work_copy;
}
array_shift($work_copy);
foreach ($work_copy as $prefix_file_key) {
$inner_anchor =& $inner_anchor[$prefix_file_key];
}
$anchor[$field_name][$file_key] = $inner_anchor[$field_name];
}
}
}
// keys: img_temp, 0, values: LocalPath, ThumbPath
}
function getArrayLevel(&$level, $prefix='')
{
$ret['keys'] = $prefix ? Array($prefix) : Array();
$ret['value'] = Array();
foreach($level as $level_key => $level_value)
{
if( is_array($level_value) )
{
$ret['keys'][] = $level_key;
$tmp = $this->getArrayLevel($level_value);
$ret['keys'] = array_merge($ret['keys'], $tmp['keys']);
$ret['value'] = array_merge($ret['value'], $tmp['value']);
}
else
{
$ret['value'][] = $level_key;
}
}
return $ret;
}
/**
* Overwrites GET events with POST events in case if they are set and not empty
*
* @return void
* @access protected
*/
protected function convertPostEvents()
{
/** @var Array $events */
$events = $this->Get('events', Array ());
if ( is_array($events) ) {
$events = array_filter($events);
foreach ($events as $prefix_special => $event_name) {
$this->Set($prefix_special . '_event', $event_name);
}
}
}
function finalizeParsing($passed = Array())
{
if (!$passed) {
return;
}
foreach ($passed as $passed_prefix) {
$this->discoverUnit($passed_prefix); // from mod-rewrite url parsing
}
$this->Set('passed', implode(',', $this->getDiscoveredUnits()));
}
/**
* Saves variables from array specified
* into common variable storage place
*
* @param Array $array
* @param bool $strip_slashes
* @return Array
* @access private
*/
function AddVars($array, $strip_slashes = true)
{
if ( $strip_slashes ) {
$array = $this->StripSlashes($array);
}
foreach ($array as $key => $value) {
$this->Set($key, $value);
}
return $array;
}
function MergeVars($array, $strip_slashes = true)
{
if ( $strip_slashes ) {
$array = $this->StripSlashes($array);
}
foreach ($array as $key => $value_array) {
// $value_array is an array too
$this->_Params = kUtil::array_merge_recursive($this->_Params, Array ($key => $value_array));
}
return $array;
}
function StripSlashes($array)
{
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = $this->StripSlashes($value);
}
else {
if (!$this->Application->isAdmin) {
// TODO: always escape output instead of input
$value = kUtil::escape($value, kUtil::ESCAPE_HTML);
}
$array[$key] = $value;
}
}
return $array;
}
/**
* Removes forceful escaping done to the variable upon Front-End submission.
*
* @param string|array $value Value.
*
* @return string|array
* @see StripSlashes
*/
public function unescapeRequestVariable($value)
{
if ( $this->Application->isAdmin ) {
return $value;
}
// This allows to revert kUtil::escape() call for each field submitted on front-end.
if ( is_array($value) ) {
foreach ( $value as $param_name => $param_value ) {
$value[$param_name] = $this->unescapeRequestVariable($param_value);
}
return $value;
}
return kUtil::unescape($value, kUtil::ESCAPE_HTML);
}
/**
* Returns all $_GET array excluding system parameters, that are not allowed to be passed through generated urls
*
* @param bool $access_error Method is called during no_permission, require login, session expiration link preparation
* @return Array
*/
function getRedirectParams($access_error = false)
{
$vars = $this->Get;
$unset_vars = Array (ENV_VAR_NAME, 'rewrite', '_mod_rw_url_', 'Action');
if (!$this->_sidInQueryString) {
$unset_vars[] = 'sid';
}
// remove system variables
foreach ($unset_vars as $var_name) {
if (array_key_exists($var_name, $vars)) {
unset($vars[$var_name]);
}
}
if ($access_error) {
// place 1 of 2 (also in UsersEventHandler::OnSessionExpire)
$vars = $this->_removePassThroughVariables($vars);
}
return $vars;
}
/**
* Removes all pass_though variables from redirect params
*
* @param Array $url_params
* @return Array
*/
function _removePassThroughVariables($url_params)
{
$pass_through = array_key_exists('pass_through', $url_params) ? $url_params['pass_through'] : '';
if (!$pass_through) {
return $url_params;
}
$pass_through = explode(',', $pass_through . ',pass_through');
foreach ($pass_through as $pass_through_var) {
unset($url_params[$pass_through_var]);
}
$url_params['no_pass_through'] = 1; // this way kApplication::HREF won't add them again
return $url_params;
}
/**
* Checks, that url is empty
*
* @return bool
* @access public
*/
public function isEmptyUrl()
{
if ( $this->Application->RewriteURLs() ) {
- return !$this->Get('_mod_rw_url_');
+ $url = $this->Get('_mod_rw_url_');
+
+ return !is_string($url) || !$url;
}
return !count($this->Get);
}
/**
* Returns the client IP address.
*
* @return string The client IP address
* @access public
*/
public function getClientIp()
{
if ( $this->_trustProxy ) {
if ( array_key_exists('HTTP_CLIENT_IP', $_SERVER) ) {
return $_SERVER['HTTP_CLIENT_IP'];
}
if ( array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) ) {
$client_ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
foreach ($client_ip as $ip_address) {
$clean_ip_address = trim($ip_address);
if ( false !== filter_var($clean_ip_address, FILTER_VALIDATE_IP) ) {
return $clean_ip_address;
}
}
return '';
}
}
return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
}
/**
* Returns headers
*
* @return array
* @access public
*/
public function getHeaders()
{
if ( function_exists('apache_request_headers') ) {
// If apache_request_headers() exists...
$headers = apache_request_headers();
if ( $headers !== false ) {
return $headers; // And works... Use it.
}
}
$headers = array();
$header_server_keys = array_filter(array_keys($_SERVER), function ($server_key) {
return strpos($server_key, 'HTTP_') === 0;
});
foreach ( $header_server_keys as $server_key ) {
$header_name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($server_key, 5)))));
$headers[$header_name] = $_SERVER[$server_key];
}
return $headers;
}
}
Event Timeline
Log In to Comment