Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Sun, Apr 20, 4:24 PM

in-portal

This file is larger than 256 KB, so syntax highlighting was skipped.
Index: branches/RC/core/kernel/constants.php
===================================================================
--- branches/RC/core/kernel/constants.php (revision 9638)
+++ branches/RC/core/kernel/constants.php (revision 9639)
@@ -1,65 +1,66 @@
<?php
// kDBList filter types (then, types are divided into classes)
define('HAVING_FILTER', 1);
define('WHERE_FILTER', 2);
define('AGGREGATE_FILTER', 3);
// kDBList filter classes
define('FLT_SYSTEM', 1); // System Having/Where filter [AND]
define('FLT_NORMAL', 2); // User Having/Where filter [OR]
define('FLT_SEARCH', 3); // User "Search" Having/Where filter [OR]
define('FLT_VIEW', 4); // User "View Menu" Having/Where filter [AND]
define('FLT_CUSTOM', 5); // Custom fields (above) grid columns [AND]
// kMultipleFilter types
define('FLT_TYPE_AND', 'AND');
define('FLT_TYPE_OR', 'OR');
// item statuses
safeDefine('STATUS_DISABLED', 0);
safeDefine('STATUS_ACTIVE', 1);
safeDefine('STATUS_PENDING', 2);
safeDefine('STATUS_PENDING_EDITING', -2);
// sections
define('stTREE', 1);
define('stTAB', 2);
// event statuses
define('erSUCCESS', 0); // event finished working succsessfully
define('erFAIL', -1); // event finished working, but result is unsuccsessfull
define('erFATAL', -2); // event experienced FATAL error - no hooks should continue!
define('erPERM_FAIL', -3); // event failed on internal permission checking (user has not permission)
define('erSTOP', -4); // event requested to stop processing (don't parse templates)
// permission types
define('ptCATEGORY', 0);
define('ptSYSTEM', 1);
// email event statuses & types
define('EVENT_TYPE_FRONTEND', 0);
define('EVENT_TYPE_ADMIN', 1);
define('EVENT_STATUS_DISABLED', 0);
define('EVENT_STATUS_ENABLED', 1);
define('EVENT_STATUS_FRONTEND', 2);
define('EDIT_MARK', '&|edit|&'); // replace this sequence inside filters to SID[_main_wid]
$application =& kApplication::Instance();
$spacer_url = $application->BaseURL().'core/admin_templates/img/spacer.gif';
define('SPACER_URL', $spacer_url);
if (!$application->IsAdmin()) {
// don't show debugger buttons on front (if not overrided in "debug.php")
safeDefine('DBG_TOOLBAR_BUTTONS', 0);
}
define('smDEBUG', 2); // show section in debug mode only
define('smSUPER_ADMIN', 4); // show section in super admin & debug mode
// common usage regular expressions
define('REGEX_EMAIL_USER', '[-a-zA-Z0-9!\#$%&*+\/=?^_`{|}~.]+');
define('REGEX_EMAIL_DOMAIN', '[a-zA-Z0-9]{1}[-.a-zA-Z0-9_]*\.[a-zA-Z]{2,6}');
+ define('ALLOW_DEFAULT_SETTINGS', '_USE_DEFAULT_USER_DATA_'); //Allow persistent vars to take data from default user's persistent data
?>
\ No newline at end of file
Property changes on: branches/RC/core/kernel/constants.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.7.2.1
\ No newline at end of property
+1.7.2.2
\ No newline at end of property
Index: branches/RC/core/kernel/session/session.php
===================================================================
--- branches/RC/core/kernel/session/session.php (revision 9638)
+++ branches/RC/core/kernel/session/session.php (revision 9639)
@@ -1,954 +1,970 @@
<?php
/*
The session works the following way:
1. When a visitor loads a page from the site the script checks if cookies_on varibale has been passed to it as a cookie.
2. If it has been passed, the script tries to get Session ID (SID) from the request:
3. Depending on session mode the script is getting SID differently.
The following modes are available:
smAUTO - Automatic mode: if cookies are on at the client side, the script relays only on cookies and
ignore all other methods of passing SID.
If cookies are off at the client side, the script relays on SID passed through query string
and referal passed by the client. THIS METHOD IS NOT 100% SECURE, as long as attacker may
get SID and substitude referal to gain access to user' session. One of the faults of this method
is that the session is only created when the visitor clicks the first link on the site, so
there is NO session at the first load of the page. (Actually there is a session, but it gets lost
after the first click because we do not use SID in query string while we are not sure if we need it)
smCOOKIES_ONLY - Cookies only: in this mode the script relays solely on cookies passed from the browser
and ignores all other methods. In this mode there is no way to use sessions for clients
without cookies support or cookies support disabled. The cookies are stored with the
full domain name and path to base-directory of script installation.
smGET_ONLY - GET only: the script will not set any cookies and will use only SID passed in
query string using GET, it will also check referal. The script will set SID at the
first load of the page
smCOOKIES_AND_GET - Combined mode: the script will use both cookies and GET right from the start. If client has
cookies enabled, the script will check SID stored in cookie and passed in query string, and will
use this SID only if both cookie and query string matches. However if cookies are disabled on the
client side, the script will work the same way as in GET_ONLY mode.
4. After the script has the SID it tries to load it from the Storage (default is database)
5. If such SID is found in the database, the script checks its expiration time. If session is not expired, it updates
its expiration, and resend the cookie (if applicable to session mode)
6. Then the script loads all the data (session variables) pertaining to the SID.
Usage:
-$session = new Session(smAUTO); //smAUTO is default, you could just leave the brackets empty, or provide another mode
+$session =& new Session(smAUTO); //smAUTO is default, you could just leave the brackets empty, or provide another mode
$session->SetCookieDomain('my.domain.com');
$session->SetCookiePath('/myscript');
$session->SetCookieName('my_sid_cookie');
$session->SetGETName('sid');
$session->InitSession();
...
//link output:
echo "<a href='index.php?'". ( $session->NeedQueryString() ? 'sid='.$session->SID : '' ) .">My Link</a>";
*/
//Implements session storage in the database
class SessionStorage extends kDBBase {
var $Expiration;
var $SessionTimeout=0;
var $DirectVars = Array();
var $ChangedDirectVars = Array();
var $PersistentVars = Array ();
var $OriginalData=Array();
var $TimestampField;
var $SessionDataTable;
var $DataValueField;
var $DataVarField;
function Init($prefix,$special)
{
parent::Init($prefix,$special);
$this->setTableName('sessions');
$this->setIDField('sid');
$this->TimestampField = 'expire';
$this->SessionDataTable = 'SessionData';
$this->DataValueField = 'value';
$this->DataVarField = 'var';
}
function setSessionTimeout($new_timeout)
{
$this->SessionTimeout = $new_timeout;
}
function StoreSession(&$session, $additional_fields = Array())
{
if (defined('IS_INSTALL') && IS_INSTALL && !$this->Application->TableFound($this->TableName)) {
return false;
}
$fields_hash = Array (
$this->IDField => $session->SID,
$this->TimestampField => $session->Expiration
);
$this->Conn->doInsert($fields_hash, $this->TableName);
foreach ($additional_fields as $field_name => $field_value) {
$this->SetField($session, $field_name, $field_value);
}
}
function DeleteSession(&$session)
{
$query = ' DELETE FROM '.$this->TableName.' WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->SID);
$this->Conn->Query($query);
$query = ' DELETE FROM '.$this->SessionDataTable.' WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->SID);
$this->Conn->Query($query);
$this->OriginalData = Array();
}
function UpdateSession(&$session, $timeout=0)
{
$this->SetField($session, $this->TimestampField, $session->Expiration);
$query = ' UPDATE '.$this->TableName.' SET '.$this->TimestampField.' = '.$session->Expiration.' WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->SID);
$this->Conn->Query($query);
}
function LocateSession($sid)
{
$query = ' SELECT * FROM '.$this->TableName.' WHERE '.$this->IDField.' = '.$this->Conn->qstr($sid);
$result = $this->Conn->GetRow($query);
if($result===false) return false;
$this->DirectVars = $result;
$this->Expiration = $result[$this->TimestampField];
return true;
}
function GetExpiration()
{
return $this->Expiration;
}
function LoadData(&$session)
{
$query = 'SELECT '.$this->DataValueField.','.$this->DataVarField.' FROM '.$this->SessionDataTable.' WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->SID);
$this->OriginalData = $this->Conn->GetCol($query, $this->DataVarField);
return $this->OriginalData;
}
/**
* Enter description here...
*
* @param Session $session
* @param string $var_name
* @param mixed $default
*/
function GetField(&$session, $var_name, $default = false)
{
return isset($this->DirectVars[$var_name]) ? $this->DirectVars[$var_name] : $default;
//return $this->Conn->GetOne('SELECT '.$var_name.' FROM '.$this->TableName.' WHERE `'.$this->IDField.'` = '.$this->Conn->qstr($session->GetID()) );
}
function SetField(&$session, $var_name, $value)
{
$value_changed = !isset($this->DirectVars[$var_name]) || ($this->DirectVars[$var_name] != $value);
if ($value_changed) {
$this->DirectVars[$var_name] = $value;
$this->ChangedDirectVars[] = $var_name;
$this->ChangedDirectVars = array_unique($this->ChangedDirectVars);
}
//return $this->Conn->Query('UPDATE '.$this->TableName.' SET '.$var_name.' = '.$this->Conn->qstr($value).' WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->GetID()) );
}
function SaveData(&$session)
{
if(!$session->SID) return false; // can't save without sid
$ses_data = $session->Data->GetParams();
$replace = '';
foreach ($ses_data as $key => $value)
{
if ( isset($this->OriginalData[$key]) && $this->OriginalData[$key] == $value)
{
continue; //skip unchanged session data
}
else
{
$replace .= sprintf("(%s, %s, %s),",
$this->Conn->qstr($session->SID),
$this->Conn->qstr($key),
$this->Conn->qstr($value));
}
}
$replace = rtrim($replace, ',');
if ($replace != '') {
$query = ' REPLACE INTO '.$this->SessionDataTable. ' ('.$this->IDField.', '.$this->DataVarField.', '.$this->DataValueField.') VALUES '.$replace;
$this->Conn->Query($query);
}
if ($this->ChangedDirectVars) {
$changes = array();
foreach ($this->ChangedDirectVars as $var) {
$changes[] = $var.' = '.$this->Conn->qstr($this->DirectVars[$var]);
}
$query = 'UPDATE '.$this->TableName.' SET '.implode(',', $changes).' WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->GetID());
$this->Conn->Query($query);
}
}
function RemoveFromData(&$session, $var)
{
$query = 'DELETE FROM '.$this->SessionDataTable.' WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->SID).
' AND '.$this->DataVarField.' = '.$this->Conn->qstr($var);
$this->Conn->Query($query);
unset($this->OriginalData[$var]);
}
function GetFromData(&$session, $var)
{
return getArrayValue($this->OriginalData, $var);
}
function GetExpiredSIDs()
{
$query = ' SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE '.$this->TimestampField.' > '.adodb_mktime();
return $this->Conn->GetCol($query);
}
function DeleteExpired()
{
$expired_sids = $this->GetExpiredSIDs();
if ($expired_sids) {
$where_clause=' WHERE '.$this->IDField.' IN ("'.implode('","',$expired_sids).'")';
$sql = 'DELETE FROM '.$this->SessionDataTable.$where_clause;
$this->Conn->Query($sql);
$sql = 'DELETE FROM '.$this->TableName.$where_clause;
$this->Conn->Query($sql);
// delete debugger ouputs left of expired sessions
foreach ($expired_sids as $expired_sid) {
$debug_file = KERNEL_PATH.'/../cache/debug_@'.$expired_sid.'@.txt';
if (file_exists($debug_file)) {
@unlink($debug_file);
}
}
}
return $expired_sids;
}
function LoadPersistentVars(&$session)
{
$user_id = $session->RecallVar('user_id');
if ($user_id != -2) {
// root & normal users
$sql = 'SELECT VariableValue, VariableName
FROM '.TABLE_PREFIX.'PersistantSessionData
WHERE PortalUserId = '.$user_id;
$this->PersistentVars = $this->Conn->GetCol($sql, 'VariableName');
}
else {
$this->PersistentVars = Array ();
}
}
function StorePersistentVar(&$session, $var_name, $var_value)
{
$user_id = $session->RecallVar('user_id');
if ($user_id == -2 || $user_id === false) {
// -2 (when not logged in), false (when after u:OnLogout event)
return ;
}
$this->PersistentVars[$var_name] = $var_value;
$key_clause = 'PortalUserId = '.$user_id.' AND VariableName = '.$this->Conn->qstr($var_name);
$sql = 'SELECT VariableValue
FROM '.TABLE_PREFIX.'PersistantSessionData
WHERE '.$key_clause;
$record_found = $this->Conn->GetOne($sql);
$fields_hash = Array (
'PortalUserId' => $user_id,
'VariableName' => $var_name,
'VariableValue' => $var_value,
);
if ($record_found) {
$this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'PersistantSessionData', $key_clause);
}
else {
$this->Conn->doInsert($fields_hash, TABLE_PREFIX.'PersistantSessionData');
}
}
function RecallPersistentVar(&$session, $var_name, $default = false)
{
- return isset($this->PersistentVars[$var_name]) ? $this->PersistentVars[$var_name] : $default;
+ if (isset($this->PersistentVars[$var_name])) {
+ return $this->PersistentVars[$var_name];
+ }
+ elseif ($default == '_USE_DEFAULT_USER_DATA_') {
+ $default_user_id = $this->Application->ConfigValue('DefaultSettingsUserId');
+ if (!$default_user_id) $default_user_id = -1;
+ $sql = 'SELECT VariableValue, VariableName
+ FROM '.TABLE_PREFIX.'PersistantSessionData
+ WHERE VariableName = '.$this->Conn->qstr($var_name).' AND PortalUserId = '.$default_user_id;
+ $value = $this->Conn->GetOne($sql);
+ if ($value !== false) {
+ $this->PersistentVars[$var_name] = $value;
+ $this->StorePersistentVar($session, $var_name, $value); //storing it, so next time we don't load default user setting
+ }
+ return $value;
+ }
+ else return $default;
}
function RemovePersistentVar(&$session, $var_name)
{
unset($this->PersistentVars[$var_name]);
$user_id = $session->RecallVar('user_id');
if ($user_id != -2) {
$sql = 'DELETE FROM '.TABLE_PREFIX.'PersistantSessionData
WHERE PortalUserId = '.$user_id.' AND VariableName = '.$this->Conn->qstr($var_name);
$this->Conn->Query($sql);
}
}
}
define('smAUTO', 1);
define('smCOOKIES_ONLY', 2);
define('smGET_ONLY', 3);
define('smCOOKIES_AND_GET', 4);
class Session extends kBase {
var $Checkers;
var $Mode;
var $OriginalMode = null;
var $GETName = 'sid';
var $CookiesEnabled = true;
var $CookieName = 'sid';
var $CookieDomain;
var $CookiePath;
var $CookieSecure = 0;
var $SessionTimeout = 3600;
var $Expiration;
var $SID;
/**
* Enter description here...
*
* @var SessionStorage
*/
var $Storage;
var $CachedNeedQueryString = null;
var $Data;
function Session($mode=smAUTO)
{
parent::kBase();
$this->SetMode($mode);
}
function SetMode($mode)
{
$this->Mode = $mode;
$this->CachedNeedQueryString = null;
$this->CachedSID = null;
}
function SetCookiePath($path)
{
$this->CookiePath = $path;
}
function SetCookieDomain($domain)
{
$this->CookieDomain = '.'.ltrim($domain, '.');
}
function SetGETName($get_name)
{
$this->GETName = $get_name;
}
function SetCookieName($cookie_name)
{
$this->CookieName = $cookie_name;
}
function InitStorage($special)
{
$this->Storage =& $this->Application->recallObject('SessionStorage.'.$special);
$this->Storage->setSessionTimeout($this->SessionTimeout);
}
function Init($prefix,$special)
{
parent::Init($prefix,$special);
$this->CheckIfCookiesAreOn();
if ($this->CookiesEnabled) $_COOKIE['cookies_on'] = 1;
$this->Checkers = Array();
$this->InitStorage($special);
- $this->Data = new Params();
+ $this->Data =& new Params();
$tmp_sid = $this->GetPassedSIDValue();
$check = $this->Check();
if( !(defined('IS_INSTALL') && IS_INSTALL) )
{
$expired_sids = $this->DeleteExpired();
if ( ( $expired_sids && in_array($tmp_sid,$expired_sids) ) || ( $tmp_sid && !$check ) ) {
$this->SetSession();
$this->Application->HandleEvent($event, 'u:OnSessionExpire');
return ;
}
}
if ($check) {
$this->SID = $this->GetPassedSIDValue();
$this->Refresh();
$this->LoadData();
}
else {
$this->SetSession();
}
if (!is_null($this->OriginalMode)) $this->SetMode($this->OriginalMode);
}
function IsHTTPSRedirect()
{
$http_referer = getArrayValue($_SERVER, 'HTTP_REFERER');
return (
( PROTOCOL == 'https://' && preg_match('#http:\/\/#', $http_referer) )
||
( PROTOCOL == 'http://' && preg_match('#https:\/\/#', $http_referer) )
);
}
function CheckReferer($for_cookies=0)
{
if (!$for_cookies) {
if ( !$this->Application->ConfigValue('SessionReferrerCheck') || $_SERVER['REQUEST_METHOD'] != 'POST') {
return true;
}
}
$path = preg_replace('/admin[\/]{0,1}$/', '', $this->CookiePath); // removing /admin for compatability with in-portal (in-link/admin/add_link.php)
$reg = '#^'.preg_quote(PROTOCOL.ltrim($this->CookieDomain, '.').$path).'#';
return preg_match($reg, getArrayValue($_SERVER, 'HTTP_REFERER') ) || (defined('IS_POPUP') && IS_POPUP);
}
/*function CheckDuplicateCookies()
{
if (isset($_SERVER['HTTP_COOKIE'])) {
$cookie_str = $_SERVER['HTTP_COOKIE'];
$cookies = explode('; ', $cookie_str);
$all_cookies = array();
foreach ($cookies as $cookie) {
list($name, $value) = explode('=', $cookie);
if (isset($all_cookies[$name])) {
//double cookie name!!!
$this->RemoveCookie($name);
}
else $all_cookies[$name] = $value;
}
}
}
function RemoveCookie($name)
{
$path = $_SERVER['PHP_SELF'];
$path_parts = explode('/', $path);
$cur_path = '';
setcookie($name, false, null, $cur_path);
foreach ($path_parts as $part) {
$cur_path .= $part;
setcookie($name, false, null, $cur_path);
$cur_path .= '/';
setcookie($name, false, null, $cur_path);
}
}*/
function CheckIfCookiesAreOn()
{
// $this->CheckDuplicateCookies();
if ($this->Mode == smGET_ONLY)
{
//we don't need to bother checking if we would not use it
$this->CookiesEnabled = false;
return;
}
$http_query =& $this->Application->recallObject('HTTPQuery');
$cookies_on = isset($http_query->Cookie['cookies_on']); // not good here
$get_sid = getArrayValue($http_query->Get, $this->GETName);
if ($this->IsHTTPSRedirect() && $get_sid) { //Redirect from http to https on different domain
$this->OriginalMode = $this->Mode;
$this->SetMode(smGET_ONLY);
}
if (!$cookies_on || $this->IsHTTPSRedirect()) {
//If referer is our server, but we don't have our cookies_on, it's definetly off
$is_install = defined('IS_INSTALL') && IS_INSTALL;
if (!$is_install && $this->CheckReferer(1) && !$this->Application->GetVar('admin') && !$this->IsHTTPSRedirect()) {
$this->CookiesEnabled = false;
}
else {
//Otherwise we still suppose cookies are on, because may be it's the first time user visits the site
//So we send cookies on to get it next time (when referal will tell us if they are realy off
$this->SetCookie('cookies_on', 1, adodb_mktime() + 31104000); //one year should be enough
}
}
else
$this->CookiesEnabled = true;
return $this->CookiesEnabled;
}
/**
* Sets cookie for current site using path and domain
*
* @param string $name
* @param mixed $value
* @param int $expires
*/
function SetCookie($name, $value, $expires = null)
{
setcookie($name, $value, $expires, $this->CookiePath, $this->CookieDomain, $this->CookieSecure);
}
function Check()
{
// we should check referer if cookies are disabled, and in combined mode
// auto mode would detect cookies, get only mode would turn it off - so we would get here
// and we don't care about referal in cookies only mode
if ( $this->Mode != smCOOKIES_ONLY && (!$this->CookiesEnabled || $this->Mode == smCOOKIES_AND_GET) ) {
if (!$this->CheckReferer())
return false;
}
$sid = $this->GetPassedSIDValue();
if (empty($sid)) return false;
//try to load session by sid, if everything is fine
$result = $this->LoadSession($sid);
return $result;
}
function LoadSession($sid)
{
if( $this->Storage->LocateSession($sid) ) {
//if we have session with such SID - get its expiration
$this->Expiration = $this->Storage->GetExpiration();
//If session has expired
if ($this->Expiration < adodb_mktime()) return false;
//Otherwise it's ok
return true;
}
else //fake or deleted due to expiration SID
return false;
}
function GetPassedSIDValue($use_cache = 1)
{
if (!empty($this->CachedSID) && $use_cache) return $this->CachedSID;
$http_query =& $this->Application->recallObject('HTTPQuery');
$get_sid = getArrayValue($http_query->Get, $this->GETName);
if ($this->Application->GetVar('admin') == 1 && $get_sid) {
$sid = $get_sid;
}
else {
switch ($this->Mode) {
case smAUTO:
//Cookies has the priority - we ignore everything else
$sid = $this->CookiesEnabled ? $this->GetSessionCookie() : $get_sid;
break;
case smCOOKIES_ONLY:
$sid = $this->GetSessionCookie();
break;
case smGET_ONLY:
$sid = $get_sid;
break;
case smCOOKIES_AND_GET:
$cookie_sid = $this->GetSessionCookie();
//both sids should match if cookies are enabled
if (!$this->CookiesEnabled || ($cookie_sid == $get_sid))
{
$sid = $get_sid; //we use get here just in case cookies are disabled
}
else
{
$sid = '';
}
break;
}
}
$this->CachedSID = $sid;
return $this->CachedSID;
}
/**
* Returns session id
*
* @return int
* @access public
*/
function GetID()
{
return $this->SID;
}
/**
* Generates new session id
*
* @return int
* @access private
*/
function GenerateSID()
{
list($usec, $sec) = explode(" ",microtime());
$sid_part_1 = substr($usec, 4, 4);
$sid_part_2 = mt_rand(1,9);
$sid_part_3 = substr($sec, 6, 4);
$digit_one = substr($sid_part_1, 0, 1);
if ($digit_one == 0) {
$digit_one = mt_rand(1,9);
$sid_part_1 = ereg_replace("^0","",$sid_part_1);
$sid_part_1=$digit_one.$sid_part_1;
}
$this->setSID($sid_part_1.$sid_part_2.$sid_part_3);
return $this->SID;
}
/**
* Set's new session id
*
* @param int $new_sid
* @access private
*/
function setSID($new_sid)
{
$this->SID=$new_sid;
$this->Application->SetVar($this->GETName,$new_sid);
}
function SetSession()
{
$this->GenerateSID();
$this->Expiration = adodb_mktime() + $this->SessionTimeout;
switch ($this->Mode) {
case smAUTO:
if ($this->CookiesEnabled) {
$this->SetSessionCookie();
}
break;
case smGET_ONLY:
break;
case smCOOKIES_ONLY:
case smCOOKIES_AND_GET:
$this->SetSessionCookie();
break;
}
$this->Storage->StoreSession($this);
if ($this->Application->IsAdmin() || $this->Special == 'admin') {
$this->StoreVar('admin', 1);
}
if ($this->Special != '') {
// front-session called from admin or otherwise, then save it's data
$this->SaveData();
}
$this->Application->resetCounters('UserSession');
}
/**
* Returns SID from cookie
*
* @return int
*/
function GetSessionCookie()
{
return isset($this->Application->HttpQuery->Cookie[$this->CookieName]) ? $this->Application->HttpQuery->Cookie[$this->CookieName] : false;
}
/**
* Updates SID in cookie with new value
*
*/
function SetSessionCookie()
{
$this->SetCookie($this->CookieName, $this->SID, $this->Expiration);
$_COOKIE[$this->CookieName] = $this->SID; // for compatibility with in-portal
}
/**
* Refreshes session expiration time
*
* @access private
*/
function Refresh()
{
if ($this->CookiesEnabled) $this->SetSessionCookie(); //we need to refresh the cookie
$this->Storage->UpdateSession($this);
}
function Destroy()
{
$this->Storage->DeleteSession($this);
- $this->Data = new Params();
+ $this->Data =& new Params();
$this->SID = '';
if ($this->CookiesEnabled) $this->SetSessionCookie(); //will remove the cookie due to value (sid) is empty
$this->SetSession(); //will create a new session
}
function NeedQueryString($use_cache = 1)
{
if ($this->CachedNeedQueryString != null && $use_cache) return $this->CachedNeedQueryString;
$result = false;
switch ($this->Mode)
{
case smAUTO:
if (!$this->CookiesEnabled) $result = true;
break;
/*case smCOOKIES_ONLY:
break;*/
case smGET_ONLY:
case smCOOKIES_AND_GET:
$result = true;
break;
}
$this->CachedNeedQueryString = $result;
return $result;
}
function LoadData()
{
$this->Data->AddParams($this->Storage->LoadData($this));
}
function PrintSession($comment='')
{
if($this->Application->isDebugMode() && constOn('DBG_SHOW_SESSIONDATA')) {
// dump session data
$this->Application->Debugger->appendHTML('SessionStorage ('.$comment.'):');
$session_data = $this->Data->GetParams();
ksort($session_data);
foreach ($session_data as $session_key => $session_value) {
if (IsSerialized($session_value)) {
$session_data[$session_key] = unserialize($session_value);
}
}
$this->Application->Debugger->dumpVars($session_data);
}
if ($this->Application->isDebugMode() && constOn('DBG_SHOW_PERSISTENTDATA')) {
// dump persistent session data
if ($this->Storage->PersistentVars) {
$this->Application->Debugger->appendHTML('Persistant Session:');
$session_data = $this->Storage->PersistentVars;
ksort($session_data);
foreach ($session_data as $session_key => $session_value) {
if (IsSerialized($session_value)) {
$session_data[$session_key] = unserialize($session_value);
}
}
$this->Application->Debugger->dumpVars($session_data);
}
}
}
function SaveData()
{
if (!$this->Application->GetVar('skip_last_template') && $this->Application->GetVar('ajax') != 'yes') {
$this->SaveLastTemplate( $this->Application->GetVar('t') );
}
$this->PrintSession('after save');
$this->Storage->SaveData($this);
}
function SaveLastTemplate($t)
{
// save last_template
$wid = $this->Application->GetVar('m_wid');
$last_env = $this->getLastTemplateENV($t, Array('m_opener' => 'u'));
$last_template = basename($_SERVER['PHP_SELF']).'|'.substr($last_env, strlen(ENV_VAR_NAME) + 1);
$this->StoreVar(rtrim('last_template_'.$wid, '_'), $last_template);
$last_env = $this->getLastTemplateENV($t, null, false);
$last_template = basename($_SERVER['PHP_SELF']).'|'.substr($last_env, strlen(ENV_VAR_NAME) + 1);
$this->StoreVar(rtrim('last_template_popup_'.$wid, '_'), $last_template);
// save other last... variables for mistical purposes (customizations may be)
$this->StoreVar('last_url', $_SERVER['REQUEST_URI']); // needed by ord:StoreContinueShoppingLink
$this->StoreVar('last_env', substr($last_env, strlen(ENV_VAR_NAME)+1));
// save last_template in persistant session
if (!$wid) {
if ($this->Application->IsAdmin()) {
// only for main window, not popups, not login template, not temp mode (used in adm:MainFrameLink tag)
$temp_mode = false;
$passed = explode(',', $this->Application->GetVar('passed'));
foreach ($passed as $passed_prefix) {
if ($this->Application->GetVar($passed_prefix.'_mode')) {
$temp_mode = true;
break;
}
}
if (!$temp_mode) {
if (isset($this->Application->HttpQuery->Get['section'])) {
// check directly in GET, bacause LinkVar (session -> request) used on these vars
$last_template .= '&section='.$this->Application->GetVar('section').'&module='.$this->Application->GetVar('module');
}
$this->StorePersistentVar('last_template_popup', $last_template);
}
}
elseif ($this->Application->GetVar('admin') == 1) {
$admin_session =& $this->Application->recallObject('Session.admin');
/* @var $admin_ses Session */
$admin_session->StorePersistentVar('last_template_popup', '../'.$last_template);
}
}
}
function getLastTemplateENV($t, $params = null, $encode = true)
{
if (!isset($params)) {
$params = Array ();
}
$params['__URLENCODE__'] = 1; // uses "&" instead of "&amp;" for url part concatenation + replaces "\" to "%5C" (works in HTML)
$ret = $this->Application->BuildEnv($t, $params, 'all');
if (!$encode) {
// cancels 2nd part of replacements, that URLENCODE does
$ret = str_replace('%5C', '\\', $ret);
}
return $ret;
}
function StoreVar($name, $value)
{
$this->Data->Set($name, $value);
}
function StorePersistentVar($name, $value)
{
$this->Storage->StorePersistentVar($this, $name, $value);
}
function LoadPersistentVars()
{
$this->Storage->LoadPersistentVars($this);
}
function StoreVarDefault($name, $value)
{
$tmp = $this->RecallVar($name);
if($tmp === false || $tmp == '')
{
$this->StoreVar($name, $value);
}
}
function RecallVar($name, $default = false)
{
$ret = $this->Data->Get($name);
return ($ret === false) ? $default : $ret;
}
function RecallPersistentVar($name, $default = false)
{
return $this->Storage->RecallPersistentVar($this, $name, $default);
}
function RemoveVar($name)
{
$this->Storage->RemoveFromData($this, $name);
$this->Data->Remove($name);
}
function RemovePersistentVar($name)
{
return $this->Storage->RemovePersistentVar($this, $name);
}
/**
* Ignores session varible value set before
*
* @param string $name
*/
function RestoreVar($name)
{
return $this->StoreVar($name, $this->Storage->GetFromData($this, $name));
}
function GetField($var_name, $default = false)
{
return $this->Storage->GetField($this, $var_name, $default);
}
function SetField($var_name, $value)
{
$this->Storage->SetField($this, $var_name, $value);
}
/**
* Deletes expired sessions
*
* @return Array expired sids if any
* @access private
*/
function DeleteExpired()
{
return $this->Storage->DeleteExpired();
}
/**
* Allows to check if user in this session is logged in or not
*
* @return bool
*/
function LoggedIn()
{
$user_id = $this->RecallVar('user_id');
$ret = $user_id > 0;
if ($this->RecallVar('admin') == 1 && ($user_id == -1)) {
$ret = true;
}
return $ret;
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/kernel/session/session.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.59.2.2
\ No newline at end of property
+1.59.2.3
\ No newline at end of property
Index: branches/RC/core/kernel/utility/temp_handler.php
===================================================================
--- branches/RC/core/kernel/utility/temp_handler.php (revision 9638)
+++ branches/RC/core/kernel/utility/temp_handler.php (revision 9639)
@@ -1,718 +1,787 @@
<?php
class kTempTablesHandler extends kBase {
var $Tables = Array();
/**
* Master table name for temp handler
*
* @var string
* @access private
*/
var $MasterTable = '';
/**
* IDs from master table
*
* @var Array
* @access private
*/
var $MasterIDs = Array();
var $AlreadyProcessed = Array();
var $DroppedTables = Array();
var $FinalRefs = Array();
var $CopiedTables = Array();
/**
* IDs of newly cloned items (key - prefix.special, value - array of ids)
*
* @var Array
*/
var $savedIDs = Array();
/**
* Description
*
* @var kDBConnection
* @access public
*/
var $Conn;
/**
* Window ID of current window
*
* @var mixed
*/
var $WindowID = '';
function kTempTablesHandler()
{
parent::kBase();
$this->Conn =& $this->Application->GetADODBConnection();
}
function SetTables($tables)
{
// set tablename as key for tables array
$ret = Array();
$this->Tables = $tables;
$this->MasterTable = $tables['TableName'];
}
function saveID($prefix, $special = '', $id = null)
{
+ if (!isset($this->savedIDs[$prefix.($special ? '.' : '').$special])) {
+ $this->savedIDs[$prefix.($special ? '.' : '').$special] = array();
+ }
+ if (is_array($id)) {
+ foreach ($id as $tmp_id => $live_id) {
+ $this->savedIDs[$prefix.($special ? '.' : '').$special][$tmp_id] = $live_id;
+ }
+ }
+ else {
$this->savedIDs[$prefix.($special ? '.' : '').$special][] = $id;
}
+ }
/**
* Get temp table name
*
* @param string $table
* @return string
*/
function GetTempName($table)
{
return $this->Application->GetTempName($table, $this->WindowID);
}
function GetTempTablePrefix()
{
return $this->Application->GetTempTablePrefix($this->WindowID);
}
/**
* Return live table name based on temp table name
*
* @param string $temp_table
* @return string
*/
function GetLiveName($temp_table)
{
return $this->Application->GetLiveName($temp_table);
}
function IsTempTable($table)
{
return $this->Application->IsTempTable($table);
}
/**
* Return temporary table name for master table
*
* @return string
* @access public
*/
function GetMasterTempName()
{
return $this->GetTempName($this->MasterTable);
}
function CreateTempTable($table)
{
$query = sprintf("CREATE TABLE %s SELECT * FROM %s WHERE 0",
$this->GetTempName($table),
$table);
$this->Conn->Query($query);
}
function BuildTables($prefix, $ids)
{
$this->WindowID = $this->Application->GetVar('m_wid');
$this->TableIdCounter = 0;
$tables = Array(
'TableName' => $this->Application->getUnitOption($prefix, 'TableName'),
'IdField' => $this->Application->getUnitOption($prefix, 'IDField'),
'IDs' => $ids,
'Prefix' => $prefix,
'TableId' => $this->TableIdCounter++,
);
/*$parent_prefix = $this->Application->getUnitOption($prefix, 'ParentPrefix');
if ($parent_prefix) {
$tables['ForeignKey'] = $this->Application->getUnitOption($prefix, 'ForeignKey');
$tables['ParentPrefix'] = $parent_prefix;
$tables['ParentTableKey'] = $this->Application->getUnitOption($prefix, 'ParentTableKey');
}*/
$this->FinalRefs[ $tables['TableName'] ] = $tables['TableId']; // don't forget to add main table to FinalRefs too
$SubItems = $this->Application->getUnitOption($prefix,'SubItems');
if (is_array($SubItems)) {
foreach ($SubItems as $prefix) {
$this->AddTables($prefix, $tables);
}
}
$this->SetTables($tables);
}
/**
* Searches through TempHandler tables info for required prefix
*
* @param string $prefix
* @param Array $master
* @return mixed
*/
function SearchTable($prefix, $master = null)
{
if (is_null($master)) {
$master = $this->Tables;
}
if ($master['Prefix'] == $prefix) {
return $master;
}
if (isset($master['SubTables'])) {
foreach ($master['SubTables'] as $sub_table) {
$found = $this->SearchTable($prefix, $sub_table);
if ($found !== false) {
return $found;
}
}
}
return false;
}
function AddTables($prefix, &$tables)
{
if (!$this->Application->prefixRegistred($prefix)) {
// allows to skip subitem processing if subitem module not enabled/installed
return ;
}
$tmp = Array(
'TableName' => $this->Application->getUnitOption($prefix,'TableName'),
'IdField' => $this->Application->getUnitOption($prefix,'IDField'),
'ForeignKey' => $this->Application->getUnitOption($prefix,'ForeignKey'),
'ParentPrefix' => $this->Application->getUnitOption($prefix, 'ParentPrefix'),
'ParentTableKey' => $this->Application->getUnitOption($prefix,'ParentTableKey'),
'Prefix' => $prefix,
'AutoClone' => $this->Application->getUnitOption($prefix,'AutoClone'),
'AutoDelete' => $this->Application->getUnitOption($prefix,'AutoDelete'),
'TableId' => $this->TableIdCounter++,
);
$this->FinalRefs[ $tmp['TableName'] ] = $tmp['TableId'];
$constrain = $this->Application->getUnitOption($prefix,'Constrain');
if ($constrain)
{
$tmp['Constrain'] = $constrain;
$this->FinalRefs[ $tmp['TableName'].$tmp['Constrain'] ] = $tmp['TableId'];
}
$SubItems = $this->Application->getUnitOption($prefix,'SubItems');
$same_sub_counter = 1;
if( is_array($SubItems) )
{
foreach($SubItems as $prefix)
{
$this->AddTables($prefix, $tmp);
}
}
if ( !is_array(getArrayValue($tables, 'SubTables')) ) {
$tables['SubTables'] = array();
}
$tables['SubTables'][] = $tmp;
}
function CloneItems($prefix, $special, $ids, $master = null, $foreign_key = null, $parent_prefix = null, $skip_filenames = false)
{
if (!isset($master)) $master = $this->Tables;
// recalling by different name, because we may get kDBList, if we recall just by prefix
if (!preg_match('/(.*)-item$/', $special)) {
$special .= '-item';
}
$object =& $this->Application->recallObject($prefix.'.'.$special, $prefix, Array('skip_autoload' => true));
$object->PopulateMultiLangFields();
foreach ($ids as $id) {
$mode = 'create';
if ( $cloned_ids = getArrayValue($this->AlreadyProcessed, $master['TableName']) ) {
// if we have already cloned the id, replace it with cloned id and set mode to update
// update mode is needed to update second ForeignKey for items cloned by first ForeignKey
if ( getArrayValue($cloned_ids, $id) ) {
$id = $cloned_ids[$id];
$mode = 'update';
}
}
$object->Load($id);
$original_values = $object->FieldValues;
if (!$skip_filenames) {
$object->NameCopy($master, $foreign_key);
}
elseif ($master['TableName'] == $this->MasterTable) {
// kCatDBItem class only has this attribute
$object->useFilenames = false;
}
if (isset($foreign_key)) {
$master_foreign_key_field = is_array($master['ForeignKey']) ? $master['ForeignKey'][$parent_prefix] : $master['ForeignKey'];
$object->SetDBField($master_foreign_key_field, $foreign_key);
}
if ($mode == 'create') {
$this->RaiseEvent('OnBeforeClone', $master['Prefix'], $special, Array($object->GetId()), $foreign_key);
}
$res = $mode == 'update' ? $object->Update() : $object->Create();
if ($res)
{
if ( $mode == 'create' && is_array( getArrayValue($master, 'ForeignKey')) ) {
// remember original => clone mapping for dual ForeignKey updating
$this->AlreadyProcessed[$master['TableName']][$id] = $object->GetId();
}
if ($object->mode == 't') {
$object->setTempID();
}
if ($mode == 'create') {
$this->RaiseEvent('OnAfterClone', $master['Prefix'], $special, Array($object->GetId()), $foreign_key, array('original_id' => $id) );
$this->saveID($master['Prefix'], $special, $object->GetID());
}
if ( is_array(getArrayValue($master, 'SubTables')) ) {
foreach($master['SubTables'] as $sub_table) {
if (!getArrayValue($sub_table, 'AutoClone')) continue;
$sub_TableName = ($object->mode == 't') ? $this->GetTempName($sub_table['TableName']) : $sub_table['TableName'];
$foreign_key_field = is_array($sub_table['ForeignKey']) ? $sub_table['ForeignKey'][$master['Prefix']] : $sub_table['ForeignKey'];
$parent_key_field = is_array($sub_table['ParentTableKey']) ? $sub_table['ParentTableKey'][$master['Prefix']] : $sub_table['ParentTableKey'];
$query = 'SELECT '.$sub_table['IdField'].' FROM '.$sub_TableName.'
WHERE '.$foreign_key_field.' = '.$original_values[$parent_key_field];
if (isset($sub_table['Constrain'])) $query .= ' AND '.$sub_table['Constrain'];
$sub_ids = $this->Conn->GetCol($query);
if ( is_array(getArrayValue($sub_table, 'ForeignKey')) ) {
// $sub_ids could containt newly cloned items, we need to remove it here
// to escape double cloning
$cloned_ids = getArrayValue($this->AlreadyProcessed, $sub_table['TableName']);
if ( !$cloned_ids ) $cloned_ids = Array();
$new_ids = array_values($cloned_ids);
$sub_ids = array_diff($sub_ids, $new_ids);
}
$parent_key = $object->GetDBField($parent_key_field);
$this->CloneItems($sub_table['Prefix'], $special, $sub_ids, $sub_table, $parent_key, $master['Prefix']);
}
}
}
}
if (!$ids) {
$this->savedIDs[$prefix.($special ? '.' : '').$special] = Array();
}
return $this->savedIDs[$prefix.($special ? '.' : '').$special];
}
function DeleteItems($prefix, $special, $ids, $master=null, $foreign_key=null)
{
if (!isset($master)) $master = $this->Tables;
if( strpos($prefix,'.') !== false ) list($prefix,$special) = explode('.', $prefix, 2);
$prefix_special = rtrim($prefix.'.'.$special, '.');
//recalling by different name, because we may get kDBList, if we recall just by prefix
$recall_prefix = $prefix_special.($special ? '' : '.').'-item';
$object =& $this->Application->recallObject($recall_prefix, $prefix, Array('skip_autoload' => true));
foreach ($ids as $id)
{
$object->Load($id);
$original_values = $object->FieldValues;
if( !$object->Delete($id) ) continue;
if ( is_array(getArrayValue($master, 'SubTables')) ) {
foreach($master['SubTables'] as $sub_table) {
if (!getArrayValue($sub_table, 'AutoDelete')) continue;
$sub_TableName = ($object->mode == 't') ? $this->GetTempName($sub_table['TableName']) : $sub_table['TableName'];
$foreign_key_field = is_array($sub_table['ForeignKey']) ? getArrayValue($sub_table, 'ForeignKey', $master['Prefix']) : $sub_table['ForeignKey'];
$parent_key_field = is_array($sub_table['ParentTableKey']) ? getArrayValue($sub_table, 'ParentTableKey', $master['Prefix']) : $sub_table['ParentTableKey'];
if (!$foreign_key_field || !$parent_key_field) continue;
$query = 'SELECT '.$sub_table['IdField'].' FROM '.$sub_TableName.'
WHERE '.$foreign_key_field.' = '.$original_values[$parent_key_field];
$sub_ids = $this->Conn->GetCol($query);
$parent_key = $object->GetDBField(is_array($sub_table['ParentTableKey']) ? $sub_table['ParentTableKey'][$prefix] : $sub_table['ParentTableKey']);
$this->DeleteItems($sub_table['Prefix'], '', $sub_ids, $sub_table, $parent_key);
}
}
}
}
function DoCopyLiveToTemp($master, $ids, $parent_prefix=null)
{
// when two tables refers the same table as sub-sub-table, and ForeignKey and ParentTableKey are arrays
// the table will be first copied by first sub-table, then dropped and copied over by last ForeignKey in the array
// this should not do any problems :)
if ( !preg_match("/.*\.[0-9]+/", $master['Prefix']) ) {
if( $this->DropTempTable($master['TableName']) )
{
$this->CreateTempTable($master['TableName']);
}
}
if (is_array($ids)) {
$ids = join(',', $ids);
}
$table_sig = $master['TableName'].(isset($master['Constrain']) ? $master['Constrain'] : '');
if ($ids != '' && !in_array($table_sig, $this->CopiedTables)) {
if ( getArrayValue($master, 'ForeignKey') ) {
if ( is_array($master['ForeignKey']) ) {
$key_field = $master['ForeignKey'][$parent_prefix];
}
else {
$key_field = $master['ForeignKey'];
}
}
else {
$key_field = $master['IdField'];
}
$query = 'INSERT INTO '.$this->GetTempName($master['TableName']).'
SELECT * FROM '.$master['TableName'].'
WHERE '.$key_field.' IN ('.$ids.')';
if (isset($master['Constrain'])) $query .= ' AND '.$master['Constrain'];
$this->Conn->Query($query);
$this->CopiedTables[] = $table_sig;
$query = 'SELECT '.$master['IdField'].' FROM '.$master['TableName'].'
WHERE '.$key_field.' IN ('.$ids.')';
if (isset($master['Constrain'])) $query .= ' AND '.$master['Constrain'];
$this->RaiseEvent( 'OnAfterCopyToTemp', $master['Prefix'], '', $this->Conn->GetCol($query) );
}
if ( getArrayValue($master, 'SubTables') ) {
foreach ($master['SubTables'] as $sub_table) {
$parent_key = is_array($sub_table['ParentTableKey']) ? $sub_table['ParentTableKey'][$master['Prefix']] : $sub_table['ParentTableKey'];
if (!$parent_key) continue;
if ( $ids != '' && $parent_key != $key_field ) {
$query = 'SELECT '.$parent_key.' FROM '.$master['TableName'].'
WHERE '.$key_field.' IN ('.$ids.')';
$sub_foreign_keys = join(',', $this->Conn->GetCol($query));
}
else {
$sub_foreign_keys = $ids;
}
$this->DoCopyLiveToTemp($sub_table, $sub_foreign_keys, $master['Prefix']);
}
}
}
function GetForeignKeys($master, $sub_table, $live_id, $temp_id=null)
{
$mode = 1; //multi
if (!is_array($live_id)) {
$live_id = Array($live_id);
$mode = 2; //single
}
if (isset($temp_id) && !is_array($temp_id)) $temp_id = Array($temp_id);
if ( isset($sub_table['ParentTableKey']) ) {
if ( is_array($sub_table['ParentTableKey']) ) {
$parent_key_field = $sub_table['ParentTableKey'][$master['Prefix']];
}
else {
$parent_key_field = $sub_table['ParentTableKey'];
}
}
else {
$parent_key_field = $master['IdField'];
}
if ( $cached = getArrayValue($this->FKeysCache, $master['TableName'].'.'.$parent_key_field) ) {
if ( array_key_exists(serialize($live_id), $cached) ) {
list($live_foreign_key, $temp_foreign_key) = $cached[serialize($live_id)];
if ($mode == 1) {
return $live_foreign_key;
}
else {
return Array($live_foreign_key[0], $temp_foreign_key[0]);
}
}
}
if ($parent_key_field != $master['IdField']) {
$query = 'SELECT '.$parent_key_field.' FROM '.$master['TableName'].'
WHERE '.$master['IdField'].' IN ('.join(',', $live_id).')';
$live_foreign_key = $this->Conn->GetCol($query);
if (isset($temp_id)) {
// because DoCopyTempToOriginal resets negative IDs to 0 in temp table (one by one) before copying to live
$temp_key = $temp_id < 0 ? 0 : $temp_id;
$query = 'SELECT '.$parent_key_field.' FROM '.$this->GetTempName($master['TableName']).'
WHERE '.$master['IdField'].' IN ('.join(',', $temp_key).')';
$temp_foreign_key = $this->Conn->GetCol($query);
}
else {
$temp_foreign_key = Array();
}
}
else {
$live_foreign_key = $live_id;
$temp_foreign_key = $temp_id;
}
$this->FKeysCache[$master['TableName'].'.'.$parent_key_field][serialize($live_id)] = Array($live_foreign_key, $temp_foreign_key);
if ($mode == 1) {
return $live_foreign_key;
}
else {
return Array($live_foreign_key[0], $temp_foreign_key[0]);
}
}
function DoCopyTempToOriginal($master, $parent_prefix = null, $current_ids = Array())
{
if (!$current_ids) {
$query = 'SELECT '.$master['IdField'].' FROM '.$this->GetTempName($master['TableName']);
if (isset($master['Constrain'])) $query .= ' WHERE '.$master['Constrain'];
$current_ids = $this->Conn->GetCol($query);
}
$table_sig = $master['TableName'].(isset($master['Constrain']) ? $master['Constrain'] : '');
if ($current_ids) {
// delete all ids from live table - for MasterTable ONLY!
// because items from Sub Tables get deteleted in CopySubTablesToLive !BY ForeignKey!
if ($master['TableName'] == $this->MasterTable) {
$this->RaiseEvent( 'OnBeforeDeleteFromLive', $master['Prefix'], '', $current_ids );
$query = 'DELETE FROM '.$master['TableName'].' WHERE '.$master['IdField'].' IN ('.join(',', $current_ids).')';
$this->Conn->Query($query);
}
if ( getArrayValue($master, 'SubTables') ) {
if( in_array($table_sig, $this->CopiedTables) || $this->FinalRefs[$table_sig] != $master['TableId'] ) return;
foreach($current_ids AS $id)
{
$this->RaiseEvent( 'OnBeforeCopyToLive', $master['Prefix'], '', Array($id) );
//reset negative ids to 0, so autoincrement in live table works fine
if($id < 0)
{
$query = 'UPDATE '.$this->GetTempName($master['TableName']).'
SET '.$master['IdField'].' = 0
WHERE '.$master['IdField'].' = '.$id;
if (isset($master['Constrain'])) $query .= ' AND '.$master['Constrain'];
$this->Conn->Query($query);
$id_to_copy = 0;
}
else
{
$id_to_copy = $id;
}
//copy current id_to_copy (0 for new or real id) to live table
$query = 'INSERT INTO '.$master['TableName'].'
SELECT * FROM '.$this->GetTempName($master['TableName']).'
WHERE '.$master['IdField'].' = '.$id_to_copy;
$this->Conn->Query($query);
$insert_id = $id_to_copy == 0 ? $this->Conn->getInsertID() : $id_to_copy;
- $this->saveID($master['Prefix'], '', $insert_id);
+ $this->saveID($master['Prefix'], '', array($id => $insert_id));
$this->RaiseEvent( 'OnAfterCopyToLive', $master['Prefix'], '', Array($insert_id), null, array('temp_id' => $id) );
$this->UpdateForeignKeys($master, $insert_id, $id);
//delete already copied record from master temp table
$query = 'DELETE FROM '.$this->GetTempName($master['TableName']).'
WHERE '.$master['IdField'].' = '.$id_to_copy;
if (isset($master['Constrain'])) $query .= ' AND '.$master['Constrain'];
$this->Conn->Query($query);
}
$this->CopiedTables[] = $table_sig;
// when all of ids in current master has been processed, copy all sub-tables data
$this->CopySubTablesToLive($master, $current_ids);
}
elseif( !in_array($table_sig, $this->CopiedTables) && ($this->FinalRefs[$table_sig] == $master['TableId']) ) { //If current master doesn't have sub-tables - we could use mass operations
// We don't need to delete items from live here, as it get deleted in the beggining of the method for MasterTable
// or in parent table processing for sub-tables
$this->RaiseEvent('OnBeforeCopyToLive', $master['Prefix'], '', $current_ids);
- // reset ALL negative IDs to 0 so it get inserted into live table with autoincrement
+ $live_ids = array();
+ foreach ($current_ids as $an_id) {
+ if ($an_id > 0) {
+ $live_ids[$an_id] = $an_id;
+ // positive (already live) IDs will be copied in on query all togather below,
+ // so we just store it here
+ continue;
+ }
+ else { // zero or negaitve ids should be copied one by one to get their InsertId
+ // reseting to 0 so it get inserted into live table with autoincrement
$query = 'UPDATE '.$this->GetTempName($master['TableName']).'
SET '.$master['IdField'].' = 0
- WHERE '.$master['IdField'].' < 0';
- if (isset($master['Constrain'])) $query .= ' AND '.$master['Constrain'];
+ WHERE '.$master['IdField'].' = '.$an_id;
+ // constrain is not needed here because ID is already unique
$this->Conn->Query($query);
+ // copying
+ $query = 'INSERT INTO '.$master['TableName'].'
+ SELECT * FROM '.$this->GetTempName($master['TableName']).'
+ WHERE '.$master['IdField'].' = 0';
+ $this->Conn->Query($query);
+ $live_ids[$an_id] = $this->Conn->getInsertID(); //storing newly created live id
+ //delete already copied record from master temp table
+ $query = 'DELETE FROM '.$this->GetTempName($master['TableName']).'
+ WHERE '.$master['IdField'].' = 0';
+ $this->Conn->Query($query);
+ }
+ }
// copy ALL records to live table
$query = 'INSERT INTO '.$master['TableName'].'
SELECT * FROM '.$this->GetTempName($master['TableName']);
if (isset($master['Constrain'])) $query .= ' WHERE '.$master['Constrain'];
$this->Conn->Query($query);
$this->CopiedTables[] = $table_sig;
- /*
+ $this->RaiseEvent('OnAfterCopyToLive', $master['Prefix'], '', $live_ids);
- !!! WE NEED TO FIND A WAY TO DETERMINE IF OnAfterCopyToLive is not an empty method, and do on-by-one insert
- and pass Ids to OnAfterCopyToLive, otherwise it's not smart to do on-by-one insert for any object
- OR WE COULD FIND A WAY TO GET ALL INSERTED IDS as an array and iterate them !!!
+ $this->saveID($master['Prefix'], '', $live_ids);
- $this->RaiseEvent('OnAfterCopyToLive', IDS ??? );
- */
// no need to clear temp table - it will be dropped by next statement
}
}
if ($this->FinalRefs[ $master['TableName'] ] != $master['TableId']) return;
/*if ( is_array(getArrayValue($master, 'ForeignKey')) ) { //if multiple ForeignKeys
if ( $master['ForeignKey'][$parent_prefix] != end($master['ForeignKey']) ) {
return; // Do not delete temp table if not all ForeignKeys have been processed (current is not the last)
}
}*/
$this->DropTempTable($master['TableName']);
$this->Application->resetCounters($master['TableName']);
if (!isset($this->savedIDs[ $master['Prefix'] ])) {
$this->savedIDs[ $master['Prefix'] ] = Array();
}
return $this->savedIDs[ $master['Prefix'] ];
}
function UpdateForeignKeys($master, $live_id, $temp_id) {
foreach ($master['SubTables'] as $sub_table) {
$foreign_key_field = is_array($sub_table['ForeignKey']) ? getArrayValue($sub_table, 'ForeignKey', $master['Prefix']) : $sub_table['ForeignKey'];
if (!$foreign_key_field) return;
list ($live_foreign_key, $temp_foreign_key) = $this->GetForeignKeys($master, $sub_table, $live_id, $temp_id);
//Update ForeignKey in sub TEMP table
if ($live_foreign_key != $temp_foreign_key) {
$query = 'UPDATE '.$this->GetTempName($sub_table['TableName']).'
SET '.$foreign_key_field.' = '.$live_foreign_key.'
WHERE '.$foreign_key_field.' = '.$temp_foreign_key;
if (isset($sub_table['Constrain'])) $query .= ' AND '.$sub_table['Constrain'];
$this->Conn->Query($query);
}
}
}
function CopySubTablesToLive($master, $current_ids) {
foreach ($master['SubTables'] as $sub_table) {
$table_sig = $sub_table['TableName'].(isset($sub_table['Constrain']) ? $sub_table['Constrain'] : '');
// delete records from live table by foreign key, so that records deleted from temp table
// get deleted from live
if (count($current_ids) > 0 && !in_array($table_sig, $this->CopiedTables) ) {
$foreign_key_field = is_array($sub_table['ForeignKey']) ? getArrayValue($sub_table, 'ForeignKey', $master['Prefix']) : $sub_table['ForeignKey'];
if (!$foreign_key_field) continue;
$foreign_keys = $this->GetForeignKeys($master, $sub_table, $current_ids);
if (count($foreign_keys) > 0) {
$query = 'SELECT '.$sub_table['IdField'].' FROM '.$sub_table['TableName'].'
WHERE '.$foreign_key_field.' IN ('.join(',', $foreign_keys).')';
if (isset($sub_table['Constrain'])) $query .= ' AND '.$sub_table['Constrain'];
if ( $this->RaiseEvent( 'OnBeforeDeleteFromLive', $sub_table['Prefix'], '', $this->Conn->GetCol($query), $foreign_keys ) ){
$query = 'DELETE FROM '.$sub_table['TableName'].'
WHERE '.$foreign_key_field.' IN ('.join(',', $foreign_keys).')';
if (isset($sub_table['Constrain'])) $query .= ' AND '.$sub_table['Constrain'];
$this->Conn->Query($query);
}
}
}
//sub_table passed here becomes master in the method, and recursively updated and copy its sub tables
$this->DoCopyTempToOriginal($sub_table, $master['Prefix']);
}
}
function RaiseEvent($name, $prefix, $special, $ids, $foreign_key = null, $add_params = null)
{
if ( !is_array($ids) ) return ;
$event_key = $prefix.($special ? '.' : '').$special.':'.$name;
$event = new kEvent($event_key);
if (isset($foreign_key)) {
$event->setEventParam('foreign_key', $foreign_key);
}
foreach($ids as $id)
{
$event->setEventParam('id', $id);
if (is_array($add_params)) {
foreach ($add_params as $name => $val) {
$event->setEventParam($name, $val);
}
}
$this->Application->HandleEvent($event);
}
return $event->status == erSUCCESS;
}
function DropTempTable($table)
{
if( in_array($table, $this->DroppedTables) ) return false;
$query = sprintf("DROP TABLE IF EXISTS %s",
$this->GetTempName($table)
);
array_push($this->DroppedTables, $table);
$this->DroppedTables = array_unique($this->DroppedTables);
$this->Conn->Query($query);
return true;
}
function PrepareEdit()
{
$this->DoCopyLiveToTemp($this->Tables, $this->Tables['IDs']);
+ if ($this->Application->getUnitOption($this->Tables['Prefix'],'CheckSimulatniousEdit')) {
+ $this->CheckSimultaniousEdit();
+ }
}
function SaveEdit($master_ids = Array())
{
return $this->DoCopyTempToOriginal($this->Tables, null, $master_ids);
}
function CancelEdit($master=null)
{
if (!isset($master)) $master = $this->Tables;
$this->DropTempTable($master['TableName']);
if ( getArrayValue($master, 'SubTables') ) {
foreach ($master['SubTables'] as $sub_table) {
$this->CancelEdit($sub_table);
}
}
}
+ function CheckSimultaniousEdit()
+ {
+ $tables = $this->Conn->GetCol('SHOW TABLES');
+ $mask_edit_table = '/'.TABLE_PREFIX.'ses_(.*)_edit_'.$this->MasterTable.'$/';
+ $sql='SELECT COUNT(*) FROM '.$this->TableName.' WHERE '.$this->IDField.' = \'%s\'';
+ $my_sid = $this->Application->GetSID();
+ $ids = join(',',$this->Tables['IDs']);
+ $sids = array();
+ if (!$ids) return ;
+ foreach($tables as $table)
+ {
+ if( preg_match($mask_edit_table,$table,$rets) )
+ {
+ $sid = preg_replace('/(.*)_(.*)/', '\\1', $rets[1]); // remove popup's wid from sid
+ if ($sid == $my_sid) continue;
+ $found = $this->Conn->GetOne("SELECT COUNT({$this->Tables['IdField']}) FROM $table WHERE {$this->Tables['IdField']} IN ($ids)");
+ if (!$found || in_array($sid, $sids)) continue;
+ $sids[] = $sid;
+ }
+ }
+ if ($sids) {
+ //detect who is it
+ $users = $this->Conn->GetCol(
+ ' SELECT
+ CONCAT(IF (s.PortalUserId = -1, \'root\',
+ IF (s.PortalUserId = -2, \'Guest\',
+ CONCAT(FirstName, \' \', LastName, \' (\', Login, \')\')
+ )
+ ), \' IP: \', s.IpAddress, \'\') FROM '.TABLE_PREFIX.'UserSession AS s
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser AS u
+ ON u.PortalUserId = s.PortalUserId
+ WHERE s.SessionKey IN ('.join(',',$sids).')');
+ if ($users) {
+ $this->Application->SetVar('_simultanious_edit_message',
+ sprintf($this->Application->Phrase('la_record_being_edited_by'), join(",\n", $users))
+ );
+ }
+ }
+ }
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/kernel/utility/temp_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.30
\ No newline at end of property
+1.30.2.1
\ No newline at end of property
Index: branches/RC/core/kernel/utility/debugger.php
===================================================================
--- branches/RC/core/kernel/utility/debugger.php (revision 9638)
+++ branches/RC/core/kernel/utility/debugger.php (revision 9639)
@@ -1,1303 +1,1304 @@
<?php
if( !class_exists('Debugger') ) {
class Debugger {
/**
* Set to true if fatal error occured
*
* @var bool
*/
var $IsFatalError = false;
/**
* Debugger data for building report
*
* @var Array
*/
var $Data = Array();
var $ProfilerData = Array();
var $ProfilerTotals = Array();
var $ProfilerTotalCount = Array();
var $ProfilePoints = Array();
/**
* Prevent recursion when processing debug_backtrace() function results
*
* @var Array
*/
var $RecursionStack = Array();
var $scrollbarWidth = 0;
/**
* Long errors are saved here, because trigger_error doesn't support error messages over 1KB in size
*
* @var Array
*/
var $longErrors = Array();
var $IncludesData = Array();
var $IncludeLevel = 0;
var $reportDone = false;
/**
* Transparent spacer image used in case of none spacer image defined via SPACER_URL contant.
* Used while drawing progress bars (memory usage, time usage, etc.)
*
* @var string
*/
var $dummyImage = '';
/**
* Temporary files created by debugger will be stored here
*
* @var string
*/
var $tempFolder = '';
/**
* Debug rows will be separated using this string before writing to debug file
*
* @var string
*/
var $rowSeparator = '@@';
/**
* Base URL for debugger includes
*
* @var string
*/
var $baseURL = '';
function Debugger()
{
global $start, $dbg_options;
// check if user haven't defined DEBUG_MODE contant directly
if (defined('DEBUG_MODE') && DEBUG_MODE) {
die('error: contant DEBUG_MODE defined directly, please use <strong>$dbg_options</strong> array instead');
}
// check IP before enabling debug mode
$ip_match = $this->ipMatch(isset($dbg_options['DBG_IP']) ? $dbg_options['DBG_IP'] : '');
if (!$ip_match) {
define('DEBUG_MODE', 0);
return ;
}
// debug is allowed for user, continue initialization
$this->InitDebugger();
$this->profileStart('kernel4_startup', 'Startup and Initialization of kernel4', $start);
$this->profileStart('script_runtime', 'Script runtime', $start);
error_reporting(E_ALL);
ini_set('display_errors', $this->constOn('DBG_ZEND_PRESENT') ? 0 : 1); // show errors on screen in case if not in Zend Studio debugging
$this->scrollbarWidth = $this->isGecko() ? 22 : 25; // vertical scrollbar width differs in Firefox and other browsers
$this->appendRequest();
}
/**
* Checks, that user IP address is within allowed range
*
* @param string $ip_list semi-column (by default) separated ip address list
* @param string $separator ip address separator (default ";")
*
* @return bool
*/
function ipMatch($ip_list, $separator = ';')
{
$ip_match = false;
$ip_addresses = $ip_list ? explode($separator, $ip_list) : Array ();
foreach ($ip_addresses as $ip_address) {
if ($this->netMatch($ip_address, $_SERVER['REMOTE_ADDR'])) {
$ip_match = true;
break;
}
}
return $ip_match;
}
/**
* Set's default values to constants debugger uses
*
*/
function InitDebugger()
{
global $dbg_options;
unset($_REQUEST['debug_host'], $_REQUEST['debug_fastfile'], $dbg_options['DBG_IP']); // this var messed up whole detection stuff :(
// Detect fact, that this session beeing debugged by Zend Studio
foreach ($_REQUEST as $rq_name => $rq_value) {
if (substr($rq_name, 0, 6) == 'debug_') {
$this->safeDefine('DBG_ZEND_PRESENT', 1);
break;
}
}
$this->safeDefine('DBG_ZEND_PRESENT', 0); // set this constant value to 0 (zero) to debug debugger using Zend Studio
// set default values for debugger constants
$dbg_constMap = Array(
'DBG_USE_HIGHLIGHT' => 1, // highlight output same as php code using "highlight_string" function
'DBG_WINDOW_WIDTH' => 700, // set width of debugger window (in pixels) for better viewing large amount of debug data
'DBG_USE_SHUTDOWN_FUNC' => DBG_ZEND_PRESENT ? 0 : 1, // use shutdown function to include debugger code into output
'DBG_HANDLE_ERRORS' => DBG_ZEND_PRESENT ? 0 : 1, // handle all allowed by php (see php manual) errors instead of default handler
'DBG_IGNORE_STRICT_ERRORS' => 1, // ignore PHP5 errors about private/public view modified missing in class declarations
'DBG_DOMVIEWER' => '/temp/domviewer.html', // path to DOMViewer on website
'DOC_ROOT' => str_replace('\\', '/', realpath($_SERVER['DOCUMENT_ROOT']) ), // windows hack
'DBG_LOCAL_BASE_PATH' => 'w:', // replace DOC_ROOT in filenames (in errors) using this path
);
// only for IE, in case if no windows php script editor defined
if (!defined('DBG_EDITOR')) {
// $dbg_constMap['DBG_EDITOR'] = 'c:\Program Files\UltraEdit\uedit32.exe %F/%L';
$dbg_constMap['DBG_EDITOR'] = 'c:\Program Files\Zend\ZendStudio-5.2.0\bin\ZDE.exe %F';
}
if (isset($_REQUEST['ajax']) && $_REQUEST['ajax'] && constOn('DBG_SKIP_AJAX')) {
$this->safeDefine('DBG_SKIP_REPORTING', 1);
}
// user defined options override debugger defaults
$dbg_constMap = $this->array_merge_recursive2($dbg_constMap, $dbg_options);
foreach ($dbg_constMap as $dbg_constName => $dbg_constValue) {
$this->safeDefine($dbg_constName, $dbg_constValue);
}
}
function constOn($const_name)
{
return defined($const_name) && constant($const_name);
}
function safeDefine($const_name, $const_value) {
if (!defined($const_name)) {
define($const_name, $const_value);
}
}
function array_merge_recursive2($paArray1, $paArray2)
{
if (!is_array($paArray1) or !is_array($paArray2)) {
return $paArray2;
}
foreach ($paArray2 AS $sKey2 => $sValue2) {
$paArray1[$sKey2] = isset($paArray1[$sKey2]) ? array_merge_recursive2($paArray1[$sKey2], $sValue2) : $sValue2;
}
return $paArray1;
}
function netMatch($network, $ip) {
$network = trim($network);
$ip = trim($ip);
if ($network == $ip) {
// comparing 2 ip addresses directly
return true;
}
$d = strpos($network, '-');
if ($d === false) {
// sigle subnet specified
$ip_arr = explode('/', $network);
if (!preg_match("@\d*\.\d*\.\d*\.\d*@", $ip_arr[0], $matches)) {
$ip_arr[0] .= '.0'; // Alternate form 194.1.4/24
}
$network_long = ip2long($ip_arr[0]);
$x = ip2long($ip_arr[1]);
$mask = long2ip($x) == $ip_arr[1] ? $x : (0xffffffff << (32 - $ip_arr[1]));
$ip_long = ip2long($ip);
return ($ip_long & $mask) == ($network_long & $mask);
}
else {
// ip address range specified
$from = ip2long(trim(substr($network, 0, $d)));
$to = ip2long(trim(substr($network, $d + 1)));
$ip = ip2long($ip);
return ($ip >= $from && $ip <= $to);
}
}
function InitReport()
{
if (!class_exists('kApplication')) return false;
$application =& kApplication::Instance();
// string used to separate debugger records while in file (used in debugger dump filename too)
$this->rowSeparator = '@'.(is_object($application->Factory) ? $application->GetSID() : 0).'@';
// include debugger files from this url
$reg_exp = '/^'.preg_quote(FULL_PATH, '/').'/';
$kernel_path = preg_replace($reg_exp, '', KERNEL_PATH, 1);
$this->baseURL = PROTOCOL.SERVER_NAME.rtrim(BASE_PATH, '/').$kernel_path.'/utility/debugger';
// save debug output in this folder
$this->tempFolder = defined('WRITEABLE') ? WRITEABLE.'/cache' : FULL_PATH.'/kernel/cache';
}
function mapLongError($msg)
{
$key = $this->generateID();
$this->longErrors[$key] = $msg;
return $key;
}
/**
* Appends all passed variable values (wihout variable names) to debug output
*
*/
function dumpVars()
{
$dump_mode = 'var_dump';
$dumpVars = func_get_args();
if ($dumpVars[count($dumpVars) - 1] === 'STRICT') {
$dump_mode = 'strict_var_dump';
array_pop($dumpVars);
}
foreach ($dumpVars as $varValue) {
$this->Data[] = Array('value' => $varValue, 'debug_type' => $dump_mode);
}
}
function prepareHTML($dataIndex)
{
$Data =& $this->Data[$dataIndex];
if ($Data['debug_type'] == 'html') {
return $Data['html'];
}
switch ($Data['debug_type']) {
case 'error':
$fileLink = $this->getFileLink($Data['file'], $Data['line']);
$ret = '<b class="debug_error">'.$this->getErrorNameByCode($Data['no']).'</b>: '.$Data['str'];
$ret .= ' in <b>'.$fileLink.'</b> on line <b>'.$Data['line'].'</b>';
return $ret;
break;
case 'var_dump':
return $this->highlightString( $this->print_r($Data['value'], true) );
break;
case 'strict_var_dump':
return $this->highlightString( var_export($Data['value'], true) );
break;
case 'trace':
ini_set('memory_limit', '500M');
$trace =& $Data['trace'];
$i = 0; $traceCount = count($trace);
$ret = '';
while ($i < $traceCount) {
$traceRec =& $trace[$i];
$argsID = 'trace_args_'.$dataIndex.'_'.$i;
$has_args = isset($traceRec['args']);
if (isset($traceRec['file'])) {
$func_name = isset($traceRec['class']) ? $traceRec['class'].$traceRec['type'].$traceRec['function'] : $traceRec['function'];
$args_link = $has_args ? '<a href="javascript:$Debugger.ToggleTraceArgs(\''.$argsID.'\');" title="Show/Hide Function Arguments"><b>Function</b></a>' : '<b>Function</b>';
$ret .= $args_link.': '.$this->getFileLink($traceRec['file'], $traceRec['line'], $func_name);
$ret .= ' in <b>'.basename($traceRec['file']).'</b> on line <b>'.$traceRec['line'].'</b><br>';
}
else {
$ret .= 'no file information available';
}
if ($has_args) {
// if parameter value is longer then 200 symbols, then leave only first 50
$args = $this->highlightString($this->print_r($traceRec['args'], true));
$ret .= '<div id="'.$argsID.'" style="display: none;">'.$args.'</div>';
}
$i++;
}
return $ret;
break;
case 'profiler':
$profileKey = $Data['profile_key'];
$Data =& $this->ProfilerData[$profileKey];
$runtime = ($Data['ends'] - $Data['begins']); // in seconds
$totals_key = getArrayValue($Data, 'totalsKey');
if ($totals_key) {
$total_before = $Data['totalsBefore'];
$total = $this->ProfilerTotals[$totals_key];
$div_width = Array();
$total_width = ($this->getWindowWidth() - 10);
$div_width['before'] = round(($total_before / $total) * $total_width);
$div_width['current'] = round(($runtime / $total) * $total_width);
$div_width['left'] = round((($total - $total_before - $runtime) / $total) * $total_width);
$ret = '<b>Name</b>: '.$Data['description'].'<br />';
$additional = isset($Data['additional']) ? $Data['additional'] : Array ();
if (isset($Data['file'])) {
array_unshift($additional, Array('name' => 'File', 'value' => $this->getFileLink($Data['file'], $Data['line'], basename($Data['file']).':'.$Data['line'])));
}
array_unshift($additional, Array('name' => 'Runtime', 'value' => $runtime.'s'));
foreach ($additional as $mixed_param) {
$ret .= '[<strong>'.$mixed_param['name'].'</strong>: '.$mixed_param['value'].'] ';
}
/*if (isset($Data['file'])) {
$ret .= '[<b>Runtime</b>: '.$runtime.'s] [<b>File</b>: '.$this->getFileLink($Data['file'], $Data['line'], basename($Data['file']).':'.$Data['line']).']<br />';
}
else {
$ret .= '<b>Runtime</b>: '.$runtime.'s<br />';
}*/
$ret .= '<div class="dbg_profiler" style="width: '.$div_width['before'].'px; border-right: 0px; background-color: #298DDF;"><img src="'.$this->dummyImage.'" width="1" height="1"/></div>';
$ret .= '<div class="dbg_profiler" style="width: '.$div_width['current'].'px; border-left: 0px; border-right: 0px; background-color: #EF4A4A;"><img src="'.$this->dummyImage.'" width="1" height="1"/></div>';
$ret .= '<div class="dbg_profiler" style="width: '.$div_width['left'].'px; border-left: 0px; background-color: #DFDFDF;"><img src="'.$this->dummyImage.'" width="1" height="1"/></div>';
return $ret;
}
else {
return '<b>Name</b>: '.$Data['description'].'<br><b>Runtime</b>: '.$runtime.'s';
}
break;
default:
return 'incorrect debug data';
break;
}
}
function getWindowWidth()
{
return DBG_WINDOW_WIDTH - $this->scrollbarWidth - 8;
}
/**
* Tells debugger to skip objects that are heavy in plan of memory usage while printing debug_backtrace results
*
* @param Object $object
* @return bool
*/
function IsBigObject(&$object)
{
$skip_classes = Array(
defined('APPLICATION_CLASS') ? APPLICATION_CLASS : 'kApplication',
'kFactory',
'kUnitConfigReader',
'TemplateParser',
);
foreach ($skip_classes as $class_name) {
if (strtolower(get_class($object)) == strtolower($class_name)) {
return true;
}
}
return false;
}
/**
* Advanced version of print_r (for debugger only). Don't print objects recursively
*
* @param Array $array
* @param bool $return_output return output or print it out
* @param int $tab_count offset in tabs
* @return string
*/
function print_r(&$array, $return_output = false, $tab_count = -1)
{
static $first_line = true;
// not an array at all
if (!is_array($array)) {
switch (gettype($array)) {
case 'NULL':
return 'NULL'."\n";
break;
case 'object':
return $this->processObject($array, $tab_count);
break;
default:
// number or string
if (strlen($array) > 200) {
$array = substr($array, 0, 50).' ...';
}
return $array."\n";
break;
}
}
$output = '';
$tab_count++;
$output .= "Array\n".str_repeat(' ', $tab_count)."(\n";
$tab_count++;
$tabsign = $tab_count ? str_repeat(' ', $tab_count) : '';
$array_keys = array_keys($array);
foreach ($array_keys as $key) {
switch (gettype($array[$key])) {
case 'array':
$output .= $tabsign.'['.$key.'] = '.$this->print_r($array[$key], true, $tab_count);
break;
case 'boolean':
$output .= $tabsign.'['.$key.'] = '.($array[$key] ? 'true' : 'false')."\n";
break;
case 'integer':
case 'double':
case 'string':
if (strlen($array[$key]) > 200) {
$array[$key] = substr($array[$key], 0, 50).' ...';
}
$output .= $tabsign.'['.$key.'] = '.$array[$key]."\n";
break;
case 'NULL':
$output .= $tabsign.'['.$key."] = NULL\n";
break;
case 'object':
$output .= $tabsign.'['.$key."] = ";
$output .= "Object (".get_class($array[$key]).") = \n".str_repeat(' ', $tab_count + 1)."(\n";
$output .= $this->processObject($array[$key], $tab_count + 2);
$output .= str_repeat(' ', $tab_count + 1).")\n";
break;
default:
$output .= $tabsign.'['.$key.'] unknown = '.gettype($array[$key])."\n";
break;
}
}
$tab_count--;
$output .= str_repeat(' ', $tab_count).")\n";
if ($first_line) {
$first_line = false;
$output .= "\n";
}
$tab_count--;
if ($return_output) {
return $output;
}
else {
echo $output;
}
return true;
}
function processObject(&$object, $tab_count)
{
$object_class = get_class($object);
if (!in_array($object_class, $this->RecursionStack)) {
if ($this->IsBigObject($object)) {
return 'SKIPPED (class: '.$object_class.")\n";
}
$attribute_names = get_class_vars($object_class);
if (!$attribute_names) {
return "NO_ATTRIBUTES\n";
}
else {
$output = '';
array_push($this->RecursionStack, $object_class);
$tabsign = $tab_count ? str_repeat(' ', $tab_count) : '';
foreach ($attribute_names as $attribute_name => $attribute_value) {
if (is_object($object->$attribute_name)) {
// it is object
$output .= $tabsign.'['.$attribute_name.'] = '.$this->processObject($object->$attribute_name, $tab_count + 1);
}
else {
$output .= $tabsign.'['.$attribute_name.'] = '.$this->print_r($object->$attribute_name, true, $tab_count);
}
}
array_pop($this->RecursionStack);
return $output;
}
}
else {
// object [in recursion stack]
return '*** RECURSION *** (class: '.$object_class.")\n";
}
}
/**
* Format SQL Query using predefined formatting
* and highlighting techniques
*
* @param string $sql
* @return string
*/
function formatSQL($sql)
{
$sql = preg_replace('/(\n|\t| )+/is', ' ', $sql);
$sql = preg_replace('/(CREATE TABLE|DROP TABLE|SELECT|UPDATE|SET|REPLACE|INSERT|DELETE|VALUES|FROM|LEFT JOIN|INNER JOIN|LIMIT|WHERE|HAVING|GROUP BY|ORDER BY) /is', "\n\t$1 ", $sql);
return $this->highlightString($sql);
}
function highlightString($string)
{
if (!$this->constOn('DBG_USE_HIGHLIGHT')) {
return $string;
}
$string = str_replace( Array('\\', '/') , Array('_no_match_string_', '_n_m_s_'), $string);
$string = highlight_string('<?php'.$string.'?>', true);
$string = str_replace( Array('_no_match_string_', '_n_m_s_'), Array('\\', '/'), $string);
return preg_replace('/&lt;\?(.*)php(.*)\?&gt;/Us', '\\2', $string);
}
/**
* Determine by php type of browser used to show debugger
*
* @return bool
*/
function isGecko()
{
- return strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'firefox') !== false;
+ // we need isset because we may run scripts from shell with no user_agent at all
+ return isset($_SERVER['HTTP_USER_AGENT']) && strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'firefox') !== false;
}
/**
* Returns link for editing php file (from error) in external editor
*
* @param string $file filename with path from root folder
* @param int $lineno line number in file where error is found
* @param string $title text to show on file edit link
* @return string
*/
function getFileLink($file, $lineno = 1, $title = '')
{
if (!$title) {
$title = str_replace('/', '\\', $this->getLocalFile($file));
}
if ($this->isGecko()) {
return '<a href="file://'.$this->getLocalFile($file).'">'.$title.'</a>';
}
else {
return '<a href="javascript:$Debugger.editFile(\''.$this->getLocalFile($file).'\', '.$lineno.');" title="'.$file.'">'.$title.'</a>';
}
}
/**
* Converts filepath on server to filepath in mapped DocumentRoot on developer pc
*
* @param string $remoteFile
* @return string
*/
function getLocalFile($remoteFile)
{
return preg_replace('/^'.preg_quote(DOC_ROOT, '/').'/', DBG_LOCAL_BASE_PATH, $remoteFile, 1);
}
/**
* Appends call trace till this method call
*
*/
function appendTrace()
{
$trace = debug_backtrace();
array_shift($trace);
$this->Data[] = Array('trace' => $trace, 'debug_type' => 'trace');
}
function appendMemoryUsage($msg, $used = null)
{
if (!isset($used)) {
$used = round(memory_get_usage() / 1024);
}
$this->appendHTML('<b>Memory usage</b> '.$msg.' '.$used.'Kb');
}
/**
* Appends HTML code whithout transformations
*
* @param string $html
*/
function appendHTML($html)
{
$this->Data[] = Array('html' => $html, 'debug_type' => 'html');
}
/**
* Change debugger info that was already generated before.
* Returns true if html was set.
*
* @param int $index
* @param string $html
* @param string $type = {'append','prepend','replace'}
* @return bool
*/
function setHTMLByIndex($index, $html, $type = 'append')
{
if (!isset($this->Data[$index]) || $this->Data[$index]['debug_type'] != 'html') {
return false;
}
switch ($type) {
case 'append':
$this->Data[$index]['html'] .= '<br>'.$html;
break;
case 'prepend':
$this->Data[$index]['html'] = $this->Data[$index]['html'].'<br>'.$html;
break;
case 'replace':
$this->Data[$index]['html'] = $html;
break;
}
return true;
}
/**
* Move $debugLineCount lines of input from debug output
* end to beginning.
*
* @param int $debugLineCount
*/
function moveToBegin($debugLineCount)
{
$lines = array_splice($this->Data,count($this->Data)-$debugLineCount,$debugLineCount);
$this->Data = array_merge($lines,$this->Data);
}
function moveAfterRow($new_row, $debugLineCount)
{
$lines = array_splice($this->Data,count($this->Data)-$debugLineCount,$debugLineCount);
$rows_before = array_splice($this->Data,0,$new_row,$lines);
$this->Data = array_merge($rows_before,$this->Data);
}
function appendRequest()
{
if (isset($_SERVER['SCRIPT_FILENAME'])) {
$script = $_SERVER['SCRIPT_FILENAME'];
}
else {
$script = $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF'];
}
$this->appendHTML('ScriptName: <b>'.$this->getFileLink($script, 1, basename($script)).'</b> (<b>'.dirname($script).'</b>)');
if (isset($_REQUEST['ajax']) && $_REQUEST['ajax'] == 'yes') {
$this->appendHTML('RequestURI: '.$_SERVER['REQUEST_URI'].' (QS Length:'.strlen($_SERVER['QUERY_STRING']).')');
}
$this->appendHTML('<a href="http://www.brainjar.com/dhtml/domviewer/" target="_blank">DomViewer</a>: <input id="dbg_domviewer" type="text" value="window" style="border: 1px solid #000000;"/>&nbsp;<button class="button" onclick="return $Debugger.OpenDOMViewer();">Show</button>');
ob_start();
?>
<table border="0" cellspacing="0" cellpadding="0" class="dbg_flat_table" style="width: <?php echo $this->getWindowWidth(); ?>px;">
<thead style="font-weight: bold;">
<td width="20">Src</td><td>Name</td><td>Value</td>
</thead>
<?php
foreach ($_REQUEST as $key => $value) {
if(!is_array($value) && trim($value) == '') {
$value = '<b class="debug_error">no value</b>';
}
else {
$value = htmlspecialchars($this->print_r($value, true));
}
$in_cookie = isset($_COOKIE[$key]);
$src = isset($_GET[$key]) && !$in_cookie ? 'GE' : (isset($_POST[$key]) && !$in_cookie ? 'PO' : ($in_cookie ? 'CO' : '?') );
echo '<tr><td>'.$src.'</td><td>'.$key.'</td><td>'.$value.'</td></tr>';
}
?>
</table>
<?php
$this->appendHTML(ob_get_contents());
ob_end_clean();
}
/**
* Appends php session content to debugger output
*
*/
function appendSession()
{
if (isset($_SESSION) && $_SESSION) {
$this->appendHTML('PHP Session: [<b>'.ini_get('session.name').'</b>]');
$this->dumpVars($_SESSION);
$this->moveToBegin(2);
}
}
function profileStart($key, $description = null, $timeStamp = null)
{
if (!isset($timeStamp)) {
$timeStamp = $this->getMoment();
}
$this->ProfilerData[$key] = Array('begins' => $timeStamp, 'ends' => 5000, 'debuggerRowID' => count($this->Data));
if (isset($description)) {
$this->ProfilerData[$key]['description'] = $description;
}
if (substr($key, 0, 4) == 'sql_') {
// append place from what was called
$trace_results = debug_backtrace();
$trace_count = count($trace_results);
$i = 0;
while ($i < $trace_count) {
$trace_file = basename($trace_results[$i]['file']);
if ($trace_file != 'db_connection.php' && $trace_file != 'adodb.inc.php') {
break;
}
$i++;
}
$this->ProfilerData[$key]['file'] = $trace_results[$i]['file'];
$this->ProfilerData[$key]['line'] = $trace_results[$i]['line'];
unset($trace_results);
}
$this->Data[] = Array('profile_key' => $key, 'debug_type' => 'profiler');
}
function profileFinish($key, $description = null, $timeStamp = null)
{
if (!isset($timeStamp)) {
$timeStamp = $this->getMoment();
}
$this->ProfilerData[$key]['ends'] = $timeStamp;
if (isset($description)) {
$this->ProfilerData[$key]['description'] = $description;
}
if (substr($key, 0, 4) == 'sql_') {
$func_arguments = func_get_args();
$rows_affected = $func_arguments[3];
if ($rows_affected > 0) {
$additional = Array (
Array ('name' => 'Affected Rows', 'value' => $rows_affected),
);
if (isset($func_arguments[4])) {
$additional[] = Array ('name' => 'Result', 'value' => $func_arguments[4]);
}
$this->ProfilerData[$key]['additional'] =& $additional;
}
}
}
function profilerAddTotal($total_key, $key = null, $value = null)
{
if (!isset($this->ProfilerTotals[$total_key])) {
$this->ProfilerTotals[$total_key] = 0;
$this->ProfilerTotalCount[$total_key] = 0;
}
if (!isset($value)) {
$value = $this->ProfilerData[$key]['ends'] - $this->ProfilerData[$key]['begins'];
}
if (isset($key)) {
$this->ProfilerData[$key]['totalsKey'] = $total_key;
$this->ProfilerData[$key]['totalsBefore'] = $this->ProfilerTotals[$total_key];
}
$this->ProfilerTotals[$total_key] += $value;
$this->ProfilerTotalCount[$total_key]++;
}
function getMoment()
{
list($usec, $sec) = explode(' ', microtime());
return ((float)$usec + (float)$sec);
}
function generateID()
{
list($usec, $sec) = explode(' ', microtime());
$id_part_1 = substr($usec, 4, 4);
$id_part_2 = mt_rand(1,9);
$id_part_3 = substr($sec, 6, 4);
$digit_one = substr($id_part_1, 0, 1);
if ($digit_one == 0) {
$digit_one = mt_rand(1,9);
$id_part_1 = ereg_replace("^0",'',$id_part_1);
$id_part_1=$digit_one.$id_part_1;
}
return $id_part_1.$id_part_2.$id_part_3;
}
function getErrorNameByCode($error_code)
{
$error_map = Array(
'Fatal Error' => Array(E_USER_ERROR),
'Warning' => Array(E_WARNING, E_USER_WARNING),
'Notice' => Array(E_NOTICE, E_USER_NOTICE),
);
if (defined('E_STRICT')) {
$error_map['PHP5 Strict'] = Array(E_STRICT);
}
if (defined('E_RECOVERABLE_ERROR')) {
$error_map['Fatal Error (recoverable)'] = Array(E_RECOVERABLE_ERROR);
}
foreach ($error_map as $error_name => $error_codes) {
if (in_array($error_code, $error_codes)) {
return $error_name;
}
}
return '';
}
/**
* Returns profile total key (check against unexisting key too)
*
* @param string $key
* @return int
*/
function getProfilerTotal($key)
{
if (isset($this->ProfilerTotalCount[$key])) {
return (int)$this->ProfilerTotalCount[$key];
}
return 0;
}
function ProfilePoint($title, $level=1)
{
$trace_results = debug_backtrace();
$level = min($level,count($trace_results)-1);
do {
$point = $trace_results[$level];
$location = $point['file'].':'.$point['line'];
$level++;
$has_more = isset($trace_results[$level]);
} while ($has_more && $point['function'] == $trace_results[$level]['function'] );
if ($location == ':') {
echo '';
}
if (!isset($this->ProfilePoints[$title])) {
$this->ProfilePoints[$title] = array();
}
if (!isset($this->ProfilePoints[$title][$location])) {
$this->ProfilePoints[$title][$location] = 0;
}
$this->ProfilePoints[$title][$location]++;
}
/**
* Generates report
*
*/
function printReport($returnResult = false, $clean_output_buffer = true)
{
if ($this->reportDone) {
// don't print same report twice (in case if shutdown function used + compression + fatal error)
return '';
}
$this->profileFinish('script_runtime');
$this->breakOutofBuffering();
$debugger_start = memory_get_usage();
if (defined('SPACER_URL')) {
$this->dummyImage = SPACER_URL;
}
$this->InitReport(); // set parameters required by AJAX
// defined here, because user can define this contant while script is running, not event before debugger is started
$this->safeDefine('DBG_RAISE_ON_WARNINGS', 0);
$this->safeDefine('DBG_TOOLBAR_BUTTONS', 1);
$this->appendSession(); // show php session if any
// ensure, that 1st line of debug output always is this one:
$top_line = '<table cellspacing="0" cellpadding="0" style="width: '.$this->getWindowWidth().'px; margin: 0px;"><tr><td align="left" width="50%">[<a href="javascript:window.location.reload();">Reload Frame</a>] [<a href="javascript:$Debugger.Toggle(27);">Hide Debugger</a>]</td><td align="right" width="50%">[Current Time: <b>'.date('H:i:s').'</b>] [File Size: <b>#DBG_FILESIZE#</b>]</td></tr></table>';
$this->appendHTML($top_line);
$this->moveToBegin(1);
if (count($this->ProfilePoints)>0) {
foreach($this->ProfilePoints as $point => $locations) {
arsort($this->ProfilePoints[$point]);
}
$this->appendHTML($this->highlightString($this->print_r($this->ProfilePoints, true)));
/*foreach ($this->ProfilePoints as $point => $locations) {
foreach ($locations as $location => $occurences) {
}
}*/
}
if ($this->constOn('DBG_SQL_PROFILE') && isset($this->ProfilerTotals['sql'])) {
// sql query profiling was enabled -> show totals
$this->appendHTML('<b>SQL Total time:</b> '.$this->ProfilerTotals['sql'].' <b>Number of queries</b>: '.$this->ProfilerTotalCount['sql']);
}
if ($this->constOn('DBG_PROFILE_INCLUDES') && isset($this->ProfilerTotals['includes'])) {
// included file profiling was enabled -> show totals
$this->appendHTML('<b>Included Files Total time:</b> '.$this->ProfilerTotals['includes'].' Number of includes: '.$this->ProfilerTotalCount['includes']);
}
if ($this->constOn('DBG_PROFILE_MEMORY')) {
// detailed memory usage reporting by objects was enabled -> show totals
$this->appendHTML('<b>Memory used by Objects:</b> '.round($this->ProfilerTotals['objects'] / 1024, 2).'Kb');
}
if ($this->constOn('DBG_INCLUDED_FILES')) {
$files = get_included_files();
$this->appendHTML('<b>Included files:</b>');
foreach ($files as $file) {
$this->appendHTML($this->getFileLink($this->getLocalFile($file)).' ('.round(filesize($file) / 1024, 2).'Kb)');
}
}
/*if ($this->constOn('DBG_PROFILE_INCLUDES')) {
$this->appendHTML('<b>Included files statistics:</b>'.( $this->constOn('DBG_SORT_INCLUDES_MEM') ? ' (sorted by memory usage)':''));
$totals = Array( 'mem' => 0, 'time' => 0);
$totals_configs = Array( 'mem' => 0, 'time' => 0);
if (is_array($this->IncludesData['mem'])) {
if ( $this->constOn('DBG_SORT_INCLUDES_MEM') ) {
array_multisort($this->IncludesData['mem'], SORT_DESC, $this->IncludesData['file'], $this->IncludesData['time'], $this->IncludesData['level']);
}
foreach ($this->IncludesData['file'] as $key => $file_name) {
$this->appendHTML( str_repeat('&nbsp;->&nbsp;', ($this->IncludesData['level'][$key] >= 0 ? $this->IncludesData['level'][$key] : 0)).$file_name.' Mem: '.sprintf("%.4f Kb", $this->IncludesData['mem'][$key]/1024).' Time: '.sprintf("%.4f", $this->IncludesData['time'][$key]));
if ($this->IncludesData['level'][$key] == 0) {
$totals['mem'] += $this->IncludesData['mem'][$key];
$totals['time'] += $this->IncludesData['time'][$key];
}
else if ($this->IncludesData['level'][$key] == -1) {
$totals_configs['mem'] += $this->IncludesData['mem'][$key];
$totals_configs['time'] += $this->IncludesData['time'][$key];
}
}
$this->appendHTML('<b>Sub-Total classes:</b> '.' Mem: '.sprintf("%.4f Kb", $totals['mem']/1024).' Time: '.sprintf("%.4f", $totals['time']));
$this->appendHTML('<b>Sub-Total configs:</b> '.' Mem: '.sprintf("%.4f Kb", $totals_configs['mem']/1024).' Time: '.sprintf("%.4f", $totals_configs['time']));
$this->appendHTML('<span class="error"><b>Grand Total:</b></span> '.' Mem: '.sprintf("%.4f Kb", ($totals['mem']+$totals_configs['mem'])/1024).' Time: '.sprintf("%.4f", $totals['time']+$totals_configs['time']));
}
}*/
$is_ajax = isset($_GET['ajax']) && $_GET['ajax'] == 'yes';
$skip_reporting = $this->constOn('DBG_SKIP_REPORTING') || $this->constOn('DBG_ZEND_PRESENT');
if (($is_ajax && !constOn('DBG_SKIP_AJAX')) || !$skip_reporting) {
$debug_file = $this->tempFolder.'/debug_'.$this->rowSeparator.'.txt';
if (file_exists($debug_file)) unlink($debug_file);
$i = 0;
$fp = fopen($debug_file, 'a');
$lineCount = count($this->Data);
while ($i < $lineCount) {
fwrite($fp, $this->prepareHTML($i).$this->rowSeparator);
$i++;
}
fclose($fp);
}
if ($skip_reporting) {
// let debugger write report and then don't output anything
$this->reportDone = true;
return '';
}
$dbg_path = str_replace(FULL_PATH, '', $this->tempFolder);
ob_start();
// the <script .. /script> and hidden div helps browser to break out of script tag or attribute esacped
// with " or ' in case fatal error (or user-error) occurs inside it in compiled template,
// otherwise it has no effect
?>
<div style="display: none" x='nothing'><script></script></div><html><body></body></html>
<script type="text/javascript" src="<?php echo $this->baseURL; ?>/debugger.js"></script>
<link rel="stylesheet" rev="stylesheet" href="<?php echo $this->baseURL; ?>/debugger.css" type="text/css" media="screen" />
<div id="debug_layer" class="debug_layer_container" style="display: none; width: <?php echo DBG_WINDOW_WIDTH; ?>px;">
<div class="debug_layer" style="width: <?php echo $this->getWindowWidth(); ?>px;">
<table width="100%" cellpadding="0" cellspacing="1" border="0" class="debug_layer_table" style="width: <?php echo $this->getWindowWidth(); ?>px;" align="left">
<tbody id="debug_table"></tbody>
</table>
</div>
</div>
<script type="text/javascript">
var $Debugger = new Debugger(<?php echo "'".$this->rowSeparator."', ".$this->getProfilerTotal('error_handling').', '.($this->IsFatalError ? 'true' : 'false').', '.$this->getProfilerTotal('sql'); ?>);
$Debugger.DOMViewerURL = '<?php echo constant('DBG_DOMVIEWER'); ?>';
$Debugger.EditorPath = '<?php echo defined('DBG_EDITOR') ? addslashes(DBG_EDITOR) : '' ?>';
$Debugger.DebugURL = '<?php echo $this->baseURL.'/debugger_responce.php?sid='.$this->rowSeparator.'&path='.urlencode($dbg_path); ?>';
<?php
if ($this->IsFatalError || DBG_RAISE_ON_WARNINGS) {
echo '$Debugger.Toggle();';
}
if (DBG_TOOLBAR_BUTTONS) {
echo '$Debugger.AddToolbar("$Debugger");';
}
?>
window.focus();
</script>
<?php
if (!isset($this->ProfilerTotals['error_handling'])) {
$memory_used = $debugger_start;
$this->ProfilerTotalCount['error_handling'] = 0;
}
else {
$memory_used = $debugger_start - $this->ProfilerTotals['error_handling'];
}
if ($returnResult) {
$ret = ob_get_contents();
if ($clean_output_buffer) {
ob_end_clean();
}
$ret .= $this->getShortReport($memory_used);
$this->reportDone = true;
return $ret;
}
else {
if (!$this->constOn('DBG_HIDE_FULL_REPORT')) {
$this->breakOutofBuffering();
}
elseif ($clean_output_buffer) {
ob_clean();
}
echo $this->getShortReport($memory_used);
$this->reportDone = true;
}
}
/**
* Format's memory usage report by debugger
*
* @return string
* @access private
*/
function getShortReport($memory_used)
{
if ($this->constOn('DBG_TOOLBAR_BUTTONS')) {
// we have sql & error count in toolbar, don't duplicate here
$info = Array(
'Script Runtime' => 'PROFILE:script_runtime',
'SQL\'s Runtime' => 'PROFILE_T:sql',
);
}
else {
// toolbar not visible, then show sql & error count too
$info = Array (
'Script Runtime' => 'PROFILE:script_runtime',
'SQL\'s Runtime' => 'PROFILE_T:sql',
'-' => 'SEP:-',
'Notice / Warning' => 'PROFILE_TC:error_handling',
'SQLs Count' => 'PROFILE_TC:sql',
);
}
$ret = '<tr><td>Application:</td><td><b>'.$this->formatSize($memory_used).'</b> ('.$memory_used.')</td></tr>';
foreach ($info as $title => $value_key) {
list ($record_type, $record_data) = explode(':', $value_key, 2);
switch ($record_type) {
case 'PROFILE': // profiler totals value
$Data =& $this->ProfilerData[$record_data];
$profile_time = ($Data['ends'] - $Data['begins']); // in seconds
$ret .= '<tr><td>'.$title.':</td><td><b>'.sprintf('%.5f', $profile_time).' s</b></td></tr>';
break;
case 'PROFILE_TC': // profile totals record count
$record_cell = '<td>';
if ($record_data == 'error_handling' && $this->ProfilerTotalCount[$record_data] > 0) {
$record_cell = '<td class="debug_error">';
}
$ret .= '<tr>'.$record_cell.$title.':</td>'.$record_cell.'<b>'.$this->ProfilerTotalCount[$record_data].'</b></td></tr>';
break;
case 'PROFILE_T': // profile total
$record_cell = '<td>';
$ret .= '<tr>'.$record_cell.$title.':</td>'.$record_cell.'<b>'.sprintf('%.5f', $this->ProfilerTotals[$record_data]).' s</b></td></tr>';
break;
case 'SEP':
$ret .= '<tr><td colspan="2" style="height: 1px; background-color: #000000; padding: 0px;"><img src="'.$this->dummyImage.'" height="1" alt=""/></td></tr>';
break;
}
}
return '<br /><table class="dbg_stats_table"><tr><td style="border-color: #FFFFFF;"><table class="dbg_stats_table" align="left">'.$ret.'</table></td></tr></table>';
}
/**
* User-defined error handler
*
* @param int $errno
* @param string $errstr
* @param string $errfile
* @param int $errline
* @param array $errcontext
*/
function saveError($errno, $errstr, $errfile = '', $errline = '', $errcontext = '')
{
$this->ProfilerData['error_handling']['begins'] = memory_get_usage();
$errorType = $this->getErrorNameByCode($errno);
if (!$errorType) {
trigger_error('Unknown error type ['.$errno.']', E_USER_ERROR);
return false;
}
if ($this->constOn('DBG_IGNORE_STRICT_ERRORS') && defined('E_STRICT') && ($errno == E_STRICT)) return;
if (preg_match('/(.*)#([\d]+)$/', $errstr, $rets) ) {
// replace short message with long one (due triger_error limitations on message size)
$long_id = $rets[2];
$errstr = $this->longErrors[$long_id];
unset($this->longErrors[$long_id]);
}
if (strpos($errfile,'eval()\'d code') !== false) {
$errstr = '[<b>EVAL</b>, line <b>'.$errline.'</b>]: '.$errstr;
$tmpStr = $errfile;
$pos = strpos($tmpStr,'(');
$errfile = substr($tmpStr, 0, $pos);
$pos++;
$errline = substr($tmpStr,$pos,strpos($tmpStr,')',$pos)-$pos);
}
$this->Data[] = Array('no' => $errno, 'str' => $errstr, 'file' => $errfile, 'line' => $errline, 'context' => $errcontext, 'debug_type' => 'error');
$this->ProfilerData['error_handling']['ends'] = memory_get_usage();
$this->profilerAddTotal('error_handling', 'error_handling');
if (substr($errorType, 0, 5) == 'Fatal') {
$this->IsFatalError = true;
// append debugger report to data in buffer & clean buffer afterwards
die( $this->breakOutofBuffering(false) . $this->printReport(true) );
}
}
function breakOutofBuffering($flush = true)
{
$buffer_content = Array();
while (ob_get_level()) {
$buffer_content[] = ob_get_clean();
}
$ret = implode('', array_reverse($buffer_content));
if ($flush) {
echo $ret;
flush();
}
return $ret;
}
function saveToFile($msg)
{
$fp = fopen($_SERVER['DOCUMENT_ROOT'].'/vb_debug.txt', 'a');
fwrite($fp, $msg."\n");
fclose($fp);
}
/**
* Formats file/memory size in nice way
*
* @param int $bytes
* @return string
* @access public
*/
function formatSize($bytes)
{
if ($bytes >= 1099511627776) {
$return = round($bytes / 1024 / 1024 / 1024 / 1024, 2);
$suffix = "TB";
} elseif ($bytes >= 1073741824) {
$return = round($bytes / 1024 / 1024 / 1024, 2);
$suffix = "GB";
} elseif ($bytes >= 1048576) {
$return = round($bytes / 1024 / 1024, 2);
$suffix = "MB";
} elseif ($bytes >= 1024) {
$return = round($bytes / 1024, 2);
$suffix = "KB";
} else {
$return = $bytes;
$suffix = "Byte";
}
$return .= ' '.$suffix;
return $return;
}
function printConstants($constants)
{
if (!is_array($constants)) {
$constants = explode(',', $constants);
}
$contant_tpl = '<tr><td>%s</td><td><b>%s</b></td></tr>';
$ret = '<table class="dbg_flat_table" style="width: '.$this->getWindowWidth().'px;">';
foreach ($constants as $constant_name) {
$ret .= sprintf($contant_tpl, $constant_name, constant($constant_name));
}
$ret .= '</table>';
$this->appendHTML($ret);
}
function AttachToApplication() {
if (!$this->constOn('DBG_HANDLE_ERRORS')) return true;
if (class_exists('kApplication')) {
restore_error_handler();
$application =& kApplication::Instance();
$application->Debugger =& $this;
$application->errorHandlers[] = Array(&$this, 'saveError');
}
else {
set_error_handler(Array(&$this, 'saveError'));
}
}
}
if (!function_exists('memory_get_usage')) {
function memory_get_usage(){ return -1; }
}
if (!Debugger::constOn('DBG_ZEND_PRESENT')) {
$debugger = new Debugger();
}
if (Debugger::constOn('DBG_USE_SHUTDOWN_FUNC')) {
register_shutdown_function( Array(&$debugger, 'printReport') );
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/kernel/utility/debugger.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.76
\ No newline at end of property
+1.76.2.1
\ No newline at end of property
Index: branches/RC/core/kernel/db/db_tag_processor.php
===================================================================
--- branches/RC/core/kernel/db/db_tag_processor.php (revision 9638)
+++ branches/RC/core/kernel/db/db_tag_processor.php (revision 9639)
@@ -1,2064 +1,2074 @@
<?php
class kDBTagProcessor extends TagProcessor {
/**
* Description
*
* @var kDBConnection
* @access public
*/
var $Conn;
function kDBTagProcessor()
{
parent::kBase();
$this->Conn =& $this->Application->GetADODBConnection();
}
/**
* Returns true if "new" button was pressed in toolbar
*
* @param Array $params
* @return bool
*/
function IsNewMode($params)
{
$object =& $this->getObject($params);
return $object->GetID() <= 0;
}
/**
* Returns view menu name for current prefix
*
* @param Array $params
* @return string
*/
function GetItemName($params)
{
$item_name = $this->Application->getUnitOption($this->Prefix, 'ViewMenuPhrase');
return $this->Application->Phrase($item_name);
}
function ViewMenu($params)
{
$block_params = $params;
unset($block_params['block']);
$block_params['name'] = $params['block'];
$list =& $this->GetList($params);
$block_params['PrefixSpecial'] = $list->getPrefixSpecial();
return $this->Application->ParseBlock($block_params);
}
function SearchKeyword($params)
{
$list =& $this->GetList($params);
return $this->Application->RecallVar($list->getPrefixSpecial().'_search_keyword');
}
/**
* Draw filter menu content (for ViewMenu) based on filters defined in config
*
* @param Array $params
* @return string
*/
function DrawFilterMenu($params)
{
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['spearator_block'];
$separator = $this->Application->ParseBlock($block_params);
$filter_menu = $this->Application->getUnitOption($this->Prefix,'FilterMenu');
if(!$filter_menu)
{
trigger_error('<span class="debug_error">no filters defined</span> for prefix <b>'.$this->Prefix.'</b>, but <b>DrawFilterMenu</b> tag used', E_USER_WARNING);
return '';
}
// Params: label, filter_action, filter_status
$block_params['name'] = $params['item_block'];
$view_filter = $this->Application->RecallVar($this->getPrefixSpecial().'_view_filter');
if($view_filter === false)
{
$event_params = Array('prefix'=>$this->Prefix,'special'=>$this->Special,'name'=>'OnRemoveFilters');
$this->Application->HandleEvent( new kEvent($event_params) );
$view_filter = $this->Application->RecallVar($this->getPrefixSpecial().'_view_filter');
}
$view_filter = unserialize($view_filter);
$filters = Array();
$prefix_special = $this->getPrefixSpecial();
foreach ($filter_menu['Filters'] as $filter_key => $filter_params) {
$group_params = isset($filter_params['group_id']) ? $filter_menu['Groups'][ $filter_params['group_id'] ] : Array();
if (!isset($group_params['element_type'])) {
$group_params['element_type'] = 'checkbox';
}
if (!$filter_params) {
$filters[] = $separator;
continue;
}
$block_params['label'] = addslashes( $this->Application->Phrase($filter_params['label']) );
if (getArrayValue($view_filter,$filter_key)) {
$submit = 0;
if (isset($params['old_style'])) {
$status = $group_params['element_type'] == 'checkbox' ? 1 : 2;
}
else {
$status = $group_params['element_type'] == 'checkbox' ? '[\'img/check_on.gif\']' : '[\'img/menu_dot.gif\']';
}
}
else {
$submit = 1;
$status = 'null';
}
$block_params['filter_action'] = 'set_filter("'.$prefix_special.'","'.$filter_key.'","'.$submit.'",'.$params['ajax'].');';
$block_params['filter_status'] = $status; // 1 - checkbox, 2 - radio, 0 - no image
$filters[] = $this->Application->ParseBlock($block_params);
}
return implode('', $filters);
}
function IterateGridFields($params)
{
$mode = $params['mode'];
$def_block = isset($params['block']) ? $params['block'] : '';
$force_block = isset($params['force_block']) ? $params['force_block'] : false;
$grids = $this->Application->getUnitOption($this->Prefix,'Grids');
$grid_config = $grids[$params['grid']]['Fields'];
$picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
/* @var $picker_helper kColumnPickerHelper */
$picker_helper->ApplyPicker($this->getPrefixSpecial(), $grid_config, $params['grid']);
$std_params['pass_params']='true';
$std_params['PrefixSpecial']=$this->getPrefixSpecial();
$o = '';
$i = 0;
foreach ($grid_config as $field => $options) {
$i++;
$block_params = Array();
$block_params['name'] = $force_block ? $force_block : (isset($options[$mode.'_block']) ? $options[$mode.'_block'] : $def_block);
$block_params['field'] = $field;
$block_params['sort_field'] = isset($options['sort_field']) ? $options['sort_field'] : $field;
$block_params['filter_field'] = isset($options['filter_field']) ? $options['filter_field'] : $field;
$w = $picker_helper->GetWidth($field);
if ($w) $options['width'] = $w;
if (isset($options['filter_width'])) {
$block_params['filter_width'] = $options['filter_width'];
}
elseif (isset($options['width'])) {
if (isset($options['filter_block']) && preg_match('/range/', $options['filter_block'])) {
if ($options['width'] < 60) {
$options['width'] = 60;
$block_params['filter_width'] = 20;
}
else {
$block_params['filter_width'] = $options['width'] - 40;
}
}
else {
$block_params['filter_width'] = max($options['width']-10, 20);
}
}
if (isset($block_params['filter_width'])) $block_params['filter_width'] .= 'px';
$field_options = $this->Application->getUnitOption($this->Prefix.'.'.$field, 'Fields');
if (isset($field_options['use_phrases'])) {
$block_params['use_phrases'] = $field_options['use_phrases'];
}
$block_params['is_last'] = ($i == count($grid_config));
$block_params = array_merge($std_params, $options, $block_params);
$o.= $this->Application->ParseBlock($block_params, 1);
}
return $o;
}
function PickerCRC($params)
{
/* @var $picker_helper kColumnPickerHelper */
$picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
$picker_helper->SetGridName($params['grid']);
$data = $picker_helper->LoadColumns($this->getPrefixSpecial());
return $data['crc'];
}
function FreezerPosition($params)
{
/* @var $picker_helper kColumnPickerHelper */
$picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
$picker_helper->SetGridName($params['grid']);
$data = $picker_helper->LoadColumns($this->getPrefixSpecial());
$freezer_pos = array_search('__FREEZER__', $data['order']);
return $freezer_pos === false || in_array('__FREEZER__', $data['hidden_fields']) ? 1 : ++$freezer_pos;
}
function GridFieldsCount($params)
{
$grids = $this->Application->getUnitOption($this->Prefix, 'Grids');
$grid_config = $grids[$params['grid']]['Fields'];
return count($grid_config);
}
/**
* Prints list content using block specified
*
* @param Array $params
* @return string
* @access public
*/
function PrintList($params)
{
$params['no_table'] = 1;
return $this->PrintList2($params);
}
function InitList($params)
{
$list_name = isset($params['list_name']) ? $params['list_name'] : '';
$names_mapping = $this->Application->GetVar('NamesToSpecialMapping');
if( !getArrayValue($names_mapping, $this->Prefix, $list_name) )
{
$list =& $this->GetList($params);
}
}
function BuildListSpecial($params)
{
return $this->Special;
}
/**
* Returns key, that identifies each list on template (used internally, not tag)
*
* @param Array $params
* @return string
*/
function getUniqueListKey($params)
{
$types = $this->SelectParam($params, 'types');
$except = $this->SelectParam($params, 'except');
$list_name = $this->SelectParam($params, 'list_name');
if (!$list_name) {
$list_name = $this->Application->Parser->GetParam('list_name');
}
return $types.$except.$list_name;
}
/**
* Enter description here...
*
* @param Array $params
* @return kDBList
*/
function &GetList($params)
{
$list_name = $this->SelectParam($params, 'list_name,name');
if (!$list_name) {
$list_name = $this->Application->Parser->GetParam('list_name');
}
$requery = isset($params['requery']) && $params['requery'];
if ($list_name && !$requery){
$names_mapping = $this->Application->GetVar('NamesToSpecialMapping');
$special = is_array($names_mapping) && isset($names_mapping[$this->Prefix]) && isset($names_mapping[$this->Prefix][$list_name]) ? $names_mapping[$this->Prefix][$list_name] : false;
// $special = getArrayValue($names_mapping, $this->Prefix, $list_name);
if(!$special)
{
$special = $this->BuildListSpecial($params);
}
}
else
{
$special = $this->BuildListSpecial($params);
}
$prefix_special = rtrim($this->Prefix.'.'.$special, '.');
$params['skip_counting'] = true;
$list =& $this->Application->recallObject( $prefix_special, $this->Prefix.'_List', $params);
if ($requery) {
$this->Application->HandleEvent($an_event, $prefix_special.':OnListBuild', $params);
}
$list->Query($requery);
$this->Special = $special;
if ($list_name) {
$names_mapping[$this->Prefix][$list_name] = $special;
$this->Application->SetVar('NamesToSpecialMapping', $names_mapping);
}
return $list;
}
function ListMarker($params)
{
$list =& $this->GetList($params);
$ret = $list->getPrefixSpecial();
if( getArrayValue($params, 'as_preg') ) $ret = preg_quote($ret, '/');
return $ret;
}
/**
* Prepares name for field with event in it (used only on front-end)
*
* @param Array $params
* @return string
*/
function SubmitName($params)
{
$list =& $this->GetList($params);
$prefix_special = $list->getPrefixSpecial();
return 'events['.$prefix_special.']['.$params['event'].']';
}
/**
* Prints list content using block specified
*
* @param Array $params
* @return string
* @access public
*/
function PrintList2($params)
{
$per_page = $this->SelectParam($params, 'per_page,max_items');
if ($per_page !== false) $params['per_page'] = $per_page;
$list =& $this->GetList($params);
$o = '';
$direction = (isset($params['direction']) && $params['direction']=="H")?"H":"V";
$columns = (isset($params['columns'])) ? $params['columns'] : 1;
$id_field = (isset($params['id_field'])) ? $params['id_field'] : $this->Application->getUnitOption($this->Prefix, 'IDField');
if ($columns>1 && $direction=="V") {
$list->Records = $this->LinearToVertical($list->Records, $columns, $list->GetPerPage());
$list->SelectedCount=count($list->Records);
ksort($list->Records); // this is issued twice, maybe need to be removed
}
$list->GoFirst();
$block_params=$this->prepareTagParams($params);
$block_params['name']=$this->SelectParam($params, 'render_as,block');
$block_params['pass_params']='true';
$block_params['column_width'] = 100 / $columns;
$block_start_row_params = $this->prepareTagParams($params);
$block_start_row_params['name'] = $this->SelectParam($params, 'row_start_render_as,block_row_start,row_start_block');
$block_end_row_params=$this->prepareTagParams($params);
$block_end_row_params['name'] = $this->SelectParam($params, 'row_end_render_as,block_row_end,row_end_block');
$block_empty_cell_params = $this->prepareTagParams($params);
$block_empty_cell_params['name'] = $this->SelectParam($params, 'empty_cell_render_as,block_empty_cell,empty_cell_block');
$i=0;
$backup_id=$this->Application->GetVar($this->Prefix."_id");
$displayed = array();
$column_number = 1;
$cache_mod_rw = $this->Application->getUnitOption($this->Prefix, 'CacheModRewrite') && $this->Application->RewriteURLs();
while (!$list->EOL())
{
$this->Application->SetVar( $this->getPrefixSpecial().'_id', $list->GetDBField($id_field) ); // for edit/delete links using GET
$this->Application->SetVar( $this->Prefix.'_id', $list->GetDBField($id_field) );
$block_params['is_last'] = ($i == $list->SelectedCount - 1);
$block_params['not_last'] = !$block_params['is_last']; // for front-end
if ($cache_mod_rw) {
$this->Application->setCache('filenames', $this->Prefix.'_'.$list->GetDBField($id_field), $list->GetDBField('Filename'));
$this->Application->setCache('filenames', 'c_'.$list->GetDBField('CategoryId'), $list->GetDBField('CategoryFilename'));
}
if ($i % $columns == 0) {
// record in this iteration is first in row, then open row
$column_number = 1;
$o.= $block_start_row_params['name'] ?
$this->Application->ParseBlock($block_start_row_params, 1) :
(!isset($params['no_table']) ? '<tr>' : '');
}
else {
$column_number++;
}
$block_params['first_col'] = $column_number == 1 ? 1 : 0;
$block_params['last_col'] = $column_number == $columns ? 1 : 0;
$block_params['column_number'] = $column_number;
$this->PrepareListElementParams($list, $block_params); // new, no need to rewrite PrintList
$o.= $this->Application->ParseBlock($block_params, 1);
array_push($displayed, $list->GetDBField($id_field));
if (($i+1) % $columns == 0) {
// record in next iteration is first in row too, then close this row
$o.= $block_end_row_params['name'] ?
$this->Application->ParseBlock($block_end_row_params, 1) :
(!isset($params['no_table']) ? '</tr>' : '');
}
$list->GoNext();
$i++;
}
// append empty cells in place of missing cells in last row
while ($i % $columns != 0) {
// until next cell will be in new row append empty cells
$o .= $block_empty_cell_params['name'] ? $this->Application->ParseBlock($block_empty_cell_params, 1) : '<td>&nbsp;</td>';
if (($i+1) % $columns == 0) {
// record in next iteration is first in row too, then close this row
$o .= $block_end_row_params['name'] ? $this->Application->ParseBlock($block_end_row_params, 1) : '</tr>';
}
$i++;
}
$cur_displayed = $this->Application->GetVar($this->Prefix.'_displayed_ids');
if (!$cur_displayed) {
$cur_displayed = Array();
}
else {
$cur_displayed = explode(',', $cur_displayed);
}
$displayed = array_unique(array_merge($displayed, $cur_displayed));
$this->Application->SetVar($this->Prefix.'_displayed_ids', implode(',',$displayed));
$this->Application->SetVar( $this->Prefix.'_id', $backup_id);
$this->Application->SetVar( $this->getPrefixSpecial().'_id', '');
if (isset($params['more_link_render_as'])) {
$block_params = $params;
$params['render_as'] = $params['more_link_render_as'];
$o .= $this->MoreLink($params);
}
return $o;
}
/**
* Allows to modify block params & current list record before PrintList parses record
*
* @param kDBList $object
* @param Array $block_params
*/
function PrepareListElementParams(&$object, &$block_params)
{
// $fields_hash =& $object->Records[$this->CurrentIndex];
//
// $object->Records[$this->CurrentIndex] =& $fields_hash;
}
function MoreLink($params)
{
$per_page = $this->SelectParam($params, 'per_page,max_items');
if ($per_page !== false) $params['per_page'] = $per_page;
$list =& $this->GetList($params);
if ($list->PerPage < $list->RecordsCount) {
$block_params = array();
$block_params['name'] = $this->SelectParam($params, 'render_as,block');
return $this->Application->ParseBlock($block_params, 1);
}
}
function NotLastItem($params)
{
$object =& $this->getList($params); // maybe we should use $this->GetList($params) instead
return ($object->CurrentIndex < min($object->PerPage == -1 ? $object->RecordsCount : $object->PerPage, $object->RecordsCount) - 1);
}
function PageLink($params)
{
$t = isset($params['template']) ? $params['template'] : '';
unset($params['template']);
if (!$t) $t = $this->Application->GetVar('t');
if (isset($params['page'])) {
$this->Application->SetVar($this->getPrefixSpecial().'_Page', $params['page']);
unset($params['page']);
}
if (!isset($params['pass'])) {
$params['pass'] = 'm,'.$this->getPrefixSpecial();
}
return $this->Application->HREF($t, '', $params);
}
function ColumnWidth($params)
{
$columns = $this->Application->Parser->GetParam('columns');
return round(100/$columns).'%';
}
/**
* Append prefix and special to tag
* params (get them from tagname) like
* they were really passed as params
*
* @param Array $tag_params
* @return Array
* @access protected
*/
function prepareTagParams($tag_params = Array())
{
/*if (isset($tag_params['list_name'])) {
$list =& $this->GetList($tag_params);
$this->Init($list->Prefix, $list->Special);
}*/
$ret = $tag_params;
$ret['Prefix'] = $this->Prefix;
$ret['Special'] = $this->Special;
$ret['PrefixSpecial'] = $this->getPrefixSpecial();
return $ret;
}
function GetISO($currency)
{
if ($currency == 'selected') {
$iso = $this->Application->RecallVar('curr_iso');
}
elseif ($currency == 'primary' || $currency == '') {
$iso = $this->Application->GetPrimaryCurrency();
}
else { //explicit currency
$iso = $currency;
}
return $iso;
}
function ConvertCurrency($value, $iso)
{
$converter =& $this->Application->recallObject('kCurrencyRates');
// convery primary currency to selected (if they are the same, converter will just return)
$value = $converter->Convert($value, 'PRIMARY', $iso);
return $value;
}
function AddCurrencySymbol($value, $iso)
{
$currency =& $this->Application->recallObject('curr.-'.$iso, null, Array('skip_autoload' => true));
if( !$currency->isLoaded() ) $currency->Load($iso, 'ISO');
$symbol = $currency->GetDBField('Symbol');
if (!$symbol) $symbol = $currency->GetDBField('ISO').'&nbsp;';
if ($currency->GetDBField('SymbolPosition') == 0) {
$value = $symbol.$value;
}
if ($currency->GetDBField('SymbolPosition') == 1) {
$value = $value.$symbol;
}
return $value;
}
/**
* Get's requested field value
*
* @param Array $params
* @return string
* @access public
*/
function Field($params)
{
$field = $this->SelectParam($params, 'name,field');
if( !$this->Application->IsAdmin() ) $params['no_special'] = 'no_special';
$object =& $this->getObject($params);
if ( $this->HasParam($params, 'db') )
{
$value = $object->GetDBField($field);
}
else
{
if( $this->HasParam($params, 'currency') )
{
$iso = $this->GetISO($params['currency']);
$original = $object->GetDBField($field);
$value = $this->ConvertCurrency($original, $iso);
$object->SetDBField($field, $value);
$object->Fields[$field]['converted'] = true;
}
$format = getArrayValue($params, 'format');
if( !$format || $format == '$format' )
{
$format = null;
}
else
{
if(preg_match("/_regional_(.*)/", $format, $regs))
{
$lang =& $this->Application->recallObject('lang.current');
$format = $lang->GetDBField($regs[1]);
}
}
$value = $object->GetField($field, $format);
if( $this->SelectParam($params, 'negative') )
{
if(strpos($value, '-') === 0)
{
$value = substr($value, 1);
}
else
{
$value = '-'.$value;
}
}
if( $this->HasParam($params, 'currency') )
{
$value = $this->AddCurrencySymbol($value, $iso);
$params['no_special'] = 1;
}
}
if( !$this->HasParam($params, 'no_special') ) $value = htmlspecialchars($value);
if( getArrayValue($params,'checked' ) ) $value = ($value == ( isset($params['value']) ? $params['value'] : 1)) ? 'checked' : '';
if( isset($params['plus_or_as_label']) ) {
$value = substr($value, 0,1) == '+' ? substr($value, 1) : $this->Application->Phrase($value);
}
elseif( isset($params['as_label']) && $params['as_label'] ) $value = $this->Application->Phrase($value);
$first_chars = $this->SelectParam($params,'first_chars,cut_first');
if($first_chars)
{
$needs_cut = strlen($value) > $first_chars;
- $value = substr($value,0,$first_chars);
+ $value = extension_loaded('mbstring') ? mb_substr($value,0,$first_chars) : substr($value,0,$first_chars);
if($needs_cut) $value .= ' ...';
}
if( getArrayValue($params,'nl2br' ) ) $value = nl2br($value);
if ($value != '') $this->Application->Parser->DataExists = true;
if( $this->HasParam($params, 'currency') )
{
//restoring value in original currency, for other Field tags to work properly
$object->SetDBField($field, $original);
}
return $value;
}
function SetField($params)
{
// <inp2:SetField field="Value" src=p:cust_{$custom_name}"/>
$object =& $this->getObject($params);
$dst_field = $this->SelectParam($params, 'name,field');
list($prefix_special, $src_field) = explode(':', $params['src']);
$src_object =& $this->Application->recallObject($prefix_special);
$object->SetDBField($dst_field, $src_object->GetDBField($src_field));
}
/**
* Checks if parameter is passed
* Note: works like Tag and line simple method too
*
* @param Array $params
* @param string $param_name
* @return bool
*/
function HasParam($params, $param_name = null)
{
if( !isset($param_name) )
{
$param_name = $this->SelectParam($params, 'name');
$params = $this->Application->Parser->Params;
}
$value = isset($params[$param_name]) ? $params[$param_name] : false;
return $value && ($value != '$'.$param_name);
}
function PhraseField($params)
{
$field_label = $this->Field($params);
$translation = $this->Application->Phrase( $field_label );
return $translation;
}
function Error($params)
{
$field = $this->SelectParam($params, 'name,field');
$object =& $this->getObject($params);
$msg = $object->GetErrorMsg($field, false);
return $msg;
}
function HasError($params)
{
if ($params['field'] == 'any')
{
$object =& $this->getObject($params);
$skip_fields = getArrayValue($params, 'except');
$skip_fields = $skip_fields ? explode(',', $skip_fields) : Array();
return $object->HasErrors($skip_fields);
}
else
{
$fields = $this->SelectParam($params, 'field,fields');
$fields = explode(',', $fields);
$res = false;
foreach($fields as $field)
{
$params['field'] = $field;
$res = $res || ($this->Error($params) != '');
}
return $res;
}
}
function ErrorWarning($params)
{
if (!isset($params['field'])) {
$params['field'] = 'any';
}
if ($this->HasError($params)) {
$params['prefix'] = $this->getPrefixSpecial();
return $this->Application->ParseBlock($params);
}
}
function IsRequired($params)
{
$field = $params['field'];
$object =& $this->getObject($params);;
$formatter_class = getArrayValue($object->Fields, $field, 'formatter');
if ($formatter_class == 'kMultiLanguage')
{
$formatter =& $this->Application->recallObject($formatter_class);
$field = $formatter->LangFieldName($field);
}
$options = $object->GetFieldOptions($field);
return getArrayValue($options,'required');
}
function FieldOption($params)
{
$object =& $this->getObject($params);;
$options = $object->GetFieldOptions($params['field']);
$ret = isset($options[$params['option']]) ? $options[$params['option']] : '';
if (isset($params['as_label']) && $params['as_label']) $ret = $this->Application->ReplaceLanguageTags($ret);
return $ret;
}
function PredefinedOptions($params)
{
$field = $params['field'];
$object =& $this->getObject($params);
$value = $object->GetDBField($field);
$options = $object->GetFieldOptions($field);
if( $this->HasParam($params,'has_empty') )
{
$empty_value = getArrayValue($params, 'empty_value');
if($empty_value === false) $empty_value = '';
$options['options'] = array_merge_recursive2( Array($empty_value => ''), $options['options'] );
}
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $this->SelectParam($params, 'render_as,block');
$block_params['field'] = $params['field'];
$block_params['pass_params'] = 'true';
$block_params['field_name'] = $this->InputName($params);
$block_params['PrefixSpecial'] = $this->getPrefixSpecial();
$selected_param_name = getArrayValue($params,'selected_param');
if(!$selected_param_name) $selected_param_name = $params['selected'];
$selected = $params['selected'];
$o = '';
if( $this->HasParam($params,'no_empty') && !getArrayValue($options['options'],'') ) array_shift($options['options']);
if( strpos($value, '|') !== false )
{
// multiple selection checkboxes
$value = explode('|', substr($value, 1, -1) );
foreach ($options['options'] as $key => $val)
{
$block_params['key'] = $key;
$block_params['option'] = $val;
$block_params[$selected_param_name] = ( in_array($key, $value) ? ' '.$selected : '');
$o .= $this->Application->ParseBlock($block_params, 1);
}
}
else
{
// single selection radio or checkboxes
+ if (!isset($options['options']) || !is_array($options['options'])) {
+ trigger_error("Options not defined for {$object->Prefix} field $field", E_USER_WARNING);
+ }
foreach ($options['options'] as $key => $val)
{
$block_params['key'] = $key;
$block_params['option'] = $val;
$block_params[$selected_param_name] = (strlen($key) == strlen($value) && ($key == $value) ? ' '.$selected : '');
$o .= $this->Application->ParseBlock($block_params, 1);
}
}
return $o;
}
function PredefinedSearchOptions($params)
{
$object =& $this->getObject($params);
/* @var $object kDBList */
$field = $params['field'];
$saved_value = $object->Queried ? $object->GetDBField($field) : null;
$object->SetDBField($field, $this->SearchField($params));
$view_name = $this->Application->RecallVar($this->getPrefixSpecial().'_current_view');
- $custom_filter = $this->Application->RecallPersistentVar($this->getPrefixSpecial().'_custom_filter.'.$view_name);
+ $custom_filter = $this->Application->RecallPersistentVar($this->getPrefixSpecial().'_custom_filter.'.$view_name, ALLOW_DEFAULT_SETTINGS);
$ret = $this->PredefinedOptions($params);
$object->SetDBField($field, $saved_value);
return $ret;
}
function Format($params)
{
$field = $this->SelectParam($params, 'name,field');
$object =& $this->getObject($params);
$options = $object->GetFieldOptions($field);
$format = $options[ $this->SelectParam($params, 'input_format') ? 'input_format' : 'format' ];
$formatter_class = getArrayValue($options,'formatter');
if ($formatter_class) {
$formatter =& $this->Application->recallObject($formatter_class);
$human_format = getArrayValue($params,'human');
$edit_size = getArrayValue($params,'edit_size');
$sample = getArrayValue($params,'sample');
if($sample)
{
return $formatter->GetSample($field, $options, $object);
}
elseif($human_format || $edit_size)
{
$format = $formatter->HumanFormat($format);
return $edit_size ? strlen($format) : $format;
}
}
return $format;
}
/**
* Returns grid padination information
* Can return links to pages
*
* @param Array $params
* @return mixed
*/
function PageInfo($params)
{
$object =& $this->GetList($params);
/* @var $object kDBList */
$type = $params['type'];
unset($params['type']); // remove parameters used only by current tag
$ret = '';
switch ($type) {
case 'current':
$ret = $object->Page;
break;
case 'total':
$ret = $object->GetTotalPages();
break;
case 'prev':
$ret = $object->Page > 1 ? $object->Page - 1 : false;
break;
case 'next':
$ret = $object->Page < $object->GetTotalPages() ? $object->Page + 1 : false;
break;
}
if ($ret && isset($params['as_link']) && $params['as_link']) {
unset($params['as_link']); // remove parameters used only by current tag
$params['page'] = $ret;
$current_page = $object->Page; // backup current page
$ret = $this->PageLink($params);
$this->Application->SetVar($object->getPrefixSpecial().'_Page', $current_page); // restore page
}
return $ret;
}
/**
* Print grid pagination using
* block names specified
*
* @param Array $params
* @return string
* @access public
*/
function PrintPages($params)
{
$list =& $this->GetList($params);
$prefix_special = $list->getPrefixSpecial();
$total_pages = $list->GetTotalPages();
if ($total_pages > 1) $this->Application->Parser->DataExists = true;
if($total_pages == 0) $total_pages = 1; // display 1st page as selected in case if we have no pages at all
$o = '';
// what are these 2 lines for?
$this->Application->SetVar($prefix_special.'_event','');
$this->Application->SetVar($prefix_special.'_id','');
$current_page = $list->Page; // $this->Application->RecallVar($prefix_special.'_Page');
$block_params = $this->prepareTagParams($params);
$split = ( isset($params['split'] ) ? $params['split'] : 10 );
$split_start = $current_page - ceil($split/2);
if ($split_start < 1){
$split_start = 1;
}
$split_end = $split_start + $split-1;
if ($split_end > $total_pages) {
$split_end = $total_pages;
$split_start = max($split_end - $split + 1, 1);
}
if ($current_page > 1){
$prev_block_params = $this->prepareTagParams();
if ($total_pages > $split){
$prev_block_params['page'] = max($current_page-$split, 1);
$prev_block_params['name'] = $this->SelectParam($params, 'prev_page_split_render_as,prev_page_split_block');
if ($prev_block_params['name']){
$o .= $this->Application->ParseBlock($prev_block_params, 1);
}
}
$prev_block_params['name'] = 'page';
$prev_block_params['page'] = $current_page-1;
$prev_block_params['name'] = $this->SelectParam($params, 'prev_page_render_as,block_prev_page,prev_page_block');
if ($prev_block_params['name']) {
$this->Application->SetVar($this->getPrefixSpecial().'_Page', $current_page-1);
$o .= $this->Application->ParseBlock($prev_block_params, 1);
}
}
else {
if ( $no_prev_page_block = $this->SelectParam($params, 'no_prev_page_render_as,block_no_prev_page') ) {
$block_params['name'] = $no_prev_page_block;
$o .= $this->Application->ParseBlock($block_params, 1);
}
}
$separator_params['name'] = $this->SelectParam($params, 'separator_render_as,block_separator');
for ($i = $split_start; $i <= $split_end; $i++)
{
if ($i == $current_page) {
$block = $this->SelectParam($params, 'current_render_as,active_render_as,block_current,active_block');
}
else {
$block = $this->SelectParam($params, 'link_render_as,inactive_render_as,block_link,inactive_block');
}
$block_params['name'] = $block;
$block_params['page'] = $i;
$this->Application->SetVar($this->getPrefixSpecial().'_Page', $i);
$o .= $this->Application->ParseBlock($block_params, 1);
if ($this->SelectParam($params, 'separator_render_as,block_separator')
&& $i < $split_end)
{
$o .= $this->Application->ParseBlock($separator_params, 1);
}
}
if ($current_page < $total_pages){
$next_block_params = $this->prepareTagParams();
$next_block_params['page']=$current_page+1;
$next_block_params['name'] = $this->SelectParam($params, 'next_page_render_as,block_next_page,next_page_block');
if ($next_block_params['name']){
$this->Application->SetVar($this->getPrefixSpecial().'_Page', $current_page+1);
$o .= $this->Application->ParseBlock($next_block_params, 1);
}
if ($total_pages > $split){
$next_block_params['page']=min($current_page+$split, $total_pages);
$next_block_params['name'] = $this->SelectParam($params, 'next_page_split_render_as,next_page_split_block');
if ($next_block_params['name']){
$o .= $this->Application->ParseBlock($next_block_params, 1);
}
}
}
$this->Application->SetVar($this->getPrefixSpecial().'_Page', $current_page);
return $o;
}
/**
* Print grid pagination using
* block names specified
*
* @param Array $params
* @return string
* @access public
*/
function PaginationBar($params)
{
return $this->PrintPages($params);
}
/**
* Returns field name (processed by kMultiLanguage formatter
* if required) and item's id from it's IDField or field required
*
* @param Array $params
* @return Array (id,field)
* @access private
*/
function prepareInputName($params)
{
$field = $this->SelectParam($params, 'name,field');
$object =& $this->getObject($params);
$formatter_class = getArrayValue($object->Fields, $field, 'formatter');
if ($formatter_class == 'kMultiLanguage')
{
$formatter =& $this->Application->recallObject($formatter_class);
/* @var $formatter kMultiLanguage */
$force_primary = isset($object->Fields[$field]['force_primary']) && $object->Fields[$field]['force_primary'];
$field = $formatter->LangFieldName($field, $force_primary);
}
$id_field = getArrayValue($params, 'IdField');
$id = $id_field ? $object->GetDBField($id_field) : $object->GetID();
return Array($id, $field);
}
/**
* Returns input field name to
* be placed on form (for correct
* event processing)
*
* @param Array $params
* @return string
* @access public
*/
function InputName($params)
{
list($id, $field) = $this->prepareInputName($params);
$ret = $this->getPrefixSpecial().'['.$id.']['.$field.']';
if( getArrayValue($params, 'as_preg') ) $ret = preg_quote($ret, '/');
return $ret;
}
/**
* Allows to override various field options through hidden fields with specific names in submit.
* This tag generates this special names
*
* @param Array $params
* @return string
* @author Alex
*/
function FieldModifier($params)
{
list($id, $field) = $this->prepareInputName($params);
$ret = 'field_modifiers['.$this->getPrefixSpecial().']['.$field.']['.$params['type'].']';
if( getArrayValue($params, 'as_preg') ) $ret = preg_quote($ret, '/');
if (isset($params['value'])) {
$object =& $this->getObject($params);
$field_modifiers[$field][$params['type']] = $params['value'];
$object->ApplyFieldModifiers($field_modifiers);
}
return $ret;
}
/**
* Returns index where 1st changable sorting field begins
*
* @return int
* @access private
*/
function getUserSortIndex()
{
$list_sortings = $this->Application->getUnitOption($this->Prefix, 'ListSortings');
$sorting_prefix = getArrayValue($list_sortings, $this->Special) ? $this->Special : '';
$user_sorting_start = 0;
if ( $forced_sorting = getArrayValue($list_sortings, $sorting_prefix, 'ForcedSorting') ) {
$user_sorting_start = count($forced_sorting);
}
return $user_sorting_start;
}
/**
* Returns order direction for given field
*
*
*
* @param Array $params
* @return string
* @access public
*/
function Order($params)
{
$field = $params['field'];
$user_sorting_start = $this->getUserSortIndex();
$list =& $this->GetList($params);
if ($list->GetOrderField($user_sorting_start) == $field)
{
return strtolower($list->GetOrderDirection($user_sorting_start));
}
elseif($list->GetOrderField($user_sorting_start+1) == $field)
{
return '2_'.strtolower($list->GetOrderDirection($user_sorting_start+1));
}
else
{
return 'no';
}
}
/**
* Get's information of sorting field at "pos" position,
* like sorting field name (type="field") or sorting direction (type="direction")
*
* @param Array $params
* @return mixed
*/
function OrderInfo($params)
{
$user_sorting_start = $this->getUserSortIndex() + --$params['pos'];
$list =& $this->GetList($params);
// $object =& $this->Application->recallObject( $this->getPrefixSpecial() );
if($params['type'] == 'field') return $list->GetOrderField($user_sorting_start);
if($params['type'] == 'direction') return $list->GetOrderDirection($user_sorting_start);
}
/**
* Checks if sorting field/direction matches passed field/direction parameter
*
* @param Array $params
* @return bool
*/
function IsOrder($params)
{
$params['type'] = isset($params['field']) ? 'field' : 'direction';
$value = $this->OrderInfo($params);
if( isset($params['field']) ) return $params['field'] == $value;
if( isset($params['direction']) ) return $params['direction'] == $value;
}
/**
* Returns list perpage
*
* @param Array $params
* @return int
*/
function PerPage($params)
{
$object =& $this->getObject($params);
return $object->PerPage;
}
/**
* Checks if list perpage matches value specified
*
* @param Array $params
* @return bool
*/
function PerPageEquals($params)
{
$object =& $this->getObject($params);
return $object->PerPage == $params['value'];
}
function SaveEvent($params)
{
// SaveEvent is set during OnItemBuild, but we may need it before any other tag calls OnItemBuild
$object =& $this->getObject($params);
return $this->Application->GetVar($this->getPrefixSpecial().'_SaveEvent');
}
function NextId($params)
{
$object =& $this->getObject($params);
$wid = $this->Application->GetTopmostWid($this->Prefix);
$session_name = rtrim($this->getPrefixSpecial().'_selected_ids_'.$wid, '_');
$ids = explode(',', $this->Application->RecallVar($session_name));
$cur_id = $object->GetID();
$i = array_search($cur_id, $ids);
if ($i !== false) {
return $i < count($ids) - 1 ? $ids[$i + 1] : '';
}
return '';
}
function PrevId($params)
{
$object =& $this->getObject($params);
$wid = $this->Application->GetTopmostWid($this->Prefix);
$session_name = rtrim($this->getPrefixSpecial().'_selected_ids_'.$wid, '_');
$ids = explode(',', $this->Application->RecallVar($session_name));
$cur_id = $object->GetID();
$i = array_search($cur_id, $ids);
if ($i !== false) {
return $i > 0 ? $ids[$i - 1] : '';
}
return '';
}
function IsSingle($params)
{
return ($this->NextId($params) === '' && $this->PrevId($params) === '');
}
function IsLast($params)
{
return ($this->NextId($params) === '');
}
function IsFirst($params)
{
return ($this->PrevId($params) === '');
}
/**
* Checks if field value is equal to proposed one
*
* @param Array $params
* @return bool
*/
function FieldEquals($params)
{
$object =& $this->getObject($params);
$ret = $object->GetDBField($this->SelectParam($params, 'name,field')) == $params['value'];
// if( getArrayValue($params,'inverse') ) $ret = !$ret;
return $ret;
}
function ItemIcon($params)
{
$object =& $this->getObject($params);
$grids = $this->Application->getUnitOption($this->Prefix,'Grids');
$icons =& $grids[ $params['grid'] ]['Icons'];
$key = '';
$status_fields = $this->Application->getUnitOption($this->Prefix,'StatusField');
if(!$status_fields) return $icons['default'];
foreach($status_fields as $status_field)
{
$key .= $object->GetDBField($status_field).'_';
}
$key = rtrim($key,'_');
$value = ($key !== false) ? $key : 'default';
return isset($icons[$value]) ? $icons[$value] : $icons['default'];
}
/**
* Generates bluebar title + initializes prefixes used on page
*
* @param Array $params
* @return string
*/
function SectionTitle($params)
{
$preset_name = replaceModuleSection($params['title_preset']);
$title_presets = $this->Application->getUnitOption($this->Prefix,'TitlePresets');
$title_info = getArrayValue($title_presets, $preset_name);
if ($title_info === false) {
$title = str_replace('#preset_name#', $preset_name, $params['title']);
if ($this->Application->ConfigValue('UseSmallHeader') && isset($params['group_title']) && $params['group_title']) {
$title .= ' - '.$params['group_title'];
}
return $title;
}
if (getArrayValue($title_presets,'default')) {
// use default labels + custom labels specified in preset used
$title_info = array_merge_recursive2($title_presets['default'], $title_info);
}
$title = $title_info['format'];
// 1. get objects in use for title construction
$objects = Array();
$object_status = Array();
$status_labels = Array();
$prefixes = getArrayValue($title_info,'prefixes');
$all_tag_params = getArrayValue($title_info,'tag_params');
if ($prefixes) {
// extract tag_perams passed directly to SectionTitle tag for specific prefix
foreach ($params as $tp_name => $tp_value) {
if (preg_match('/(.*)\[(.*)\]/', $tp_name, $regs)) {
$all_tag_params[ $regs[1] ][ $regs[2] ] = $tp_value;
unset($params[$tp_name]);
}
}
$tag_params = Array();
foreach ($prefixes as $prefix_special) {
$prefix_data = $this->Application->processPrefix($prefix_special);
$prefix_data['prefix_special'] = rtrim($prefix_data['prefix_special'],'.');
if ($all_tag_params) {
$tag_params = getArrayValue($all_tag_params, $prefix_data['prefix_special']);
if (!$tag_params) $tag_params = Array();
}
$tag_params = array_merge_recursive2($params, $tag_params);
$objects[ $prefix_data['prefix_special'] ] =& $this->Application->recallObject($prefix_data['prefix_special'], $prefix_data['prefix'], $tag_params);
$object_status[ $prefix_data['prefix_special'] ] = $objects[ $prefix_data['prefix_special'] ]->IsNewItem() ? 'new' : 'edit';
// a. set object's status field (adding item/editing item) for each object in title
if (getArrayValue($title_info[ $object_status[ $prefix_data['prefix_special'] ].'_status_labels' ],$prefix_data['prefix_special'])) {
$status_labels[ $prefix_data['prefix_special'] ] = $title_info[ $object_status[ $prefix_data['prefix_special'] ].'_status_labels' ][ $prefix_data['prefix_special'] ];
$title = str_replace('#'.$prefix_data['prefix_special'].'_status#', $status_labels[ $prefix_data['prefix_special'] ], $title);
}
// b. setting object's titlefield value (in titlebar ONLY) to default in case if object beeing created with no titlefield filled in
if ($object_status[ $prefix_data['prefix_special'] ] == 'new') {
$new_value = $this->getInfo( $objects[ $prefix_data['prefix_special'] ], 'titlefield' );
if(!$new_value && getArrayValue($title_info['new_titlefield'],$prefix_data['prefix_special']) ) $new_value = $this->Application->Phrase($title_info['new_titlefield'][ $prefix_data['prefix_special'] ]);
$title = str_replace('#'.$prefix_data['prefix_special'].'_titlefield#', $new_value, $title);
}
}
}
// 2. replace phrases if any found in format string
$title = $this->Application->ReplaceLanguageTags($title,false);
// 3. find and replace any replacement vars
preg_match_all('/#(.*_.*)#/Uis',$title,$rets);
if ($rets[1]) {
$replacement_vars = array_keys( array_flip($rets[1]) );
foreach ($replacement_vars as $replacement_var) {
$var_info = explode('_',$replacement_var,2);
$object =& $objects[ $var_info[0] ];
$new_value = $this->getInfo($object,$var_info[1]);
$title = str_replace('#'.$replacement_var.'#', $new_value, $title);
}
}
// replace trailing spaces inside title preset + '' occurences into single space
$title = preg_replace('/[ ]*\'\'[ ]*/', ' ', $title);
if ($this->Application->ConfigValue('UseSmallHeader') && isset($params['group_title']) && $params['group_title']) {
$title .= ' - '.$params['group_title'];
}
$cut_first = getArrayValue($params, 'cut_first');
if ($cut_first && strlen($title) > $cut_first) {
if (!preg_match('/<a href="(.*)">(.*)<\/a>/',$title)) {
$title = substr($title, 0, $cut_first).' ...';
}
}
return $title;
}
function getInfo(&$object, $info_type)
{
switch ($info_type)
{
case 'titlefield':
$field = $this->Application->getUnitOption($object->Prefix,'TitleField');
return $field !== false ? $object->GetField($field) : 'TitleField Missing';
break;
case 'recordcount':
$of_phrase = $this->Application->Phrase('la_of');
return $object->NoFilterCount != $object->RecordsCount ? $object->RecordsCount.' '.$of_phrase.' '.$object->NoFilterCount : $object->RecordsCount;
break;
default:
return $object->GetField($info_type);
break;
}
}
function GridInfo($params)
{
$object =& $this->GetList($params);
/* @var $object kDBList */
switch ($params['type']) {
case 'filtered':
return $object->GetRecordsCount();
case 'total':
return $object->GetNoFilterCount();
case 'from':
return $object->RecordsCount ? $object->Offset+1 : 0; //0-based
case 'to':
return min($object->Offset + $object->PerPage, $object->RecordsCount);
case 'total_pages':
return $object->GetTotalPages();
case 'needs_pagination':
return ($object->RecordsCount > $object->PerPage) || ($object->Page > 1);
}
}
/**
* Parses block depending on its element type.
* For radio and select elements values are taken from 'value_list_field' in key1=value1,key2=value2
* format. key=value can be substituted by <SQL>SELECT f1 AS OptionName, f2 AS OptionValue... FROM <PREFIX>TableName </SQL>
* where prefix is TABLE_PREFIX
*
* @param Array $params
* @return string
*/
function ConfigFormElement($params)
{
$object =& $this->getObject($params);
$field = $params['field'];
$helper =& $this->Application->recallObject('InpCustomFieldsHelper');
$element_type = $object->GetDBField($params['element_type_field']);
if($element_type == 'label') $element_type = 'text';
$params['name'] = $params['blocks_prefix'].$element_type;
switch ($element_type) {
case 'select':
case 'multiselect':
case 'radio':
$field_options = $object->GetFieldOptions($field, 'options');
if ($object->GetDBField('DirectOptions')) {
// used for custom fields
$field_options['options'] = $object->GetDBField('DirectOptions');
}
else {
// used for configuration
$field_options['options'] = $helper->GetValuesHash( $object->GetDBField($params['value_list_field']) );
}
$object->SetFieldOptions($field, $field_options);
break;
case 'text':
case 'textarea':
$params['field_params'] = $helper->ParseConfigSQL($object->GetDBField($params['value_list_field']));
break;
case 'password':
case 'checkbox':
default:
break;
}
return $this->Application->ParseBlock($params, 1);
}
/**
* Get's requested custom field value
*
* @param Array $params
* @return string
* @access public
*/
function CustomField($params)
{
$params['name'] = 'cust_'.$this->SelectParam($params, 'name,field');
return $this->Field($params);
}
function CustomFieldLabel($params)
{
$object =& $this->getObject($params);
$field = $this->SelectParam($params, 'name,field');
$sql = 'SELECT FieldLabel
FROM '.$this->Application->getUnitOption('cf', 'TableName').'
WHERE FieldName = '.$this->Conn->qstr($field);
return $this->Application->Phrase($this->Conn->GetOne($sql));
}
/**
* transposes 1-dimensional array elements for vertical alignment according to given columns and per_page parameters
*
* @param array $arr
* @param int $columns
* @param int $per_page
* @return array
*/
function LinearToVertical(&$arr, $columns, $per_page)
{
$rows = $columns;
// in case if after applying per_page limit record count less then
// can fill requrested column count, then fill as much as we can
$cols = min(ceil($per_page / $columns), ceil(count($arr) / $columns));
$imatrix = array();
for ($row = 0; $row < $rows; $row++) {
for ($col = 0; $col < $cols; $col++) {
$source_index = $row * $cols + $col;
if (!isset($arr[$source_index])) {
// in case if source array element count is less then element count in one row
continue;
}
$imatrix[$col * $rows + $row] = $arr[$source_index];
}
}
return array_values($imatrix);
}
/**
* If data was modfied & is in TempTables mode, then parse block with name passed;
* remove modification mark if not in TempTables mode
*
* @param Array $params
* @return string
* @access public
* @author Alexey
*/
function SaveWarning($params)
{
$main_prefix = getArrayValue($params, 'main_prefix');
if ($main_prefix && $main_prefix != '$main_prefix') {
$top_prefix = $main_prefix;
}
else {
$top_prefix = $this->Application->GetTopmostPrefix($this->Prefix);
}
$temp_tables = substr($this->Application->GetVar($top_prefix.'_mode'), 0, 1) == 't';
$modified = $this->Application->RecallVar($top_prefix.'_modified');
if ($temp_tables && $modified) {
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $this->SelectParam($params, 'render_as,name');
$block_params['edit_mode'] = $temp_tables ? 1 : 0;
return $this->Application->ParseBlock($block_params);
}
$this->Application->RemoveVar($top_prefix.'_modified');
return '';
}
/**
* Returns list record count queries (on all pages)
*
* @param Array $params
* @return int
*/
function TotalRecords($params)
{
$list =& $this->GetList($params);
if (!$list->Counted) $list->CountRecs();
return $list->RecordsCount;
}
/**
* Range filter field name
*
* @param Array $params
* @return string
*/
function SearchInputName($params)
{
$field = $this->SelectParam($params, 'field,name');
$ret = 'custom_filters['.$this->getPrefixSpecial().']['.$params['grid'].']['.$field.']['.$params['filter_type'].']';
if (isset($params['type'])) {
$ret .= '['.$params['type'].']';
}
return $ret;
}
/**
* Return range filter field value
*
* @param Array $params
* @return string
*/
function SearchField($params) // RangeValue
{
$field = $this->SelectParam($params, 'field,name');
$view_name = $this->Application->RecallVar($this->getPrefixSpecial().'_current_view');
- $custom_filter = $this->Application->RecallPersistentVar($this->getPrefixSpecial().'_custom_filter.'.$view_name);
+ $custom_filter = $this->Application->RecallPersistentVar($this->getPrefixSpecial().'_custom_filter.'.$view_name, ALLOW_DEFAULT_SETTINGS);
$custom_filter = $custom_filter ? unserialize($custom_filter) : Array();
if (isset($custom_filter[ $params['grid'] ][$field])) {
$ret = $custom_filter[ $params['grid'] ][$field][ $params['filter_type'] ]['submit_value'];
if (isset($params['type'])) {
$ret = $ret[ $params['type'] ];
}
if( !$this->HasParam($params, 'no_special') ) $ret = htmlspecialchars($ret);
return $ret;
}
return '';
}
function SearchFormat($params)
{
$field = $params['field'];
$object =& $this->GetList($params);
$options = $object->GetFieldOptions($field);
$format = $options[ $this->SelectParam($params, 'input_format') ? 'input_format' : 'format' ];
$formatter_class = getArrayValue($options,'formatter');
if($formatter_class)
{
$formatter =& $this->Application->recallObject($formatter_class);
$human_format = getArrayValue($params,'human');
$edit_size = getArrayValue($params,'edit_size');
$sample = getArrayValue($params,'sample');
if($sample)
{
return $formatter->GetSample($field, $options, $object);
}
elseif($human_format || $edit_size)
{
$format = $formatter->HumanFormat($format);
return $edit_size ? strlen($format) : $format;
}
}
return $format;
}
/**
* Returns error of range field
*
* @param unknown_type $params
* @return unknown
*/
function SearchError($params)
{
$field = $this->SelectParam($params, 'field,name');
$error_var_name = $this->getPrefixSpecial().'_'.$field.'_error';
$pseudo = $this->Application->RecallVar($error_var_name);
if ($pseudo) {
$this->Application->RemoveVar($error_var_name);
}
$object =& $this->Application->recallObject($this->Prefix.'.'.$this->Special.'-item', null, Array('skip_autoload' => true));
/* @var $object kDBItem */
$object->SetError($field, $pseudo);
return $object->GetErrorMsg($field, false);
}
/**
* Returns templates path for module, which is gathered from prefix module
*
* @param Array $params
* @return string
* @author Alex
*/
function ModulePath($params)
{
$force_module = getArrayValue($params, 'module');
if ($force_module) {
if ($force_module == '#session#') {
$force_module = preg_replace('/([^:]*):.*/', '\1', $this->Application->RecallVar('module'));
if (!$force_module) $force_module = 'core';
}
else {
$force_module = strtolower($force_module);
}
if ($force_module == 'core') {
$module_folder = 'core';
}
else {
$module_folder = trim( $this->Application->findModule('Name', $force_module, 'Path'), '/');
}
}
else {
$module_folder = $this->Application->getUnitOption($this->Prefix, 'ModuleFolder');
}
return '../../'.$module_folder.'/admin_templates/';
}
/**
* Returns object used in tag processor
*
* @access public
* @return kDBBase
*/
function &getObject($params = Array())
{
$object =& $this->Application->recallObject($this->getPrefixSpecial(), $this->Prefix, $params);
if (isset($params['requery']) && $params['requery']) {
$this->Application->HandleEvent($q_event, $this->getPrefixSpecial().':LoadItem');
}
return $object;
}
/**
* Checks if object propery value matches value passed
*
* @param Array $params
* @return bool
*/
function PropertyEquals($params)
{
$object =& $this->getObject($params);
$property_name = $this->SelectParam($params, 'name,var,property');
return $object->$property_name == $params['value'];
}
/**
* Group list records by header, saves internal order in group
*
* @param Array $records
* @param string $heading_field
*/
function groupRecords(&$records, $heading_field)
{
$sorted = Array();
$i = 0; $record_count = count($records);
while ($i < $record_count) {
$sorted[ $records[$i][$heading_field] ][] = $records[$i];
$i++;
}
$records = Array();
foreach ($sorted as $heading => $heading_records) {
$records = array_merge_recursive($records, $heading_records);
}
}
function DisplayOriginal($params)
{
return false;
}
function MultipleEditing($params)
{
$wid = $this->Application->GetTopmostWid($this->Prefix);
$session_name = rtrim($this->getPrefixSpecial().'_selected_ids_'.$wid, '_');
$selected_ids = explode(',', $this->Application->RecallVar($session_name));
$ret = '';
if ($selected_ids) {
$selected_ids = explode(',', $selected_ids);
$object =& $this->getObject( array_merge_recursive2($params, Array('skip_autoload' => true)) );
$params['name'] = $params['render_as'];
foreach ($selected_ids as $id) {
$object->Load($id);
$ret .= $this->Application->ParseBlock($params);
}
}
return $ret;
}
function ExportStatus($params)
{
$export_object =& $this->Application->recallObject('CatItemExportHelper');
$event = new kEvent($this->getPrefixSpecial().':OnDummy');
$action_method = 'perform'.ucfirst($this->Special);
$field_values = $export_object->$action_method($event);
// finish code is done from JS now
if ($field_values['start_from'] >= $field_values['total_records'])
{
if ($this->Special == 'import') {
$this->Application->StoreVar('PermCache_UpdateRequired', 1);
$this->Application->Redirect('in-portal/categories/cache_updater', Array('m_opener' => 'r', 'pass' => 'm', 'continue' => 1, 'no_amp' => 1));
}
elseif ($this->Special == 'export') {
$finish_t = $this->Application->RecallVar('export_finish_t');
$this->Application->Redirect($finish_t, Array('pass' => 'all'));
$this->Application->RemoveVar('export_finish_t');
}
}
$export_options = $export_object->loadOptions($event);
return $export_options['start_from'] * 100 / $export_options['total_records'];
}
/**
* Returns path where exported category items should be saved
*
* @param Array $params
*/
function ExportPath($params)
{
$ret = EXPORT_PATH.'/';
if( getArrayValue($params, 'as_url') )
{
$ret = str_replace( FULL_PATH.'/', $this->Application->BaseURL(), $ret);
}
$export_options = unserialize($this->Application->RecallVar($this->getPrefixSpecial().'_options'));
$ret .= $export_options['ExportFilename'].'.'.($export_options['ExportFormat'] == 1 ? 'csv' : 'xml');
return $ret;
}
function FieldTotal($params)
{
$list =& $this->GetList($params);
return $list->GetFormattedTotal($this->SelectParam($params, 'field,name'), $params['function']);
}
function FCKEditor($params) {
$params['no_special'] = 1;
$value = $this->Field($params);
$name = $this->InputName($params);
$theme_path = $this->Application->BaseURL().substr($this->Application->GetFrontThemePath(), 1);
$bgcolor = isset($params['bgcolor']) ? $params['bgcolor'] : $this->Application->GetVar('bgcolor');
if (!$bgcolor) $bgcolor = '#ffffff';
include_once(FULL_PATH.'/core/cmseditor/fckeditor.php');
$oFCKeditor = new FCKeditor($name);
$oFCKeditor->BasePath = BASE_PATH.'/core/cmseditor/';
$oFCKeditor->Width = $params['width'] ;
$oFCKeditor->Height = $params['height'] ;
$oFCKeditor->ToolbarSet = 'Advanced' ;
$oFCKeditor->Value = $value ;
$oFCKeditor->Config = Array(
//'UserFilesPath' => $pathtoroot.'kernel/user_files',
'ProjectPath' => BASE_PATH.'/',
'CustomConfigurationsPath' => $this->Application->BaseURL().'core/admin_templates/js/inp_fckconfig.js',
'StylesXmlPath' => $theme_path.'/inc/styles.xml',
'EditorAreaCSS' => $theme_path.'/inc/style.css',
'DefaultClass' => 'Default Text',
// 'Debug' => 1,
'Admin' => 1,
'K4' => 1,
'newBgColor' => $bgcolor,
);
return $oFCKeditor->CreateHtml();
}
function IsNewItem($params)
{
$object =& $this->getObject($params);
return $object->IsNewItem();
}
/**
* Creates link to an item including only it's id
*
* @param Array $params
* @return string
*/
function ItemLink($params)
{
$object =& $this->getObject($params);
if (!isset($params['pass'])) {
$params['pass'] = 'm';
}
$params[$object->getPrefixSpecial().'_id'] = $object->GetID();
$m =& $this->Application->recallObject('m_TagProcessor');
return $m->t($params);
}
function PresetFormFields($params)
{
$prefix = $this->getPrefixSpecial();
if (!$this->Application->GetVar($prefix.'_event')) {
$this->Application->HandleEvent(new kEvent($prefix.':OnNew'));
}
}
function PrintSerializedFields($params)
{
$object =& $this->getObject();
$field = $this->SelectParam($params, 'field');
$data = unserialize($object->GetDBField($field));
$o = '';
$std_params['name'] = $params['render_as'];
$std_params['field'] = $params['field'];
$std_params['pass_params'] = true;
foreach ($data as $key => $row) {
$block_params = array_merge($std_params, $row, array('key'=>$key));
$o .= $this->Application->ParseBlock($block_params);
}
return $o;
}
/**
* Checks if current prefix is main item
*
* @param Array $params
* @return bool
*/
function IsTopmostPrefix($params)
{
return $this->Prefix == $this->Application->GetTopmostPrefix($this->Prefix);
}
+ function PermSection($params)
+ {
+ $section = $this->SelectParam($params, 'section,name');
+ $perm_sections = $this->Application->getUnitOption($this->Prefix, 'PermSection');
+ return isset($perm_sections[$section]) ? $perm_sections[$section] : '';
+ }
+
function PerPageSelected($params)
{
$list =& $this->GetList($params);
return $list->PerPage == $params['per_page'] ? $params['selected'] : '';
}
/**
* Returns prefix + generated sepcial + any word
*
* @param Array $params
* @return string
*/
function VarName($params)
{
$list =& $this->GetList($params);
return $list->getPrefixSpecial().'_'.$params['type'];
}
/**
* Returns edit tabs by specified preset name or false in case of error
*
* @param string $preset_name
* @return mixed
*/
function getEditTabs($preset_name)
{
$presets = $this->Application->getUnitOption($this->Prefix, 'EditTabPresets');
if (!$presets || !isset($presets[$preset_name]) || count($presets[$preset_name]) == 0) {
return false;
}
return $presets[$preset_name];
}
/**
* Detects if specified preset has tabs in it
*
* @param Array $params
* @return bool
*/
function HasEditTabs($params)
{
return $this->getEditTabs($params['preset_name']) ? true : false;
}
/**
* Sorts edit tabs based on their priority
*
* @param Array $tab_a
* @param Array $tab_b
* @return int
*/
function sortEditTabs($tab_a, $tab_b)
{
if ($tab_a['priority'] == $tab_b['priority']) {
return 0;
}
return $tab_a['priority'] < $tab_b['priority'] ? -1 : 1;
}
/**
* Prints edit tabs based on preset name specified
*
* @param Array $params
* @return string
*/
function PrintEditTabs($params)
{
$edit_tabs = $this->getEditTabs($params['preset_name']);
if (!$edit_tabs) {
return ;
}
usort($edit_tabs, Array (&$this, 'sortEditTabs'));
$ret = '';
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
foreach ($edit_tabs as $tab_info) {
$block_params['title'] = $tab_info['title'];
$block_params['template'] = $tab_info['t'];
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Performs image resize to required dimensions and returns resulting url (cached resized image)
*
* @param Array $params
* @return string
*/
/*function ImageSrc($params)
{
$max_width = isset($params['MaxWidth']) ? $params['MaxWidth'] : false;
$max_height = isset($params['MaxHeight']) ? $params['MaxHeight'] : false;
$object =& $this->getObject($params);
$field = $this->SelectParam($params, 'name,field');
return $object->GetField($field, 'resize:'.$max_width.'x'.$max_height);
}*/
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/kernel/db/db_tag_processor.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.97.2.7
\ No newline at end of property
+1.97.2.8
\ No newline at end of property
Index: branches/RC/core/kernel/db/dblist.php
===================================================================
--- branches/RC/core/kernel/db/dblist.php (revision 9638)
+++ branches/RC/core/kernel/db/dblist.php (revision 9639)
@@ -1,934 +1,934 @@
<?php
/**
* DBList
*
* Desciption
* @package kernel4
*/
class kDBList extends kDBBase {
/**
* Holds totals for fields specified in config
*
* @var Array
*/
var $Totals = Array();
/**
* Description
*
* @var array
* @access public
*/
var $OrderFields;
/**
* Holds counted total number of records in the query - without pagination (system+user filters)
*
* @var int
* @access public
*/
var $RecordsCount;
/**
* Records count with system filters only applied
*
* @var int
* @access private
*/
var $NoFilterCount = 0;
/**
* Record count selected to be
* showed on current page
*
* @var int
*/
var $SelectedCount=0;
/**
* Array of records selected
*
* @var Array
* @access private
*/
var $Records;
var $CurrentIndex = 0;
/**
* List items per-page
*
* @var int
* @access public
*/
var $PerPage;
/**
* Pages count in list based on PerPage & RecordsCount attributes
*
* @var int
* @access public
*/
var $TotalPages;
/**
* Description
*
* @var int
* @access public
*/
var $Direction;
/**
* Holds current page number - used when forming LIMIT clause of SELECT statement
*
* @var int
* @access public
*/
var $Page;
/**
* Holds offset for LIMIT clause, calculated in {@link kDBList::PerPage()}
*
* @var int
* @access private
*/
var $Offset;
/**
* Count SQL was already issued on query
*
* @var bool
* @access private
*/
var $hasCounted = false;
/**
* Holds list WHERE filter object
*
* @var kMultipleFilter
* @access private
*/
var $WhereFilter = Array(FLT_SYSTEM => null, FLT_NORMAL => null, FLT_SEARCH => null, FLT_VIEW => null);
/**
* Holds list HAVING filter object
*
* @var kMultipleFilter
* @access private
*/
var $HavingFilter = Array(FLT_SYSTEM => null, FLT_NORMAL => null, FLT_SEARCH => null, FLT_VIEW => null);
var $AggregateFilter = Array(FLT_SYSTEM => null, FLT_NORMAL => null);
var $GroupByFields = Array();
var $Queried = false;
var $Counted = false;
var $TotalsCalculated = false;
/**
* Creates kDBList
*
* @return kDBList
*/
function kDBList()
{
parent::kDBBase();
$this->OrderFields = Array();
$filters = $this->getFilterStructure();
foreach ($filters as $filter_params) {
$filter =& $this->$filter_params['type'];
$filter[ $filter_params['class'] ] =& $this->Application->makeClass('kMultipleFilter', $filter_params['join_using']);
}
$this->PerPage = -1;
}
/**
* Returns information about all possible filter types
*
* @return Array
*/
function getFilterStructure()
{
$filters = Array (
Array ('type' => 'WhereFilter', 'class' => FLT_SYSTEM, 'join_using' => FLT_TYPE_AND),
Array ('type' => 'WhereFilter', 'class' => FLT_NORMAL, 'join_using' => FLT_TYPE_OR),
Array ('type' => 'WhereFilter', 'class' => FLT_SEARCH, 'join_using' => FLT_TYPE_OR),
Array ('type' => 'WhereFilter', 'class' => FLT_VIEW, 'join_using' => FLT_TYPE_AND),
Array ('type' => 'WhereFilter', 'class' => FLT_CUSTOM, 'join_using' => FLT_TYPE_AND),
Array ('type' => 'HavingFilter', 'class' => FLT_SYSTEM, 'join_using' => FLT_TYPE_AND),
Array ('type' => 'HavingFilter', 'class' => FLT_NORMAL, 'join_using' => FLT_TYPE_OR),
Array ('type' => 'HavingFilter', 'class' => FLT_SEARCH, 'join_using' => FLT_TYPE_OR),
Array ('type' => 'HavingFilter', 'class' => FLT_VIEW, 'join_using' => FLT_TYPE_AND),
Array ('type' => 'HavingFilter', 'class' => FLT_CUSTOM, 'join_using' => FLT_TYPE_AND),
Array ('type' => 'AggregateFilter', 'class' => FLT_SYSTEM, 'join_using' => FLT_TYPE_AND),
Array ('type' => 'AggregateFilter', 'class' => FLT_NORMAL, 'join_using' => FLT_TYPE_OR),
Array ('type' => 'AggregateFilter', 'class' => FLT_VIEW, 'join_using' => FLT_TYPE_AND),
);
return $filters;
}
/**
* Adds new or replaces old filter with same name
*
* @param string $name filter name (for internal use)
* @param string $clause where/having clause part (no OR/AND allowed)
* @param int $filter_type is filter having filter or where filter
* @param int $filter_scope filter subtype: FLT_NORMAL,FLT_SYSTEM,FLT_SEARCH,FLT_VIEW,FLT_CUSTOM
* @access public
*/
function addFilter($name, $clause, $filter_type = WHERE_FILTER, $filter_scope = FLT_SYSTEM)
{
$filter_source = Array( WHERE_FILTER => 'WhereFilter',
HAVING_FILTER => 'HavingFilter',
AGGREGATE_FILTER => 'AggregateFilter');
$filter_name = $filter_source[$filter_type];
$filter =& $this->$filter_name;
$filter =& $filter[$filter_scope];
$filter->addFilter($name,$clause);
}
/**
* Reads filter content
*
* @param string $name filter name (for internal use)
* @param int $filter_type is filter having filter or where filter
* @param int $filter_scope filter subtype: FLT_NORMAL,FLT_SYSTEM,FLT_SEARCH,FLT_VIEW,FLT_CUSTOM
* @access public
*/
function getFilter($name, $filter_type = WHERE_FILTER, $filter_scope = FLT_SYSTEM)
{
$filter_source = Array( WHERE_FILTER => 'WhereFilter',
HAVING_FILTER => 'HavingFilter',
AGGREGATE_FILTER => 'AggregateFilter');
$filter_name = $filter_source[$filter_type];
$filter =& $this->$filter_name;
$filter =& $filter[$filter_scope];
return $filter->getFilter($name);
}
/**
* Removes specified filter from filters list
*
* @param string $name filter name (for internal use)
* @param int $filter_type is filter having filter or where filter
* @param int $filter_scope filter subtype: FLT_NORMAL,FLT_SYSTEM,FLT_SEARCH,FLT_VIEW,FLT_CUSTOM
* @access public
*/
function removeFilter($name, $filter_type = WHERE_FILTER, $filter_scope = FLT_SYSTEM)
{
$filter_source = Array( WHERE_FILTER => 'WhereFilter',
HAVING_FILTER => 'HavingFilter',
AGGREGATE_FILTER => 'AggregateFilter');
$filter_name = $filter_source[$filter_type];
$filter =& $this->$filter_name;
$filter =& $filter[$filter_scope];
$filter->removeFilter($name);
}
/**
* Clear list filters
*
*/
function clearFilters()
{
$filters = $this->getFilterStructure();
foreach ($filters as $filter_params) {
$filter =& $this->$filter_params['type'];
$filter[ $filter_params['class'] ]->clearFilters();
}
}
/**
* Counts the total number of records base on the query resulted from {@link kDBList::GetSelectSQL()}
*
* The method modifies the query to substitude SELECT part (fields listing) with COUNT(*).
* Special care should be applied when working with lists based on grouped queries, all aggregate function fields
* like SUM(), AVERAGE() etc. should be added to CountedSQL by using {@link kDBList::SetCountedSQL()}
*
* @access public
* @param string
* @return void
*/
function CountRecs()
{
$all_sql = $this->GetSelectSQL(true,false);
$sql = $this->getCountSQL($all_sql);
$this->Counted = true;
if( $this->GetGroupClause() )
{
$this->RecordsCount = count( $this->Conn->GetCol($sql) );
}
else
{
$this->RecordsCount = (int)$this->Conn->GetOne($sql);
}
$system_sql = $this->GetSelectSQL(true,true);
if($system_sql == $all_sql) //no need to query the same again
{
$this->NoFilterCount = $this->RecordsCount;
return;
}
$sql = $this->getCountSQL($system_sql);
if( $this->GetGroupClause() )
{
$this->NoFilterCount = count( $this->Conn->GetCol($sql) );
}
else
{
$this->NoFilterCount = (int)$this->Conn->GetOne($sql);
}
}
function GetNoFilterCount()
{
if (!$this->Counted) {
$this->CountRecs();
}
return $this->NoFilterCount;
}
function GetRecordsCount()
{
if (!$this->Counted) {
$this->CountRecs();
}
return $this->RecordsCount;
}
function getCountSQL($sql)
{
if ( preg_match("/DISTINCT(.*?)FROM(?!_)/is",$sql,$regs ) )
{
return preg_replace("/^\s*SELECT DISTINCT(.*?)FROM(?!_)/is", "SELECT COUNT(DISTINCT ".$regs[1].") AS count FROM", $sql);
}
else
{
return preg_replace("/^\s*SELECT(.*?)FROM(?!_)/is", "SELECT COUNT(*) AS count FROM ", $sql);
}
}
/**
* Queries the database with SQL resulted from {@link kDBList::GetSelectSQL()} and stores result in {@link kDBList::SelectRS}
*
* All the sorting, pagination, filtration of the list should be set prior to calling Query().
*
* @access public
* @param string
* @return void
*/
function Query($force=false)
{
if (!$force && $this->Queried) return true;
$q = $this->GetSelectSQL();
//$rs = $this->Conn->SelectLimit($q, $this->PerPage, $this->Offset);
//in case we have not counted records try to select one more item to find out if we have something more than perpage
$limit = $this->Counted ? $this->PerPage : $this->PerPage+1;
$sql = $q.' '.$this->Conn->getLimitClause($this->Offset,$limit);
$this->Records = $this->Conn->Query($sql);
if (!$this->Records && ($this->Page > 1)) {
// no records & page > 1, try to reset to 1st page (works only when list in not counted before)
$this->Application->StoreVar($this->getPrefixSpecial().'_Page', 1);
$this->SetPage(1);
$this->Query($force);
}
$this->SelectedCount = count($this->Records);
if (!$this->Counted) $this->RecordsCount = $this->SelectedCount;
if (!$this->Counted && $this->SelectedCount > $this->PerPage && $this->PerPage != -1) $this->SelectedCount--;
if ($this->Records === false) {
//handle errors here
return false;
}
$this->Queried = true;
return true;
}
function CalculateTotals()
{
$this->Totals = Array();
$fields = Array();
foreach($this->Fields as $field_name => $field_options)
{
$totals = getArrayValue($field_options, 'totals');
if(!$totals) continue;
$calculated_field = isset($this->CalculatedFields[$field_name]) && isset($this->VirtualFields[$field_name]);
$db_field = !isset($this->VirtualFields[$field_name]);
if($calculated_field || $db_field)
{
$field_expression = $calculated_field ? $this->CalculatedFields[$field_name] : '`'.$this->TableName.'`.`'.$field_name.'`';
$fields[$field_name] = $totals.'('.$field_expression.') AS '.$field_name.'_'.$totals;
}
}
if(!$fields) return false;
$sql = $this->GetSelectSQL(true, false);
$fields = implode(', ', $fields);
if ( preg_match("/DISTINCT(.*?)FROM(?!_)/is",$sql,$regs ) )
{
$sql = preg_replace("/^.*SELECT DISTINCT(.*?)FROM(?!_)/is", 'SELECT '.$fields.' FROM', $sql);
}
else
{
$sql = preg_replace("/^.*SELECT(.*?)FROM(?!_)/is", 'SELECT '.$fields.' FROM ', $sql);
}
$totals = $this->Conn->Query($sql);
foreach($totals as $totals_row)
{
foreach($totals_row as $total_field => $field_value)
{
if(!isset($this->Totals[$total_field])) $this->Totals[$total_field] = 0;
$this->Totals[$total_field] += $field_value;
}
}
$this->TotalsCalculated = true;
}
function getTotal($field, $total_function)
{
if (!$this->TotalsCalculated) $this->CalculateTotals();
return $this->Totals[$field.'_'.$total_function];
}
function GetFormattedTotal($field, $total_function)
{
$val = $this->getTotal($field, $total_function);
$options = $this->GetFieldOptions($field);
$res = $val;
if (isset($options['formatter'])) {
$formatter =& $this->Application->recallObject($options['formatter']);
$res = $formatter->Format($val, $field, $this );
}
return $res;
}
/**
* Builds full select query except for LIMIT clause
*
* @access public
* @return string
*/
function GetSelectSQL($for_counting=false,$system_filters_only=false)
{
$q = parent::GetSelectSQL($this->SelectClause);
$q = !$for_counting ? $this->addCalculatedFields($q, 0) : str_replace('%2$s', '', $q);
$where = $this->GetWhereClause($for_counting,$system_filters_only);
$having = $this->GetHavingClause($for_counting,$system_filters_only);
$order = $this->GetOrderClause();
$group = $this->GetGroupClause();
if (!empty($where)) $q .= ' WHERE ' . $where;
if (!empty($group)) $q .= ' GROUP BY ' . $group;
if (!empty($having)) $q .= ' HAVING ' . $having;
if ( !$for_counting && !empty($order) ) $q .= ' ORDER BY ' . $order;
return $this->replaceModePrefix( str_replace('%1$s', $this->TableName, $q) );
}
/**
* Enter description here...
*
* @param string $clause where clause to extract calculated fields from
* @param int $aggregated 0 - having + aggregated, 1 - having only, 2 - aggregated only
* @return string
*/
function extractCalculatedFields($clause, $aggregated = 1)
{
$fields = $this->getCalculatedFields($aggregated);
if (is_array($fields) && count($fields) > 0) {
foreach ($fields as $field_name => $field_expression) {
$clause = preg_replace('/(\\(+)[(,` ]*'.$field_name.'[` ]{1}/', '\1 '.$field_expression.' ', $clause);
$clause = preg_replace('/[,` ]{1}'.$field_name.'[` ]{1}/', ' '.$field_expression.' ', $clause);
}
}
return $clause;
}
/**
* Returns WHERE clause of the query
*
* @access public
* @param bool $for_counting merge where filters with having filters + replace field names for having fields with their values
* @return string
*/
function GetWhereClause($for_counting=false,$system_filters_only=false)
{
$where =& $this->Application->makeClass('kMultipleFilter');
$where->addFilter('system_where', $this->WhereFilter[FLT_SYSTEM] );
if (!$system_filters_only) {
$where->addFilter('view_where', $this->WhereFilter[FLT_VIEW] );
$search_w = $this->WhereFilter[FLT_SEARCH]->getSQL();
if ($search_w || $for_counting) { // move search_having to search_where in case search_where isset or we are counting
$search_h = $this->extractCalculatedFields( $this->HavingFilter[FLT_SEARCH]->getSQL() );
$search_w = ($search_w && $search_h) ? $search_w.' OR '.$search_h : $search_w.$search_h;
$where->addFilter('search_where', $search_w );
}
// CUSTOM
$search_w = $this->WhereFilter[FLT_CUSTOM]->getSQL();
if ($search_w || $for_counting) { // move search_having to search_where in case search_where isset or we are counting
$search_h = $this->extractCalculatedFields( $this->HavingFilter[FLT_CUSTOM]->getSQL() );
$search_w = ($search_w && $search_h) ? $search_w.' AND '.$search_h : $search_w.$search_h;
$where->addFilter('custom_where', $search_w );
}
// CUSTOM
}
if( $for_counting ) // add system_having and view_having to where
{
$where->addFilter('system_having', $this->extractCalculatedFields($this->HavingFilter[FLT_SYSTEM]->getSQL()) );
if (!$system_filters_only) $where->addFilter('view_having', $this->extractCalculatedFields( $this->HavingFilter[FLT_VIEW]->getSQL() ) );
}
return $where->getSQL();
}
/**
* Depricated method
*
* @param string $clause
* @todo REMOVE
*/
function SetWhereClause($clause)
{
if( $this->Application->isDebugMode() )
{
global $debugger;
$debugger->appendTrace();
}
trigger_error('Depricated method <b>kDBList->SetWhereClause</b>. Use <b>kDBList->addFilter</b> instead.', E_USER_ERROR);
}
/**
* Returns HAVING clause of the query
*
* @param bool $for_counting don't return having filter in case if this is counting sql
* @param bool $system_filters_only return only system having filters
* @param int $aggregated 0 - aggregated and having, 1 - having only, 2 - aggregated only
* @return string
* @access public
*/
function GetHavingClause($for_counting=false, $system_filters_only=false, $aggregated = 0)
{
if ($for_counting) {
$aggregate_filter =& $this->Application->makeClass('kMultipleFilter');
$aggregate_filter->addFilter('aggregate_system', $this->AggregateFilter[FLT_SYSTEM]);
if (!$system_filters_only) {
$aggregate_filter->addFilter('aggregate_view', $this->AggregateFilter[FLT_VIEW]);
}
return $this->extractCalculatedFields($aggregate_filter->getSQL(), 2);
}
$having =& $this->Application->makeClass('kMultipleFilter');
$having->addFilter('system_having', $this->HavingFilter[FLT_SYSTEM] );
if ($aggregated == 0) {
if (!$system_filters_only) {
$having->addFilter('view_aggregated', $this->AggregateFilter[FLT_VIEW] );
}
$having->addFilter('system_aggregated', $this->AggregateFilter[FLT_SYSTEM]);
}
if (!$system_filters_only) {
$having->addFilter('view_having', $this->HavingFilter[FLT_VIEW] );
$having->addFilter('custom_having', $this->HavingFilter[FLT_CUSTOM] );
$search_w = $this->WhereFilter[FLT_SEARCH]->getSQL();
if (!$search_w) {
$having->addFilter('search_having', $this->HavingFilter[FLT_SEARCH] );
}
}
return $having->getSQL();
}
/**
* Returns GROUP BY clause of the query
*
* @access public
* @return string
*/
function GetGroupClause()
{
return $this->GroupByFields ? implode(',', $this->GroupByFields) : '';
}
function AddGroupByField($field)
{
$this->GroupByFields[$field] = $field;
}
function RemoveGroupByField($field)
{
unset($this->GroupByFields[$field]);
}
/**
* Adds order field to ORDER BY clause
*
* @access public
* @param string $field Field name
* @param string $direction Direction of ordering (asc|desc)
* @param bool $is_expression this is expression, that should not be escapted by "`" symbols
* @return void
*/
function AddOrderField($field, $direction = 'asc', $is_expression = false)
{
// original multilanguage field - convert to current lang field
$formatter = isset($this->Fields[$field]['formatter']) ? $this->Fields[$field]['formatter'] : false;
if ($formatter == 'kMultiLanguage' && !isset($this->Fields[$field]['master_field'])) {
$lang = $this->Application->GetVar('m_lang');
$field = 'l'.$lang.'_'.$field;
}
if (!isset($this->Fields[$field]) && $field != 'RAND()' && !$is_expression) {
trigger_error('<span class="debug_error">Incorrect sorting</span> defined (field = <b>'.$field.'</b>; direction = <b>'.$direction.'</b>) in config for prefix <b>'.$this->Prefix.'</b>', E_USER_WARNING);
}
$this->OrderFields[] = Array($field, $direction, $is_expression);
}
/**
* Removes all order fields
*
* @access public
* @return void
*/
function ClearOrderFields()
{
$this->OrderFields = Array();
}
/**
* Returns ORDER BY Clause of the query
*
* The method builds order by clause by iterating {@link kDBList::OrderFields} array and concatenating it.
*
* @access public
* @return string
*/
function GetOrderClause()
{
$ret = '';
foreach ($this->OrderFields as $field) {
$name = $field[0];
$ret .= isset($this->Fields[$name]) && !isset($this->VirtualFields[$name]) ? '`'.$this->TableName.'`.' : '';
if ($field[0] == 'RAND()' || $field[2]) {
$ret .= $field[0].' '.$field[1].',';
}
else {
- $ret .= '`'.$field[0] . '` ' . $field[1] . ',';
+ $ret .= (strpos($field[0], '.') === false ? '`'.$field[0] . '`' : $field[0]) . ' ' . $field[1] . ',';
}
}
$ret = rtrim($ret, ',');
return $ret;
}
function GetOrderField($pos=NULL)
{
if(!(isset($this->OrderFields[$pos]) && $this->OrderFields[$pos]) )
{
$pos = 0;
}
return isset($this->OrderFields[$pos][0]) ? $this->OrderFields[$pos][0] : '';
}
function GetOrderDirection($pos=NULL)
{
if( !getArrayValue($this->OrderFields, $pos) ) $pos = 0;
return getArrayValue($this->OrderFields, $pos, 1);
}
/**
* Return unformatted field value
*
* @param string
* @return mixed
* @access public
*/
function GetDBField($name)
{
$row =& $this->getCurrentRecord();
return $row[$name];
}
/**
* Returns ID of currently processed record
*
* @return int
* @access public
*/
function GetID()
{
return $this->Queried ? $this->GetDBField($this->IDField) : null;
}
/**
* Allows kDBTagProcessor.SectionTitle to detect if it's editing or new item creation
*
* @return bool
*/
function IsNewItem()
{
// no such thing as NewItem for lists :)
return false;
}
function HasField($name)
{
$row =& $this->getCurrentRecord();
return isset($row[$name]);
}
function GetFieldValues()
{
return $this->getCurrentRecord();
}
/**
* Returns current record from list
*
* @return Array
*/
function &getCurrentRecord()
{
return $this->Records[$this->CurrentIndex];
}
/**
* Description
*
* @access public
* @param string
* @return void
*/
function GoFirst()
{
$this->CurrentIndex = 0;
}
/**
* Description
*
* @access public
* @return void
*/
function GoNext()
{
$this->CurrentIndex++;
}
/**
* Description
*
* @access public
* @return void
*/
function GoPrev()
{
if ($this->CurrentIndex>0)
$this->CurrentIndex--;
}
/**
* Description
*
* @access public
* @return bool
*/
function EOL()
{
return ($this->CurrentIndex >= $this->SelectedCount);
}
/**
* Description
*
* @access public
* @param string
* @return void
*/
function GetTotalPages()
{
if (!$this->Counted) $this->CountRecs();
if ($this->PerPage == -1) return 1;
$this->TotalPages = (($this->RecordsCount - ($this->RecordsCount % $this->PerPage)) / $this->PerPage) // integer part of division
+ (($this->RecordsCount % $this->PerPage) != 0); // adds 1 if there is a reminder
return $this->TotalPages;
}
/**
* Sets number of records to query per page
*
* @access public
* @param int $per_page Number of records to display per page
* @return void
*/
function SetPerPage($per_page)
{
$this->PerPage = $per_page;
}
function GetPerPage()
{
return $this->PerPage == -1 ? $this->RecordsCount : $this->PerPage;
}
/**
* Description
*
* @access public
* @param int $page
* @return void
*/
function SetPage($page)
{
if ($this->PerPage == -1) {
$this->Page = 1;
return;
}
if ($page < 1) $page = 1;
$this->Offset = ($page-1)*$this->PerPage;
if ($this->Counted && $this->Offset > $this->RecordsCount) {
$this->SetPage(1);
}
else {
$this->Page = $page;
}
//$this->GoFirst();
}
/**
* Sets current item field value
* (doesn't apply formatting)
*
* @access public
* @param string $name Name of the field
* @param mixed $value Value to set the field to
* @return void
*/
function SetDBField($name,$value)
{
$this->Records[$this->CurrentIndex][$name] = $value;
}
/**
* Apply where clause, that links this object to it's parent item
*
* @param string $special
* @access public
*/
function linkToParent($special)
{
$parent_prefix = $this->Application->getUnitOption($this->Prefix, 'ParentPrefix');
if($parent_prefix)
{
$parent_table_key = $this->Application->getUnitOption($this->Prefix, 'ParentTableKey');
if (is_array($parent_table_key)) $parent_table_key = getArrayValue($parent_table_key, $parent_prefix);
$foreign_key_field = $this->Application->getUnitOption($this->Prefix, 'ForeignKey');
if (is_array($foreign_key_field)) $foreign_key_field = getArrayValue($foreign_key_field, $parent_prefix);
if (!$parent_table_key || !$foreign_key_field) return ;
$parent_object =& $this->Application->recallObject($parent_prefix.'.'.$special);
$parent_id = $parent_object->GetDBField($parent_table_key);
if (!$parent_id) return ;
$this->addFilter('parent_filter', '`'.$this->TableName.'`.`'.$foreign_key_field.'` = '.$parent_id); // only for list in this case
}
}
/**
* Returns true if list was queried (same name as for kDBItem for easy usage)
*
* @return bool
*/
function isLoaded()
{
return $this->Queried;
}
/**
* Returns specified field value from all selected rows.
* Don't affect current record index
*
* @param string $field
* @return Array
*/
function GetCol($field)
{
$i = 0;
$ret = Array ();
while ($i < $this->SelectedCount) {
$ret[] = $this->Records[$i][$field];
$i++;
}
return $ret;
}
/**
* Set's field error, if pseudo passed not found then create it with message text supplied.
* Don't owerrite existing pseudo translation.
*
* @param string $field
* @param string $pseudo
* @param string $error_label
*/
function SetError($field, $pseudo, $error_label = null, $error_params = null)
{
$error_field = isset($this->Fields[$field]['error_field']) ? $this->Fields[$field]['error_field'] : $field;
$this->FieldErrors[$error_field]['pseudo'] = $pseudo;
$var_name = $this->getPrefixSpecial().'_'.$field.'_error';
$previous_pseudo = $this->Application->RecallVar($var_name);
if ($previous_pseudo) {
// don't set more then one error on field
return ;
}
$this->Application->StoreVar($var_name, $pseudo);
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/kernel/db/dblist.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.30.2.2
\ No newline at end of property
+1.30.2.3
\ No newline at end of property
Index: branches/RC/core/kernel/db/db_event_handler.php
===================================================================
--- branches/RC/core/kernel/db/db_event_handler.php (revision 9638)
+++ branches/RC/core/kernel/db/db_event_handler.php (revision 9639)
@@ -1,2178 +1,2193 @@
<?php
define('EH_CUSTOM_PROCESSING_BEFORE',1);
define('EH_CUSTOM_PROCESSING_AFTER',2);
/**
* 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')
*
*/
/**
* EventHandler that is used to process
* any database related events
*
*/
class kDBEventHandler extends kEventHandler {
/**
* Description
*
* @var kDBConnection
* @access public
*/
var $Conn;
/**
* Adds ability to address db connection
*
* @return kDBEventHandler
* @access public
*/
function kDBEventHandler()
{
parent::kBase();
$this->Conn =& $this->Application->GetADODBConnection();
}
/**
* Checks permissions of user
*
* @param kEvent $event
*/
function CheckPermission(&$event)
{
if (!$this->Application->IsAdmin()) {
$allow_events = Array('OnSearch', 'OnSearchReset', 'OnNew');
if (in_array($event->Name, $allow_events)) {
// allow search on front
return true;
}
}
$section = $event->getSection();
if (!preg_match('/^CATEGORY:(.*)/', $section)) {
// only if not category item events
if ((substr($event->Name, 0, 9) == 'OnPreSave') || ($event->Name == 'OnSave')) {
if ($this->isNewItemCreate($event)) {
return $this->Application->CheckPermission($section.'.add', 1);
}
else {
return $this->Application->CheckPermission($section.'.add', 1) || $this->Application->CheckPermission($section.'.edit', 1);
}
}
}
if ($event->Name == 'OnPreCreate') {
// save category_id before item create (for item category selector not to destroy permission checking category)
$this->Application->LinkVar('m_cat_id');
}
return parent::CheckPermission($event);
}
/**
* Allows to override standart permission mapping
*
*/
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array(
'OnLoad' => Array('self' => 'view', 'subitem' => 'view'),
'OnItemBuild' => Array('self' => 'view', 'subitem' => 'view'),
'OnBuild' => Array('self' => true),
'OnNew' => Array('self' => 'add', 'subitem' => 'add|edit'),
'OnCreate' => Array('self' => 'add', 'subitem' => 'add|edit'),
'OnUpdate' => Array('self' => 'edit', 'subitem' => 'add|edit'),
'OnSetPrimary' => Array('self' => 'add|edit', 'subitem' => 'add|edit'),
'OnDelete' => Array('self' => 'delete', 'subitem' => 'add|edit'),
'OnMassDelete' => Array('self' => 'delete', 'subitem' => 'add|edit'),
'OnMassClone' => Array('self' => 'add', 'subitem' => 'add|edit'),
'OnCut' => array('self'=>'edit', 'subitem' => 'edit'),
'OnCopy' => array('self'=>'edit', 'subitem' => 'edit'),
'OnPaste' => array('self'=>'edit', 'subitem' => 'edit'),
'OnSelectItems' => Array('self' => 'add|edit', 'subitem' => 'add|edit'),
'OnProcessSelected' => Array('self' => 'add|edit', 'subitem' => 'add|edit'),
'OnSelectUser' => Array('self' => 'add|edit', 'subitem' => 'add|edit'),
'OnMassApprove' => Array('self' => 'advanced:approve|edit', 'subitem' => 'advanced:approve|add|edit'),
'OnMassDecline' => Array('self' => 'advanced:decline|edit', 'subitem' => 'advanced:decline|add|edit'),
'OnMassMoveUp' => Array('self' => 'advanced:move_up|edit', 'subitem' => 'advanced:move_up|add|edit'),
'OnMassMoveDown' => Array('self' => 'advanced:move_down|edit', 'subitem' => 'advanced:move_down|add|edit'),
'OnPreCreate' => Array('self' => 'add|add.pending', 'subitem' => 'edit|edit.pending'),
'OnEdit' => Array('self' => 'edit|edit.pending', 'subitem' => 'edit|edit.pending'),
'OnExport' => Array('self' => 'view|advanced:export'),
'OnExportBegin' => Array('self' => 'view|advanced:export'),
'OnExportProgress' => Array('self' => 'view|advanced:export'),
// theese event do not harm, but just in case check them too :)
'OnCancelEdit' => Array('self' => true, 'subitem' => true),
'OnCancel' => Array('self' => true, 'subitem' => true),
'OnReset' => Array('self' => true, 'subitem' => true),
'OnSetSorting' => Array('self' => true, 'subitem' => true),
'OnSetSortingDirect' => Array('self' => true, 'subitem' => true),
'OnSetFilter' => Array('self' => true, 'subitem' => true),
'OnApplyFilters' => Array('self' => true, 'subitem' => true),
'OnRemoveFilters' => Array('self' => true, 'subitem' => true),
'OnSetFilterPattern' => Array('self' => true, 'subitem' => true),
'OnSetPerPage' => Array('self' => true, 'subitem' => true),
'OnSearch' => Array('self' => true, 'subitem' => true),
'OnSearchReset' => Array('self' => true, 'subitem' => true),
'OnGoBack' => Array('self' => true, 'subitem' => true),
// it checks permission itself since flash uploader does not send cookies
'OnUploadFile' => Array('self'=>true, 'subitem'=>true),
'OnViewFile' => Array('self'=>true, 'subitem'=>true),
'OnSaveWidths' => Array('self'=>true, 'subitem'=>true),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
function mapEvents()
{
$events_map = Array(
'OnRemoveFilters' => 'FilterAction',
'OnApplyFilters' => 'FilterAction',
'OnMassApprove'=>'iterateItems',
'OnMassDecline'=>'iterateItems',
'OnMassMoveUp'=>'iterateItems',
'OnMassMoveDown'=>'iterateItems',
);
$this->eventMethods = array_merge($this->eventMethods, $events_map);
}
/**
* Returns ID of current item to be edited
* by checking ID passed in get/post as prefix_id
* or by looking at first from selected ids, stored.
* Returned id is also stored in Session in case
* it was explicitly passed as get/post
*
* @param kEvent $event
* @return int
*/
function getPassedID(&$event)
{
if ($event->getEventParam('raise_warnings') === false) {
$event->setEventParam('raise_warnings', 1);
}
if (preg_match('/^auto-(.*)/', $event->Special, $regs) && $this->Application->prefixRegistred($regs[1])) {
// <inp2:lang.auto-phrase_Field name="DateFormat"/> - returns field DateFormat value from language (LanguageId is extracted from current phrase object)
$main_object =& $this->Application->recallObject($regs[1]);
/* @var $main_object kDBItem */
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
return $main_object->GetDBField($id_field);
}
// 1. get id from post (used in admin)
$ret = $this->Application->GetVar($event->getPrefixSpecial(true).'_id');
if ($ret) {
return $ret;
}
// 2. get id from env (used in front)
$ret = $this->Application->GetVar($event->getPrefixSpecial().'_id');
if ($ret) {
return $ret;
}
// recall selected ids array and use the first one
$ids = $this->Application->GetVar($event->getPrefixSpecial().'_selected_ids');
if ($ids != '') {
$ids = explode(',',$ids);
if ($ids) {
$ret = array_shift($ids);
}
}
else { // if selected ids are not yet stored
$this->StoreSelectedIDs($event);
return $this->Application->GetVar($event->getPrefixSpecial(true).'_id'); // StoreSelectedIDs sets this variable
}
return $ret;
}
/**
* Prepares and stores selected_ids string
* in Session and Application Variables
* by getting all checked ids from grid plus
* id passed in get/post as prefix_id
*
* @param kEvent $event
* @param Array $ids
*
* @return Array ids stored
*/
function StoreSelectedIDs(&$event, $ids = null)
{
$wid = $this->Application->GetTopmostWid($event->Prefix);
$session_name = rtrim($event->getPrefixSpecial().'_selected_ids_'.$wid, '_');
if (isset($ids)) {
// save ids directly if they given
$this->Application->StoreVar($session_name, implode(',', $ids));
return $ids;
}
$ret = Array();
// May be we don't need this part: ?
$passed = $this->Application->GetVar($event->getPrefixSpecial(true).'_id');
if($passed !== false && $passed != '')
{
array_push($ret, $passed);
}
$ids = Array();
// get selected ids from post & save them to session
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
$id_field = $this->Application->getUnitOption($event->Prefix,'IDField');
foreach($items_info as $id => $field_values)
{
if( getArrayValue($field_values,$id_field) ) array_push($ids,$id);
}
//$ids=array_keys($items_info);
}
$ret = array_unique(array_merge($ret, $ids));
$this->Application->SetVar($event->getPrefixSpecial().'_selected_ids', implode(',',$ret));
$this->Application->LinkVar($event->getPrefixSpecial().'_selected_ids', $session_name);
// This is critical - otherwise getPassedID will return last ID stored in session! (not exactly true)
// this smells... needs to be refactored
$first_id = getArrayValue($ret,0);
if (($first_id === false) && ($event->getEventParam('raise_warnings') == 1)) {
if ($this->Application->isDebugMode()) {
$this->Application->Debugger->appendTrace();
}
trigger_error('Requested ID for prefix <b>'.$event->getPrefixSpecial().'</b> <span class="debug_error">not passed</span>',E_USER_NOTICE);
}
$this->Application->SetVar($event->getPrefixSpecial(true).'_id', $first_id);
return $ret;
}
/**
* Returns stored selected ids as an array
*
* @param kEvent $event
* @param bool $from_session return ids from session (written, when editing was started)
* @return array
*/
function getSelectedIDs(&$event, $from_session = false)
{
if ($from_session) {
$wid = $this->Application->GetTopmostWid($event->Prefix);
$var_name = rtrim($event->getPrefixSpecial().'_selected_ids_'.$wid, '_');
$ret = $this->Application->RecallVar($var_name);
}
else {
$ret = $this->Application->GetVar($event->getPrefixSpecial().'_selected_ids');
}
return explode(',', $ret);
}
/**
* Returs associative array of submitted fields for current item
* Could be used while creating/editing single item -
* meaning on any edit form, except grid edit
*
* @param kEvent $event
*/
function getSubmittedFields(&$event)
{
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
$field_values = $items_info ? array_shift($items_info) : Array();
return $field_values;
}
/**
* Removes any information about current/selected ids
* from Application variables and Session
*
* @param kEvent $event
*/
function clearSelectedIDs(&$event)
{
$prefix_special = $event->getPrefixSpecial();
$ids = implode(',', $this->getSelectedIDs($event, true));
$event->setEventParam('ids', $ids);
$wid = $this->Application->GetTopmostWid($event->Prefix);
$session_name = rtrim($prefix_special.'_selected_ids_'.$wid, '_');
$this->Application->RemoveVar($session_name);
$this->Application->SetVar($prefix_special.'_selected_ids', '');
$this->Application->SetVar($prefix_special.'_id', ''); // $event->getPrefixSpecial(true).'_id' too may be
}
/*function SetSaveEvent(&$event)
{
$this->Application->SetVar($event->Prefix_Special.'_SaveEvent','OnUpdate');
$this->Application->LinkVar($event->Prefix_Special.'_SaveEvent');
}*/
/**
* Common builder part for Item & List
*
* @param kDBBase $object
* @param kEvent $event
* @access private
*/
function dbBuild(&$object, &$event)
{
$object->Configure( $event->getEventParam('populate_ml_fields') || $this->Application->getUnitOption($event->Prefix, 'PopulateMlFields') );
$this->PrepareObject($object, $event);
// force live table if specified or is original item
$live_table = $event->getEventParam('live_table') || $event->Special == 'original';
if( $this->UseTempTables($event) && !$live_table )
{
$object->SwitchToTemp();
}
// This strange constuction creates hidden field for storing event name in form submit
// It pass SaveEvent to next screen, otherwise after unsuccsefull create it will try to update rather than create
$current_event = $this->Application->GetVar($event->Prefix_Special.'_event');
// $this->Application->setEvent($event->Prefix_Special, $current_event);
$this->Application->setEvent($event->Prefix_Special, '');
$save_event = $this->UseTempTables($event) && $this->Application->GetTopmostPrefix($event->Prefix) == $event->Prefix ? 'OnSave' : 'OnUpdate';
$this->Application->SetVar($event->Prefix_Special.'_SaveEvent',$save_event);
}
/**
* Checks, that currently loaded item is allowed for viewing (non permission-based)
*
* @param kEvent $event
* @return bool
*/
function checkItemStatus(&$event)
{
$status_fields = $this->Application->getUnitOption($event->Prefix,'StatusField');
if (!$status_fields) {
return true;
}
$status_field = array_shift($status_fields);
if ($status_field == 'Status' || $status_field == 'Enabled') {
$object =& $event->getObject();
if (!$object->isLoaded()) {
return true;
}
return $object->GetDBField($status_field) == STATUS_ACTIVE;
}
return true;
}
/**
* Builds item (loads if needed)
*
* @param kEvent $event
* @access protected
*/
function OnItemBuild(&$event)
{
$object =& $event->getObject();
$this->dbBuild($object,$event);
$sql = $this->ItemPrepareQuery($event);
$sql = $this->Application->ReplaceLanguageTags($sql);
$object->setSelectSQL($sql);
// 2. loads if allowed
$auto_load = $this->Application->getUnitOption($event->Prefix,'AutoLoad');
$skip_autload = $event->getEventParam('skip_autoload');
if ($auto_load && !$skip_autload) {
$perm_status = true;
$user_id = $this->Application->RecallVar('user_id');
$event->setEventParam('top_prefix', $this->Application->GetTopmostPrefix($event->Prefix, true));
$status_checked = false;
if ($user_id == -1 || $this->CheckPermission($event)) {
// don't autoload item, when user doesn't have view permission
$this->LoadItem($event);
$status_checked = true;
if ($user_id != -1 && !$this->Application->IsAdmin() && !$this->checkItemStatus($event)) {
$perm_status = false;
}
}
else {
$perm_status = false;
}
if (!$perm_status) {
// when no permission to view item -> redirect to no pemrission template
if ($this->Application->isDebugMode()) {
$this->Application->Debugger->appendTrace();
}
trigger_error('ItemLoad Permission Failed for prefix ['.$event->getPrefixSpecial().'] in <strong>'.($status_checked ? 'checkItemStatus' : 'CheckPermission').'</strong>', E_USER_WARNING);
$next_template = $this->Application->IsAdmin() ? 'no_permission' : $this->Application->ConfigValue('NoPermissionTemplate');
$this->Application->Redirect($next_template, Array('next_template' => $this->Application->GetVar('t')));
}
}
$actions =& $this->Application->recallObject('kActions');
$actions->Set($event->Prefix_Special.'_GoTab', '');
$actions->Set($event->Prefix_Special.'_GoId', '');
}
/**
* Build subtables array from configs
*
* @param kEvent $event
*/
function OnTempHandlerBuild(&$event)
{
$object =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
/* @var $object kTempTablesHandler */
$object->BuildTables( $event->Prefix, $this->getSelectedIDs($event) );
}
/**
* Enter description here...
*
* @param kEvent $event
* @return unknown
*/
function UseTempTables(&$event)
{
$object = &$event->getObject();
$top_prefix = $this->Application->GetTopmostPrefix($event->Prefix);
$var_names = Array (
$top_prefix,
rtrim($top_prefix.'_'.$event->Special, '_'),
rtrim($top_prefix.'.'.$event->Special, '.'),
);
$var_names = array_unique($var_names);
$temp_mode = false;
foreach ($var_names as $var_name) {
$value = $this->Application->GetVar($var_name.'_mode');
if (substr($value, 0, 1) == 't') {
$temp_mode = true;
break;
}
}
return $temp_mode;
}
/**
* Returns table prefix from event (temp or live)
*
* @param kEvent $event
* @return string
* @todo Needed? Should be refactored (by Alex)
*/
function TablePrefix(&$event)
{
return $this->UseTempTables($event) ? $this->Application->GetTempTablePrefix('prefix:'.$event->Prefix).TABLE_PREFIX : TABLE_PREFIX;
}
/**
* Load item if id is available
*
* @param kEvent $event
*/
function LoadItem(&$event)
{
$object =& $event->getObject();
$id = $this->getPassedID($event);
if ($object->Load($id)) {
$actions =& $this->Application->recallObject('kActions');
$actions->Set($event->Prefix_Special.'_id', $object->GetID() );
}
else {
$object->setID($id);
}
}
/**
* Builds list
*
* @param kEvent $event
* @access protected
*/
function OnListBuild(&$event)
{
$object =& $event->getObject();
/* @var $object kDBList */
$this->dbBuild($object,$event);
$sql = $this->ListPrepareQuery($event);
$sql = $this->Application->ReplaceLanguageTags($sql);
$object->setSelectSQL($sql);
$object->Counted = false; // when requery="1" should re-count records too!
$object->ClearOrderFields(); // prevents duplicate order fields, when using requery="1"
$object->linkToParent( $this->getMainSpecial($event) );
$this->AddFilters($event);
$this->SetCustomQuery($event); // new!, use this for dynamic queries based on specials for ex.
$this->SetPagination($event);
$this->SetSorting($event);
// $object->CalculateTotals(); // Now called in getTotals to avoid extra query
$actions =& $this->Application->recallObject('kActions');
$actions->Set('remove_specials['.$event->Prefix_Special.']', '0');
$actions->Set($event->Prefix_Special.'_GoTab', '');
}
/**
* Get's special of main item for linking with subitem
*
* @param kEvent $event
* @return string
*/
function getMainSpecial(&$event)
{
$special = $event->getEventParam('main_special');
if($special === false || $special == '$main_special')
{
$special = $event->Special;
}
return $special;
}
/**
* Apply any custom changes to list's sql query
*
* @param kEvent $event
* @access protected
* @see OnListBuild
*/
function SetCustomQuery(&$event)
{
}
/**
* Set's new perpage for grid
*
* @param kEvent $event
*/
function OnSetPerPage(&$event)
{
$per_page = $this->Application->GetVar($event->getPrefixSpecial(true).'_PerPage');
$this->Application->StoreVar($event->getPrefixSpecial().'_PerPage', $per_page);
$view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view');
$this->Application->StorePersistentVar($event->getPrefixSpecial().'_PerPage.'.$view_name, $per_page);
}
/**
* Set's correct page for list
* based on data provided with event
*
* @param kEvent $event
* @access private
* @see OnListBuild
*/
function SetPagination(&$event)
{
// get PerPage (forced -> session -> config -> 10)
$per_page = $this->getPerPage($event);
$object =& $event->getObject();
$object->SetPerPage($per_page);
$this->Application->StoreVarDefault($event->getPrefixSpecial().'_Page', 1);
$page = $this->Application->GetVar($event->getPrefixSpecial().'_Page');
if (!$page) {
$page = $this->Application->GetVar($event->getPrefixSpecial(true).'_Page');
}
if (!$page) {
$page = $this->Application->RecallVar($event->getPrefixSpecial().'_Page');
}
else {
$this->Application->StoreVar($event->getPrefixSpecial().'_Page', $page);
}
if( !$event->getEventParam('skip_counting') )
{
$pages = $object->GetTotalPages();
if($page > $pages)
{
$this->Application->StoreVar($event->getPrefixSpecial().'_Page', 1);
$page = 1;
}
}
/*$per_page = $event->getEventParam('per_page');
if ($per_page == 'list_next') {
$cur_page = $page;
$cur_per_page = $per_page;
$object->SetPerPage(1);
$object =& $this->Application->recallObject($event->Prefix);
$cur_item_index = $object->CurrentIndex;
$page = ($cur_page-1) * $cur_per_page + $cur_item_index + 1;
$object->SetPerPage(1);
}*/
$object->SetPage($page);
}
/**
* Returns current per-page setting for list
*
* @param kEvent $event
* @return int
*/
function getPerPage(&$event)
{
// 1. per-page is passed as tag parameter to PrintList, InitList, etc.
$per_page = $event->getEventParam('per_page');
/*if ($per_page == 'list_next') {
$per_page = '';
}*/
// 2. per-page variable name is store into config variable
$config_mapping = $this->Application->getUnitOption($event->Prefix, 'ConfigMapping');
if ($config_mapping) {
switch ( $per_page ){
case 'short_list' :
$per_page = $this->Application->ConfigValue($config_mapping['ShortListPerPage']);
break;
case 'default' :
$per_page = $this->Application->ConfigValue($config_mapping['PerPage']);
break;
}
}
if (!$per_page) {
// per-page is stored to persistent session
$view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view');
$storage_prefix = $event->getEventParam('same_special') ? $event->Prefix : $event->getPrefixSpecial();
$per_page = $this->Application->RecallPersistentVar($storage_prefix.'_PerPage.'.$view_name);
if (!$per_page) {
// per-page is stored to current session
$per_page = $this->Application->RecallVar($storage_prefix.'_PerPage');
}
if (!$per_page) {
if ($config_mapping) {
if (!isset($config_mapping['PerPage'])) {
trigger_error('Incorrect mapping of <span class="debug_error">PerPage</span> key in config for prefix <b>'.$event->Prefix.'</b>', E_USER_WARNING);
}
$per_page = $this->Application->ConfigValue($config_mapping['PerPage']);
}
if (!$per_page) {
// none of checked above per-page locations are useful, then try default value
$per_page = 10;
}
}
}
return $per_page;
}
/**
* Set's correct sorting for list
* based on data provided with event
*
* @param kEvent $event
* @access private
* @see OnListBuild
*/
function SetSorting(&$event)
{
$event->setPseudoClass('_List');
$object =& $event->getObject();
$storage_prefix = $event->getEventParam('same_special') ? $event->Prefix : $event->Prefix_Special;
$cur_sort1 = $this->Application->RecallVar($storage_prefix.'_Sort1');
$cur_sort1_dir = $this->Application->RecallVar($storage_prefix.'_Sort1_Dir');
$cur_sort2 = $this->Application->RecallVar($storage_prefix.'_Sort2');
$cur_sort2_dir = $this->Application->RecallVar($storage_prefix.'_Sort2_Dir');
$sorting_configs = $this->Application->getUnitOption($event->Prefix, 'ConfigMapping');
$list_sortings = $this->Application->getUnitOption($event->Prefix, 'ListSortings');
$sorting_prefix = getArrayValue($list_sortings, $event->Special) ? $event->Special : '';
$tag_sort_by = $event->getEventParam('sort_by');
if ($tag_sort_by) {
if ($tag_sort_by == 'random') {
$by = 'RAND()';
$dir = '';
}
else {
list($by, $dir) = explode(',', $tag_sort_by);
}
$object->AddOrderField($by, $dir);
}
if ($sorting_configs && isset ($sorting_configs['DefaultSorting1Field'])){
$list_sortings[$sorting_prefix]['Sorting'] = Array(
$this->Application->ConfigValue($sorting_configs['DefaultSorting1Field']) => $this->Application->ConfigValue($sorting_configs['DefaultSorting1Dir']),
$this->Application->ConfigValue($sorting_configs['DefaultSorting2Field']) => $this->Application->ConfigValue($sorting_configs['DefaultSorting2Dir']),
);
}
// Use default if not specified
if ( !$cur_sort1 || !$cur_sort1_dir)
{
if ( $sorting = getArrayValue($list_sortings, $sorting_prefix, 'Sorting') ) {
reset($sorting);
$cur_sort1 = key($sorting);
$cur_sort1_dir = current($sorting);
if (next($sorting)) {
$cur_sort2 = key($sorting);
$cur_sort2_dir = current($sorting);
}
}
}
if ( $forced_sorting = getArrayValue($list_sortings, $sorting_prefix, 'ForcedSorting') ) {
foreach ($forced_sorting as $field => $dir) {
$object->AddOrderField($field, $dir);
}
}
if($cur_sort1 != '' && $cur_sort1_dir != '')
{
$object->AddOrderField($cur_sort1, $cur_sort1_dir);
}
if($cur_sort2 != '' && $cur_sort2_dir != '')
{
$object->AddOrderField($cur_sort2, $cur_sort2_dir);
}
}
/**
* Add filters found in session
*
* @param kEvent $event
*/
function AddFilters(&$event)
{
$object =& $event->getObject();
$edit_mark = rtrim($this->Application->GetSID().'_'.$this->Application->GetTopmostWid($event->Prefix), '_');
// add search filter
$filter_data = $this->Application->RecallVar($event->getPrefixSpecial().'_search_filter');
if ($filter_data) {
$filter_data = unserialize($filter_data);
foreach ($filter_data as $filter_field => $filter_params) {
$filter_type = ($filter_params['type'] == 'having') ? HAVING_FILTER : WHERE_FILTER;
$filter_value = str_replace(EDIT_MARK, $edit_mark, $filter_params['value']);
$object->addFilter($filter_field, $filter_value, $filter_type, FLT_SEARCH);
}
}
// add custom filter
$view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view');
$custom_filters = $this->Application->RecallPersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name);
if ($custom_filters) {
$grid_name = $event->getEventParam('grid');
$custom_filters = unserialize($custom_filters);
if (isset($custom_filters[$grid_name])) {
foreach ($custom_filters[$grid_name] as $field_name => $field_options) {
list ($filter_type, $field_options) = each($field_options);
if (isset($field_options['value']) && $field_options['value']) {
$filter_type = ($field_options['sql_filter_type'] == 'having') ? HAVING_FILTER : WHERE_FILTER;
$filter_value = str_replace(EDIT_MARK, $edit_mark, $field_options['value']);
$object->addFilter($field_name, $filter_value, $filter_type, FLT_CUSTOM);
}
}
}
}
$view_filter = $this->Application->RecallVar($event->getPrefixSpecial().'_view_filter');
if($view_filter)
{
$view_filter = unserialize($view_filter);
$temp_filter =& $this->Application->makeClass('kMultipleFilter');
$filter_menu = $this->Application->getUnitOption($event->Prefix,'FilterMenu');
$group_key = 0; $group_count = count($filter_menu['Groups']);
while($group_key < $group_count)
{
$group_info = $filter_menu['Groups'][$group_key];
$temp_filter->setType( constant('FLT_TYPE_'.$group_info['mode']) );
$temp_filter->clearFilters();
foreach ($group_info['filters'] as $flt_id)
{
$sql_key = getArrayValue($view_filter,$flt_id) ? 'on_sql' : 'off_sql';
if ($filter_menu['Filters'][$flt_id][$sql_key] != '')
{
$temp_filter->addFilter('view_filter_'.$flt_id, $filter_menu['Filters'][$flt_id][$sql_key]);
}
}
$object->addFilter('view_group_'.$group_key, $temp_filter, $group_info['type'] , FLT_VIEW);
$group_key++;
}
}
}
/**
* Set's new sorting for list
*
* @param kEvent $event
* @access protected
*/
function OnSetSorting(&$event)
{
$cur_sort1 = $this->Application->RecallVar($event->Prefix_Special.'_Sort1');
$cur_sort1_dir = $this->Application->RecallVar($event->Prefix_Special.'_Sort1_Dir');
$use_double_sorting = $this->Application->ConfigValue('UseDoubleSorting') !== false ? $this->Application->ConfigValue('UseDoubleSorting') : true;
if ($use_double_sorting) {
$cur_sort2 = $this->Application->RecallVar($event->Prefix_Special.'_Sort2');
$cur_sort2_dir = $this->Application->RecallVar($event->Prefix_Special.'_Sort2_Dir');
}
$passed_sort1 = $this->Application->GetVar($event->getPrefixSpecial(true).'_Sort1');
if ($cur_sort1 == $passed_sort1) {
$cur_sort1_dir = $cur_sort1_dir == 'asc' ? 'desc' : 'asc';
}
else {
if ($use_double_sorting) {
$cur_sort2 = $cur_sort1;
$cur_sort2_dir = $cur_sort1_dir;
}
$cur_sort1 = $passed_sort1;
$cur_sort1_dir = 'asc';
}
$this->Application->StoreVar($event->Prefix_Special.'_Sort1', $cur_sort1);
$this->Application->StoreVar($event->Prefix_Special.'_Sort1_Dir', $cur_sort1_dir);
if ($use_double_sorting) {
$this->Application->StoreVar($event->Prefix_Special.'_Sort2', $cur_sort2);
$this->Application->StoreVar($event->Prefix_Special.'_Sort2_Dir', $cur_sort2_dir);
}
}
/**
* Reset grid sorting to default (from config)
*
* @param kEvent $event
*/
function OnResetSorting(&$event)
{
$this->Application->RemoveVar($event->Prefix_Special.'_Sort1');
$this->Application->RemoveVar($event->Prefix_Special.'_Sort1_Dir');
$this->Application->RemoveVar($event->Prefix_Special.'_Sort2');
$this->Application->RemoveVar($event->Prefix_Special.'_Sort2_Dir');
}
/**
* Creates needed sql query to load item,
* if no query is defined in config for
* special requested, then use default
* query
*
* @param kEvent $event
* @access protected
*/
function ItemPrepareQuery(&$event)
{
$sqls = $this->Application->getUnitOption($event->Prefix, 'ItemSQLs', Array ());
$special = array_key_exists($event->Special, $sqls) ? $event->Special : '';
if (!array_key_exists($special, $sqls)) {
// preferred special not found in ItemSQLs -> use analog from ListSQLs
return $this->ListPrepareQuery($event);
}
return $sqls[$special];
}
/**
* Creates needed sql query to load list,
* if no query is defined in config for
* special requested, then use default
* query
*
* @param kEvent $event
* @access protected
*/
function ListPrepareQuery(&$event)
{
$sqls = $this->Application->getUnitOption($event->Prefix, 'ListSQLs', Array ());
return $sqls[ array_key_exists($event->Special, $sqls) ? $event->Special : '' ];
}
/**
* Apply custom processing to item
*
* @param kEvent $event
*/
function customProcessing(&$event, $type)
{
}
/* Edit Events mostly used in Admin */
/**
* Creates new kDBItem
*
* @param kEvent $event
* @access protected
*/
function OnCreate(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
/* @var $object kDBItem */
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if ($items_info) {
list($id,$field_values) = each($items_info);
$object->SetFieldsFromHash($field_values);
}
$this->customProcessing($event,'before');
//look at kDBItem' Create for ForceCreateId description, it's rarely used and is NOT set by default
if( $object->Create($event->getEventParam('ForceCreateId')) )
{
if( $object->IsTempTable() ) $object->setTempID();
$this->customProcessing($event,'after');
$event->status=erSUCCESS;
$event->redirect_params = Array('opener'=>'u');
}
else
{
$event->status = erFAIL;
$event->redirect = false;
$this->Application->SetVar($event->Prefix_Special.'_SaveEvent','OnCreate');
$object->setID($id);
}
}
/**
* Updates kDBItem
*
* @param kEvent $event
* @access protected
*/
function OnUpdate(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
foreach($items_info as $id => $field_values)
{
$object->Load($id);
$object->SetFieldsFromHash($field_values);
$this->customProcessing($event, 'before');
if( $object->Update($id) )
{
$this->customProcessing($event, 'after');
$event->status=erSUCCESS;
}
else
{
$event->status=erFAIL;
$event->redirect=false;
break;
}
}
}
$event->redirect_params = Array('opener'=>'u');
}
/**
* Delete's kDBItem object
*
* @param kEvent $event
* @access protected
*/
function OnDelete(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
/* @var $temp kTempTablesHandler */
$temp->DeleteItems($event->Prefix, $event->Special, Array($this->getPassedID($event)));
}
/**
* Prepares new kDBItem object
*
* @param kEvent $event
* @access protected
*/
function OnNew(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
/* @var $object kDBItem */
$object->Clear(0);
$this->Application->SetVar($event->Prefix_Special.'_SaveEvent', 'OnCreate');
$table_info = $object->getLinkedInfo();
$object->SetDBField($table_info['ForeignKey'], $table_info['ParentId']);
$event->redirect = false;
}
/**
* Cancel's kDBItem Editing/Creation
*
* @param kEvent $event
* @access protected
*/
function OnCancel(&$event)
{
$object =& $event->getObject(Array('skip_autoload' => true));
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
if ($items_info) {
$delete_ids = Array();
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
foreach ($items_info as $id => $field_values) {
$object->Load($id);
// record created for using with selector (e.g. Reviews->Select User), and not validated => Delete it
if ($object->isLoaded() && !$object->Validate() && ($id <= 0) ) {
$delete_ids[] = $id;
}
}
if ($delete_ids) {
$temp->DeleteItems($event->Prefix, $event->Special, $delete_ids);
}
}
$event->redirect_params = Array('opener'=>'u');
}
/**
* Deletes all selected items.
* Automatically recurse into sub-items using temp handler, and deletes sub-items
* by calling its Delete method if sub-item has AutoDelete set to true in its config file
*
* @param kEvent $event
*/
function OnMassDelete(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$event->status=erSUCCESS;
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$ids = $this->StoreSelectedIDs($event);
$event->setEventParam('ids', $ids);
$this->customProcessing($event, 'before');
$ids = $event->getEventParam('ids');
if($ids)
{
$temp->DeleteItems($event->Prefix, $event->Special, $ids);
}
$this->clearSelectedIDs($event);
}
/**
* Sets window id (of first opened edit window) to temp mark in uls
*
* @param kEvent $event
*/
function setTempWindowID(&$event)
{
$mode = $this->Application->GetVar($event->Prefix.'_mode');
if ($mode == 't') {
$wid = $this->Application->GetVar('m_wid');
$this->Application->SetVar($event->Prefix.'_mode', 't'.$wid);
}
}
/**
* Prepare temp tables and populate it
* with items selected in the grid
*
* @param kEvent $event
*/
function OnEdit(&$event)
{
$this->setTempWindowID($event);
$this->StoreSelectedIDs($event);
$var_name = $event->getPrefixSpecial().'_file_pending_actions'.$this->Application->GetVar('m_wid');
$this->Application->RemoveVar($var_name);
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
/* @var $temp kTempTablesHandler */
$temp->PrepareEdit();
$event->redirect=false;
}
/**
* Saves content of temp table into live and
* redirects to event' default redirect (normally grid template)
*
* @param kEvent $event
*/
function OnSave(&$event)
{
$event->CallSubEvent('OnPreSave');
if ($event->status == erSUCCESS) {
$skip_master = false;
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
if (!$this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
$live_ids = $temp->SaveEdit($event->getEventParam('master_ids') ? $event->getEventParam('master_ids') : Array());
// Deleteing files scheduled for delete
$var_name = $event->getPrefixSpecial().'_file_pending_actions'.$this->Application->GetVar('m_wid');
$schedule = $this->Application->RecallVar($var_name);
$schedule = $schedule ? unserialize($schedule) : array();
foreach ($schedule as $data) {
if ($data['action'] == 'delete') {
unlink($data['file']);
}
}
if ($live_ids) {
// ensure, that newly created item ids are avalable as if they were selected from grid
// NOTE: only works if main item has subitems !!!
$this->StoreSelectedIDs($event, $live_ids);
}
}
$this->clearSelectedIDs($event);
$event->redirect_params = Array('opener' => 'u');
$this->Application->RemoveVar($event->getPrefixSpecial().'_modified');
// all temp tables are deleted here => all after hooks should think, that it's live mode now
$this->Application->SetVar($event->Prefix.'_mode', '');
}
}
/**
* Cancels edit
* Removes all temp tables and clears selected ids
*
* @param kEvent $event
*/
function OnCancelEdit(&$event)
{
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$temp->CancelEdit();
$this->clearSelectedIDs($event);
$event->redirect_params = Array('opener'=>'u');
$this->Application->RemoveVar($event->getPrefixSpecial().'_modified');
}
/**
* Allows to determine if we are creating new item or editing already created item
*
* @param kEvent $event
* @return bool
*/
function isNewItemCreate(&$event)
{
$event->setEventParam('raise_warnings', 0);
$object =& $event->getObject();
return !$object->IsLoaded();
// $item_id = $this->getPassedID($event);
// return ($item_id == '') ? true : false;
}
/**
* Saves edited item into temp table
* If there is no id, new item is created in temp table
*
* @param kEvent $event
*/
function OnPreSave(&$event)
{
//$event->redirect = false;
// if there is no id - it means we need to create an item
if (is_object($event->MasterEvent)) {
$event->MasterEvent->setEventParam('IsNew',false);
}
if ($this->isNewItemCreate($event)) {
$event->CallSubEvent('OnPreSaveCreated');
if (is_object($event->MasterEvent)) {
$event->MasterEvent->setEventParam('IsNew',true);
}
return;
}
$object =& $event->getObject( Array('skip_autoload' => true) );
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if ($items_info) {
foreach ($items_info as $id => $field_values) {
$object->SetDefaultValues();
$object->Load($id);
$object->SetFieldsFromHash($field_values);
$this->customProcessing($event, 'before');
if( $object->Update($id) )
{
$this->customProcessing($event, 'after');
$event->status=erSUCCESS;
}
else {
$event->status = erFAIL;
$event->redirect = false;
break;
}
}
}
}
/**
* Saves edited item in temp table and loads
* item with passed id in current template
* Used in Prev/Next buttons
*
* @param kEvent $event
*/
function OnPreSaveAndGo(&$event)
{
$event->CallSubEvent('OnPreSave');
if ($event->status == erSUCCESS) {
$event->SetRedirectParam($event->getPrefixSpecial(true).'_id', $this->Application->GetVar($event->Prefix_Special.'_GoId'));
}
}
/**
* Saves edited item in temp table and goes
* to passed tabs, by redirecting to it with OnPreSave event
*
* @param kEvent $event
*/
function OnPreSaveAndGoToTab(&$event)
{
$event->CallSubEvent('OnPreSave');
if ($event->status==erSUCCESS) {
$event->redirect=$this->Application->GetVar($event->getPrefixSpecial(true).'_GoTab');
}
}
/**
* Saves editable list and goes to passed tab,
* by redirecting to it with empty event
*
* @param kEvent $event
*/
function OnUpdateAndGoToTab(&$event)
{
$event->setPseudoClass('_List');
$event->CallSubEvent('OnUpdate');
if ($event->status==erSUCCESS) {
$event->redirect=$this->Application->GetVar($event->getPrefixSpecial(true).'_GoTab');
}
}
/**
* Prepare temp tables for creating new item
* but does not create it. Actual create is
* done in OnPreSaveCreated
*
* @param kEvent $event
*/
function OnPreCreate(&$event)
{
$this->setTempWindowID($event);
$this->clearSelectedIDs($event);
$object =& $event->getObject( Array('skip_autoload' => true) );
$temp =& $this->Application->recallObject($event->Prefix.'_TempHandler', 'kTempTablesHandler');
$temp->PrepareEdit();
$object->setID(0);
$this->Application->SetVar($event->getPrefixSpecial().'_id',0);
$this->Application->SetVar($event->getPrefixSpecial().'_PreCreate', 1);
$event->redirect=false;
}
/**
* Creates a new item in temp table and
* stores item id in App vars and Session on succsess
*
* @param kEvent $event
*/
function OnPreSaveCreated(&$event)
{
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info) $field_values = array_shift($items_info);
$object =& $event->getObject( Array('skip_autoload' => true) );
$object->SetFieldsFromHash($field_values);
$this->customProcessing($event, 'before');
if( $object->Create() )
{
$this->customProcessing($event, 'after');
$event->redirect_params[$event->getPrefixSpecial(true).'_id'] = $object->GetId();
$event->status=erSUCCESS;
}
else
{
$event->status=erFAIL;
$event->redirect=false;
$object->setID(0);
}
}
function OnReset(&$event)
{
//do nothing - should reset :)
if ($this->isNewItemCreate($event)) {
// just reset id to 0 in case it was create
$object =& $event->getObject( Array('skip_autoload' => true) );
$object->setID(0);
$this->Application->SetVar($event->getPrefixSpecial().'_id',0);
}
}
/**
* Apply same processing to each item beeing selected in grid
*
* @param kEvent $event
* @access private
*/
function iterateItems(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$object =& $event->getObject( Array('skip_autoload' => true) );
$ids = $this->StoreSelectedIDs($event);
if ($ids) {
$status_field = array_shift( $this->Application->getUnitOption($event->Prefix,'StatusField') );
foreach ($ids as $id) {
$object->Load($id);
switch ($event->Name) {
case 'OnMassApprove':
$object->SetDBField($status_field, 1);
break;
case 'OnMassDecline':
$object->SetDBField($status_field, 0);
break;
case 'OnMassMoveUp':
$object->SetDBField('Priority', $object->GetDBField('Priority') + 1);
break;
case 'OnMassMoveDown':
$object->SetDBField('Priority', $object->GetDBField('Priority') - 1);
break;
}
if ($object->Update()) {
$event->status = erSUCCESS;
}
else {
$event->status = erFAIL;
$event->redirect = false;
break;
}
}
}
$this->clearSelectedIDs($event);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnMassClone(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$event->status = erSUCCESS;
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$ids = $this->StoreSelectedIDs($event);
if ($ids) {
$temp->CloneItems($event->Prefix, $event->Special, $ids);
}
$this->clearSelectedIDs($event);
}
function check_array($records, $field, $value)
{
foreach ($records as $record) {
if ($record[$field] == $value) {
return true;
}
}
return false;
}
function OnPreSavePopup(&$event)
{
$object =& $event->getObject();
$this->RemoveRequiredFields($object);
$event->CallSubEvent('OnPreSave');
$this->finalizePopup($event);
}
/* End of Edit events */
// III. Events that allow to put some code before and after Update,Load,Create and Delete methods of item
/**
* Occurse before loading item, 'id' parameter
* allows to get id of item beeing loaded
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemLoad(&$event)
{
}
/**
* Occurse after loading item, 'id' parameter
* allows to get id of item that was loaded
*
* @param kEvent $event
* @access public
*/
function OnAfterItemLoad(&$event)
{
}
/**
* Occurse before creating item
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemCreate(&$event)
{
}
/**
* Occurse after creating item
*
* @param kEvent $event
* @access public
*/
function OnAfterItemCreate(&$event)
{
}
/**
* Occurse before updating item
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemUpdate(&$event)
{
}
/**
* Occurse after updating item
*
* @param kEvent $event
* @access public
*/
function OnAfterItemUpdate(&$event)
{
}
/**
* Occurse before deleting item, id of item beeing
* deleted is stored as 'id' event param
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemDelete(&$event)
{
}
/**
* Occurse after deleting item, id of deleted item
* is stored as 'id' param of event
*
* @param kEvent $event
* @access public
*/
function OnAfterItemDelete(&$event)
{
}
/**
* Occurs after successful item validation
*
* @param kEvent $event
*/
function OnAfterItemValidate(&$event)
{
}
/**
* Occures after an item has been copied to temp
* Id of copied item is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnAfterCopyToTemp(&$event)
{
}
/**
* Occures before an item is deleted from live table when copying from temp
* (temp handler deleted all items from live and then copy over all items from temp)
* Id of item being deleted is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnBeforeDeleteFromLive(&$event)
{
}
/**
* Occures before an item is copied to live table (after all foreign keys have been updated)
* Id of item being copied is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnBeforeCopyToLive(&$event)
{
}
/**
* !!! NOT FULLY IMPLEMENTED - SEE TEMP HANDLER COMMENTS (search by event name)!!!
* Occures after an item has been copied to live table
* Id of copied item is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnAfterCopyToLive(&$event)
{
}
/**
* Occures before an item is cloneded
* Id of ORIGINAL item is passed as event' 'id' param
* Do not call object' Update method in this event, just set needed fields!
*
* @param kEvent $event
*/
function OnBeforeClone(&$event)
{
}
/**
* Occures after an item has been cloned
* Id of newly created item is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnAfterClone(&$event)
{
}
/**
* Ensures that popup will be closed automatically
* and parent window will be refreshed with template
* passed
*
* @param kEvent $event
* @access public
*/
function finalizePopup(&$event)
{
$event->SetRedirectParam('opener', 'u');
/*return ;
// 2. substitute opener
$opener_stack = $this->Application->RecallVar('opener_stack');
$opener_stack = $opener_stack ? unserialize($opener_stack) : Array();
//array_pop($opener_stack);
$t = $this->Application->RecallVar('return_template');
$this->Application->RemoveVar('return_template');
// restore original "m" prefix all params, that have values before opening selector
$return_m = $this->Application->RecallVar('return_m');
$this->Application->RemoveVar('return_m');
$this->Application->HttpQuery->parseEnvPart($return_m);
$pass_events = $event->getEventParam('pass_events');
$redirect_params = array_merge_recursive2($event->redirect_params, Array('m_opener' => 'u', '__URLENCODE__' => 1));
$new_level = 'index.php|'.ltrim($this->Application->BuildEnv($t, $redirect_params, 'all', $pass_events), ENV_VAR_NAME.'=');
array_push($opener_stack, $new_level);
$this->Application->StoreVar('opener_stack', serialize($opener_stack));*/
}
/**
* Create search filters based on search query
*
* @param kEvent $event
* @access protected
*/
function OnSearch(&$event)
{
$event->setPseudoClass('_List');
$search_helper =& $this->Application->recallObject('SearchHelper');
$search_helper->performSearch($event);
}
/**
* Clear search keywords
*
* @param kEvent $event
* @access protected
*/
function OnSearchReset(&$event)
{
$search_helper =& $this->Application->recallObject('SearchHelper');
$search_helper->resetSearch($event);
}
/**
* Set's new filter value (filter_id meaning from config)
*
* @param kEvent $event
*/
function OnSetFilter(&$event)
{
$filter_id = $this->Application->GetVar('filter_id');
$filter_value = $this->Application->GetVar('filter_value');
$view_filter = $this->Application->RecallVar($event->getPrefixSpecial().'_view_filter');
$view_filter = $view_filter ? unserialize($view_filter) : Array();
$view_filter[$filter_id] = $filter_value;
$this->Application->StoreVar( $event->getPrefixSpecial().'_view_filter', serialize($view_filter) );
}
function OnSetFilterPattern(&$event)
{
$filters = $this->Application->GetVar($event->getPrefixSpecial(true).'_filters');
if (!$filters) return ;
$view_filter = $this->Application->RecallVar($event->getPrefixSpecial().'_view_filter');
$view_filter = $view_filter ? unserialize($view_filter) : Array();
$filters = explode(',', $filters);
foreach ($filters as $a_filter) {
list($id, $value) = explode('=', $a_filter);
$view_filter[$id] = $value;
}
$this->Application->StoreVar( $event->getPrefixSpecial().'_view_filter', serialize($view_filter) );
$event->redirect = false;
}
/**
* Add/Remove all filters applied to list from "View" menu
*
* @param kEvent $event
*/
function FilterAction(&$event)
{
$view_filter = Array();
$filter_menu = $this->Application->getUnitOption($event->Prefix,'FilterMenu');
switch ($event->Name)
{
case 'OnRemoveFilters':
$filter_value = 1;
break;
case 'OnApplyFilters':
$filter_value = 0;
break;
}
foreach($filter_menu['Filters'] as $filter_key => $filter_params)
{
if(!$filter_params) continue;
$view_filter[$filter_key] = $filter_value;
}
$this->Application->StoreVar( $event->getPrefixSpecial().'_view_filter', serialize($view_filter) );
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnPreSaveAndOpenTranslator(&$event)
{
$this->Application->SetVar('allow_translation', true);
$object =& $event->getObject();
$this->RemoveRequiredFields($object);
$event->CallSubEvent('OnPreSave');
if ($event->status == erSUCCESS) {
$resource_id = $this->Application->GetVar('translator_resource_id');
if ($resource_id) {
$t_prefixes = explode(',', $this->Application->GetVar('translator_prefixes'));
$cdata =& $this->Application->recallObject($t_prefixes[1], null, Array('skip_autoload' => true));
$cdata->Load($resource_id, 'ResourceId');
if (!$cdata->isLoaded()) {
$cdata->SetDBField('ResourceId', $resource_id);
$cdata->Create();
}
$this->Application->SetVar($cdata->getPrefixSpecial().'_id', $cdata->GetID());
}
$event->redirect = $this->Application->GetVar('translator_t');
$event->redirect_params = Array('pass'=>'all,trans,'.$this->Application->GetVar('translator_prefixes'),
$event->getPrefixSpecial(true).'_id' => $object->GetID(),
'trans_event' => 'OnLoad',
'trans_prefix' => $this->Application->GetVar('translator_prefixes'),
'trans_field' => $this->Application->GetVar('translator_field'),
'trans_multi_line' => $this->Application->GetVar('translator_multi_line'),
);
// 1. SAVE LAST TEMPLATE TO SESSION (really needed here, because of tweaky redirect)
$last_template = $this->Application->RecallVar('last_template');
preg_match('/index4\.php\|'.$this->Application->GetSID().'-(.*):/U', $last_template, $rets);
$this->Application->StoreVar('return_template', $this->Application->GetVar('t'));
}
}
function RemoveRequiredFields(&$object)
{
// making all field non-required to achieve successful presave
foreach($object->Fields as $field => $options)
{
if(isset($options['required']))
{
unset($object->Fields[$field]['required']);
}
}
}
/**
* Saves selected user in needed field
*
* @param kEvent $event
*/
function OnSelectUser(&$event)
{
$items_info = $this->Application->GetVar('u');
if ($items_info) {
$user_id = array_shift( array_keys($items_info) );
$object =& $event->getObject();
$this->RemoveRequiredFields($object);
$is_new = !$object->isLoaded();
$is_main = substr($this->Application->GetVar($event->Prefix.'_mode'), 0, 1) == 't';
if ($is_new) {
$new_event = $is_main ? 'OnPreCreate' : 'OnNew';
$event->CallSubEvent($new_event);
$event->redirect = true;
}
$object->SetDBField($this->Application->RecallVar('dst_field'), $user_id);
if ($is_new) {
$object->Create();
if (!$is_main && $object->IsTempTable()) {
$object->setTempID();
}
}
else {
$object->Update();
}
}
$event->SetRedirectParam($event->getPrefixSpecial().'_id', $object->GetID());
$this->finalizePopup($event);
}
/** EXPORT RELATED **/
/**
* Shows export dialog
*
* @param kEvent $event
*/
function OnExport(&$event)
{
$this->StoreSelectedIDs($event);
$selected_ids = $this->getSelectedIDs($event);
if (implode(',', $selected_ids) == '') {
// K4 fix when no ids found bad selected ids array is formed
$selected_ids = false;
}
$this->Application->StoreVar($event->Prefix.'_export_ids', $selected_ids ? implode(',', $selected_ids) : '' );
$export_t = $this->Application->GetVar('export_template');
$this->Application->LinkVar('export_finish_t');
$this->Application->LinkVar('export_progress_t');
$this->Application->StoreVar('export_oroginal_special', $event->Special);
$export_helper =& $this->Application->recallObject('CatItemExportHelper');
$event->redirect = $export_t ? $export_t : $export_helper->getModuleFolder($event).'/export';
list($index_file, $env) = explode('|', $this->Application->RecallVar('last_template'));
$finish_url = $this->Application->BaseURL('/admin').$index_file.'?'.ENV_VAR_NAME.'='.$env;
$this->Application->StoreVar('export_finish_url', $finish_url);
$redirect_params = Array(
$this->Prefix.'.export_event' => 'OnNew',
'pass' => 'all,'.$this->Prefix.'.export');
$event->setRedirectParams($redirect_params);
}
/**
* 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)
{
if ($event->Special == 'export' || $event->Special == 'import')
{
$export_helper =& $this->Application->recallObject('CatItemExportHelper');
$export_helper->prepareExportColumns($event);
}
}
/**
* Returns specific to each item type columns only
*
* @param kEvent $event
* @return Array
*/
function getCustomExportColumns(&$event)
{
return Array();
}
/**
* Export form validation & processing
*
* @param kEvent $event
*/
function OnExportBegin(&$event)
{
$export_helper =& $this->Application->recallObject('CatItemExportHelper');
/* @var $export_helper kCatDBItemExportHelper */
$export_helper->OnExportBegin($event);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnExportCancel(&$event)
{
$this->OnGoBack($event);
}
/**
* Allows configuring export options
*
* @param kEvent $event
*/
function OnBeforeExportBegin(&$event)
{
}
function OnDeleteExportPreset(&$event)
{
$object =& $event->GetObject();
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
list($id,$field_values) = each($items_info);
$preset_key = $field_values['ExportPresets'];
$user =& $this->Application->recallObject('u.current');
$export_settings = $user->getPersistantVar('export_settings');
if (!$export_settings) return ;
$export_settings = unserialize($export_settings);
if (!isset($export_settings[$event->Prefix])) return ;
$to_delete = '';
$export_presets = array(''=>'');
foreach ($export_settings[$event->Prefix] as $key => $val) {
if (implode('|', $val['ExportColumns']) == $preset_key) {
$to_delete = $key;
break;
}
}
if ($to_delete) {
unset($export_settings[$event->Prefix][$to_delete]);
$user->setPersistantVar('export_settings', serialize($export_settings));
}
}
}
/**
* Saves changes & changes language
*
* @param kEvent $event
*/
function OnPreSaveAndChangeLanguage(&$event)
{
$event->CallSubEvent('OnPreSave');
if ($event->status == erSUCCESS) {
$this->Application->SetVar('m_lang', $this->Application->GetVar('language'));
}
}
function OnUploadFile(&$event)
{
// Flash uploader does NOT send correct cookies, so we need to make our own check
$cookie_name = 'adm_'.$this->Application->ConfigValue('SessionCookieName');
$this->Application->HttpQuery->Cookie['cookies_on'] = 1;
$this->Application->HttpQuery->Cookie[$cookie_name] = $this->Application->GetVar('flashsid');
$admin_ses =& $this->Application->recallObject('Session.admin');
/* @var $admin_ses Session */
$user = $admin_ses->RecallVar('user_id');
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$section = $event->getSection();
if (!$perm_helper->CheckUserPermission($user, $section.'.add') && !$perm_helper->CheckUserPermission($user, $section.'.edit')) {
$event->status = erPERM_FAIL;
header('HTTP/1.0 403 You don\'t have permissions to upload');
exit;
return;
}
if (!$cookie_name) $cookie_name = 'sid';
$value = $this->Application->GetVar('Filedata');
if (!$value) return ;
$tmp_path = defined('WRITEABLE') ? WRITEABLE.'/tmp/' : FULL_PATH.'/kernel/cache/';
$fname = $value['name'];
$id = $this->Application->GetVar('id');
if ($id) $fname = $id.'_'.$fname;
if (!is_writable($tmp_path)) {
header('HTTP/1.0 500 Write permissions not set on the server');
exit;
}
move_uploaded_file($value['tmp_name'], $tmp_path.$fname);
exit;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnDeleteFile(&$event)
{
if (strpos($this->Application->GetVar('file'), '../') !== false) return ;
$object =& $event->getObject(array('skip_autoload'=>true));
$options = $object->GetFieldOptions($this->Application->GetVar('field'));
$var_name = $event->getPrefixSpecial().'_file_pending_actions'.$this->Application->GetVar('m_wid');
$schedule = $this->Application->RecallVar($var_name);
$schedule = $schedule ? unserialize($schedule) : array();
$schedule[] = array('action'=>'delete', 'file'=>$path = FULL_PATH.$options['upload_dir'].$this->Application->GetVar('file'));
$this->Application->StoreVar($var_name, serialize($schedule));
$this->Application->Session->SaveData();
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnViewFile(&$event)
{
if (strpos($this->Application->GetVar('file'), '../') !== false) return ;
if ($this->Application->GetVar('tmp')) {
$path = (defined('WRITEABLE') ? WRITEABLE.'/tmp/' : FULL_PATH.'/kernel/cache/').$this->Application->GetVar('id').'_'.$this->Application->GetVar('file');
}
else {
$object =& $event->getObject(array('skip_autoload'=>true));
$options = $object->GetFieldOptions($this->Application->GetVar('field'));
$path = FULL_PATH.$options['upload_dir'].$this->Application->GetVar('file');
}
$type = mime_content_type($path);
header('Content-Length: '.filesize($path));
header('Content-Type: '.$type);
safeDefine('DBG_SKIP_REPORTING',1);
readfile($path);
exit();
}
/**
* Returns auto-complete values for ajax-dropdown
*
* @param kEvent $event
*/
function OnSuggestValues(&$event)
{
$this->Application->XMLHeader();
$field = $this->Application->GetVar('field');
$cur_value = $this->Application->GetVar('cur_value');
if (!$field || !$cur_value) {
exit;
}
$object =& $event->getObject();
$sql = 'SELECT DISTINCT '.$field.'
FROM '.$object->TableName.'
WHERE '.$field.' LIKE '.$this->Conn->qstr($cur_value.'%').'
ORDER BY '.$field.'
LIMIT 0,20';
$data = $this->Conn->GetCol($sql);
echo '<suggestions>';
foreach ($data as $item) {
echo '<item>'.$item.'</item>';
}
echo '</suggestions>';
$event->status = erSTOP;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnSaveWidths(&$event)
{
safeDefine('DBG_SKIP_REPORTING', 1);
$lang =& $this->Application->recallObject('lang.current');
// header('Content-type: text/xml; charset='.$lang->GetDBField('Charset'));
$picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
/* @var $picker_helper kColumnPickerHelper */
$picker_helper->PreparePicker($event->getPrefixSpecial(), $this->Application->GetVar('grid_name'));
$picker_helper->SaveWidths($event->getPrefixSpecial(), $this->Application->GetVar('widths'));
exit;
}
+ /**
+ * Called from CSV import script after item fields
+ * are set and validated, but before actual item create/update.
+ * If event status is erSUCCESS, line will be imported,
+ * else it will not be imported but added to skipped lines
+ * and displayed in the end of import.
+ * Event status is preset from import script.
+ *
+ * @param kEvent $event
+ */
+ function OnBeforeCSVLineImport(&$event)
+ {
+ // abstract, for hooking
+ }
+
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/kernel/db/db_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.99.2.12
\ No newline at end of property
+1.99.2.13
\ No newline at end of property
Index: branches/RC/core/kernel/application.php
===================================================================
--- branches/RC/core/kernel/application.php (revision 9638)
+++ branches/RC/core/kernel/application.php (revision 9639)
@@ -1,2555 +1,2563 @@
<?php
/**
* Basic class for Kernel3-based Application
*
* This class is a Facade for any other class which needs to deal with Kernel3 framework.<br>
* The class incapsulates the main run-cycle of the script, provide access to all other objects in the framework.<br>
* <br>
* The class is a singleton, which means that there could be only one instance of KernelApplication in the script.<br>
* This could be guranteed by NOT calling the class constuctor directly, but rather calling KernelApplication::Instance() method,
* which returns an instance of the application. The method gurantees that it will return exactly the same instance for any call.<br>
* See singleton pattern by GOF.
* @package kernel4
*/
class kApplication {
/**
* Is true, when Init method was called already, prevents double initialization
*
* @var bool
*/
var $InitDone = false;
/**
* Holds internal TemplateParser object
* @access private
* @var TemplateParser
*/
var $Parser;
/**
* New Parser (Experimental)
*
* @var NParser
*/
var $NParser;
/**
* Holds parser output buffer
* @access private
* @var string
*/
var $HTML;
/**
* Prevents request from beeing proceeded twice in case if application init is called mere then one time
*
* @var bool
* @todo This is not good anyway (by Alex)
*/
var $RequestProcessed = false;
/**
* The main Factory used to create
* almost any class of kernel and
* modules
*
* @access private
* @var kFactory
*/
var $Factory;
/**
* All ConfigurationValues table content (hash) here
*
* @var Array
* @access private
*/
var $ConfigHash = Array();
/**
* Ids of config variables used in current run (for caching)
*
* @var Array
* @access private
*/
var $ConfigCacheIds = array();
/**
* Template names, that will be used instead of regular templates
*
* @var Array
*/
var $ReplacementTemplates = Array ();
/**
* Reference to debugger
*
* @var Debugger
*/
var $Debugger = null;
/**
* Holds all phrases used
* in code and template
*
* @var PhrasesCache
*/
var $Phrases;
/**
* Modules table content, key - module name
*
* @var Array
*/
var $ModuleInfo = Array();
/**
* Holds DBConnection
*
* @var kDBConnection
*/
var $Conn = null;
/**
* Maintains list of user-defined error handlers
*
* @var Array
*/
var $errorHandlers = Array();
// performance needs:
/**
* Holds a refererence to httpquery
*
* @var kHttpQuery
*/
var $HttpQuery = null;
/**
* Holds a reference to UnitConfigReader
*
* @var kUnitConfigReader
*/
var $UnitConfigReader = null;
/**
* Holds a reference to Session
*
* @var Session
*/
var $Session = null;
/**
* Holds a ref to kEventManager
*
* @var kEventManager
*/
var $EventManager = null;
/**
* Ref to itself, needed because everybody used to write $this->Application, even inside kApplication
*
* @var kApplication
*/
var $Application = null;
/**
* Ref for TemplatesChache
*
* @var TemplatesCache
*/
var $TemplatesCache = null;
var $CompilationCache = array(); //used when compiling templates
var $CachedProcessors = array(); //used when running compiled templates
var $LambdaElements = 1; // for autonumbering unnamed RenderElements [any better place for this prop? KT]
/**
* Returns kApplication instance anywhere in the script.
*
* This method should be used to get single kApplication object instance anywhere in the
* Kernel-based application. The method is guranteed to return the SAME instance of kApplication.
* Anywhere in the script you could write:
* <code>
* $application =& kApplication::Instance();
* </code>
* or in an object:
* <code>
* $this->Application =& kApplication::Instance();
* </code>
* to get the instance of kApplication. Note that we call the Instance method as STATIC - directly from the class.
* To use descendand of standard kApplication class in your project you would need to define APPLICATION_CLASS constant
* BEFORE calling kApplication::Instance() for the first time. If APPLICATION_CLASS is not defined the method would
* create and return default KernelApplication instance.
* @static
* @access public
* @return kApplication
*/
function &Instance()
{
static $instance = false;
if(!$instance)
{
safeDefine('APPLICATION_CLASS', 'kApplication');
$class = APPLICATION_CLASS;
$instance = new $class();
$instance->Application =& $instance;
}
return $instance;
}
/**
* Initializes the Application
*
* @access public
* @see kHTTPQuery
* @see Session
* @see TemplatesCache
* @return bool Was Init actually made now or before
*/
function Init()
{
if($this->InitDone) return false;
if (!constOn('SKIP_OUT_COMPRESSION')) {
ob_start(); // collect any output from method (other then tags) into buffer
}
if(defined('DEBUG_MODE') && $this->isDebugMode() && constOn('DBG_PROFILE_MEMORY')) {
$this->Debugger->appendMemoryUsage('Application before Init:');
}
if (!$this->isDebugMode() && !constOn('DBG_ZEND_PRESENT')) {
error_reporting(0);
ini_set('display_errors', 0);
}
if (!constOn('DBG_ZEND_PRESENT')) {
$error_handler = set_error_handler( Array(&$this,'handleError') );
if ($error_handler) $this->errorHandlers[] = $error_handler;
}
$this->Conn = new kDBConnection(SQL_TYPE, Array(&$this, 'handleSQLError') );
$this->Conn->debugMode = $this->isDebugMode();
$this->Conn->Connect(SQL_SERVER, SQL_USER, SQL_PASS, SQL_DB);
$this->Factory = new kFactory();
$this->registerDefaultClasses();
$this->Phrases = new PhrasesCache();
$this->EventManager =& $this->Factory->makeClass('EventManager');
$this->Factory->Storage['EventManager'] =& $this->EventManager;
$this->RegisterDefaultBuildEvents();
$this->SetDefaultConstants();
$this->UnitConfigReader =& $this->recallObject('kUnitConfigReader');
$this->UnitConfigReader->scanModules(MODULES_PATH);
$this->registerModuleConstants();
$rewrite_on = $this->ConfigValue('UseModRewrite');
// admin=1 - when front is browsed using admin session
$admin_on = getArrayValue($_REQUEST, 'admin') || $this->IsAdmin();
define('MOD_REWRITE', $rewrite_on && !$admin_on ? 1 : 0);
$this->HttpQuery =& $this->recallObject('HTTPQuery');
$this->Session =& $this->recallObject('Session');
$this->HttpQuery->AfterInit();
$this->LoadCache();
$this->InitConfig();
$this->Phrases->Init('phrases');
$this->UnitConfigReader->AfterConfigRead();
/*// Module items are recalled during url parsing & PhrasesCache is needed already there,
// because it's used in their build events. That's why phrases cache initialization is
// called from kHTTPQuery in case when mod_rewrite is used
if (!$this->RewriteURLs()) {
$this->Phrases = new PhrasesCache();
}*/
if(!$this->RecallVar('UserGroups')) {
$session =& $this->recallObject('Session');
$user_groups = trim($session->GetField('GroupList'), ',');
if (!$user_groups) $user_groups = $this->ConfigValue('User_GuestGroup');
$this->StoreVar('UserGroups', $user_groups);
}
if ($this->GetVar('m_cat_id') === false) $this->SetVar('m_cat_id', 0);
if( !$this->RecallVar('curr_iso') ) $this->StoreVar('curr_iso', $this->GetPrimaryCurrency() );
$this->SetVar('visits_id', $this->RecallVar('visit_id') );
$language =& $this->recallObject( 'lang.current', null, Array('live_table' => true) );
+ if (preg_match('/utf-8/', $language->GetDBField('Charset'))) {
+ setlocale(LC_ALL, 'en_US.UTF-8');
+ }
$this->ValidateLogin();
if($this->isDebugMode()) {
$this->Debugger->profileFinish('kernel4_startup');
}
$this->InitDone = true;
$this->HandleEvent( new kEvent('adm:OnStartup') );
return true;
}
/**
* Returns module information. Searches module by requested field
*
* @param string $field
* @param mixed $value
* @param string field value to returns, if not specified, then return all fields
* @param string field to return
* @return Array
*/
function findModule($field, $value, $return_field = null)
{
$found = false;
foreach ($this->ModuleInfo as $module_name => $module_info) {
if (strtolower($module_info[$field]) == strtolower($value)) {
$found = true;
break;
}
}
if ($found) {
return isset($return_field) ? $module_info[$return_field] : $module_info;
}
return false;
}
function refreshModuleInfo()
{
if (defined('IS_INSTALL') && IS_INSTALL && !$this->TableFound('Modules')) {
$this->registerModuleConstants();
return false;
}
$modules_helper =& $this->recallObject('ModulesHelper');
$this->ModuleInfo = $this->Conn->Query('SELECT * FROM '.TABLE_PREFIX.'Modules WHERE Loaded = 1 ORDER BY LoadOrder', 'Name');
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'Modules
WHERE '.$modules_helper->getWhereClause().'
ORDER BY LoadOrder';
$this->ModuleInfo = $this->Conn->Query($sql, 'Name');
$this->registerModuleConstants();
}
/**
* Checks if passed language id if valid and sets it to primary otherwise
*
*/
function VerifyLanguageId()
{
$language_id = $this->GetVar('m_lang');
if (!$language_id) {
$language_id = 'default';
}
$this->SetVar('lang.current_id', $language_id );
$this->SetVar('m_lang', $language_id );
$lang_mode = $this->GetVar('lang_mode');
$this->SetVar('lang_mode', '');
$lang =& $this->recallObject('lang.current');
if ( !$lang->IsLoaded() || (!$this->Application->IsAdmin() && !$lang->GetDBField('Enabled')) ) {
if (!defined('IS_INSTALL')) $this->ApplicationDie('Unknown or disabled language');
}
$this->SetVar('lang_mode',$lang_mode);
}
/**
* Checks if passed theme id if valid and sets it to primary otherwise
*
*/
function VerifyThemeId()
{
if ($this->Application->IsAdmin()) {
safeDefine('THEMES_PATH', '/core/admin_templates');
return;
}
$path = $this->GetFrontThemePath();
if ($path === false) {
$this->ApplicationDie('No Primary Theme Selected or Current Theme is Unknown or Disabled');
}
safeDefine('THEMES_PATH', $path);
/*
$theme_id = $this->GetVar('m_theme');
if (!$theme_id) {
$theme_id = $this->GetDefaultThemeId();
if (!$theme_id) {
if (!defined('IS_INSTALL')) $this->ApplicationDie('No Primary Theme Selected');
}
}
$this->SetVar('m_theme', $theme_id);
$this->SetVar('theme.current_id', $theme_id ); // KOSTJA: this is to fool theme' getPassedId
$theme =& $this->recallObject('theme.current');
if (!$theme->IsLoaded() || !$theme->GetDBField('Enabled')) {
if (!defined('IS_INSTALL')) $this->ApplicationDie('Unknown or disabled theme');
}
safeDefine('THEMES_PATH', '/themes/'.$theme->GetDBField('Name'));
*/
}
function GetFrontThemePath($force=0)
{
static $path=null;
if (!$force && isset($path)) return $path;
$theme_id = $this->GetVar('m_theme');
if (!$theme_id) {
$theme_id = $this->GetDefaultThemeId(1); //1 to force front-end mode!
if (!$theme_id) {
return false;
}
}
$this->SetVar('m_theme', $theme_id);
$this->SetVar('theme.current_id', $theme_id ); // KOSTJA: this is to fool theme' getPassedId
$theme =& $this->recallObject('theme.current');
if (!$theme->IsLoaded() || !$theme->GetDBField('Enabled')) {
return false;
}
$path = '/themes/'.$theme->GetDBField('Name');
return $path;
}
function GetDefaultLanguageId()
{
static $language_id = 0;
if ($language_id > 0) return $language_id;
$table = $this->getUnitOption('lang','TableName');
$id_field = $this->getUnitOption('lang','IDField');
$sql = 'SELECT '.$id_field.'
FROM '.$table.'
WHERE (PrimaryLang = 1) AND (Enabled = 1)';
$language_id = $this->Conn->GetOne($sql);
if (!$language_id && defined('IS_INSTALL') && IS_INSTALL) {
$language_id = 1;
}
return $language_id;
}
function GetDefaultThemeId($force_front=0)
{
static $theme_id = 0;
if($theme_id > 0) return $theme_id;
if (constOn('DBG_FORCE_THEME')) {
$theme_id = DBG_FORCE_THEME;
}
elseif (!$force_front && $this->IsAdmin()) {
$theme_id = 999;
}
else {
$table = $this->getUnitOption('theme','TableName');
$id_field = $this->getUnitOption('theme','IDField');
$sql = 'SELECT '.$id_field.'
FROM '.$table.'
WHERE (PrimaryTheme = 1) AND (Enabled = 1)';
$theme_id = $this->Conn->GetOne($sql);
}
return $theme_id;
}
function GetPrimaryCurrency()
{
if ($this->isModuleEnabled('In-Commerce')) {
$table = $this->getUnitOption('curr', 'TableName');
return $this->Conn->GetOne('SELECT ISO FROM '.$table.' WHERE IsPrimary = 1');
}
else {
return 'USD';
}
}
/**
* Registers default classes such as ItemController, GridController and LoginController
*
* Called automatically while initializing Application
* @access private
* @return void
*/
function RegisterDefaultClasses()
{
$this->registerClass('kTempTablesHandler', KERNEL_PATH.'/utility/temp_handler.php');
$this->registerClass('kEventManager', KERNEL_PATH.'/event_manager.php', 'EventManager');
$this->registerClass('kUnitConfigReader', KERNEL_PATH.'/utility/unit_config_reader.php');
$this->registerClass('kArray', KERNEL_PATH.'/utility/params.php');
$this->registerClass('Params', KERNEL_PATH.'/utility/params.php');
$this->registerClass('kHelper', KERNEL_PATH.'/kbase.php');
$this->registerClass('kCache', KERNEL_PATH.'/utility/cache.php', 'Cache', Array('Params'));
$this->registerClass('kHTTPQuery', KERNEL_PATH.'/utility/http_query.php', 'HTTPQuery', Array('Params') );
$this->registerClass('Session', KERNEL_PATH.'/session/session.php');
$this->registerClass('SessionStorage', KERNEL_PATH.'/session/session.php');
$this->registerClass('Params', KERNEL_PATH.'/utility/params.php', 'kActions');
$this->registerClass('kMultipleFilter', KERNEL_PATH.'/utility/filters.php');
$this->registerClass('kDBList', KERNEL_PATH.'/db/dblist.php');
$this->registerClass('kDBItem', KERNEL_PATH.'/db/dbitem.php');
$this->registerClass('kDBEventHandler', KERNEL_PATH.'/db/db_event_handler.php');
$this->registerClass('kTagProcessor', KERNEL_PATH.'/processors/tag_processor.php');
$this->registerClass('kMainTagProcessor', KERNEL_PATH.'/processors/main_processor.php','m_TagProcessor', 'kTagProcessor');
$this->registerClass('kDBTagProcessor', KERNEL_PATH.'/db/db_tag_processor.php', null, 'kTagProcessor');
$this->registerClass('TemplatesCache', KERNEL_PATH.'/parser/template.php',null, 'kDBTagProcessor');
$this->registerClass('Template', KERNEL_PATH.'/parser/template.php');
$this->registerClass('TemplateParser', KERNEL_PATH.'/parser/template_parser.php',null, 'kDBTagProcessor');
if (defined('NPARSER') && 'NPARSER') {
$this->registerClass('NParser', KERNEL_PATH.'/nparser/nparser.php');
}
$this->registerClass('kEmailSendingHelper', KERNEL_PATH.'/utility/email_send.php', 'EmailSender', Array('kHelper'));
$this->registerClass('kSocket', KERNEL_PATH.'/utility/socket.php', 'Socket');
if (file_exists(MODULES_PATH.'/in-commerce/units/currencies/currency_rates.php')) {
$this->registerClass('kCurrencyRates', MODULES_PATH.'/in-commerce/units/currencies/currency_rates.php');
}
$this->registerClass('FCKeditor', FULL_PATH.'/admin/editor/cmseditor/fckeditor.php'); // need this?
/* Moved from MyApplication */
$this->registerClass('Inp1Parser',KERNEL_PATH.'/../units/general/inp1_parser.php','Inp1Parser');
$this->registerClass('InpSession',KERNEL_PATH.'/../units/general/inp_ses_storage.php','Session');
$this->registerClass('InpSessionStorage',KERNEL_PATH.'/../units/general/inp_ses_storage.php','SessionStorage');
$this->registerClass('kCatDBItem',KERNEL_PATH.'/../units/general/cat_dbitem.php');
$this->registerClass('kCatDBItemExportHelper',KERNEL_PATH.'/../units/general/cat_dbitem_export.php', 'CatItemExportHelper');
$this->registerClass('kCatDBList',KERNEL_PATH.'/../units/general/cat_dblist.php');
$this->registerClass('kCatDBEventHandler',KERNEL_PATH.'/../units/general/cat_event_handler.php');
$this->registerClass('kCatDBTagProcessor',KERNEL_PATH.'/../units/general/cat_tag_processor.php');
// Do not move to config - this helper is used before configs are read
$this->registerClass('kModulesHelper', KERNEL_PATH.'/../units/general/helpers/modules.php', 'ModulesHelper');
/* End moved */
}
function RegisterDefaultBuildEvents()
{
$event_manager =& $this->recallObject('EventManager');
$event_manager->registerBuildEvent('kTempTablesHandler', 'OnTempHandlerBuild');
}
/**
* Returns item's filename that corresponds id passed. If possible, then get it from cache
*
* @param string $prefix
* @param int $id
* @return string
*/
function getFilename($prefix, $id, $category_id=null)
{
$filename = $this->getCache('filenames', $prefix.'_'.$id);
if ($filename === false) {
$table = $this->getUnitOption($prefix, 'TableName');
$id_field = $this->getUnitOption($prefix, 'IDField');
if ($prefix == 'c') {
if(!$id) {
$this->setCache('filenames', $prefix.'_'.$id, '');
return '';
}
// this allows to save 2 sql queries for each category
$sql = 'SELECT NamedParentPath, CachedCategoryTemplate
FROM '.$table.'
WHERE '.$id_field.' = '.$this->Conn->qstr($id);
$category_data = $this->Conn->GetRow($sql);
$filename = $category_data['NamedParentPath'];
$this->setCache('category_templates', $id, $category_data['CachedCategoryTemplate']);
// $this->setCache('item_templates', $id, $category_data['CachedItemTemplate']);
}
else {
$resource_id = $this->Conn->GetOne('SELECT ResourceId FROM '.$table.' WHERE '.$id_field.' = '.$this->Conn->qstr($id));
if (is_null($category_id)) $category_id = $this->GetVar('m_cat_id');
$sql = 'SELECT Filename FROM '.TABLE_PREFIX.'CategoryItems WHERE ItemResourceId = '.$resource_id.' AND CategoryId = '.$category_id;
$filename = $this->Conn->GetOne($sql);
/*if (!$filename) {
$sql = 'SELECT Filename FROM '.TABLE_PREFIX.'CategoryItems WHERE ItemResourceId = '.$resource_id.' AND PrimaryCat = 1';
$filename = $this->Conn->GetOne($sql);
}*/
/*$sql = 'SELECT Filename
FROM '.$table.'
WHERE '.$id_field.' = '.$this->Conn->qstr($id);
$filename = $this->Conn->GetOne($sql);*/
}
$this->setCache('filenames', $prefix.'_'.$id, $filename);
}
return $filename;
}
/**
* Adds new value to cache $cache_name and identified by key $key
*
* @param string $cache_name cache name
* @param int $key key name to add to cache
* @param mixed $value value of chached record
*/
function setCache($cache_name, $key, $value)
{
$cache =& $this->recallObject('Cache');
$cache->setCache($cache_name, $key, $value);
}
/**
* Returns cached $key value from cache named $cache_name
*
* @param string $cache_name cache name
* @param int $key key name from cache
* @return mixed
*/
function getCache($cache_name, $key)
{
$cache =& $this->recallObject('Cache');
return $cache->getCache($cache_name, $key);
}
/**
* Defines default constants if it's not defined before - in config.php
*
* @access private
*/
function SetDefaultConstants() // it's defined in startup.php - can be removed??
{
safeDefine('SERVER_NAME', $_SERVER['HTTP_HOST']);
}
/**
* Registers each module specific constants if any found
*
*/
function registerModuleConstants()
{
if (file_exists(KERNEL_PATH.'/constants.php')) {
k4_include_once(KERNEL_PATH.'/constants.php');
}
if (!$this->ModuleInfo) return false;
foreach($this->ModuleInfo as $module_name => $module_info)
{
$module_path = '/'.$module_info['Path'];
$contants_file = FULL_PATH.$module_path.'constants.php';
if( file_exists($contants_file) ) k4_include_once($contants_file);
}
return true;
}
function ProcessRequest()
{
$event_manager =& $this->recallObject('EventManager');
/* @var $event_manager kEventManager */
if($this->isDebugMode() && constOn('DBG_SHOW_HTTPQUERY')) {
$this->Debugger->appendHTML('HTTPQuery:');
$this->Debugger->dumpVars($this->HttpQuery->_Params);
}
$event_manager->ProcessRequest();
$event_manager->RunRegularEvents(reBEFORE);
$this->RequestProcessed = true;
}
/**
* Actually runs the parser against current template and stores parsing result
*
* This method gets t variable passed to the script, loads the template given in t variable and
* parses it. The result is store in {@link $this->HTML} property.
* @access public
* @return void
*/
function Run()
{
if($this->isDebugMode() && constOn('DBG_PROFILE_MEMORY')) {
$this->Debugger->appendMemoryUsage('Application before Run:');
}
if ($this->IsAdmin()) {
// for permission checking in events & templates
$this->LinkVar('module'); // for common configuration templates
$this->LinkVar('section'); // for common configuration templates
if ($this->GetVar('m_opener') == 'p') {
$this->LinkVar('main_prefix'); // window prefix, that opened selector
$this->LinkVar('dst_field'); // field to set value choosed in selector
// $this->LinkVar('return_template'); // template to go, when something was coosen from popup (from finalizePopup)
// $this->LinkVar('return_m'); // main env part to restore after popup will be closed (from finalizePopup)
}
if ($this->GetVar('ajax') == 'yes' && !$this->GetVar('debug_ajax')) {
// hide debug output from ajax requests automatically
define('DBG_SKIP_REPORTING', 1);
}
}
if (!$this->RequestProcessed) $this->ProcessRequest();
$this->InitParser();
$t = $this->GetVar('t');
if ($this->isModuleEnabled('In-Edit')) {
$cms_handler =& $this->recallObject('cms_EventHandler');
if (!$this->TemplatesCache->TemplateExists($t) && !$this->IsAdmin()) {
$t = $cms_handler->GetDesignTemplate();
}
/*else {
$cms_handler->SetCatByTemplate();
}*/
}
if ($this->isModuleEnabled('Proj-CMS')) {
$cms_handler =& $this->recallObject('st_EventHandler');
if (!$this->TemplatesCache->TemplateExists($t) && !$this->IsAdmin()) {
$t = $cms_handler->GetDesignTemplate();
}
}
if($this->isDebugMode() && constOn('DBG_PROFILE_MEMORY')) {
$this->Debugger->appendMemoryUsage('Application before Parsing:');
}
if (defined('NPARSER') && 'NPARSER') {
$this->HTML = $this->NParser->Run( $t );
}
else {
$this->HTML = $this->Parser->ParseTemplate( $t );
}
if ($this->isDebugMode() && constOn('DBG_PROFILE_MEMORY')) {
$this->Debugger->appendMemoryUsage('Application after Parsing:');
}
}
function InitParser()
{
if (defined('NPARSER') && 'NPARSER') {
if( !is_object($this->NParser) ) {
$this->NParser =& $this->recallObject('NParser');
$this->TemplatesCache =& $this->recallObject('TemplatesCache');
// can be removed in future
// $this->Parser =& $this->recallObject('TemplateParser');
$this->Parser =& $this->NParser;
}
}
else {
if( !is_object($this->Parser) ) {
$this->Parser =& $this->recallObject('TemplateParser');
$this->TemplatesCache =& $this->recallObject('TemplatesCache');
}
}
}
/**
* Send the parser results to browser
*
* Actually send everything stored in {@link $this->HTML}, to the browser by echoing it.
* @access public
* @return void
*/
function Done()
{
+ $this->HandleEvent( new kEvent('adm:OnBeforeShutdown') );
if ($this->isDebugMode() && constOn('DBG_PROFILE_MEMORY')) {
$this->Debugger->appendMemoryUsage('Application before Done:');
}
if ($this->GetVar('admin')) {
$reg = '/('.preg_quote(BASE_PATH, '/').'.*\.html)(#.*){0,1}(")/sU';
$this->HTML = preg_replace($reg, "$1?admin=1$2$3", $this->HTML);
}
//eval("?".">".$this->HTML);
if ($this->isDebugMode()) {
$this->EventManager->RunRegularEvents(reAFTER);
$this->Session->SaveData();
$this->HTML = ob_get_clean() . $this->HTML . $this->Debugger->printReport(true);
}
else {
$this->HTML = ob_get_clean().$this->HTML;
}
if ($this->UseOutputCompression()) {
header('Content-Encoding: gzip');
$compression_level = $this->ConfigValue('OutputCompressionLevel');
if ($compression_level < 0 || $compression_level > 9) $compression_level = 7;
echo gzencode($this->HTML, $compression_level);
}
else {
echo $this->HTML;
}
$this->UpdateCache();
flush();
if ($this->isDebugMode() && constOn('DBG_CACHE')) {
$cache =& $this->recallObject('Cache');
$cache->printStatistics();
}
$this->EventManager->RunRegularEvents(reAFTER);
$this->Session->SaveData();
}
/**
* Checks if output compression options is available
*
* @return string
*/
function UseOutputCompression()
{
if (constOn('IS_INSTALL') || constOn('DBG_ZEND_PRESENT') || constOn('SKIP_OUT_COMPRESSION')) return false;
return $this->ConfigValue('UseOutputCompression') && function_exists('gzencode') && strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip');
}
// Facade
/**
* Returns current session id (SID)
* @access public
* @return longint
*/
function GetSID()
{
$session =& $this->recallObject('Session');
return $session->GetID();
}
function DestroySession()
{
$session =& $this->recallObject('Session');
$session->Destroy();
}
/**
* Returns variable passed to the script as GET/POST/COOKIE
*
* @access public
* @param string $name Name of variable to retrieve
* @param int $default default value returned in case if varible not present
* @return mixed
*/
function GetVar($name, $default = false)
{
// $http_query =& $this->recallObject('HTTPQuery');
return isset($this->HttpQuery->_Params[$name]) ? $this->HttpQuery->_Params[$name] : $default;
}
/**
* Returns ALL variables passed to the script as GET/POST/COOKIE
*
* @access public
* @return array
*/
function GetVars()
{
return $this->HttpQuery->GetParams();
}
/**
* Set the variable 'as it was passed to the script through GET/POST/COOKIE'
*
* This could be useful to set the variable when you know that
* other objects would relay on variable passed from GET/POST/COOKIE
* or you could use SetVar() / GetVar() pairs to pass the values between different objects.<br>
*
* This method is formerly known as $this->Session->SetProperty.
* @param string $var Variable name to set
* @param mixed $val Variable value
* @access public
* @return void
*/
function SetVar($var,$val)
{
// $http_query =& $this->recallObject('HTTPQuery');
return $this->HttpQuery->Set($var, $val);
}
/**
* Deletes kHTTPQuery variable
*
* @param string $var
* @todo think about method name
*/
function DeleteVar($var)
{
return $this->HttpQuery->Remove($var);
}
/**
* Deletes Session variable
*
* @param string $var
*/
function RemoveVar($var)
{
return $this->Session->RemoveVar($var);
}
function RemovePersistentVar($var)
{
return $this->Session->RemovePersistentVar($var);
}
/**
* Restores Session variable to it's db version
*
* @param string $var
*/
function RestoreVar($var)
{
return $this->Session->RestoreVar($var);
}
/**
* Returns session variable value
*
* Return value of $var variable stored in Session. An optional default value could be passed as second parameter.
*
* @see SimpleSession
* @access public
* @param string $var Variable name
* @param mixed $default Default value to return if no $var variable found in session
* @return mixed
*/
function RecallVar($var,$default=false)
{
return $this->Session->RecallVar($var,$default);
}
function RecallPersistentVar($var, $default = false)
{
return $this->Session->RecallPersistentVar($var, $default);
}
/**
* Stores variable $val in session under name $var
*
* Use this method to store variable in session. Later this variable could be recalled.
* @see RecallVar
* @access public
* @param string $var Variable name
* @param mixed $val Variable value
*/
function StoreVar($var, $val)
{
$session =& $this->recallObject('Session');
$this->Session->StoreVar($var, $val);
}
function StorePersistentVar($var, $val)
{
$this->Session->StorePersistentVar($var, $val);
}
function StoreVarDefault($var, $val)
{
$session =& $this->recallObject('Session');
$this->Session->StoreVarDefault($var, $val);
}
/**
* Links HTTP Query variable with session variable
*
* If variable $var is passed in HTTP Query it is stored in session for later use. If it's not passed it's recalled from session.
* This method could be used for making sure that GetVar will return query or session value for given
* variable, when query variable should overwrite session (and be stored there for later use).<br>
* This could be used for passing item's ID into popup with multiple tab -
* in popup script you just need to call LinkVar('id', 'current_id') before first use of GetVar('id').
* After that you can be sure that GetVar('id') will return passed id or id passed earlier and stored in session
* @access public
* @param string $var HTTP Query (GPC) variable name
* @param mixed $ses_var Session variable name
* @param mixed $default Default variable value
*/
function LinkVar($var, $ses_var = null, $default = '')
{
if (!isset($ses_var)) $ses_var = $var;
if ($this->GetVar($var) !== false) {
$this->StoreVar($ses_var, $this->GetVar($var));
}
else {
$this->SetVar($var, $this->RecallVar($ses_var, $default));
}
}
/**
* Returns variable from HTTP Query, or from session if not passed in HTTP Query
*
* The same as LinkVar, but also returns the variable value taken from HTTP Query if passed, or from session if not passed.
* Returns the default value if variable does not exist in session and was not passed in HTTP Query
*
* @see LinkVar
* @access public
* @param string $var HTTP Query (GPC) variable name
* @param mixed $ses_var Session variable name
* @param mixed $default Default variable value
* @return mixed
*/
function GetLinkedVar($var, $ses_var = null, $default = '')
{
$this->LinkVar($var, $ses_var, $default);
return $this->GetVar($var);
}
function AddBlock($name, $tpl)
{
$this->cache[$name] = $tpl;
}
/* Seems to be not used anywhere... /Kostja
function SetTemplateBody($title,$body)
{
$templates_cache =& $this->recallObject('TemplatesCache');
$templates_cache->SetTemplateBody($title,$body);
}*/
function ProcessTag($tag_data)
{
$a_tag = new Tag($tag_data,$this->Parser);
return $a_tag->DoProcessTag();
}
function ProcessParsedTag($prefix, $tag, $params)
{
if (defined('NPARSER') && NPARSER) {
$p = $this->Parser->GetProcessor($prefix);
return $p->ProcessParsedTag($tag, $params, $prefix);
}
$a_tag = new Tag('',$this->Parser);
$a_tag->Tag = $tag;
$tmp=$this->Application->processPrefix($prefix);
$a_tag->Processor = $tmp['prefix'];
$a_tag->Special = $tmp['special'];
$a_tag->NamedParams = $params;
return $a_tag->DoProcessTag();
}
/**
* Return ADODB Connection object
*
* Returns ADODB Connection object already connected to the project database, configurable in config.php
* @access public
* @return kDBConnection
*/
function &GetADODBConnection()
{
return $this->Conn;
}
function ParseBlock($params,$pass_params=0,$as_template=false)
{
if (substr($params['name'], 0, 5) == 'html:') return substr($params['name'], 6);
return $this->Parser->ParseBlock($params, $pass_params, $as_template);
}
/**
* Returns index file, that could be passed as parameter to method, as parameter to tag and as constant or not passed at all
*
* @param string $prefix
* @param string $index_file
* @param Array $params
* @return string
*/
function getIndexFile($prefix, $index_file, &$params)
{
if (isset($params['index_file'])) {
$index_file = $params['index_file'];
unset($params['index_file']);
return $index_file;
}
if (isset($index_file)) {
return $index_file;
}
if (defined('INDEX_FILE')) {
return INDEX_FILE;
}
$cut_prefix = trim(BASE_PATH, '/').'/'.trim($prefix, '/');
return trim(preg_replace('/'.preg_quote($cut_prefix, '/').'(.*)/', '\\1', $_SERVER['PHP_SELF']), '/');
}
/**
* Return href for template
*
* @access public
* @param string $t Template path
* @var string $prefix index.php prefix - could be blank, 'admin'
*/
function HREF($t, $prefix='', $params=null, $index_file=null)
{
if(!$t) $t = $this->GetVar('t'); // moved from kMainTagProcessor->T()
if ($this->isModuleEnabled('Proj-CMS')) {
$t = preg_replace('/^Content\//', '', $t);
}
/*if ($this->GetVar('skip_last_template')) {
$params['opener'] = 'p';
$this->SetVar('m_opener', 'p');
}
if ($t == 'incs/close_popup') {
// because this template closes the popup and we don't need popup mark here anymore
$params['m_opener'] = 's';
}*/
if( substr($t, -4) == '.tpl' ) $t = substr($t, 0, strlen($t) - 4 );
if ( $this->IsAdmin() && $prefix == '') $prefix = ADMIN_DIRECTORY;
if ( $this->IsAdmin() && $prefix == '_FRONT_END_') $prefix = '';
$index_file = $this->getIndexFile($prefix, $index_file, $params);
if (isset($params['_auto_prefix_'])) {
unset($params['_auto_prefix_']); // this is parser-related param, do not need to pass it here
}
$ssl = isset($params['__SSL__']) ? $params['__SSL__'] : null;
if ($ssl !== null) {
$session =& $this->recallObject('Session');
$cookie_url = trim($session->CookieDomain.$session->CookiePath, '/.');
if ($ssl) {
$target_url = $this->ConfigValue('SSL_URL');
}
else {
$target_url = 'http://'.DOMAIN.$this->ConfigValue('Site_Path');
}
if (!preg_match('#'.preg_quote($cookie_url).'#', $target_url)) {
$session->SetMode(smGET_ONLY);
}
}
if (isset($params['opener']) && $params['opener'] == 'u') {
$wid = $this->Application->GetVar('m_wid');
$stack_name = rtrim('opener_stack_'.$wid, '_');
$opener_stack = $this->RecallVar($stack_name);
if ($opener_stack && $opener_stack != serialize(Array())) {
$opener_stack = unserialize($opener_stack);
list($index_file, $env) = explode('|', $opener_stack[count($opener_stack) - 1]);
$ret = $this->BaseURL($prefix, $ssl).$index_file.'?'.ENV_VAR_NAME.'='.$env;
if ( getArrayValue($params,'escape') ) $ret = addslashes($ret);
if (isset($params['m_opener']) && $params['m_opener'] == 'u') {
array_pop($opener_stack);
if (!$opener_stack) {
$this->RemoveVar($stack_name);
// remove popups last templates, because popup is closing now
$this->RemoveVar('last_template_'.$wid);
$this->RemoveVar('last_template_popup_'.$wid);
// don't save popups last templates again :)
$this->SetVar('skip_last_template', 1);
}
else {
$this->StoreVar($stack_name, serialize($opener_stack));
}
}
return $ret;
}
else {
//define('DBG_REDIRECT', 1);
$t = $this->GetVar('t');
}
}
$pass = isset($params['pass']) ? $params['pass'] : '';
$pass_events = isset($params['pass_events']) ? $params['pass_events'] : false; // pass events with url
$map_link = '';
if( isset($params['anchor']) )
{
$map_link = '#'.$params['anchor'];
unset($params['anchor']);
}
if ( isset($params['no_amp']) )
{
$params['__URLENCODE__'] = $params['no_amp'];
unset($params['no_amp']);
}
$no_rewrite = false;
if( isset($params['__NO_REWRITE__']) )
{
$no_rewrite = true;
unset($params['__NO_REWRITE__']);
}
$force_rewrite = false;
if( isset($params['__MOD_REWRITE__']) )
{
$force_rewrite = true;
unset($params['__MOD_REWRITE__']);
}
$force_no_sid = false;
if( isset($params['__NO_SID__']) )
{
$force_no_sid = true;
unset($params['__NO_SID__']);
}
// append pass through variables to each link to be build
// $params = array_merge_recursive2($this->getPassThroughVariables($params), $params);
$params = array_merge($this->getPassThroughVariables($params), $params);
if ($force_rewrite || ($this->RewriteURLs($ssl) && !$no_rewrite))
{
$session =& $this->recallObject('Session');
if( $session->NeedQueryString() && !$force_no_sid ) $params['sid'] = $this->GetSID();
$url = $this->BuildEnv_NEW($t, $params, $pass, $pass_events);
$ret = $this->BaseURL($prefix, $ssl).$url.$map_link;
}
else
{
unset($params['pass_category']); // we don't need to pass it when mod_rewrite is off
$env = $this->BuildEnv($t, $params, $pass, $pass_events);
$ret = $this->BaseURL($prefix, $ssl).$index_file.'?'.$env.$map_link;
}
return $ret;
}
/**
* Returns variables with values that should be passed throught with this link + variable list
*
* @param Array $params
* @return Array
*/
function getPassThroughVariables(&$params)
{
static $cached_pass_through = null;
if (isset($params['no_pass_through']) && $params['no_pass_through']) {
unset($params['no_pass_through']);
return Array();
}
// because pass through is not changed during script run, then we can cache it
if (is_null($cached_pass_through)) {
$cached_pass_through = Array();
$pass_through = $this->Application->GetVar('pass_through');
if ($pass_through) {
// names of variables to pass to each link
$cached_pass_through['pass_through'] = $pass_through;
$pass_through = explode(',', $pass_through);
foreach ($pass_through as $pass_through_var) {
$cached_pass_through[$pass_through_var] = $this->Application->GetVar($pass_through_var);
}
}
}
return $cached_pass_through;
}
/**
* Returns sorted array of passed prefixes (to build url from)
*
* @param string $pass
* @return Array
*/
function getPassInfo($pass = 'all')
{
if (!$pass) $pass = 'all';
$pass = trim(
preg_replace(
'/(?<=,|\\A)all(?=,|\\z)/',
trim($this->GetVar('passed'), ','),
trim($pass, ',')
),
',');
if (!$pass) {
return Array();
}
$pass_info = array_unique( explode(',', $pass) ); // array( prefix[.special], prefix[.special] ...
sort($pass_info, SORT_STRING); // to be prefix1,prefix1.special1,prefix1.special2,prefix3.specialX
// ensure that "m" prefix is at the beginning
$main_index = array_search('m', $pass_info);
if ($main_index !== false) {
unset($pass_info[$main_index]);
array_unshift($pass_info, 'm');
}
return $pass_info;
}
function BuildEnv_NEW($t, $params, $pass='all', $pass_events = false)
{
// $session =& $this->recallObject('Session');
$force_admin = getArrayValue($params,'admin') || $this->GetVar('admin');
// if($force_admin) $sid = $this->GetSID();
$ret = '';
$env = '';
$encode = false;
if (isset($params['__URLENCODE__']))
{
$encode = $params['__URLENCODE__'];
unset($params['__URLENCODE__']);
}
if (isset($params['__SSL__'])) {
unset($params['__SSL__']);
}
$m_only = true;
$pass_info = $this->getPassInfo($pass);
if ($pass_info) {
if ($pass_info[0] == 'm') array_shift($pass_info);
$params['t'] = $t;
foreach($pass_info as $pass_index => $pass_element)
{
list($prefix) = explode('.', $pass_element);
$require_rewrite = $this->findModule('Var', $prefix) && $this->getUnitOption($prefix, 'CatalogItem');
if ($require_rewrite) {
// if next prefix is same as current, but with special => exclude current prefix from url
$next_prefix = getArrayValue($pass_info, $pass_index + 1);
if ($next_prefix) {
$next_prefix = substr($next_prefix, 0, strlen($prefix) + 1);
if ($prefix.'.' == $next_prefix) continue;
}
$a = $this->BuildModuleEnv_NEW($pass_element, $params, $pass_events);
if ($a) {
$ret .= '/'.$a;
$m_only = false;
}
}
else
{
$env .= ':'.$this->BuildModuleEnv($pass_element, $params, $pass_events);
}
}
if (!$m_only) $params['pass_category'] = 1;
$ret = $this->BuildModuleEnv_NEW('m', $params, $pass_events).$ret;
$cat_processed = isset($params['category_processed']) && $params['category_processed'];
if ($cat_processed) {
unset($params['category_processed']);
}
if (!$m_only || !$cat_processed || !defined('EXP_DIR_URLS')) {
$ret = trim($ret, '/').'.html';
}
else {
$ret .= '/';
}
// $ret = trim($ret, '/').'/';
if($env) $params[ENV_VAR_NAME] = ltrim($env, ':');
}
unset($params['pass'], $params['opener'], $params['m_event']);
if ($force_admin) $params['admin'] = 1;
if( getArrayValue($params,'escape') )
{
$ret = addslashes($ret);
unset($params['escape']);
}
$ret = str_replace('%2F', '/', urlencode($ret));
$params_str = '';
$join_string = $encode ? '&' : '&amp;';
foreach ($params as $param => $value)
{
$params_str .= $join_string.$param.'='.$value;
}
$ret .= preg_replace('/^'.$join_string.'(.*)/', '?\\1', $params_str);
if ($encode) {
$ret = str_replace('\\', '%5C', $ret);
}
return $ret;
}
function BuildModuleEnv_NEW($prefix_special, &$params, $pass_events = false)
{
$event_params = Array('pass_events' => $pass_events, 'url_params' => $params);
$event = new kEvent($prefix_special.':BuildEnv', $event_params);
$this->HandleEvent($event);
$params = $event->getEventParam('url_params'); // save back unprocessed parameters
$ret = '';
if ($event->getEventParam('env_string')) {
$ret = trim( $event->getEventParam('env_string'), '/');
}
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
*/
function BuildModuleEnv($prefix_special, &$params, $pass_events = false)
{
list($prefix) = explode('.', $prefix_special);
$query_vars = $this->getUnitOption($prefix, 'QueryString');
//if pass events is off and event is not implicity passed
if( !$pass_events && !isset($params[$prefix_special.'_event']) ) {
$params[$prefix_special.'_event'] = ''; // remove event from url if requested
//otherwise it will use value from get_var
}
if(!$query_vars) return '';
$tmp_string = Array(0 => $prefix_special);
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;
$tmp_string[$index] = isset( $params[$var_name] ) ? $params[$var_name] : $this->GetVar($var_name);
if ( isset($params[$var_name]) ) unset( $params[$var_name] );
}
$escaped = array();
foreach ($tmp_string as $tmp_val) {
$escaped[] = str_replace(Array('-',':'), Array('\-','\:'), $tmp_val);
}
$ret = implode('-', $escaped);
if ($this->getUnitOption($prefix, 'PortalStyleEnv') == true)
{
$ret = preg_replace('/^([a-zA-Z]+)-([0-9]+)-(.*)/','\\1\\2-\\3', $ret);
}
return $ret;
}
function BuildEnv($t, $params, $pass='all', $pass_events = false, $env_var = true)
{
$session =& $this->recallObject('Session');
$ssl = isset($params['__SSL__']) ? $params['__SSL__'] : 0;
$sid = $session->NeedQueryString() && !$this->RewriteURLs($ssl) ? $this->GetSID() : '';
// if (getArrayValue($params,'admin') == 1) $sid = $this->GetSID();
$ret = '';
if ($env_var) {
$ret = ENV_VAR_NAME.'=';
}
$ret .= $sid.(constOn('INPORTAL_ENV') ? '-' : ':');
$encode = false;
if (isset($params['__URLENCODE__'])) {
$encode = $params['__URLENCODE__'];
unset($params['__URLENCODE__']);
}
if (isset($params['__SSL__'])) {
unset($params['__SSL__']);
}
$env_string = '';
$category_id = isset($params['m_cat_id']) ? $params['m_cat_id'] : $this->GetVar('m_cat_id');
$item_id = 0;
$pass_info = $this->getPassInfo($pass);
if ($pass_info) {
if ($pass_info[0] == 'm') array_shift($pass_info);
foreach ($pass_info as $pass_element) {
list($prefix) = explode('.', $pass_element);
$require_rewrite = $this->findModule('Var', $prefix);
if ($require_rewrite) {
$item_id = isset($params[$pass_element.'_id']) ? $params[$pass_element.'_id'] : $this->GetVar($pass_element.'_id');
}
$env_string .= ':'.$this->BuildModuleEnv($pass_element, $params, $pass_events);
}
}
if (strtolower($t) == '__default__') {
// to put category & item templates into cache
$filename = $this->getFilename('c', $category_id);
if ($item_id) {
$mod_rw_helper =& $this->Application->recallObject('ModRewriteHelper');
$t = $mod_rw_helper->GetItemTemplate($category_id, $pass_element); // $pass_element should be the last processed element
// $t = $this->getCache('item_templates', $category_id);
}
elseif ($category_id) {
$t = $this->getCache('category_templates', $category_id);
}
else {
$t = 'index';
}
}
$ret .= $t.':'.$this->BuildModuleEnv('m', $params, $pass_events).$env_string;
unset($params['pass'], $params['opener'], $params['m_event']);
if ($this->GetVar('admin') && !isset($params['admin'])) {
$params['admin'] = 1;
}
if( isset($params['escape']) && $params['escape'] )
{
$ret = addslashes($ret);
unset($params['escape']);
}
$join_string = $encode ? '&' : '&amp;';
$params_str = '';
foreach ($params as $param => $value)
{
$params_str .= $join_string.$param.'='.$value;
}
$ret .= $params_str;
if ($encode) {
$ret = str_replace('\\', '%5C', $ret);
}
return $ret;
}
function BaseURL($prefix='', $ssl=null)
{
if ($ssl === null) {
return PROTOCOL.SERVER_NAME.(defined('PORT')?':'.PORT : '').rtrim(BASE_PATH, '/').$prefix.'/';
}
else {
if ($ssl) {
return rtrim( $this->ConfigValue('SSL_URL'), '/').$prefix.'/';
}
else {
return 'http://'.DOMAIN.(defined('PORT')?':'.PORT : '').rtrim( $this->ConfigValue('Site_Path'), '/').$prefix.'/';
}
}
}
function Redirect($t='', $params=null, $prefix='', $index_file=null)
{
$js_redirect = getArrayValue($params, 'js_redirect');
if (preg_match("/external:(.*)/", $t, $rets)) {
$location = $rets[1];
}
else {
if ($t == '' || $t === true) $t = $this->GetVar('t');
// pass prefixes and special from previous url
if( isset($params['js_redirect']) ) unset($params['js_redirect']);
if (!isset($params['pass'])) $params['pass'] = 'all';
if ($this->GetVar('ajax') == 'yes' && $t == $this->GetVar('t')) {
// redirects to the same template as current
$params['ajax'] = 'yes';
}
$params['__URLENCODE__'] = 1;
$location = $this->HREF($t, $prefix, $params, $index_file);
//echo " location : $location <br>";
}
$a_location = $location;
$location = "Location: $location";
if ($this->isDebugMode() && constOn('DBG_REDIRECT')) {
$this->Debugger->appendTrace();
echo "<b>Debug output above!!!</b> Proceed to redirect: <a href=\"$a_location\">$a_location</a><br>";
}
else {
if ($js_redirect) {
$this->SetVar('t', 'redirect');
$this->SetVar('redirect_to_js', addslashes($a_location) );
$this->SetVar('redirect_to', $a_location);
return true;
}
else {
if ($this->GetVar('ajax') == 'yes' && $t != $this->GetVar('t')) {
// redirection to other then current template during ajax request
echo '#redirect#'.$a_location;
}
elseif (headers_sent() != '') {
// some output occured -> redirect using javascript
echo '<script type="text/javascript">window.location.href = \''.$a_location.'\';</script>';
}
else {
// no output before -> redirect using HTTP header
// header('HTTP/1.1 302 Found');
header("$location");
}
}
}
ob_end_flush();
// session expiration is called from session initialization,
// that's why $this->Session may be not defined here
$session =& $this->Application->recallObject('Session');
/* @var $session Session */
+ $this->HandleEvent( new kEvent('adm:OnBeforeShutdown') );
$session->SaveData();
exit;
}
function Phrase($label)
{
return $this->Phrases->GetPhrase($label);
}
/**
* Replace language tags in exclamation marks found in text
*
* @param string $text
* @param bool $force_escape force escaping, not escaping of resulting string
* @return string
* @access public
*/
function ReplaceLanguageTags($text, $force_escape=null)
{
// !!!!!!!!
// if( !is_object($this->Phrases) ) $this->Debugger->appendTrace();
return $this->Phrases->ReplaceLanguageTags($text,$force_escape);
}
/**
* Checks if user is logged in, and creates
* user object if so. User object can be recalled
* later using "u.current" prefix_special. Also you may
* get user id by getting "u.current_id" variable.
*
* @access private
*/
function ValidateLogin()
{
$session =& $this->recallObject('Session');
$user_id = $session->GetField('PortalUserId');
if (!$user_id && $user_id != -1) $user_id = -2;
$this->SetVar('u.current_id', $user_id);
if (!$this->IsAdmin()) {
// needed for "profile edit", "registration" forms ON FRONT ONLY
$this->SetVar('u_id', $user_id);
}
$this->StoreVar('user_id', $user_id);
if ($this->GetVar('expired') == 1) {
// this parameter is set only from admin
$user =& $this->recallObject('u.current');
$user->SetError('ValidateLogin', 'session_expired', 'la_text_sess_expired');
}
if (($user_id != -2) && constOn('DBG_REQUREST_LOG') ) {
$http_query =& $this->recallObject('HTTPQuery');
$http_query->writeRequestLog(DBG_REQUREST_LOG);
}
if ($user_id != -2) {
// normal users + root
$this->LoadPersistentVars();
}
}
/**
* Loads current user persistent session data
*
*/
function LoadPersistentVars()
{
$this->Session->LoadPersistentVars();
}
function LoadCache() {
$cache_key = $this->GetVar('t').$this->GetVar('m_theme').$this->GetVar('m_lang').$this->IsAdmin();
$query = sprintf("SELECT PhraseList, ConfigVariables FROM %s WHERE Template = %s",
TABLE_PREFIX.'PhraseCache',
$this->Conn->Qstr(md5($cache_key)));
$res = $this->Conn->GetRow($query);
if ($res) {
$this->Caches['PhraseList'] = $res['PhraseList'] ? explode(',', $res['PhraseList']) : array();
$config_ids = $res['ConfigVariables'] ? explode(',', $res['ConfigVariables']) : array();
if (isset($this->Caches['ConfigVariables'])) {
$config_ids = array_diff($config_ids, $this->Caches['ConfigVariables']);
}
}
else {
$config_ids = array();
}
$this->Caches['ConfigVariables'] = $config_ids;
$this->ConfigCacheIds = $config_ids;
}
function UpdateCache()
{
$update = false;
//something changed
$update = $update || $this->Phrases->NeedsCacheUpdate();
$update = $update || (count($this->ConfigCacheIds) && $this->ConfigCacheIds != $this->Caches['ConfigVariables']);
if ($update) {
$cache_key = $this->GetVar('t').$this->GetVar('m_theme').$this->GetVar('m_lang').$this->IsAdmin();
$query = sprintf("REPLACE %s (PhraseList, CacheDate, Template, ConfigVariables)
VALUES (%s, %s, %s, %s)",
TABLE_PREFIX.'PhraseCache',
$this->Conn->Qstr(join(',', $this->Phrases->Ids)),
adodb_mktime(),
$this->Conn->Qstr(md5($cache_key)),
$this->Conn->qstr(implode(',', array_unique($this->ConfigCacheIds))));
$this->Conn->Query($query);
}
}
function InitConfig()
{
if (isset($this->Caches['ConfigVariables']) && count($this->Caches['ConfigVariables']) > 0) {
$this->ConfigHash = array_merge($this->ConfigHash, $this->Conn->GetCol(
'SELECT VariableValue, VariableName FROM '.TABLE_PREFIX.'ConfigurationValues
WHERE VariableId IN ('.implode(',', $this->Caches['ConfigVariables']).')', 'VariableName'));
}
}
/**
* Returns configuration option value by name
*
* @param string $name
* @return string
*/
function ConfigValue($name)
{
$res = isset($this->ConfigHash[$name]) ? $this->ConfigHash[$name] : false;
if ($res !== false) return $res;
if (defined('IS_INSTALL') && IS_INSTALL && !$this->TableFound('ConfigurationValues')) {
return false;
}
$res = $this->Conn->GetRow('SELECT VariableId, VariableValue FROM '.TABLE_PREFIX.'ConfigurationValues WHERE VariableName = '.$this->Conn->qstr($name));
if ($res) {
$this->ConfigHash[$name] = $res['VariableValue'];
$this->ConfigCacheIds[] = $res['VariableId'];
return $res['VariableValue'];
}
return false;
}
function UpdateConfigCache()
{
if ($this->ConfigCacheIds) {
}
}
/**
* Allows to process any type of event
*
* @param kEvent $event
* @access public
* @author Alex
*/
function HandleEvent(&$event, $params=null, $specificParams=null)
{
if ( isset($params) ) {
$event = new kEvent( $params, $specificParams );
}
if (!isset($this->EventManager)) {
$this->EventManager =& $this->recallObject('EventManager');
}
$this->EventManager->HandleEvent($event);
}
/**
* Registers new class in the factory
*
* @param string $real_class Real name of class as in class declaration
* @param string $file Filename in what $real_class is declared
* @param string $pseudo_class Name under this class object will be accessed using getObject method
* @param Array $dependecies List of classes required for this class functioning
* @access public
* @author Alex
*/
function registerClass($real_class, $file, $pseudo_class = null, $dependecies = Array() )
{
$this->Factory->registerClass($real_class, $file, $pseudo_class, $dependecies);
}
/**
* Add $class_name to required classes list for $depended_class class.
* All required class files are included before $depended_class file is included
*
* @param string $depended_class
* @param string $class_name
* @author Alex
*/
function registerDependency($depended_class, $class_name)
{
$this->Factory->registerDependency($depended_class, $class_name);
}
/**
* Registers Hook from subprefix event to master prefix event
*
* @param string $hookto_prefix
* @param string $hookto_special
* @param string $hookto_event
* @param string $mode
* @param string $do_prefix
* @param string $do_special
* @param string $do_event
* @param string $conditional
* @access public
* @todo take care of a lot parameters passed
* @author Kostja
*/
function registerHook($hookto_prefix, $hookto_special, $hookto_event, $mode, $do_prefix, $do_special, $do_event, $conditional)
{
$event_manager =& $this->recallObject('EventManager');
$event_manager->registerHook($hookto_prefix, $hookto_special, $hookto_event, $mode, $do_prefix, $do_special, $do_event, $conditional);
}
/**
* Allows one TagProcessor tag act as other TagProcessor tag
*
* @param Array $tag_info
* @author Kostja
*/
function registerAggregateTag($tag_info)
{
$aggregator =& $this->recallObject('TagsAggregator', 'kArray');
$aggregator->SetArrayValue($tag_info['AggregateTo'], $tag_info['AggregatedTagName'], Array($tag_info['LocalPrefix'], $tag_info['LocalTagName'], getArrayValue($tag_info, 'LocalSpecial')));
}
/**
* Returns object using params specified,
* creates it if is required
*
* @param string $name
* @param string $pseudo_class
* @param Array $event_params
* @return Object
* @author Alex
*/
function &recallObject($name,$pseudo_class=null,$event_params=Array())
{
$result =& $this->Factory->getObject($name, $pseudo_class, $event_params);
return $result;
}
/**
* Returns object using Variable number of params,
* all params starting with 4th are passed to object consturctor
*
* @param string $name
* @param string $pseudo_class
* @param Array $event_params
* @return Object
* @author Alex
*/
function &recallObjectP($name,$pseudo_class=null,$event_params=Array())
{
$func_args = func_get_args();
$result =& ref_call_user_func_array( Array(&$this->Factory, 'getObjectP'), $func_args );
return $result;
}
/**
* Returns tag processor for prefix specified
*
* @param string $prefix
* @return kDBTagProcessor
*/
function &recallTagProcessor($prefix)
{
$this->InitParser(); // because kDBTagProcesor is in TemplateParser dependencies
$result =& $this->recallObject($prefix.'_TagProcessor');
return $result;
}
/**
* Checks if object with prefix passes was already created in factory
*
* @param string $name object presudo_class, prefix
* @return bool
* @author Kostja
*/
function hasObject($name)
{
return isset($this->Factory->Storage[$name]);
}
/**
* Removes object from storage by given name
*
* @param string $name Object's name in the Storage
* @author Kostja
*/
function removeObject($name)
{
$this->Factory->DestroyObject($name);
}
/**
* Get's real class name for pseudo class,
* includes class file and creates class
* instance
*
* @param string $pseudo_class
* @return Object
* @access public
* @author Alex
*/
function &makeClass($pseudo_class)
{
$func_args = func_get_args();
$result =& ref_call_user_func_array( Array(&$this->Factory, 'makeClass'), $func_args);
return $result;
}
/**
* Checks if application is in debug mode
*
* @param bool $check_debugger check if kApplication debugger is initialized too, not only for defined DEBUG_MODE constant
* @return bool
* @author Alex
* @access public
*/
function isDebugMode($check_debugger = true)
{
$debug_mode = defined('DEBUG_MODE') && DEBUG_MODE;
if ($check_debugger) {
$debug_mode = $debug_mode && is_object($this->Debugger);
}
return $debug_mode;
}
/**
* Checks if it is admin
*
* @return bool
* @author Alex
*/
function IsAdmin()
{
return constOn('ADMIN');
}
/**
* Apply url rewriting used by mod_rewrite or not
*
* @param bool $ssl Force ssl link to be build
* @return bool
*/
function RewriteURLs($ssl = false)
{
// case #1,#4:
// we want to create https link from http mode
// we want to create https link from https mode
// conditions: ($ssl || PROTOCOL == 'https://') && $this->ConfigValue('UseModRewriteWithSSL')
// case #2,#3:
// we want to create http link from https mode
// we want to create http link from http mode
// conditions: !$ssl && (PROTOCOL == 'https://' || PROTOCOL == 'http://')
$allow_rewriting =
(!$ssl && (PROTOCOL == 'https://' || PROTOCOL == 'http://')) // always allow mod_rewrite for http
|| // or allow rewriting for redirect TO httpS or when already in httpS
(($ssl || PROTOCOL == 'https://') && $this->ConfigValue('UseModRewriteWithSSL')); // but only if it's allowed in config!
return constOn('MOD_REWRITE') && $allow_rewriting;
}
/**
* Reads unit (specified by $prefix)
* option specified by $option
*
* @param string $prefix
* @param string $option
* @param mixed $default
* @return string
* @access public
* @author Alex
*/
function getUnitOption($prefix, $option, $default = false)
{
/*if (!isset($this->UnitConfigReader)) {
$this->UnitConfigReader =& $this->recallObject('kUnitConfigReader');
}*/
return $this->UnitConfigReader->getUnitOption($prefix, $option, $default);
}
/**
* Set's new unit option value
*
* @param string $prefix
* @param string $name
* @param string $value
* @author Alex
* @access public
*/
function setUnitOption($prefix, $option, $value)
{
// $unit_config_reader =& $this->recallObject('kUnitConfigReader');
return $this->UnitConfigReader->setUnitOption($prefix,$option,$value);
}
/**
* Read all unit with $prefix options
*
* @param string $prefix
* @return Array
* @access public
* @author Alex
*/
function getUnitOptions($prefix)
{
// $unit_config_reader =& $this->recallObject('kUnitConfigReader');
return $this->UnitConfigReader->getUnitOptions($prefix);
}
/**
* Returns true if config exists and is allowed for reading
*
* @param string $prefix
* @return bool
*/
function prefixRegistred($prefix)
{
/*if (!isset($this->UnitConfigReader)) {
$this->UnitConfigReader =& $this->recallObject('kUnitConfigReader');
}*/
return $this->UnitConfigReader->prefixRegistred($prefix);
}
/**
* Splits any mixing of prefix and
* special into correct ones
*
* @param string $prefix_special
* @return Array
* @access public
* @author Alex
*/
function processPrefix($prefix_special)
{
return $this->Factory->processPrefix($prefix_special);
}
/**
* Set's new event for $prefix_special
* passed
*
* @param string $prefix_special
* @param string $event_name
* @access public
*/
function setEvent($prefix_special,$event_name)
{
$event_manager =& $this->recallObject('EventManager');
$event_manager->setEvent($prefix_special,$event_name);
}
/**
* SQL Error Handler
*
* @param int $code
* @param string $msg
* @param string $sql
* @return bool
* @access private
* @author Alex
*/
function handleSQLError($code, $msg, $sql)
{
if ( isset($this->Debugger) )
{
$errorLevel = constOn('DBG_SQL_FAILURE') && !defined('IS_INSTALL') ? E_USER_ERROR : E_USER_WARNING;
$this->Debugger->appendTrace();
$error_msg = '<span class="debug_error">'.$msg.' ('.$code.')</span><br><a href="javascript:$Debugger.SetClipboard(\''.htmlspecialchars($sql).'\');"><b>SQL</b></a>: '.$this->Debugger->formatSQL($sql);
$long_id = $this->Debugger->mapLongError($error_msg);
trigger_error( substr($msg.' ('.$code.') ['.$sql.']',0,1000).' #'.$long_id, $errorLevel);
return true;
}
else
{
//$errorLevel = constOn('IS_INSTALL') ? E_USER_WARNING : E_USER_ERROR;
$errorLevel = E_USER_WARNING;
trigger_error('<b>SQL Error</b> in sql: '.$sql.', code <b>'.$code.'</b> ('.$msg.')', $errorLevel);
/*echo '<b>xProcessing SQL</b>: '.$sql.'<br>';
echo '<b>Error ('.$code.'):</b> '.$msg.'<br>';*/
return $errorLevel == E_USER_ERROR ? false : true;
}
}
/**
* Default error handler
*
* @param int $errno
* @param string $errstr
* @param string $errfile
* @param int $errline
* @param Array $errcontext
*/
function handleError($errno, $errstr, $errfile = '', $errline = '', $errcontext = '')
{
if( constOn('SILENT_LOG') )
{
$fp = fopen(FULL_PATH.'/silent_log.txt','a');
$time = adodb_date('d/m/Y H:i:s');
fwrite($fp, '['.$time.'] #'.$errno.': '.strip_tags($errstr).' in ['.$errfile.'] on line '.$errline."\n");
fclose($fp);
}
if( !$this->errorHandlers ) {
if ($errno == E_USER_ERROR) {
header('HTTP/1.0 500 Script Fatal Error');
echo ('<div style="background-color: #FEFFBF; margin: auto; padding: 10px; border: 2px solid red; text-align: center">
<strong>Fatal Error: </strong>
'."$errstr in $errfile on line $errline".'
</div>');
exit;
}
return true;
}
$i = 0; // while (not foreach) because it is array of references in some cases
$eh_count = count($this->errorHandlers);
while($i < $eh_count)
{
if( is_array($this->errorHandlers[$i]) )
{
$object =& $this->errorHandlers[$i][0];
$method = $this->errorHandlers[$i][1];
$object->$method($errno, $errstr, $errfile, $errline, $errcontext);
}
else
{
$function = $this->errorHandlers[$i];
$function($errno, $errstr, $errfile, $errline, $errcontext);
}
$i++;
}
}
/**
* Returns & blocks next ResourceId available in system
*
* @return int
* @access public
* @author Alex
*/
function NextResourceId()
{
$table_name = TABLE_PREFIX.'IdGenerator';
$this->Conn->Query('LOCK TABLES '.$table_name.' WRITE');
$this->Conn->Query('UPDATE '.$table_name.' SET lastid = lastid + 1');
$id = $this->Conn->GetOne('SELECT lastid FROM '.$table_name);
if($id === false)
{
$this->Conn->Query('INSERT INTO '.$table_name.' (lastid) VALUES (2)');
$id = 2;
}
$this->Conn->Query('UNLOCK TABLES');
return $id - 1;
}
/**
* Returns genealogical main prefix for subtable prefix passes
* OR prefix, that has been found in REQUEST and some how is parent of passed subtable prefix
*
* @param string $current_prefix
* @param string $real_top if set to true will return real topmost prefix, regardless of its id is passed or not
* @return string
* @access public
* @author Kostja / Alex
*/
function GetTopmostPrefix($current_prefix, $real_top=false)
{
// 1. get genealogical tree of $current_prefix
$prefixes = Array ($current_prefix);
while ( $parent_prefix = $this->getUnitOption($current_prefix, 'ParentPrefix') ) {
$current_prefix = $parent_prefix;
array_unshift($prefixes, $current_prefix);
}
if ($real_top) return $current_prefix;
// 2. find what if parent is passed
$passed = explode(',', $this->GetVar('all_passed'));
foreach ($prefixes as $a_prefix) {
if (in_array($a_prefix, $passed)) {
return $a_prefix;
}
}
return $current_prefix;
}
/**
* Triggers email event of type Admin
*
* @param string $email_event_name
* @param int $to_user_id
* @param array $send_params associative array of direct send params, possible keys: to_email, to_name, from_email, from_name, message, message_text
* @return unknown
*/
function &EmailEventAdmin($email_event_name, $to_user_id = -1, $send_params = false)
{
$event =& $this->EmailEvent($email_event_name, 1, $to_user_id, $send_params);
return $event;
}
/**
* Triggers email event of type User
*
* @param string $email_event_name
* @param int $to_user_id
* @param array $send_params associative array of direct send params, possible keys: to_email, to_name, from_email, from_name, message, message_text
* @return unknown
*/
function &EmailEventUser($email_event_name, $to_user_id = -1, $send_params = false)
{
$event =& $this->EmailEvent($email_event_name, 0, $to_user_id, $send_params);
return $event;
}
/**
* Triggers general email event
*
* @param string $email_event_name
* @param int $email_event_type ( 0 for User, 1 for Admin)
* @param int $to_user_id
* @param array $send_params associative array of direct send params,
* possible keys: to_email, to_name, from_email, from_name, message, message_text
* @return unknown
*/
function &EmailEvent($email_event_name, $email_event_type, $to_user_id = -1, $send_params = false)
{
$params = array(
'EmailEventName' => $email_event_name,
'EmailEventToUserId' => $to_user_id,
'EmailEventType' => $email_event_type,
);
if ($send_params) {
$params['DirectSendParams'] = $send_params;
}
$event_str = isset($send_params['use_special']) ? 'emailevents.'.$send_params['use_special'].':OnEmailEvent' : 'emailevents:OnEmailEvent';
$this->HandleEvent($event, $event_str, $params);
return $event;
}
/**
* Allows to check if user in this session is logged in or not
*
* @return bool
*/
function LoggedIn()
{
// no session during expiration process
return is_null($this->Session) ? false : $this->Session->LoggedIn();
}
/**
* Check current user permissions based on it's group permissions in specified category
*
* @param string $name permission name
* @param int $cat_id category id, current used if not specified
* @param int $type permission type {1 - system, 0 - per category}
* @return int
*/
function CheckPermission($name, $type = 1, $cat_id = null)
{
$perm_helper =& $this->recallObject('PermissionsHelper');
return $perm_helper->CheckPermission($name, $type, $cat_id);
}
/**
* Set's any field of current visit
*
* @param string $field
* @param mixed $value
*/
function setVisitField($field, $value)
{
$visit =& $this->recallObject('visits');
$visit->SetDBField($field, $value);
$visit->Update();
}
/**
* Allows to check if in-portal is installed
*
* @return bool
*/
function isInstalled()
{
return $this->InitDone && (count($this->ModuleInfo) > 0);
}
/**
* Allows to determine if module is installed & enabled
*
* @param string $module_name
* @return bool
*/
function isModuleEnabled($module_name)
{
return $this->findModule('Name', $module_name) !== false;
}
function reportError($class, $method)
{
$this->Debugger->appendTrace();
trigger_error('depricated method <b>'.$class.'->'.$method.'(...)</b>', E_USER_ERROR);
}
/**
* Returns Window ID of passed prefix main prefix (in edit mode)
*
* @param string $prefix
* @return mixed
*/
function GetTopmostWid($prefix)
{
$top_prefix = $this->GetTopmostPrefix($prefix);
$mode = $this->GetVar($top_prefix.'_mode');
return $mode != '' ? substr($mode, 1) : '';
}
/**
* Get temp table name
*
* @param string $table
* @param mixed $wid
* @return string
*/
function GetTempName($table, $wid = '')
{
if (preg_match('/prefix:(.*)/', $wid, $regs)) {
$wid = $this->GetTopmostWid($regs[1]);
}
return TABLE_PREFIX.'ses_'.$this->GetSID().($wid ? '_'.$wid : '').'_edit_'.$table;
}
function GetTempTablePrefix($wid = '')
{
if (preg_match('/prefix:(.*)/', $wid, $regs)) {
$wid = $this->GetTopmostWid($regs[1]);
}
return TABLE_PREFIX.'ses_'.$this->GetSID().($wid ? '_'.$wid : '').'_edit_';
}
function IsTempTable($table)
{
return preg_match('/'.TABLE_PREFIX.'ses_'.$this->GetSID().'(_[\d]+){0,1}_edit_(.*)/',$table);
}
/**
* Return live table name based on temp table name
*
* @param string $temp_table
* @return string
*/
function GetLiveName($temp_table)
{
if( preg_match('/'.TABLE_PREFIX.'ses_'.$this->GetSID().'(_[\d]+){0,1}_edit_(.*)/',$temp_table, $rets) )
{
// cut wid from table end if any
return $rets[2];
}
else
{
return $temp_table;
}
}
function CheckProcessors($processors)
{
foreach ($processors as $a_processor)
{
if (!isset($this->CachedProcessors[$a_processor])) {
$this->CachedProcessors[$a_processor] =& $this->recallObject($a_processor.'_TagProcessor');
}
}
}
function TimeZoneAdjustment($time_zone = null)
{
+ if ($time_zone == 'GMT') {
+ return (-1) * adodb_date('Z');
+ }
$target_zone = isset($time_zone) ? $time_zone : $this->ConfigValue('Config_Site_Time');
return 3600 * ($target_zone - $this->ConfigValue('Config_Server_Time'));
}
function ApplicationDie($message = '')
{
$message = ob_get_clean().$message;
if ($this->isDebugMode()) {
$message .= $this->Debugger->printReport(true);
}
echo $this->UseOutputCompression() ? gzencode($message, DBG_COMPRESSION_LEVEL) : $message;
exit;
}
/* moved from MyApplication */
function getUserGroups($user_id)
{
switch($user_id)
{
case -1:
$user_groups = $this->ConfigValue('User_LoggedInGroup');
break;
case -2:
$user_groups = $this->ConfigValue('User_LoggedInGroup');
$user_groups .= ','.$this->ConfigValue('User_GuestGroup');
break;
default:
$sql = 'SELECT GroupId FROM '.TABLE_PREFIX.'UserGroup WHERE PortalUserId = '.$user_id;
$res = $this->Conn->GetCol($sql);
$user_groups = Array( $this->ConfigValue('User_LoggedInGroup') );
if(is_array($res))
{
$user_groups = array_merge($user_groups, $res);
}
$user_groups = implode(',', $user_groups);
}
return $user_groups;
}
/**
* Allows to detect if page is browsed by spider (293 agents supported)
*
* @return bool
*/
function IsSpider()
{
static $is_spider = null;
if (!isset($is_spider)) {
$user_agent = trim($_SERVER['HTTP_USER_AGENT']);
$robots = file(FULL_PATH.'/core/robots_list.txt');
foreach ($robots as $robot_info) {
$robot_info = explode("\t", $robot_info, 3);
if ($user_agent == trim($robot_info[2])) {
$is_spider = true;
break;
}
}
}
return $is_spider;
}
/**
* Allows to detect table's presense in database
*
* @param string $table_name
* @return bool
*/
function TableFound($table_name)
{
return $this->Conn->TableFound($table_name);
}
/**
* Returns counter value
*
* @param string $name counter name
* @param Array $params counter parameters
* @param string $query_name specify query name directly (don't generate from parmeters)
* @param bool $multiple_results
* @return mixed
*/
function getCounter($name, $params = Array (), $query_name = null, $multiple_results = false)
{
$count_helper =& $this->Application->recallObject('CountHelper');
/* @var $count_helper kCountHelper */
return $count_helper->getCounter($name, $params, $query_name, $multiple_results);
}
/**
* Resets counter, whitch are affected by one of specified tables
*
* @param string $tables comma separated tables list used in counting sqls
*/
function resetCounters($tables)
{
if (constOn('IS_INSTALL')) {
return ;
}
$count_helper =& $this->Application->recallObject('CountHelper');
/* @var $count_helper kCountHelper */
return $count_helper->resetCounters($tables);
}
/**
* Sends XML header + optionally displays xml heading
*
* @param string $xml_version
* @return string
* @author Alex
*/
function XMLHeader($xml_version = false)
{
$lang =& $this->recallObject('lang.current');
header('Content-type: text/xml; charset='.$lang->GetDBField('Charset'));
return $xml_version ? '<?xml version="'.$xml_version.'" encoding="'.$lang->GetDBField('Charset').'"?>' : '';
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/kernel/application.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.186.2.3
\ No newline at end of property
+1.186.2.4
\ No newline at end of property
Index: branches/RC/core/kernel/globals.php
===================================================================
--- branches/RC/core/kernel/globals.php (revision 9638)
+++ branches/RC/core/kernel/globals.php (revision 9639)
@@ -1,608 +1,633 @@
<?php
if( !function_exists('array_merge_recursive2') )
{
/**
* array_merge_recursive2()
*
* Similar to array_merge_recursive but keyed-valued are always overwritten.
* Priority goes to the 2nd array.
*
* @static yes
* @param $paArray1 array
* @param $paArray2 array
* @return array
* @access public
*/
function array_merge_recursive2($paArray1, $paArray2)
{
if (!is_array($paArray1) or !is_array($paArray2)) { return $paArray2; }
foreach ($paArray2 AS $sKey2 => $sValue2)
{
$paArray1[$sKey2] = isset($paArray1[$sKey2]) ? array_merge_recursive2($paArray1[$sKey2], $sValue2) : $sValue2;
// $paArray1[$sKey2] = array_merge_recursive2( getArrayValue($paArray1,$sKey2), $sValue2);
}
return $paArray1;
}
}
/**
* @return int
* @param $array array
* @param $value mixed
* @desc Prepend a reference to an element to the beginning of an array. Renumbers numeric keys, so $value is always inserted to $array[0]
*/
function array_unshift_ref(&$array, &$value)
{
$return = array_unshift($array,'');
$array[0] =& $value;
return $return;
}
/**
* Same as print_r, budet designed for viewing in web page
*
* @param Array $data
* @param string $label
*/
function print_pre($data, $label='', $on_screen = false)
{
$is_debug = false;
if (class_exists('kApplication') && !$on_screen) {
$application =& kApplication::Instance();
$is_debug = $application->isDebugMode();
}
if ($is_debug) {
if ($label) $application->Debugger->appendHTML('<b>'.$label.'</b>');
$application->Debugger->dumpVars($data);
}
else
{
if ($label) echo '<b>', $label, '</b><br>';
echo '<pre>', print_r($data, true), '</pre>';
}
}
/**
* Returns array value if key exists
*
* @param Array $array searchable array
* @param int $key array key
* @return string
* @access public
*/
//
function getArrayValue(&$array, $key)
{
// global $debugger;
// if (is_object($debugger)) $debugger->ProfilePoint('getArrayValue', 1);
$ret = isset($array[$key]) ? $array[$key] : false;
if ($ret && func_num_args() > 2) {
for ($i = 2; $i < func_num_args(); $i++) {
$cur_key = func_get_arg($i);
$ret = getArrayValue( $ret, $cur_key );
if ($ret === false) break;
}
}
return $ret;
}
/**
* Rename key in associative array, maintaining keys order
*
* @param Array $array Associative Array
* @param mixed $old Old key name
* @param mixed $new New key name
* @access public
*/
function array_rename_key(&$array, $old, $new)
{
foreach ($array as $key => $val)
{
$new_array[ $key == $old ? $new : $key] = $val;
}
$array = $new_array;
}
/**
* Define constant if it was not already defined before
*
* @param string $const_name
* @param string $const_value
* @access public
*/
function safeDefine($const_name, $const_value)
{
if(!defined($const_name)) define($const_name,$const_value);
}
if( !function_exists('parse_portal_ini') )
{
function parse_portal_ini($file, $parse_section = false)
{
if (!file_exists($file)) return false;
if( file_exists($file) && !is_readable($file) ) die('Could Not Open Ini File');
$contents = file($file);
$retval = Array();
$section = '';
$ln = 1;
$resave = false;
foreach($contents as $line) {
if ($ln == 1 && $line != '<'.'?'.'php die() ?'.">\n") {
$resave = true;
}
$ln++;
$line = trim($line);
$line = eregi_replace(';[.]*','',$line);
if(strlen($line) > 0) {
//echo $line . " - ";
if(eregi('^[[a-z]+]$',str_replace(' ', '', $line))) {
//echo 'section';
$section = substr($line,1,(strlen($line)-2));
if ($parse_section) {
$retval[$section] = array();
}
continue;
} elseif(eregi('=',$line)) {
//echo 'main element';
list($key,$val) = explode(' = ',$line);
if (!$parse_section) {
$retval[trim($key)] = str_replace('"', '', $val);
}
else {
$retval[$section][trim($key)] = str_replace('"', '', $val);
}
} //end if
//echo '<br />';
} //end if
} //end foreach
if($resave)
{
$fp = fopen($file, 'w');
reset($contents);
fwrite($fp,'<'.'?'.'php die() ?'.">\n\n");
foreach($contents as $line) fwrite($fp,"$line");
fclose($fp);
}
return $retval;
}
}
if( !function_exists('getmicrotime') )
{
function getmicrotime()
{
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
}
if( !function_exists('k4_include_once') )
{
function k4_include_once($file)
{
global $debugger;
if ( defined('DEBUG_MODE') && DEBUG_MODE && isset($debugger) && constOn('DBG_PROFILE_INCLUDES') )
{
if ( in_array($file, get_required_files()) ) return;
global $debugger;
/* $debugger->IncludeLevel++;
$before_mem = memory_get_usage();
*/
$debugger->ProfileStart('inc_'.crc32($file), $file);
include_once($file);
$debugger->ProfileFinish('inc_'.crc32($file));
$debugger->profilerAddTotal('includes', 'inc_'.crc32($file));
/* $used_mem = memory_get_usage() - $before_mem;
$debugger->IncludeLevel--;
$debugger->IncludesData['file'][] = str_replace(FULL_PATH, '', $file);
$debugger->IncludesData['mem'][] = $used_mem;
$debugger->IncludesData['time'][] = $used_time;
$debugger->IncludesData['level'][] = $debugger->IncludeLevel;
*/
}
else
{
include_once($file);
}
}
}
/**
* Checks if string passed is serialized array
*
* @param string $string
* @return bool
*/
function IsSerialized($string)
{
if( is_array($string) ) return false;
return preg_match('/a:([\d]+):{/', $string);
}
if (!function_exists('makepassword4')){
function makepassword4($length=10)
{
$pass_length=$length;
$p1=array('b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z');
$p2=array('a','e','i','o','u');
$p3=array('1','2','3','4','5','6','7','8','9');
$p4=array('(','&',')',';','%'); // if you need real strong stuff
// how much elements in the array
// can be done with a array count but counting once here is faster
$s1=21;// this is the count of $p1
$s2=5; // this is the count of $p2
$s3=9; // this is the count of $p3
$s4=5; // this is the count of $p4
// possible readable combinations
$c1='121'; // will be like 'bab'
$c2='212'; // will be like 'aba'
$c3='12'; // will be like 'ab'
$c4='3'; // will be just a number '1 to 9' if you dont like number delete the 3
// $c5='4'; // uncomment to active the strong stuff
$comb='4'; // the amount of combinations you made above (and did not comment out)
for ($p=0;$p<$pass_length;)
{
mt_srand((double)microtime()*1000000);
$strpart=mt_rand(1,$comb);
// checking if the stringpart is not the same as the previous one
if($strpart<>$previous)
{
$pass_structure.=${'c'.$strpart};
// shortcutting the loop a bit
$p=$p+strlen(${'c'.$strpart});
}
$previous=$strpart;
}
// generating the password from the structure defined in $pass_structure
for ($g=0;$g<strlen($pass_structure);$g++)
{
mt_srand((double)microtime()*1000000);
$sel=substr($pass_structure,$g,1);
$pass.=${'p'.$sel}[mt_rand(0,-1+${'s'.$sel})];
}
return $pass;
}
}
if( !function_exists('unhtmlentities') )
{
function unhtmlentities($string)
{
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
$trans_tbl = array_flip ($trans_tbl);
return strtr($string, $trans_tbl);
}
}
if( !function_exists('curl_post') )
{
/**
* submits $url with $post as POST
*
* @param string $url
* @param unknown_type $post
* @return unknown
*/
- function curl_post($url, $post, $headers=null, $request_type = 'POST')
+ function curl_post($url, $post, $headers=null, $request_type = 'POST', $curl_options=null)
{
if( is_array($post) )
{
$params_str = '';
foreach($post as $key => $value) $params_str .= $key.'='.urlencode($value).'&';
$post = $params_str;
}
$ch = curl_init($url);
$dbg = false;
if (defined('DEBUG_MODE') && DEBUG_MODE && constOn('DBG_CURL')) {
$dbg = true;
safeDefine('DBG_CURL_LOGFILE', '/curl.log');
$log = fopen(FULL_PATH.DBG_CURL_LOGFILE, 'a');
curl_setopt($ch, CURLOPT_FILE, $log);
curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
curl_setopt($ch, CURLOPT_STDERR, $log);
//curl_setopt($ch, CURLOPT_WRITEHEADER, $log);
}
if (!is_null($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
// if we have post data, then POST else use GET method instead
if ($request_type == 'POST') {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
}
elseif ($request_type == 'GET' && isset($post) && strlen($post) > 0) {
curl_setopt($ch, CURLOPT_URL, preg_match('/\?/', $url) ? $url.'&'.$post : $url.'?'.$post);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_REFERER, PROTOCOL.SERVER_NAME);
curl_setopt($ch,CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 90);
+ if (is_array($curl_options)) {
+ foreach ($curl_options as $option => $value) {
+ curl_setopt($ch, $option, $value);
+ }
+ }
$ret = curl_exec($ch);
$GLOBALS['curl_errorno'] = curl_errno($ch);
$GLOBALS['curl_error'] = curl_error($ch);
curl_close($ch);
if ($dbg) {
fwrite($log, "\n".$ret);
fclose($log);
}
return $ret;
}
}
if( !function_exists('memory_get_usage') )
{
function memory_get_usage(){ return -1; }
}
function &ref_call_user_func_array($callable, $args)
{
if( is_scalar($callable) )
{
// $callable is the name of a function
$call = $callable;
}
else
{
if( is_object($callable[0]) )
{
// $callable is an object and a method name
$call = "\$callable[0]->{$callable[1]}";
}
else
{
// $callable is a class name and a static method
$call = "{$callable[0]}::{$callable[1]}";
}
}
// Note because the keys in $args might be strings
// we do this in a slightly round about way.
$argumentString = Array();
$argumentKeys = array_keys($args);
foreach($argumentKeys as $argK)
{
$argumentString[] = "\$args[$argumentKeys[$argK]]";
}
$argumentString = implode($argumentString, ', ');
// Note also that eval doesn't return references, so we
// work around it in this way...
eval("\$result =& {$call}({$argumentString});");
return $result;
}
/**
* Checks if constant is defined and has positive value
*
* @param string $const_name
* @return bool
*/
function constOn($const_name)
{
return defined($const_name) && constant($const_name);
}
function Kg2Pounds($kg)
{
$major = floor( round($kg / POUND_TO_KG, 3) );
$minor = abs(round(($kg - $major * POUND_TO_KG) / POUND_TO_KG * 16, 2));
return array($major, $minor);
}
function Pounds2Kg($pounds, $ounces=0)
{
return round(($pounds + ($ounces / 16)) * POUND_TO_KG, 5);
}
/**
* Formats file/memory size in nice way
*
* @param int $bytes
* @return string
* @access public
*/
function formatSize($bytes)
{
if ($bytes >= 1099511627776) {
$return = round($bytes / 1024 / 1024 / 1024 / 1024, 2);
$suffix = "TB";
} elseif ($bytes >= 1073741824) {
$return = round($bytes / 1024 / 1024 / 1024, 2);
$suffix = "GB";
} elseif ($bytes >= 1048576) {
$return = round($bytes / 1024 / 1024, 2);
$suffix = "MB";
} elseif ($bytes >= 1024) {
$return = round($bytes / 1024, 2);
$suffix = "KB";
} else {
$return = $bytes;
$suffix = "Byte";
}
$return .= ' '.$suffix;
return $return;
}
/**
* Enter description here...
*
* @param resource $filePointer the file resource to write to
* @param Array $data the data to write out
* @param string $delimiter the field separator
* @param string $enclosure symbol to enclose field data to
* @param string $recordSeparator symbols to separate records with
*/
function fputcsv2($filePointer, $data, $delimiter = ',', $enclosure = '"', $recordSeparator = "\r\n")
{
foreach($data as $field_index => $field_value) {
// replaces an enclosure with two enclosures
$data[$field_index] = str_replace($enclosure, $enclosure.$enclosure, $field_value);
}
$line = $enclosure.implode($enclosure.$delimiter.$enclosure, $data).$enclosure.$recordSeparator;
+ $line = preg_replace('/'.preg_quote($enclosure).'([0-9\.]+)'.preg_quote($enclosure).'/', '$1', $line);
fwrite($filePointer, $line);
}
/**
+ * Enter description here...
+ *
+ * @param resource $filePointer the file resource to write to
+ * @param Array $data the data to write out
+ * @param string $delimiter the field separator
+ * @param string $enclosure symbol to enclose field data to
+ * @param string $recordSeparator symbols to separate records with
+ */
+ function getcsvline($data, $delimiter = ',', $enclosure = '"', $recordSeparator = "\r\n")
+ {
+ foreach($data as $field_index => $field_value) {
+ // replaces an enclosure with two enclosures
+ $data[$field_index] = str_replace($enclosure, $enclosure.$enclosure, $field_value);
+ }
+ $line = $enclosure.implode($enclosure.$delimiter.$enclosure, $data).$enclosure.$recordSeparator;
+ $line = preg_replace('/'.preg_quote($enclosure).'([0-9\.]+)'.preg_quote($enclosure).'/', '$1', $line);
+ return $line;
+ }
+ /**
* Allows to replace #section# within any string with current section
*
* @param string $string
* @return string
*/
function replaceModuleSection($string)
{
$application =& kApplication::Instance();
$module_section = $application->RecallVar('section');
if ($module_section) {
// substitute section instead of #section# parameter in title preset name
$module_section = explode(':', $module_section);
$section = preg_replace('/(configuration|configure)_(.*)/i', '\\2', $module_section[count($module_section) == 2 ? 1 : 0]);
$string = str_replace('#section#', strtolower($section), $string);
}
return $string;
}
/**
* Checks, that user IP address is within allowed range
*
* @param string $ip_list semi-column (by default) separated ip address list
* @param string $separator ip address separator (default ";")
*
* @return bool
*/
function ipMatch($ip_list, $separator = ';')
{
$ip_match = false;
$ip_addresses = $ip_list ? explode($separator, $ip_list) : Array ();
foreach ($ip_addresses as $ip_address) {
if (netMatch($ip_address, $_SERVER['REMOTE_ADDR'])) {
$ip_match = true;
break;
}
}
return $ip_match;
}
function netMatch($network, $ip) {
$network = trim($network);
$ip = trim($ip);
if ($network == $ip) {
// comparing 2 ip addresses directly
return true;
}
$d = strpos($network, '-');
if ($d === false) {
// sigle subnet specified
$ip_arr = explode('/', $network);
if (!preg_match("@\d*\.\d*\.\d*\.\d*@", $ip_arr[0], $matches)) {
$ip_arr[0] .= '.0'; // Alternate form 194.1.4/24
}
$network_long = ip2long($ip_arr[0]);
$x = ip2long($ip_arr[1]);
$mask = long2ip($x) == $ip_arr[1] ? $x : (0xffffffff << (32 - $ip_arr[1]));
$ip_long = ip2long($ip);
return ($ip_long & $mask) == ($network_long & $mask);
}
else {
// ip address range specified
$from = ip2long(trim(substr($network, 0, $d)));
$to = ip2long(trim(substr($network, $d + 1)));
$ip = ip2long($ip);
return ($ip >= $from && $ip <= $to);
}
}
function request_headers()
{
if(function_exists("apache_request_headers")) // If apache_request_headers() exists...
{
if($headers = apache_request_headers()) // And works...
{
return $headers; // Use it
}
}
$headers = array();
foreach(array_keys($_SERVER) as $skey)
{
if(substr($skey, 0, 5) == "HTTP_")
{
$headername = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($skey, 0, 5)))));
$headers[$headername] = $_SERVER[$skey];
}
}
return $headers;
}
if (!function_exists('easter_date')) {
// calculates easter date, when calendar extension not installed in php
// see also: http://php.prod.intechnic.lv/manual/en/function.easter-date.php
function easter_date ($Year) {
/*
G is the Golden Number-1
H is 23-Epact (modulo 30)
I is the number of days from 21 March to the Paschal full moon
J is the weekday for the Paschal full moon (0=Sunday,
1=Monday, etc.)
L is the number of days from 21 March to the Sunday on or before
the Paschal full moon (a number between -6 and 28)
*/
$G = $Year % 19;
$C = (int)($Year / 100);
$H = (int)($C - ($C / 4) - ((8*$C+13) / 25) + 19*$G + 15) % 30;
$I = (int)$H - (int)($H / 28)*(1 - (int)($H / 28)*(int)(29 / ($H + 1))*((int)(21 - $G) / 11));
$J = ($Year + (int)($Year/4) + $I + 2 - $C + (int)($C/4)) % 7;
$L = $I - $J;
$m = 3 + (int)(($L + 40) / 44);
$d = $L + 28 - 31 * ((int)($m / 4));
$y = $Year;
$E = mktime(0,0,0, $m, $d, $y);
return $E;
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/kernel/globals.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.37.2.1
\ No newline at end of property
+1.37.2.2
\ No newline at end of property
Index: branches/RC/core/kernel/parser/construct_tags.php
===================================================================
--- branches/RC/core/kernel/parser/construct_tags.php (revision 9638)
+++ branches/RC/core/kernel/parser/construct_tags.php (revision 9639)
@@ -1,378 +1,380 @@
<?php
define('CM_PARSE', 1);
define('CM_LATE_PARSE', 2);
//Template language contruct tags (if, block...) which has opening and ending
class ConstructTag extends Tag {
var $StopTag = '';
var $SkipMode = 0;
var $Logic = 0;
function SetStopTag($tag)
{
$this->StopTag = $tag;
}
function StoreSkipMode()
{
$this->SkipMode = $this->Parser->SkipMode;
}
function RestoreSkipMode()
{
$this->Parser->SetSkipMode($this->SkipMode);
}
function RestoreThisLevelSkipMode()
{
$this->SkipMode = $this->Parser->Recursion[$this->Parser->RecursionIndex]->SkipMode;
}
function SuggestSkipMode($mode)
{
if ($mode >= 1) //if we need to skip - always forcing it
$this->Parser->SetSkipMode($mode);
else { //if we need to turn of skipping
if ($this->SkipMode == parse) //check if initially skipping was off
$this->Parser->SetSkipMode(parse); //set it to off only then
}
}
function GetLogic()
{
if ($this->Parser->SkipMode != parse) {
$this->Logic = false;
return;
}
$check = $this->GetParam('check');
if ($check) {
if (strpos($check, '_') !== false) {
list($prefix, $function) = explode('_', $check, 2);
}
else {
$function = $check;
$prefix = $this->Parser->GetParam('PrefixSpecial');
}
}
else {
$prefix = $this->GetParam('prefix');
$function = $this->GetParam('function');
}
$this->NP['prefix'] = $prefix;
$this->NP['function'] = $function;
$inverse = $this->GetParam('inverse');
if ($prefix !== false) {
- $tag = new Tag('', $this->Parser);
+ $tag =& new Tag('', $this->Parser);
$tag->Tag = $function;
$tmp = $this->Application->processPrefix($prefix);
$tag->Processor = $tmp['prefix'];
$tag->Prefix=$tmp['prefix'];
$tag->Special=$tmp['special'];
$tag->NamedParams = $this->NP;
$this->Logic = $tag->DoProcessTag();
// echo " this->Logic : ".$this->Logic."<br>";
}
else
{
$this->Logic = $function;
}
if($inverse) $this->Logic = !$this->Logic;
}
function Process()
{
switch ($this->Tag) {
case 'if':
case 'ifnot':
$this->GetLogic();
$this->SetStopTag('endif'); //This recursion level should end when 'endif' is found
$this->Parser->Recurve($this); //Saving current tag in parser recursion array
$this->StoreSkipMode(); //Storing initial SkipMode
if ($this->Logic) {
$this->SuggestSkipMode(parse); //suggest we parse it
}
else {
$this->SuggestSkipMode(skip); //suggest we don't parse it
}
break;
case 'elseif':
$if_logic = $this->Parser->Recursion[$this->Parser->RecursionIndex]->Logic;
if (!$if_logic) { //if IF or ELSEIF above have not worked
$this->GetLogic();
if ($this->Logic) { //ELSEIF should run
$this->Parser->Recursion[$this->Parser->RecursionIndex]->Logic = $this->Logic; //To escape running ELSE or ELSEIF below
$this->SuggestSkipMode(parse);
}
else { //ELSEIF should NOT run
$this->SuggestSkipMode(skip);
}
}
else //IF or ELSEIF above HAVE worked - this ELSEIF should NOT run
$this->SuggestSkipMode(skip);
break;
case 'else':
$if_logic = $this->Parser->Recursion[$this->Parser->RecursionIndex]->Logic;
$this->RestoreThisLevelSkipMode();
if (!$if_logic) { //IF was false - ELSE should run
$this->SuggestSkipMode(parse);
}
else { //IF was true - ELSE should not run
$this->SuggestSkipMode(skip);
}
break;
}
}
function CheckRecursion(&$tag)
{
if ($this->CheckEndRecursion($tag)) {
if (defined('EXPERIMENTAL_PRE_PARSE')) {
if ($tag->Tag == 'if' || $tag->Tag == 'endif') {
$this->Parser->AppendCompiledCode('}');
$this->Parser->ResetCode();
}
}
$this->RestoreSkipMode(); //Restoring original SkipMode
return true;
}
else {
if (defined('EXPERIMENTAL_PRE_PARSE')) {
// && ($tag->Tag != 'RenderElement' && isset($tag->NP['_short_closing_']))
if ($tag->Tag != 'block' && $tag->Tag != 'DefineElement' && $tag->Tag != 'Capture' && !($tag->Tag == 'RenderElement' && isset($tag->NP['_short_closing_']))) {
$this->Parser->AppendCode($tag->GetCode());
}
// $this->Parser->AppendCompiledCode( $tag->GetCode() );
}
}
return false;
}
function CheckEndRecursion(&$tag)
{
if ($tag->GetParam('_closing_tag_') == 1 && $tag->Tag == $this->Tag) {
return true;
}
return ($tag->Tag == $this->StopTag); //Tag matches StopTag we are waiting for to close current recursion
}
}
class BlockTag extends ConstructTag {
var $BlockName = '';
var $InsideBlock = 0;
function Process()
{
switch ($this->Tag) {
case 'block':
case 'DefineElement':
case 'RenderElement':
if ($this->Tag == 'DefineElement') {
$this->SetStopTag('end_define'); //This recursion level should end when 'blockend' is found
}
else {
$this->SetStopTag('blockend'); //This recursion level should end when 'blockend' is found
}
if ($this->Tag == 'RenderElement') {
$this->NP['name'] = '__lambda_element_'.abs(crc32($this->TemplateName)).'_'.$this->Application->LambdaElements++;
$RenderTag = new Tag($this->TagData.' name="'.$this->NP['name'].'"', $this->Parser);
$this->Parser->AppendCode($RenderTag->GetCode());
}
$this->Parser->Recurve($this); //Saving current tag in parser recursion array
$this->Parser->SetBuffer('');
$this->BlockName = $this->NP['name']; //Stroing BlockName
if (isset($this->NP['args']) ) {
$this->Parser->Args = explode(',', $this->NP['args']);
}
$this->StoreSkipMode();
$this->SuggestSkipMode(skip_tags); //We need to skip tags from now
break;
}
}
function CheckRecursion(&$tag)
{
if (parent::CheckRecursion($tag)) { //if endtag matches (SkipMode would be restored then)
//Creating template from buffer
//if (defined('EXPERIMENTAL_PRE_PARSE') && isset($this->Application->PreParsedBlocks[$this->BlockName])) return true;
$template = new Template();
$template->SetBody($this->Parser->GetBuffer());
//Adding template to application' cache
$this->Application->TemplatesCache->SetTemplate($this->BlockName, $template, $this->Parser->TemplateName);
if (defined('EXPERIMENTAL_PRE_PARSE')) {
$code = $this->Parser->GetCode();
/*if ($this->Parser->UsedProcessors) {
array_unshift($code, '$application->CheckProcessors(array("'.implode('", "', $this->Parser->UsedProcessors).'"));');
}
$this->Parser->UsedProcessors = null;*/
+ // because of unshift the code is added from bottom to top here, so read from the bottom below:
array_unshift($code, '$o = \'\';');
array_unshift($code, '$application->Parser->SetParams($params, false);');
array_unshift($code, '$application =& kApplication::Instance();');
array_unshift($code, 'extract($params);');
$defaults = '$defaults = Array(';
foreach ($this->NP as $name => $val) {
if ($name == 'name') continue;
$defaults .= '"'.$name.'" => "'.str_replace('"', '\"', $val).'",';
}
$defaults .= ');';
array_unshift($code, '$params = array_merge_recursive2($defaults, $params);');
array_unshift($code, $defaults);
+ // ^^^^ read up from here ^^^^
$code[] = 'return $o;';
global $debugger;
$dbg_functions = $this->Application->isDebugMode() && constOn('DBG_PRINT_PREPARSED');
$f_body = '';
//echo "<pre>";
$l = 0;
if ($dbg_functions) echo "<b>function ".$this->BlockName." {</b><br>";
foreach ($code as $line) {
$l++;
if ($dbg_functions) {
echo $l.' '.$debugger->highlightString(trim($line)."\n", true);
}
$f_body .= "\t\t".rtrim($line, "\n")."\n";
}
if ($dbg_functions) echo "<b>} // function ".$this->BlockName." end</b><br><br>";
//echo "</pre>";
//caching func body
$this->Application->PreParsedCache[$this->BlockName] = $f_body;
$compile_body = preg_replace('/\/\*COMPILE-ONLY\*\/.*/m', '', $f_body);
$func = create_function('$params', $compile_body);
$this->Application->PreParsedBlocks[$this->BlockName] = $func;
$this->Parser->Args = null;
$this->Parser->ResetCode();
$real_name = $this->Parser->AppendCompiledFunction($this->BlockName, $f_body);
if ($this->Tag == 'RenderElement') {
$RenderTag = new Tag($this->TagData.' name="'.$this->BlockName.'"', $this->Parser);
// $this->Parser->AppendCompiledCode($RenderTag->GetCode());
// for compilation run
$RenderTag->Process();
}
}
return true;
}
else {
// append the tag itself to the block - while in block, we check every tag to be 'blockend'
// if it is not - we need to append the tag to the buffer, which we'll parse later in 'parse_block'
//if ($tag->Tag != 'block') {
if (defined('EXPERIMENTAL_PRE_PARSE') && isset($this->Application->PreParsedBlocks[$this->BlockName])) {
return;
}
if (defined('EXPERIMENTAL_PRE_PARSE')) {
// $this->Parser->AppendCode($tag->GetCode());
}
else {
$this->Parser->AppendOutput($tag->GetFullTag());
}
//}
return false;
}
}
}
class CaptureTag extends ConstructTag {
var $VarName = null;
var $Mode = CM_LATE_PARSE;
function Process()
{
switch ($this->Tag) {
case 'Capture':
$this->Parser->Recurve($this); //Saving current tag in parser recursion array
$this->Parser->SetBuffer('');
$this->VarName = $this->NP['to_var']; //Stroing BlockName
$this->StoreSkipMode();
if (isset($this->NP['mode']) && $this->NP['mode'] == 'parse_now') {
$this->Mode = CM_PARSE;
}
$this->SuggestSkipMode(skip_tags);
break;
}
}
function RunCapture($f, $func, $cur_lambda)
{
$code = array();
$code[] = '/*COMPILE-ONLY*/ '.$f[2];
$code[] = '/*LAMBDA-ONLY*/ $application->PreParsedBlocks[\'capture_'.$this->VarName.'\'] = $application->PreParsedBlocks[\'capture_'.$this->VarName.$cur_lambda.'\'];';
$code[] = '$__f = $application->PreParsedBlocks[\'capture_'.$this->VarName.'\'];';
$code[] = '$application->Parser->SetParam(\''.$this->VarName.'\', $__f(array())'.');';
$code[] = '$'.$this->VarName.' = $application->Parser->GetParam(\''.$this->VarName.'\');';
$code[] = '$params[\''.$this->VarName.'\'] = $'.$this->VarName.';';
if ($this->Parser->RecursionIndex > 1) {
$this->Parser->AppendCode($code, -1);
}
else {
$this->Application->Parser->SetParam($this->VarName, $func(array()));
$this->Parser->AppendCompiledCode($code);
}
}
function CheckRecursion(&$tag)
{
if (parent::CheckRecursion($tag)) { //if endtag matches (SkipMode would be restored then)
$f_code = $this->Parser->GetCode();
array_unshift($f_code, '$o = \'\';');
array_unshift($f_code, '$application =& kApplication::Instance();');
$f_code[] = 'return $o;';
$f = $this->Parser->PrepareCompiledFunction('capture_'.$this->VarName, $f_code, false);
$f_code = trim(join("\n\t", $f_code));
$func = create_function('$params', $f_code);
$this->Application->PreParsedBlocks['capture_'.$this->VarName] = $func;
$cur_lambda = $this->Application->LambdaElements++;
$this->Application->PreParsedBlocks['capture_'.$this->VarName.$cur_lambda] = $func;
$this->Parser->AppendCompiledCode($f[1]);
if ($this->Mode == CM_PARSE) {
$this->RunCapture($f, $func, $cur_lambda);
}
elseif ($this->Mode == CM_LATE_PARSE) {
$code = array();
$code[] = '/*COMPILE-ONLY*/ '.$f[2];
$code[] = '/*LAMBDA-ONLY*/ $application->PreParsedBlocks[\'capture_'.$this->VarName.'\'] = $application->PreParsedBlocks[\'capture_'.$this->VarName.$cur_lambda.'\'];';
$code[] = '$application->LateParsed[\''.$this->VarName.'\'] = '.$cur_lambda.';';
if ($this->Parser->RecursionIndex > 1) {
$this->Parser->AppendCode($code, -1);
}
else {
$this->Parser->AppendCompiledCode($code);
}
$this->Application->LateParsed[$this->VarName] = $cur_lambda;
}
$this->Parser->ResetCode();
return true;
}
return ($tag->Tag == $this->StopTag); //Tag matches StopTag we are waiting for to close current recursion
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/kernel/parser/construct_tags.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.14.2.1
\ No newline at end of property
+1.14.2.2
\ No newline at end of property
Index: branches/RC/core/units/skins/skin_eh.php
===================================================================
--- branches/RC/core/units/skins/skin_eh.php (revision 9638)
+++ branches/RC/core/units/skins/skin_eh.php (revision 9639)
@@ -1,90 +1,91 @@
<?php
class SkinEventHandler extends kDBEventHandler {
/**
* Allows to set selected theme as primary
*
* @param kEvent $event
*/
function OnSetPrimary(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$ids = $this->StoreSelectedIDs($event);
if ($ids) {
$id = array_shift($ids);
$this->setPrimary($id);
}
$this->clearSelectedIDs($event);
}
function setPrimary($id)
{
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
$sql = 'UPDATE '.$table_name.'
SET IsPrimary = 0';
$this->Conn->Query($sql);
$sql = 'UPDATE '.$table_name.'
SET IsPrimary = 1
WHERE '.$id_field.' = '.$id;
$this->Conn->Query($sql);
}
/**
* [HOOK] Compile stylesheet file based on theme definitions
*
* @param kEvent $event
*/
function OnCompileStylesheet(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
$object->SwitchToLive();
- $ids = explode(',', $event->MasterEvent->getEventParam('ids') );
+ $ids = $event->MasterEvent->getEventParam('ids');
+ if (!is_array($ids)) $ids = explode(',', $ids);
if(!$ids) return false;
foreach($ids as $id)
{
$object->Load($id);
$this->Compile($object);
}
}
function Compile(&$object)
{
$ret = $object->GetDBField('CSS');
$options = $object->GetDBField('Options');
$options = unserialize($options);
$options['base_url'] = array('Value'=>rtrim($this->Application->BaseURL(), '/'));
foreach ($options as $key => $row) {
$ret = str_replace('@@'.$key.'@@', $row['Value'], $ret);
}
$compile_ts = adodb_mktime();
$css_path = (defined('WRITEABLE') ? WRITEABLE : FULL_PATH.'/kernel').'/user_files/';
$css_file = $css_path.'admin-'.strtolower($object->GetDBField('Name')).'-'.$compile_ts.'.css';
$fp = fopen($css_file,'w');
if($fp)
{
$prev_css = $css_path.'admin-'.strtolower($object->GetDBField('Name')).'-'.$object->GetDBField('LastCompiled').'.css';
if( file_exists($prev_css) ) unlink($prev_css);
fwrite($fp, $ret);
fclose($fp);
$sql = 'UPDATE '.$object->TableName.' SET LastCompiled = '.$compile_ts.' WHERE '.$object->IDField.' = '.$object->GetID();
$this->Conn->Query($sql);
}
}
}
\ No newline at end of file
Property changes on: branches/RC/core/units/skins/skin_eh.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.2.4.1
\ No newline at end of property
+1.2.4.2
\ No newline at end of property
Index: branches/RC/core/units/users/users_event_handler.php
===================================================================
--- branches/RC/core/units/users/users_event_handler.php (revision 9638)
+++ branches/RC/core/units/users/users_event_handler.php (revision 9639)
@@ -1,1350 +1,1375 @@
<?php
class UsersEventHandler extends kDBEventHandler
{
/**
* Allows to override standart permission mapping
*
*/
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
// admin
'OnSetPersistantVariable' => Array('self' => 'view'), // because setting to logged in user only
'OnUpdateRootPassword' => Array('self' => true), // because setting to logged in user only
// front
'OnRefreshForm' => Array('self' => true),
'OnForgotPassword' => Array('self' => true),
'OnResetPassword' => Array('self' => true),
'OnResetPasswordConfirmed' => Array('self' => true),
'OnSubscribeQuery' => Array('self' => true),
'OnSubscribeUser' => Array('self' => true),
'OnRecommend' => Array('self' => true),
'OnItemBuild' => Array('self' => true),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Shows only admins when required
*
* @param kEvent $event
*/
function SetCustomQuery(&$event)
{
$object =& $event->getObject();
/* @var $object kDBList */
if ($event->Special == 'admins') {
$object->addFilter('primary_filter', 'ug.GroupId = 11');
}
if ($event->Special == 'regular') {
$object->addFilter('primary_filter', 'ug.GroupId <> 11');
}
if (!$this->Application->IsAdmin()) {
$object->addFilter('status_filter', '%1$s.Status = '.STATUS_ACTIVE);
}
}
/**
* Checks permissions of user
*
* @param kEvent $event
*/
function CheckPermission(&$event)
{
if ($event->Name == 'OnLogin' || $event->Name == 'OnLogout') {
// permission is checked in OnLogin event directly
return true;
}
if (!$this->Application->IsAdmin()) {
$user_id = $this->Application->RecallVar('user_id');
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
if ($event->Name == 'OnCreate' && $user_id == -2) {
// "Guest" can create new users
return true;
}
if ($event->Name == 'OnUpdate' && $user_id > 0) {
$user_dummy =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true));
foreach ($items_info as $id => $field_values) {
if ($id != $user_id) {
// registered users can update their record only
return false;
}
$user_dummy->Load($id);
$status_field = array_shift($this->Application->getUnitOption($event->Prefix, 'StatusField'));
if ($user_dummy->GetDBField($status_field) != STATUS_ACTIVE) {
// not active user is not allowed to update his record (he could not activate himself manually)
return false;
}
if (isset($field_values[$status_field]) && $user_dummy->GetDBField($status_field) != $field_values[$status_field]) {
// user can't change status by himself
return false;
}
}
return true;
}
if ($event->Name == 'OnUpdate' && $user_id <= 0) {
// guests are not allowed to update their record, because they don't have it :)
return false;
}
}
return parent::CheckPermission($event);
}
function OnSessionExpire()
{
$this->Application->resetCounters('UserSession');
if ($this->Application->IsAdmin()) {
$this->Application->Redirect('index', Array('expired' => 1), '', 'index.php');
}
if ($this->Application->GetVar('admin') == 1) {
$session_admin =& $this->Application->recallObject('Session.admin');
/* @var $session_admin Session */
if (!$session_admin->LoggedIn()) {
// front-end session created from admin session & both expired
$this->Application->DeleteVar('admin');
$this->Application->Redirect('index', Array('expired' => 1), '', 'admin/index.php');
}
}
$get = $this->Application->HttpQuery->getRedirectParams();
$t = $this->Application->GetVar('t');
$get['js_redirect'] = $this->Application->ConfigValue('UseJSRedirect');
$this->Application->Redirect($t ? $t : 'index', $get);
}
/**
* Checks user data and logs it in if allowed
*
* @param kEvent $event
*/
function OnLogin(&$event)
{
// persistent session data after login is not refreshed, because redirect will follow in any case
$prefix_special = $this->Application->IsAdmin() ? 'u.current' : 'u'; // "u" used on front not to change theme
$object =& $this->Application->recallObject($prefix_special, null, Array('skip_autoload' => true));
$password = $this->Application->GetVar('password');
$invalid_pseudo = $this->Application->IsAdmin() ? 'la_invalid_password' : 'lu_invalid_password';
if(!$password)
{
$object->SetError('ValidateLogin', 'invalid_password', $invalid_pseudo);
$event->status = erFAIL;
return false;
}
$email_as_login = $this->Application->ConfigValue('Email_As_Login');
list($login_field, $submit_field) = $email_as_login && !$this->Application->IsAdmin() ? Array('Email', 'email') : Array('Login', 'login');
$login_value = $this->Application->GetVar($submit_field);
// process "Save Username" checkbox
if ($this->Application->IsAdmin()) {
$save_username = $this->Application->GetVar('cb_save_username') ? $login_value : '';
$this->Application->Session->SetCookie('save_username', $save_username, adodb_mktime() + 31104000); // 1 year expiration
$this->Application->SetVar('save_username', $save_username); // cookie will be set on next refresh, but refresh won't occur if login error present, so duplicate cookie in HTTPQuery
}
$super_admin = ($login_value == 'super-root') && $this->verifySuperAdmin();
if ($this->Application->IsAdmin() && ($login_value == 'root') || ($super_admin && $login_value == 'super-root')) {
// logging in "root" (admin only)
$login_value = 'root';
$root_password = $this->Application->ConfigValue('RootPass');
$password_formatter =& $this->Application->recallObject('kPasswordFormatter');
$test = $password_formatter->EncryptPassword($password, 'b38');
if ($root_password != $test) {
$object->SetError('ValidateLogin', 'invalid_password', $invalid_pseudo);
$event->status = erFAIL;
return false;
}
elseif ($this->checkLoginPermission($login_value)) {
$user_id = -1;
$object->Load($user_id);
$object->SetDBField('Login', $login_value);
$session =& $this->Application->recallObject('Session');
$session->SetField('PortalUserId', $user_id);
// $session->SetField('GroupList', implode(',', $groups) );
$this->Application->SetVar('u.current_id', $user_id);
$this->Application->StoreVar('user_id', $user_id);
if ($super_admin) {
$this->Application->StoreVar('super_admin', 1);
}
$this->processLoginRedirect($event, $password);
return true;
}
else {
$object->SetError('ValidateLogin', 'invalid_license', 'la_invalid_license');
$event->status = erFAIL;
return false;
}
}
/*$sql = 'SELECT PortalUserId FROM '.$object->TableName.' WHERE (%s = %s) AND (Password = MD5(%s))';
$user_id = $this->Conn->GetOne( sprintf($sql, $login_field, $this->Conn->qstr($login_value), $this->Conn->qstr($password) ) );*/
$sql = 'SELECT PortalUserId FROM '.$object->TableName.' WHERE (Email = %1$s OR Login = %1$s) AND (Password = MD5(%2$s))';
$user_id = $this->Conn->GetOne( sprintf($sql, $this->Conn->qstr($login_value), $this->Conn->qstr($password) ) );
if ($user_id) {
$object->Load($user_id);
if ($object->GetDBField('Status') == STATUS_ACTIVE) {
$groups = $object->getMembershipGroups(true);
if(!$groups) $groups = Array();
array_push($groups, $this->Application->ConfigValue('User_LoggedInGroup') );
$this->Application->StoreVar( 'UserGroups', implode(',', $groups) );
if ($this->checkLoginPermission($login_value)) {
$session =& $this->Application->recallObject('Session');
$session->SetField('PortalUserId', $user_id);
$session->SetField('GroupList', implode(',', $groups) );
$this->Application->SetVar('u.current_id', $user_id);
$this->Application->StoreVar('user_id', $user_id);
$this_login = (int)$object->getPersistantVar('ThisLogin');
$object->setPersistantVar('LastLogin', $this_login);
$object->setPersistantVar('ThisLogin', adodb_mktime());
}
else {
$object->Load(-2);
$object->SetError('ValidateLogin', 'no_permission', 'lu_no_permissions');
$event->status = erFAIL;
}
$this->processLoginRedirect($event, $password);
}
else {
$event->redirect = $this->Application->GetVar('pending_disabled_template');
}
}
else
{
$object->SetID(-2);
$object->SetError('ValidateLogin', 'invalid_password', $invalid_pseudo);
$event->status = erFAIL;
}
$event->SetRedirectParam('pass', 'all');
}
/**
* Checks that user is allowed to use super admin mode
*
* @return bool
*/
function verifySuperAdmin()
{
$sa_mode = ipMatch(defined('SA_IP') ? SA_IP : '');
return $sa_mode || $this->Application->isDebugMode();
}
/**
* Enter description here...
*
* @param string $user_name
* @return bool
*/
function checkLoginPermission($user_name)
{
$ret = true;
if ($this->Application->IsAdmin()) {
$modules_helper =& $this->Application->recallObject('ModulesHelper');
if ($user_name != 'root') {
// root is virtual user, so allow him to login to admin in any case
$ret = $this->Application->CheckPermission('ADMIN', 1);
}
$ret = $ret && $modules_helper->checkLogin();
}
else {
$ret = $this->Application->CheckPermission('LOGIN', 1);
}
return $ret;
}
/**
* Process all required data and redirect logged-in user
*
* @param kEvent $event
*/
function processLoginRedirect(&$event, $password)
{
$prefix_special = $this->Application->IsAdmin() ? 'u.current' : 'u'; // "u" used on front not to change theme
$object =& $this->Application->recallObject($prefix_special, null, Array('skip_autoload' => true));
$next_template = $this->Application->GetVar('next_template');
if ($next_template == '_ses_redirect') {
$location = $this->Application->BaseURL().$this->Application->RecallVar($next_template);
if( $this->Application->isDebugMode() && constOn('DBG_REDIRECT') )
{
$this->Application->Debugger->appendTrace();
echo "<b>Debug output above!!!</b> Proceed to redirect: <a href=\"$location\">$location</a><br>";
}
else {
header('Location: '.$location);
}
$session =& $this->Application->recallObject('Session');
$session->SaveData();
exit;
}
if ($next_template) {
$event->redirect = $next_template;
}
if ($this->Application->ConfigValue('UseJSRedirect')) {
$event->SetRedirectParam('js_redirect', 1);
}
$sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize');
$sync_manager->performAction('LoginUser', $object->GetDBField('Login'), $password);
$this->Application->resetCounters('UserSession');
}
/**
* Called when user logs in using old in-portal
*
* @param kEvent $event
*/
function OnInpLogin(&$event)
{
$sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize');
$sync_manager->performAction('LoginUser', $event->getEventParam('user'), $event->getEventParam('pass') );
if ($event->redirect && is_string($event->redirect)) {
// some real template specified instead of true
$this->Application->Redirect($event->redirect, $event->redirect_params);
}
}
/**
* Called when user logs in using old in-portal
*
* @param kEvent $event
*/
function OnInpLogout(&$event)
{
$sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize');
$sync_manager->performAction('LogoutUser');
}
function OnLogout(&$event)
{
$sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize');
$sync_manager->performAction('LogoutUser');
$session =& $this->Application->recallObject('Session');
$session->SetField('PortalUserId', -2);
$this->Application->SetVar('u.current_id', -2);
$this->Application->StoreVar('user_id', -2);
$object =& $this->Application->recallObject('u.current', null, Array('skip_autoload' => true));
$object->Load(-2);
$this->Application->DestroySession();
$group_list = $this->Application->ConfigValue('User_GuestGroup').','.$this->Application->ConfigValue('User_LoggedInGroup');
$session->SetField('GroupList', $group_list);
$this->Application->StoreVar('UserGroups', $group_list);
if ($this->Application->ConfigValue('UseJSRedirect')) {
$event->SetRedirectParam('js_redirect', 1);
}
$this->Application->resetCounters('UserSession');
$event->SetRedirectParam('pass', 'all');
}
/**
* Prefill states dropdown with correct values
*
* @param kEvent $event
* @access public
*/
function OnPrepareStates(&$event)
{
$cs_helper =& $this->Application->recallObject('CountryStatesHelper');
$cs_helper->PopulateStates($event, 'State', 'Country');
$object =& $event->getObject();
if( $object->isRequired('Country') && $cs_helper->CountryHasStates( $object->GetDBField('Country') ) ) $object->setRequired('State', true);
$object->setLogin();
}
/**
* Redirects user after succesfull registration to confirmation template (on Front only)
*
* @param kEvent $event
*/
function OnAfterItemCreate(&$event)
{
$is_subscriber = $this->Application->GetVar('IsSubscriber');
if(!$is_subscriber)
{
$object =& $event->getObject();
$ug_table = TABLE_PREFIX.'UserGroup';
if ($object->mode == 't') {
$ug_table = $this->Application->GetTempName($ug_table, 'prefix:'.$event->Prefix);
}
$sql = 'UPDATE '.$ug_table.'
SET PrimaryGroup = 0
WHERE PortalUserId = '.$object->GetDBField('PortalUserId');
$this->Conn->Query($sql);
// set primary group to user
if ($this->Application->IsAdmin() && $this->Application->GetVar('user_group')) {
// while in admin you can set any group for new users
$group_id = $this->Application->GetVar('user_group');
}
else {
$group_id = $this->Application->ConfigValue('User_NewGroup');
}
$sql = 'REPLACE INTO '.$ug_table.'(PortalUserId,GroupId,PrimaryGroup) VALUES (%s,%s,1)';
$this->Conn->Query( sprintf($sql, $object->GetID(), $group_id) );
}
}
/**
* Login user if possible, if not then redirect to corresponding template
*
* @param kEvent $event
*/
function autoLoginUser(&$event)
{
$object =& $event->getObject();
$this->Application->SetVar('u.current_id', $object->GetID() );
if($object->GetDBField('Status') == STATUS_ACTIVE && !$this->Application->ConfigValue('User_Password_Auto'))
{
$email_as_login = $this->Application->ConfigValue('Email_As_Login');
list($login_field, $submit_field) = $email_as_login ? Array('Email', 'email') : Array('Login', 'login');
$this->Application->SetVar($submit_field, $object->GetDBField($login_field) );
$this->Application->SetVar('password', $object->GetDBField('Password_plain') );
$event->CallSubEvent('OnLogin');
}
}
/**
* When creating user & user with such email exists then force to use OnUpdate insted of ?
*
* @param kEvent $event
*/
function OnSubstituteSubscriber(&$event)
{
$ret = false;
$object =& $event->getObject( Array('skip_autoload' => true) );
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
list($id, $field_values) = each($items_info);
$user_email = isset($field_values['Email']) ? $field_values['Email'] : false;
if($user_email)
{
// check if is subscriber
$verify_user =& $this->Application->recallObject('u.verify', null, Array('skip_autoload' => true) );
$verify_user->Load($user_email, 'Email');
if( $verify_user->isLoaded() && $verify_user->isSubscriberOnly() )
{
$items_info = Array( $verify_user->GetDBField('PortalUserId') => $field_values );
$this->Application->SetVar($event->getPrefixSpecial(true), $items_info);
$ret = true;
}
}
}
if( isset($event->MasterEvent) )
{
$event->MasterEvent->setEventParam('is_subscriber_only', $ret);
}
else
{
$event->setEventParam('is_subscriber_only', $ret);
}
}
/**
* Enter description here...
*
* @param kEvent $event
* @return bool
*/
function isSubscriberOnly(&$event)
{
$event->CallSubEvent('OnSubstituteSubscriber');
$is_subscriber = false;
if( $event->getEventParam('is_subscriber_only') )
{
$is_subscriber = true;
$object =& $event->getObject( Array('skip_autoload' => true) );
$this->OnUpdate($event);
if($event->status == erSUCCESS)
{
$this->OnAfterItemCreate($event);
$object->SendEmailEvents();
if( !$this->Application->IsAdmin() && ($event->status == erSUCCESS) && $event->redirect) $this->autoLoginUser($event);
}
}
return $is_subscriber;
}
/**
* Creates new user
*
* @param kEvent $event
*/
function OnCreate(&$event)
{
if( !$this->Application->IsAdmin() ) $this->setUserStatus($event);
if( !$this->isSubscriberOnly($event) )
{
$cs_helper =& $this->Application->recallObject('CountryStatesHelper');
$cs_helper->CheckStateField($event, 'State', 'Country');
$object =& $event->getObject( Array('skip_autoload' => true) );
/* @var $object kDBItem */
if ($this->Application->ConfigValue('User_Password_Auto')) {
$pass = makepassword4(rand(5,8));
$object->SetField('Password', $pass);
$object->SetField('VerifyPassword', $pass);
$this->Application->SetVar('user_password',$pass);
}
parent::OnCreate($event);
$this->Application->SetVar('u.current_id', $object->getID() ); // for affil:OnRegisterAffiliate after hook
$this->setNextTemplate($event);
if( !$this->Application->IsAdmin() && ($event->status == erSUCCESS) && $event->redirect)
{
$object->SendEmailEvents();
$this->autoLoginUser($event);
}
}
}
/**
* Set's new user status based on config options
*
* @param kEvent $event
*/
function setUserStatus(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
$new_users_allowed = $this->Application->ConfigValue('User_Allow_New');
// 1 - Instant, 2 - Not Allowed, 3 - Pending
switch ($new_users_allowed)
{
case 1: // Instant
$object->SetDBField('Status', 1);
$next_template = $this->Application->GetVar('registration_confirm_template');
if($next_template) $event->redirect = $next_template;
break;
case 3: // Pending
$next_template = $this->Application->GetVar('registration_confirm_pending_template');
if($next_template) $event->redirect = $next_template;
$object->SetDBField('Status', 2);
break;
case 2: // Not Allowed
$object->SetDBField('Status', 0);
break;
}
/*if ($object->GetDBField('PaidMember') == 1) {
$this->Application->HandleEvent($add_to_cart, 'ord:OnAddToCart');
$event->redirect = 'in-commerce/checkout/shop_cart';
} */
}
/**
* Set's new unique resource id to user
*
* @param kEvent $event
*/
function OnBeforeItemCreate(&$event)
{
$email_as_login = $this->Application->ConfigValue('Email_As_Login');
$object =& $event->getObject();
if ($email_as_login) {
$object->Fields['Email']['error_msgs']['unique'] = $this->Application->Phrase('lu_user_and_email_already_exist');
}
}
/**
* Set's new unique resource id to user
*
* @param kEvent $event
*/
function OnAfterItemValidate(&$event)
{
$object =& $event->getObject();
$resource_id = $object->GetDBField('ResourceId');
if (!$resource_id)
{
$object->SetDBField('ResourceId', $this->Application->NextResourceId() );
}
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnRecommend(&$event)
{
$friend_email = $this->Application->GetVar('friend_email');
$friend_name = $this->Application->GetVar('friend_email');
// used for error reporting only -> rewrite code + theme (by Alex)
$object =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); // TODO: change theme too
/* @var $object UsersItem */
if (preg_match("/^[_a-zA-Z0-9-\.]+@[a-zA-Z0-9-\.]+\.[a-z]{2,4}$/", $friend_email))
{
$send_params = array();
$send_params['to_email']=$friend_email;
$send_params['to_name']=$friend_name;
$user_id = $this->Application->RecallVar('user_id');
$email_event =& $this->Application->EmailEventUser('SITE.SUGGEST', $user_id, $send_params);
if ($email_event->status == erSUCCESS){
$event->redirect_params = array('opener' => 's', 'pass' => 'all');
$event->redirect = $this->Application->GetVar('template_success');
}
else {
// $event->redirect_params = array('opener' => 's', 'pass' => 'all');
// $event->redirect = $this->Application->GetVar('template_fail');
$object->SetError('Email', 'send_error', 'lu_email_send_error');
$event->status = erFAIL;
}
}
else {
$object->SetError('Email', 'invalid_email', 'lu_InvalidEmail');
$event->status = erFAIL;
}
}
/**
* Saves address changes and mades no redirect
*
* @param kEvent $event
*/
function OnUpdateAddress(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
list($id,$field_values) = each($items_info);
if($id > 0) $object->Load($id);
$object->SetFieldsFromHash($field_values);
$object->setID($id);
$object->Validate();
}
$event->redirect = false;
}
/**
* Validate subscriber's email & store it to session -> redirect to confirmation template
*
* @param kEvent $event
*/
function OnSubscribeQuery(&$event)
{
$user_email = $this->Application->GetVar('subscriber_email');
if (preg_match("/^[_a-zA-Z0-9-\.]+@[a-zA-Z0-9-\.]+\.[a-z]{2,4}$/", $user_email)) {
$object =& $this->Application->recallObject($this->Prefix.'.subscriber', null, Array('skip_autoload' => true));
/* @var $object UsersItem */
$this->Application->StoreVar('SubscriberEmail', $user_email);
$object->Load($user_email, 'Email');
if ($object->isLoaded()) {
$group_info = $this->GetGroupInfo($object->GetID());
$event->redirect = $this->Application->GetVar($group_info ? 'unsubscribe_template' : 'subscribe_template');
}
else {
$event->redirect = $this->Application->GetVar('subscribe_template');
$this->Application->StoreVar('SubscriberEmail', $user_email);
}
}
else {
// used for error reporting only -> rewrite code + theme (by Alex)
$object =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); // TODO: change theme too
/* @var $object UsersItem */
$object->SetError('SubscribeEmail', 'invalid_email', 'lu_InvalidEmail');
$event->status = erFAIL;
}
}
/**
* Subscribe/Unsubscribe user based on email stored in previous step
*
* @param kEvent $event
*/
function OnSubscribeUser(&$event)
{
$object = &$this->Application->recallObject($this->Prefix.'.subscriber', null, Array('skip_autoload' => true));
/* @var $object UsersItem */
$user_email = $this->Application->RecallVar('SubscriberEmail');
if (preg_match("/^[_a-zA-Z0-9-\.]+@[a-zA-Z0-9-\.]+\.[a-z]{2,4}$/", $user_email)) {
$this->RemoveRequiredFields($object);
$object->Load($user_email, 'Email');
if ($object->isLoaded()) {
$group_info = $this->GetGroupInfo($object->GetID());
if ($group_info){
if ($event->getEventParam('no_unsubscribe')) return;
if ($group_info['PrimaryGroup']){
// delete user
$object->Delete();
}
else {
$this->RemoveSubscriberGroup($object->GetID());
}
$event->redirect = $this->Application->GetVar('unsubscribe_ok_template');
}
else {
$this->AddSubscriberGroup($object->GetID(), 0);
$event->redirect = $this->Application->GetVar('subscribe_ok_template');
}
}
else {
$object->SetField('Email', $user_email);
$object->SetField('Login', $user_email);
$object->SetDBField('dob', 1);
$object->SetDBField('dob_date', 1);
$object->SetDBField('dob_time', 1);
$ip = getenv('HTTP_X_FORWARDED_FOR')?getenv('HTTP_X_FORWARDED_FOR'):getenv('REMOTE_ADDR');
$object->SetDBField('ip', $ip);
$this->Application->SetVar('IsSubscriber', 1);
if ($object->Create()) {
$this->AddSubscriberGroup($object->GetID(), 1);
$event->redirect = $this->Application->GetVar('subscribe_ok_template');
}
$this->Application->SetVar('IsSubscriber', 0);
}
}
}
function AddSubscriberGroup($user_id, $is_primary){
$group_id = $this->Application->ConfigValue('User_SubscriberGroup');
$sql = 'INSERT INTO '.TABLE_PREFIX.'UserGroup(PortalUserId,GroupId,PrimaryGroup) VALUES (%s,%s,'.$is_primary.')';
$this->Conn->Query( sprintf($sql, $user_id, $group_id) );
$this->Application->EmailEventAdmin('USER.SUBSCRIBE', $user_id);
$this->Application->EmailEventUser('USER.SUBSCRIBE', $user_id);
}
function RemoveSubscriberGroup($user_id){
$group_id = $this->Application->ConfigValue('User_SubscriberGroup');
$sql = 'DELETE FROM '.TABLE_PREFIX.'UserGroup WHERE PortalUserId='.$user_id.' AND GroupId='.$this->Application->ConfigValue('User_SubscriberGroup');
$this->Conn->Query($sql);
$this->Application->EmailEventAdmin('USER.UNSUBSCRIBE', $user_id);
$this->Application->EmailEventUser('USER.UNSUBSCRIBE', $user_id);
}
/**
* Allows to detect user subscription status (subscribed or not)
*
* @param int $user_id
* @return bool
*/
function GetGroupInfo($user_id)
{
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'UserGroup
WHERE (PortalUserId = '.$user_id.') AND (GroupId = '.$this->Application->ConfigValue('User_SubscriberGroup').')';
return $this->Conn->GetRow($sql);
}
function OnForgotPassword(&$event)
{
$user_object =& $this->Application->recallObject('u.forgot', null, Array('skip_autoload' => true));
/* @var $user_object UsersItem */
// used for error reporting only -> rewrite code + theme (by Alex)
$user_current_object =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); // TODO: change theme too
/* @var $user_current_object UsersItem */
$username = $this->Application->GetVar('username');
$email = $this->Application->GetVar('email');
$found = false;
$allow_reset = true;
if (strlen($username)) {
$user_object->Load($username, 'Login');
if ($user_object->isLoaded()) {
$found = ($user_object->GetDBField("Login")==$username && $user_object->GetDBField("Status")==1) && strlen($user_object->GetDBField("Password"));
}
}
else if(strlen($email)) {
$user_object->Load($email, 'Email');
if ($user_object->isLoaded()) {
$found = ($user_object->GetDBField("Email")==$email && $user_object->GetDBField("Status")==1) && strlen($user_object->GetDBField("Password"));
}
}
if ($user_object->isLoaded()) {
$PwResetConfirm = $user_object->GetDBField('PwResetConfirm');
$PwRequestTime = $user_object->GetDBField('PwRequestTime');
$PassResetTime = $user_object->GetDBField('PassResetTime');
//$MinPwResetDelay = $user_object->GetDBField('MinPwResetDelay');
$MinPwResetDelay = $this->Application->ConfigValue('Users_AllowReset');
$allow_reset = (strlen($PwResetConfirm) ?
adodb_mktime() > $PwRequestTime + $MinPwResetDelay :
adodb_mktime() > $PassResetTime + $MinPwResetDelay);
}
if ($found && $allow_reset) {
$this->Application->StoreVar('tmp_user_id', $user_object->GetDBField("PortalUserId"));
$this->Application->StoreVar('tmp_email', $user_object->GetDBField("Email"));
$confirm_template = $this->Application->GetVar('reset_confirm_template');
if (!$confirm_template) {
$this->Application->SetVar('reset_confirm_template', 'platform/login/forgotpass_reset');
}
$this->Application->EmailEventUser('USER.PSWDC', $user_object->GetDBField('PortalUserId'));
$event->redirect = $this->Application->GetVar('template_success');
}
else {
if (!strlen($username) && !strlen($email)) {
$user_current_object->SetError('Login', 'forgotpw_nodata', 'lu_ferror_forgotpw_nodata');
$user_current_object->SetError('Email', 'forgotpw_nodata', 'lu_ferror_forgotpw_nodata');
}
else {
if ($allow_reset) {
if (strlen($username)) {
$user_current_object->SetError('Login', 'unknown_username', 'lu_ferror_unknown_username');
}
if (strlen($email)) {
$user_current_object->SetError('Email', 'unknown_email', 'lu_ferror_unknown_email');
}
}
else {
if (strlen($username)) {
$user_current_object->SetError('Login', 'reset_denied', 'lu_ferror_reset_denied');
}
if (strlen($email)) {
$user_current_object->SetError('Email', 'reset_denied', 'lu_ferror_reset_denied');
}
}
}
if($user_current_object->FieldErrors){
$event->redirect = false;
}
}
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnResetPassword(&$event)
{
$user_object =& $this->Application->recallObject('u.forgot');
if($user_object->Load($this->Application->RecallVar('tmp_user_id'))){
$this->Application->EmailEventUser('USER.PSWDC', $user_object->GetDBField("PortalUserId"));
$event->redirect = $this->Application->GetVar('template_success');
$m_cat_id = $this->Application->findModule('Name', 'In-Commerce', 'RootCat');
$this->Application->SetVar('m_cat_id', $m_cat_id);
$event->SetRedirectParam('pass', 'm');
}
}
function OnResetPasswordConfirmed(&$event)
{
// used for error reporting only -> rewrite code + theme (by Alex)
$user_current_object =& $this->Application->recallObject('u', null, Array('skip_autoload' => true));// TODO: change theme too
/* @var $user_current_object UsersItem */
$passed_key = trim($this->Application->GetVar('user_key'));
if (!$passed_key) {
$event->redirect_params = Array('opener' => 's', 'pass' => 'all');
$event->redirect = false;
$user_current_object->SetError('PwResetConfirm', 'code_is_not_valid', 'lu_code_is_not_valid');
}
$user_object =& $this->Application->recallObject('u.forgot', null, Array('skip_autoload' => true));
/* @var $user_object UsersItem */
$user_object->Load($passed_key, 'PwResetConfirm');
if ($user_object->isLoaded()) {
$exp_time = $user_object->GetDBField('PwRequestTime') + 3600;
$user_object->SetDBField('PwResetConfirm', '');
$user_object->SetDBField('PwRequestTime', 0);
if ($exp_time > adodb_mktime()) {
$newpw = makepassword4();
$this->Application->StoreVar('password', $newpw);
$user_object->SetDBField('Password', $newpw);
$user_object->SetDBField('PassResetTime', adodb_mktime());
$user_object->SetDBField('PwResetConfirm', '');
$user_object->SetDBField('PwRequestTime', 0);
$user_object->Update();
$this->Application->SetVar('ForgottenPassword', $newpw);
$email_event_user =& $this->Application->EmailEventUser('USER.PSWD', $user_object->GetDBField('PortalUserId'));
$email_event_admin =& $this->Application->EmailEventAdmin('USER.PSWD');
$this->Application->DeleteVar('ForgottenPassword');
if ($email_event_user->status == erSUCCESS) {
$event->redirect_params = array('opener' => 's', 'pass' => 'all');
$event->redirect = $this->Application->GetVar('template_success');
}
$user_object->SetDBField('Password', md5($newpw));
$user_object->Update();
} else {
$user_current_object->SetError('PwResetConfirm', 'code_expired', 'lu_code_expired');
$event->redirect = false;
}
} else {
$user_current_object->SetError('PwResetConfirm', 'code_is_not_valid', 'lu_code_is_not_valid');
$event->redirect = false;
}
}
function OnUpdate(&$event)
{
$cs_helper =& $this->Application->recallObject('CountryStatesHelper');
$cs_helper->CheckStateField($event, 'State', 'Country');
parent::OnUpdate($event);
$this->setNextTemplate($event);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function setNextTemplate(&$event)
{
if( !$this->Application->IsAdmin() )
{
$event->redirect_params['opener'] = 's';
$object =& $event->getObject();
if($object->GetDBField('Status') == STATUS_ACTIVE)
{
$next_template = $this->Application->GetVar('next_template');
if($next_template) $event->redirect = $next_template;
}
}
}
/**
* Delete users from groups if their membership is expired
*
* @param kEvent $event
*/
function OnCheckExpiredMembership(&$event)
{
// send pre-expiration reminders: begin
$pre_expiration = adodb_mktime() + $this->Application->ConfigValue('User_MembershipExpirationReminder') * 3600 * 24;
$sql = 'SELECT PortalUserId, GroupId
FROM '.TABLE_PREFIX.'UserGroup
WHERE (MembershipExpires IS NOT NULL) AND (ExpirationReminderSent = 0) AND (MembershipExpires < '.$pre_expiration.')';
$skip_clause = $event->getEventParam('skip_clause');
if ($skip_clause) {
$sql .= ' AND !('.implode(') AND !(', $skip_clause).')';
}
$records = $this->Conn->Query($sql);
if ($records) {
$conditions = Array();
foreach ($records as $record) {
$email_event_user =& $this->Application->EmailEventUser('USER.MEMBERSHIP.EXPIRATION.NOTICE', $record['PortalUserId']);
$email_event_admin =& $this->Application->EmailEventAdmin('USER.MEMBERSHIP.EXPIRATION.NOTICE');
$conditions[] = '(PortalUserId = '.$record['PortalUserId'].' AND GroupId = '.$record['GroupId'].')';
}
$sql = 'UPDATE '.TABLE_PREFIX.'UserGroup
SET ExpirationReminderSent = 1
WHERE '.implode(' OR ', $conditions);
$this->Conn->Query($sql);
}
// send pre-expiration reminders: end
// remove users from groups with expired membership: begin
$sql = 'SELECT PortalUserId
FROM '.TABLE_PREFIX.'UserGroup
WHERE (MembershipExpires IS NOT NULL) AND (MembershipExpires < '.adodb_mktime().')';
$user_ids = $this->Conn->GetCol($sql);
if ($user_ids) {
foreach ($user_ids as $id) {
$email_event_user =& $this->Application->EmailEventUser('USER.MEMBERSHIP.EXPIRED', $id);
$email_event_admin =& $this->Application->EmailEventAdmin('USER.MEMBERSHIP.EXPIRED');
}
}
$sql = 'DELETE FROM '.TABLE_PREFIX.'UserGroup
WHERE (MembershipExpires IS NOT NULL) AND (MembershipExpires < '.adodb_mktime().')';
$this->Conn->Query($sql);
// remove users from groups with expired membership: end
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnRefreshForm(&$event)
{
$event->redirect = false;
$item_info = $this->Application->GetVar($event->Prefix_Special);
list($id, $fields) = each($item_info);
$object =& $event->getObject( Array('skip_autoload' => true) );
$object->setID($id);
$object->IgnoreValidation = true;
$object->SetFieldsFromHash($fields);
}
/**
* Sets persistant variable
*
* @param kEvent $event
*/
function OnSetPersistantVariable(&$event)
{
$object =& $event->getObject();
$field = $this->Application->GetVar('field');
$value = $this->Application->GetVar('value');
$object->setPersistantVar($field, $value);
$force_tab = $this->Application->GetVar('SetTab');
if ($force_tab) {
$this->Application->StoreVar('force_tab', $force_tab);
}
}
/**
* Overwritten to return user from order by special .ord
*
* @param kEvent $event
*/
function getPassedID(&$event)
{
switch ($event->Special) {
case 'ord':
$order =& $this->Application->recallObject('ord');
/* @var $order OrdersItem */
$id = $order->GetDBField('PortalUserId');
break;
case 'profile':
$id = $this->Application->GetVar('user_id');
if (!$id) {
// if none user_id given use current user id
$id = $this->Application->RecallVar('user_id');
}
break;
default:
$id = parent::getPassedID($event);
break;
}
return $id;
}
/**
* Allows to change root password
*
* @param kEvent $event
*/
function OnUpdateRootPassword(&$event)
{
$user_id = $this->Application->RecallVar('user_id');
if ($user_id != -1) {
// not "root" can't change root's password via this event
return false;
}
// put salt to user's config
$field_options = $this->Application->getUnitOption($event->Prefix.'.RootPassword', 'Fields');
$field_options['salt'] = 'b38';
$this->Application->setUnitOption($event->Prefix.'.RootPassword', 'Fields', $field_options);
$object =& $event->getObject( Array('skip_autoload' => true) );
/* @var $object UsersItem */
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if ($items_info) {
list ($id, $field_values) = each($items_info);
$this->RemoveRequiredFields($object);
$object->SetDBField('RootPassword', $this->Application->ConfigValue('RootPass'));
$object->SetFieldsFromHash($field_values);
$status = $object->Validate();
if ($status) {
// validation on, password match too
$fields_hash = Array (
'VariableValue' => $object->GetDBField('RootPassword')
);
$conf_table = $this->Application->getUnitOption('conf', 'TableName');
$this->Conn->doUpdate($fields_hash, $conf_table, 'VariableName = "RootPass"');
$event->SetRedirectParam('opener', 'u');
}
else {
$event->status = erFAIL;
$event->redirect = false;
}
}
}
/**
* 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)
{
parent::prepareObject($object, $event);
if (!$this->Application->IsAdmin()) {
if ($this->Application->RecallVar('register_captcha_code')) return ;
$captcha_helper =& $this->Application->recallObject('CaptchaHelper');
/* @var $captcha_helper kCaptchaHelper */
$this->Application->StoreVar('register_captcha_code', $captcha_helper->GenerateCaptchaCode());
}
}
/**
* Apply custom processing to item
*
* @param kEvent $event
*/
function customProcessing(&$event, $type)
{
if ($event->Name == 'OnCreate' && $type == 'before') {
$object =& $event->getObject();
/* @var $object kDBItem */
// if auto password has not been set already - store real one - to be used in email events
if (!$this->Application->GetVar('user_password')) {
$this->Application->SetVar('user_password', $object->GetDirtyField('Password'));
$object->SetDBField('Password_plain', $object->GetDirtyField('Password'));
}
// Validate captcha image if it's requried
if ($this->Application->ConfigValue('RegistrationCaptcha') && $object->GetDBField('Captcha') != $this->Application->RecallVar('register_captcha_code')) {
$object->SetError('Captcha', 'captcha_error', 'lu_captcha_error');
$captcha_helper =& $this->Application->recallObject('CaptchaHelper');
/* @var $captcha_helper kCaptchaHelper */
$this->Application->StoreVar('register_captcha_code', $captcha_helper->GenerateCaptchaCode());
}
}
}
+ function OnMassResetSettings(&$event)
+ {
+ if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
+ return;
+ }
+
+ $event->status=erSUCCESS;
+ $ids = $this->StoreSelectedIDs($event);
+
+ $default_user_id = $this->Application->ConfigValue('DefaultSettingsUserId');
+ if (in_array($default_user_id, $ids)) {
+ array_splice($ids, array_search($default_user_id, $ids), 1);
+ }
+ if ($ids) {
+ $q = 'DELETE FROM '.TABLE_PREFIX.'PersistantSessionData WHERE PortalUserId IN ('.join(',', $ids).') AND
+ (VariableName LIKE "%_columns_%"
+ OR
+ VariableName LIKE "%_filter%"
+ OR
+ VariableName LIKE "%_PerPage%")';
+ $this->Conn->Query($q);
+ }
+ $this->clearSelectedIDs($event);
+ }
+
/**
* Checks, that currently loaded item is allowed for viewing (non permission-based)
*
* @param kEvent $event
* @return bool
*/
function checkItemStatus(&$event)
{
$object =& $event->getObject();
if (!$object->isLoaded()) {
return true;
}
$virtual_users = Array (-1, -2); // root, Guest
return ($object->GetDBField('Status') == STATUS_ACTIVE) || in_array($object->GetID(), $virtual_users);
}
/**
* Sends approved/declined email event on user status change
*
* @param kEvent $event
*/
function OnAfterItemUpdate(&$event)
{
$object =& $event->getObject();
/* @var $object UsersItem */
if (!$this->Application->IsAdmin() || $object->IsTempTable()) {
return ;
}
$this->sendStatusChangeEvent($object->GetID(), $object->GetOriginalField('Status'), $object->GetDBField('Status'));
}
/**
* Stores user's original Status before overwriting with data from temp table
*
* @param kEvent $event
*/
function OnBeforeDeleteFromLive(&$event)
{
$user_status = $this->Application->GetVar('user_status');
if (!$user_status) {
$user_status = Array ();
}
$user_id = $event->getEventParam('id');
if ($user_id > 0) {
$user_status[$user_id] = $this->getUserStatus($user_id);
$this->Application->SetVar('user_status', $user_status);
}
}
/**
* Sends approved/declined email event on user status change (in temp tables during editing)
*
* @param kEvent $event
*/
function OnAfterCopyToLive(&$event)
{
$temp_id = $event->getEventParam('temp_id');
if ($temp_id == 0) {
// this is new user create, don't send email events
return ;
}
$new_status = $this->getUserStatus($temp_id);
$user_status = $this->Application->GetVar('user_status');
$this->sendStatusChangeEvent($temp_id, $user_status[$temp_id], $new_status);
}
/**
* Returns user status (active, pending, disabled) based on ID and temp mode setting
*
* @param int $user_id
* @return int
*/
function getUserStatus($user_id)
{
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
$sql = 'SELECT Status
FROM '.$table_name.'
WHERE '.$id_field.' = '.$user_id;
return $this->Conn->GetOne($sql);
}
/**
* Sends approved/declined email event on user status change
*
* @param int $user_id
* @param int $prev_status
* @param int $new_status
*/
function sendStatusChangeEvent($user_id, $prev_status, $new_status)
{
$status_events = Array (
STATUS_ACTIVE => 'USER.APPROVE',
STATUS_DISABLED => 'USER.DENY',
);
$email_event = isset($status_events[$new_status]) ? $status_events[$new_status] : false;
if (($prev_status != $new_status) && $email_event) {
$this->Application->EmailEventUser($email_event, $user_id);
$this->Application->EmailEventAdmin($email_event);
}
}
/**
* OnAfterConfigRead for users
*
* @param kEvent $event
*/
function OnAfterConfigRead(&$event)
{
parent::OnAfterConfigRead($event);
$first_country = $this->Application->ConfigValue('User_Default_Registration_Country');
if ($first_country) {
// update user country dropdown sql
$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
$fields['Country']['options_sql'] = preg_replace('/ORDER BY (.*)/', 'ORDER BY IF (DestId = '.$first_country.', 1, 0) DESC, \\1', $fields['Country']['options_sql']);
$this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
}
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/users/users_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.87.2.6
\ No newline at end of property
+1.87.2.7
\ No newline at end of property
Index: branches/RC/core/units/admin/admin_events_handler.php
===================================================================
--- branches/RC/core/units/admin/admin_events_handler.php (revision 9638)
+++ branches/RC/core/units/admin/admin_events_handler.php (revision 9639)
@@ -1,261 +1,450 @@
<?php
class AdminEventsHandler extends kDBEventHandler {
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array(
'OnSaveColumns' => array('self' => true),
'OnClosePopup' => array('self' => true),
'OnSaveSetting' => array('self' => true),
+ // export/import permissions is checked within events
+ 'OnExportCSV' => Array('self' => true),
+ 'OnGetCSV' => Array('self' => true),
+ 'OnCSVImportBegin' => Array('self' => true),
+ 'OnCSVImportStep' => Array('self' => true),
+ 'OnDropTempTablesByWID' => array('self' => true),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
function OnResetModRwCache(&$event)
{
$this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName LIKE "mod_rw%"');
}
function OnResetCMSMenuCache(&$event)
{
$this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName = "cms_menu"');
}
function OnResetSections(&$event)
{
$this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName = "sections_parsed"');
}
function OnResetConfigsCache(&$event)
{
$this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName = "config_files" OR VarName = "configs_parsed" OR VarName = "sections_parsed"');
}
function OnCompileTemplates(&$event)
{
$compiler =& $this->Application->recallObject('NParserCompiler');
/* @var $compiler NParserCompiler */
$compiler->CompileTemplatesStep();
$event->status = erSTOP;
}
/**
* Generates sturcture for specified table
*
* @param kEvent $event
* @author Alex
*/
function OnGenerateTableStructure(&$event)
{
$types_hash = Array(
'string' => 'varchar|text|mediumtext|longtext|date|datetime|time|timestamp|char|year|enum|set',
'int' => 'smallint|mediumint|int|bigint|tinyint',
'float' => 'float|double|decimal',
);
$table_name = $this->Application->GetVar('table_name');
if (!$table_name) {
echo 'error: no table name specified';
return ;
}
if (TABLE_PREFIX && !preg_match('/^'.preg_quote(TABLE_PREFIX, '/').'(.*)/', $table_name)) {
// table name without prefix, then add it
$table_name = TABLE_PREFIX.$table_name;
}
if (!$this->Conn->TableFound($table_name)) {
// table with prefix doesn't exist, assume that just config prefix passed -> resolve table name from it
$table_name = $this->Application->getUnitOption(substr($table_name, strlen(TABLE_PREFIX)), 'TableName');
}
$table_info = $this->Conn->Query('DESCRIBE '.$table_name);
// 1. prepare config keys
$id_field = '';
$fields = Array();
$float_types = Array ('float', 'double', 'numeric');
foreach ($table_info as $field_info) {
if (preg_match('/l[\d]+_.*/', $field_info['Field'])) {
// don't put multilingual fields in config
continue;
}
$field_options = Array ();
// 1. get php field type by mysql field type
foreach ($types_hash as $php_type => $db_types) {
if (preg_match('/'.$db_types.'/', $field_info['Type'])) {
$field_options['type'] = $php_type;
break;
}
}
$default_value = $field_info['Default'];
if (in_array($php_type, $float_types)) {
// this is float number
if (preg_match('/'.$db_types.'\([\d]+,([\d]+)\)/i', $field_info['Type'], $regs)) {
// size is described in structure -> add formatter
$field_options['formatter'] = 'kFormatter';
$field_options['format'] = '%01.'.$regs[1].'f';
if ($field_info['Null'] != 'YES') {
// null fields, will most likely have NULL as default value
$default_value = 0;
}
}
else {
// no size information, just convert to float
if ($field_info['Null'] != 'YES') {
// null fields, will most likely have NULL as default value
$default_value = (float)$default_value;
}
}
}
if (preg_match('/varchar\(([\d]+)\)/i', $field_info['Type'], $regs)) {
$field_options['max_len'] = (int)$regs[1];
}
if ($field_info['Null'] != 'YES') {
$field_options['not_null'] = 1;
}
if ($field_info['Key'] == 'PRI') {
$default_value = 0;
$id_field = $field_info['Field'];
}
if ($php_type == 'int' && ($field_info['Null'] != 'YES' || is_numeric($default_value))) {
// is integer field AND not null
$field_options['default'] = (int)$default_value;
}
else {
$field_options['default'] = $default_value;
}
$fields[ $field_info['Field'] ] = $this->transformDump($field_options);
}
$ret = stripslashes(var_export($fields, true));
$ret = preg_replace("/'(.*?)' => 'Array \((.*?), \)',/", "'\\1' => Array (\\2),", $ret);
$ret = preg_replace("/\n '/", "\n\t'", $ret);
$ret = "'IDField' => '".$id_field."',\n'Fields' => A".substr($ret, 1).',';
ob_start();
?>
<html>
<head>
<title>Table "<?php echo $table_name; ?>" Structure</title>
</head>
<body bgcolor="#E7E7E7">
<a href="javascript:window.close();">Close Window</a><br />
<?php echo $GLOBALS['debugger']->highlightString($ret); ?>
<br /><a href="javascript:window.close();">Close Window</a><br />
</body>
</html>
<?php
echo ob_get_clean();
$event->status = erSTOP;
}
function transformDump($dump)
{
if (is_array($dump)) {
$dump = var_export($dump, true);
}
$dump = preg_replace("/,\n[ ]*/", ', ', $dump);
$dump = preg_replace("/array \(\n[ ]*/", 'Array (', $dump); // replace array start
$dump = preg_replace("/,\n[ ]*\),/", "),", $dump); // replace array end
return $dump;
}
/**
* Refreshes ThemeFiles & Theme tables by actual content on HDD
*
* @param kEvent $event
*/
function OnRebuildThemes(&$event)
{
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$themes_helper->refreshThemes();
}
function OnSaveColumns(&$event) {
/* @var $picker_helper kColumnPickerHelper */
$picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
$picker_helper->SetGridName($this->Application->GetLinkedVar('grid_name'));
$picked = trim($this->Application->GetVar('picked_str'), '|');
$hidden = trim($this->Application->GetVar('hidden_str'), '|');
$main_prefix = $this->Application->GetVar('main_prefix');
$picker_helper->SaveColumns($main_prefix, $picked, $hidden);
$this->finalizePopup($event);
}
/**
* Saves various admin settings via ajax
*
* @param kEvent $event
*/
function OnSaveSetting(&$event)
{
if ($this->Application->GetVar('ajax') != 'yes') {
return ;
}
$var_name = $this->Application->GetVar('var_name');
$var_value = $this->Application->GetVar('var_value');
$this->Application->StorePersistentVar($var_name, $var_value);
$event->status = erSTOP;
}
/**
* Just closes popup & deletes last_template & opener_stack if popup, that is closing
*
* @param kEvent $event
*/
function OnClosePopup(&$event)
{
$event->SetRedirectParam('opener', 'u');
}
/**
* Occurs right after initialization of the kernel, used mainly as hook-to event
*
* @param kEvent $event
*/
function OnStartup(&$event)
{
}
/**
+ * Occurs right before echoing the output, in Done method of application, used mainly as hook-to event
+ *
+ * @param kEvent $event
+ */
+ function OnBeforeShutdown(&$event)
+ {
+ }
+ /**
* Is called after tree was build (when not from cache)
*
* @param kEvent $event
*/
function OnAfterBuildTree(&$event)
{
}
+ /**
+ * Called by AJAX to perform CSV export
+ *
+ * @param kEvent $event
+ */
+ function OnExportCSV(&$event)
+ {
+ $export_helper =& $this->Application->recallObject('CSVHelper');
+ /* @var $export_helper kCSVHelper */
+
+ $prefix_special = $this->Application->GetVar('PrefixSpecial');
+ if(!$prefix_special) {
+ $prefix_special = $export_helper->ExportData('prefix');
+ }
+ $prefix_elems = split('\.|_', $prefix_special, 2);
+ $perm_sections = $this->Application->getUnitOption($prefix_elems[0], 'PermSection');
+ if(!$this->Application->CheckPermission($perm_sections['main'].'.view')) {
+ $this->Application->Redirect('no_permission');
+ }
+
+ $export_helper->PrefixSpecial = $prefix_special;
+ $export_helper->grid = $this->Application->GetVar('grid');
+ $export_helper->ExportStep();
+ $event->status = erSTOP;
+ }
+
+ /**
+ * Returning created by AJAX CSV file
+ *
+ * @param kEvent $event
+ */
+ function OnGetCSV(&$event)
+ {
+ $export_helper =& $this->Application->recallObject('CSVHelper');
+ /* @var $export_helper kCSVHelper */
+
+ $prefix_special = $export_helper->ExportData('prefix');
+ $prefix_elems = split('\.|_', $prefix_special, 2);
+ $perm_sections = $this->Application->getUnitOption($prefix_elems[0], 'PermSection');
+
+ if(!$this->Application->CheckPermission($perm_sections['main'].'.view')) {
+ $this->Application->Redirect('no_permission');
+ }
+
+ $export_helper->GetCSV();
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param kEvent $event
+ */
+ function OnCSVImportBegin(&$event)
+ {
+ $prefix_special = $this->Application->GetVar('PrefixSpecial');
+ $prefix_elems = split('\.|_', $prefix_special, 2);
+ $perm_sections = $this->Application->getUnitOption($prefix_elems[0], 'PermSection');
+
+ if(!$this->Application->CheckPermission($perm_sections['main'].'.add') && !$this->Application->CheckPermission($perm_sections['main'].'.edit')) {
+ $this->Application->Redirect('no_permission');
+ }
+
+ $object =& $event->getObject( Array('skip_autoload' => true) );
+ /* @var $object kDBItem */
+ $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
+ $field_values = array_shift($items_info);
+ $object->SetFieldsFromHash($field_values);
+
+ $event->redirect = false;
+ $result = 'required';
+ if($object->GetDBField('ImportFile')) {
+ $import_helper =& $this->Application->recallObject('CSVHelper');
+ /* @var $import_helper kCSVHelper */
+ $import_helper->PrefixSpecial = $this->Application->GetVar('PrefixSpecial');
+ $import_helper->grid = $this->Application->GetVar('grid');
+ $result = $import_helper->ImportStart( $object->GetField('ImportFile', 'file_paths') );
+ if($result === true) {
+ $event->redirect = $this->Application->GetVar('next_template');
+ $event->SetRedirectParam('PrefixSpecial', $this->Application->GetVar('PrefixSpecial'));
+ $event->SetRedirectParam('grid', $this->Application->GetVar('grid'));
+ }
+ }
+
+ if($event->redirect === false) {
+ $object->SetError('ImportFile', $result);
+ $event->status = erFAIL;
+ }
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param kEvent $event
+ */
+ function OnCSVImportStep(&$event)
+ {
+ $import_helper =& $this->Application->recallObject('CSVHelper');
+ /* @var $export_helper kCSVHelper */
+
+ $prefix_special = $import_helper->ImportData('prefix');
+ $prefix_elems = split('\.|_', $prefix_special, 2);
+ $perm_sections = $this->Application->getUnitOption($prefix_elems[0], 'PermSection');
+ if(!$this->Application->CheckPermission($perm_sections['main'].'.add') && !$this->Application->CheckPermission($perm_sections['main'].'.edit')) {
+ $this->Application->Redirect('no_permission');
+ }
+
+ $import_helper->ImportStep();
+ $event->status = erSTOP;
+ }
+
function OnCheckPrefixConfig(&$event)
{
$prefix = $this->Application->GetVar('config_prefix');
$cfg =& $this->Application->recallObject('kConfigReflection');
/* @var $cfg kConfigReflection */
$cfg->LoadConfig($prefix);
$event->redirect = false;
}
+ function OnUploadFile(&$event)
+ {
+ // Flash uploader does NOT send correct cookies, so we need to make our own check
+ $cookie_name = 'adm_'.$this->Application->ConfigValue('SessionCookieName');
+ $this->Application->HttpQuery->Cookie['cookies_on'] = 1;
+ $this->Application->HttpQuery->Cookie[$cookie_name] = $this->Application->GetVar('flashsid');
+
+ $admin_ses =& $this->Application->recallObject('Session.admin');
+ /* @var $admin_ses Session */
+ $user = $admin_ses->RecallVar('user_id');
+ $perm_helper =& $this->Application->recallObject('PermissionsHelper');
+ /* @var $perm_helper kPermissionsHelper */
+
+ /*if() {
+ $prefix_special = $this->Application->GetVar('PrefixSpecial');
+ $prefix_elems = split('\.|_', $prefix_special, 2);
+ $perm_sections = $this->Application->getUnitOption($prefix_elems[0], 'PermSection');
+ $section = $perm_sections['main'];
+ }
+ else {*/
+ $section = $event->getSection();
+ /*}*/
+
+ if ($this->Application->GetVar('t') != 'import/import_start' && !$perm_helper->CheckUserPermission($user, $section.'.add') && !$perm_helper->CheckUserPermission($user, $section.'.edit')) {
+ $event->status = erPERM_FAIL;
+ header('HTTP/1.0 403 You don\'t have permissions to upload');
+ exit;
+ return;
+ }
+
+ if (!$cookie_name) $cookie_name = 'sid';
+
+ $value = $this->Application->GetVar('Filedata');
+ if (!$value) return ;
+ $tmp_path = WRITEABLE.'/tmp/';
+ $fname = $value['name'];
+ $id = $this->Application->GetVar('id');
+ if ($id) $fname = $id.'_'.$fname;
+
+ if (!is_writable($tmp_path)) {
+ header('HTTP/1.0 500 Write permissions not set on the server');
+ exit;
+ }
+
+ move_uploaded_file($value['tmp_name'], $tmp_path.$fname);
+ exit;
+ }
+
+ function OnDropTempTablesByWID(&$event)
+ {
+ $sid = $this->Application->GetSID();
+ $wid = $this->Application->GetVar('m_wid');
+ $tables = $this->Conn->GetCol('SHOW TABLES');
+ $mask_edit_table = '/'.TABLE_PREFIX.'ses_'.$sid.'_'.$wid.'_edit_(.*)$/';
+ foreach($tables as $table)
+ {
+ if( preg_match($mask_edit_table,$table,$rets) )
+ {
+ $this->Conn->Query('DROP TABLE IF EXISTS '.$table);
+ }
+ }
+ echo 'OK';
+ $event->status = erSTOP;
+ return ;
+ }
}
\ No newline at end of file
Property changes on: branches/RC/core/units/admin/admin_events_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.8.2.6
\ No newline at end of property
+1.8.2.7
\ No newline at end of property
Index: branches/RC/core/units/admin/admin_config.php
===================================================================
--- branches/RC/core/units/admin/admin_config.php (revision 9638)
+++ branches/RC/core/units/admin/admin_config.php (revision 9639)
@@ -1,56 +1,71 @@
<?php
$config = Array(
'Prefix' => 'adm',
+ 'ItemClass' => Array('class' => 'kDBItem','file'=>'','build_event'=>'OnItemBuild'),
'EventHandlerClass' => Array('class' => 'AdminEventsHandler', 'file' => 'admin_events_handler.php', 'build_event' => 'OnBuild'),
'TagProcessorClass' => Array('class' => 'AdminTagProcessor', 'file' => 'admin_tag_processor.php', 'build_event' => 'OnBuild'),
'QueryString' => Array(
1 => 'event',
),
'TitlePresets' => Array(
'tree_root' => Array('format' => '!la_section_overview!'),
'tree_reports' => Array('format' => '!la_section_overview!'),
'tree_system' => Array('format' => '!la_section_overview!'),
'tree_tools' => Array('format' => '!la_section_overview!'),
'system_tools' => Array('format' => '!la_title_SystemTools!'),
'no_permissions' => Array('format' => '!la_title_NoPermissions!'),
'column_picker' => Array('format' => '!la_title_ColumnPicker!'),
+ 'csv_export' => Array('format' => '!la_title_CSVExport!'),
+ 'csv_import' => Array('format' => '!la_title_CSVImport!'),
),
'PermSection' => array('main' => 'in-portal:service'),
'Sections' => Array(
'in-portal:root' => Array(
'parent' => null,
'icon' => 'site',
'label' => $this->Application->ConfigValue('Site_Name'),
'url' => Array('t' => 'sections_list', 'pass' => 'm', 'pass_section' => true, 'no_amp' => 1),
'permissions' => Array('advanced:admin_login', 'advanced:front_login'),
'priority' => 0,
'type' => stTREE,
'icon_module' => 'in-portal',
),
'in-portal:service' => Array(
'parent' => 'in-portal:tools',
'icon' => 'conf_general',
'label' => 'la_tab_Service',
'url' => Array('t' => 'tools/system_tools', 'pass' => 'm'),
'permissions' => Array('view'),
'priority' => 10,
'show_mode' => smDEBUG,
'type' => stTREE,
),
),
+ 'Fields' => Array(), // we need empty array because kernel doesn't use virtual fields else
+ 'VirtualFields' => Array (
+ 'ImportFile' => Array(
+ 'type'=>'string', 'formatter'=>'kUploadFormatter',
+ 'max_size'=>MAX_UPLOAD_SIZE, // in Bytes !
+ 'file_types'=>'*.csv', 'files_description'=>'!la_CSVFiles!',
+ 'upload_dir'=>'/system/import/', // relative to project's home
+ 'multiple'=>false, // false or max number of files - will be stored as serialized array of paths
+ 'direct_links'=>false, // use direct file urls or send files through wrapper (requires mod_mime_magic)
+ 'default' => null,
+ ),
+ ),
);
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/admin/admin_config.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.23
\ No newline at end of property
+1.23.2.1
\ No newline at end of property
Index: branches/RC/core/units/admin/admin_tag_processor.php
===================================================================
--- branches/RC/core/units/admin/admin_tag_processor.php (revision 9638)
+++ branches/RC/core/units/admin/admin_tag_processor.php (revision 9639)
@@ -1,862 +1,907 @@
<?php
class AdminTagProcessor extends kDBTagProcessor {
function SetConst($params)
{
$name = $this->SelectParam($params, 'name,const');
safeDefine($name, $params['value']);
}
/**
* Allows to execute js script after the page is fully loaded
*
* @param Array $params
* @return string
*/
function AfterScript($params)
{
$after_script = $this->Application->GetVar('after_script');
if ($after_script) {
return '<script type="text/javascript">'.$after_script.'</script>';
}
return '';
}
/**
* Returns section title with #section# keyword replaced with current section
*
* @param Array $params
* @return string
*/
function GetSectionTitle($params)
{
$params['name'] = replaceModuleSection($params['phrase']);
$m =& $this->Application->recallObject('m_TagProcessor');
return $m->Phrase($params);
}
/**
* Returns section icon with #section# keyword replaced with current section
*
* @param Array $params
* @return string
*/
function GetSectionIcon($params)
{
return replaceModuleSection($params['icon']);
}
/**
* Allows to detect if current template is one of listed ones
*
* @param Array $params
* @return int
*/
function TemplateMatches($params)
{
$templates = explode(',' ,$params['templates']);
$t = $this->Application->GetVar('t');
return in_array($t, $templates) ? 1 : 0;
}
/**
* Save return script in cases, when old sections are opened from new sections
*
* @param Array $params
*/
function SaveReturnScript($params)
{
// admin/save_redirect.php?do=
$m =& $this->Application->recallObject('m_TagProcessor');
$url = str_replace($this->Application->BaseURL(), '', $m->Link($params) );
$url = explode('?', $url, 2);
$url = 'save_redirect.php?'.$url[1].'&do='.$url[0];
$this->Application->StoreVar('ReturnScript', $url);
}
/**
* Redirects to correct next import step template based on import script data
*
* @param Array $params
*/
function ImportRedirect($params)
{
$import_id = $this->Application->GetVar('import_id');
if ($import_id) {
// redirect forward to step3 (import parameters coosing)
$this->Application->StoreVar('ImportScriptID', $import_id);
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'ImportScripts
WHERE is_id = '.$import_id;
$db =& $this->Application->GetADODBConnection();
$is_params = $db->GetRow($sql);
if ($is_params['is_type'] == 'db') {
$this->Application->Redirect('', null, '', 'import/step3.php');
}
elseif ($is_params['is_type'] == 'csv') {
$module = strtolower($is_params['is_Module']);
$template = $module.'/import';
$module_info = $this->Application->findModule('Name', $module);
$item_prefix = $module_info['Var'];
$pass_params = Array('m_opener' => 'd', $item_prefix.'.import_id' => 0, $item_prefix.'.import_event' => 'OnNew', 'pass' => 'm,'.$item_prefix.'.import', 'm_cat_id' => $module_info['RootCat']);
$this->Application->Redirect($template, $pass_params);
}
}
else {
// redirect back to step2 (import type choosing)
$this->Application->Redirect('', null, '', 'import/step2.php');
}
}
/**
* Returns version of module by name
*
* @param Array $params
* @return string
*/
function ModuleVersion($params)
{
return $this->Application->findModule('Name', $params['module'], 'Version');
}
/**
* Used in table form section drawing
*
* @param Array $params
* @return string
*/
function DrawTree($params)
{
static $deep_level = 0;
// when processings, then sort children by priority (key of children array)
$ret = '';
$section_name = $params['section_name'];
$params['name'] = $this->SelectParam($params, 'name,render_as,block');
$sections_helper =& $this->Application->recallObject('SectionsHelper');
$section_data =& $sections_helper->getSectionData($section_name);
$params['children_count'] = isset($section_data['children']) ? count($section_data['children']) : 0;
$params['deep_level'] = $deep_level++;
$template = $section_data['url']['t'];
unset($section_data['url']['t']);
$section_data['section_url'] = $this->Application->HREF($template, '', $section_data['url']);
$ret .= $this->Application->ParseBlock( array_merge_recursive2($params, $section_data) );
if (!isset($section_data['children'])) {
return $ret;
}
$debug_mode = $this->Application->isDebugMode();
$super_admin_mode = $this->Application->RecallVar('super_admin');
ksort($section_data['children'], SORT_NUMERIC);
foreach ($section_data['children'] as $section_name) {
$section_data =& $sections_helper->getSectionData($section_name);
if (isset($section_data['show_mode']) && is_numeric($section_data['show_mode'])) {
$show_mode = $section_data['show_mode'];
// if super admin section -> show in super admin mode & debug mode
$show_section = (($show_mode & smSUPER_ADMIN) == smSUPER_ADMIN) && ($super_admin_mode || $debug_mode);
if (!$show_section) {
// if section is in debug mode only && debug mode -> show
$show_section = (($show_mode & smDEBUG) == smDEBUG) && $debug_mode;
}
if (!$show_section) {
continue;
}
}
$params['section_name'] = $section_name;
$ret .= $this->DrawTree($params);
$deep_level--;
}
return $ret;
}
function SectionInfo($params)
{
$section = $params['section'];
if ($section == '#session#') {
$section = $this->Application->RecallVar('section');
}
$sections_helper =& $this->Application->recallObject('SectionsHelper');
/* @var $sections_helper kSectionsHelper */
$section_data =& $sections_helper->getSectionData($section);
if (isset($params['parent']) && $params['parent']) {
do {
$section_data =& $sections_helper->getSectionData($section_data['parent']);
} while (isset($section_data['use_parent_header']) && $section_data['use_parent_header']);
}
$info = $params['info'];
switch ($info) {
case 'module_path':
if (isset($params['module']) && $params['module']) {
$module = $params['module'];
}
elseif (isset($section_data['icon_module'])) {
$module = $section_data['icon_module'];
}
else {
$module = '#session#';
}
$res = $this->ModulePath(array('module' => $module));
break;
case 'perm_section':
$res = $sections_helper->getPermSection($section);
break;
default:
$res = $section_data[$info];
}
if ($info == 'label' || isset($params['as_label'])) {
$res = $this->Application->Phrase($res);
}
return $res;
}
function PrintSection($params)
{
$section_name = $params['section_name'];
if ($section_name == '#session#') {
$section_name = $this->Application->RecallVar('section');
}
$sections_helper =& $this->Application->recallObject('SectionsHelper');
/* @var $sections_helper kSectionsHelper */
if (isset($params['use_first_child']) && $params['use_first_child']) {
$section_name = $sections_helper->getFirstChild($section_name, true);
}
$section_data =& $sections_helper->getSectionData($section_name);
$params['name'] = $this->SelectParam($params, 'name,render_as,block');
$params['section_name'] = $section_name;
$template = $section_data['url']['t'];
unset($section_data['url']['t']);
$section_data['section_url'] = $this->Application->HREF($template, '', $section_data['url']);
$ret = $this->Application->ParseBlock( array_merge_recursive2($params, $section_data) );
return $ret;
}
/**
* Used in XML drawing for tree
*
* @param Array $params
* @return string
*/
function PrintSections($params)
{
// when processings, then sort children by priority (key of children array)
$ret = '';
$section_name = $params['section_name'];
if ($section_name == '#session#') {
$section_name = $this->Application->RecallVar('section');
}
$sections_helper =& $this->Application->recallObject('SectionsHelper');
/* @var $sections_helper kSectionsHelper */
$section_data =& $sections_helper->getSectionData($section_name);
$params['name'] = $this->SelectParam($params, 'name,render_as,block');
if (!isset($section_data['children'])) {
return '';
}
$debug_mode = $this->Application->isDebugMode();
$super_admin_mode = $this->Application->RecallVar('super_admin');
ksort($section_data['children'], SORT_NUMERIC);
foreach ($section_data['children'] as $section_name) {
$params['section_name'] = $section_name;
$section_data =& $sections_helper->getSectionData($section_name);
if (isset($section_data['show_mode']) && is_numeric($section_data['show_mode'])) {
$show_mode = $section_data['show_mode'];
// if super admin section -> show in super admin mode & debug mode
$show_section = (($show_mode & smSUPER_ADMIN) == smSUPER_ADMIN) && ($super_admin_mode || $debug_mode);
if (!$show_section) {
// if section is in debug mode only && debug mode -> show
$show_section = (($show_mode & smDEBUG) == smDEBUG) && $debug_mode;
}
if (!$show_section) {
continue;
}
}
if (isset($section_data['tabs_only']) && $section_data['tabs_only']) {
$perm_status = false;
$folder_label = $section_data['label'];
ksort($section_data['children'], SORT_NUMERIC);
foreach ($section_data['children'] as $priority => $section_name) {
// if only tabs in this section & none of them have permission, then skip section too
$section_name = $sections_helper->getPermSection($section_name);
$perm_status = $this->Application->CheckPermission($section_name.'.view', 1);
if ($perm_status) {
break;
}
}
if (!$perm_status) {
// no permission for all tabs -> don't display tree node either
continue;
}
$params['section_name'] = $section_name;
$section_data =& $sections_helper->getSectionData($section_name);
$section_data['label'] = $folder_label; // use folder label in tree
$section_data['is_tab'] = 1;
}
else {
$section_name = $sections_helper->getPermSection($section_name);
if (!$this->Application->CheckPermission($section_name.'.view', 1)) continue;
}
$params['children_count'] = isset($section_data['children']) ? count($section_data['children']) : 0;
$template = $section_data['url']['t'];
unset($section_data['url']['t']);
$section_data['section_url'] = $this->Application->HREF($template, '', $section_data['url']);
$late_load = getArrayValue($section_data, 'late_load');
if ($late_load) {
$t = $late_load['t'];
unset($late_load['t']);
$section_data['late_load'] = $this->Application->HREF($t, '', $late_load);
$params['children_count'] = 99;
}
else {
$section_data['late_load'] = '';
}
$ret .= $this->Application->ParseBlock( array_merge_recursive2($params, $section_data) );
$params['section_name'] = $section_name;
}
return preg_replace("/\r\n|\n/", '', $ret);
}
function ListSectionPermissions($params)
{
$section_name = isset($params['section_name']) ? $params['section_name'] : $this->Application->GetVar('section_name');
$sections_helper =& $this->Application->recallObject('SectionsHelper');
$section_data =& $sections_helper->getSectionData($section_name);
$block_params = array_merge_recursive2($section_data, Array('name' => $params['render_as'], 'section_name' => $section_name));
$ret = '';
foreach ($section_data['permissions'] as $perm_name) {
if (preg_match('/^advanced:(.*)/', $perm_name) != $params['type']) continue;
$block_params['perm_name'] = $perm_name;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
function ModuleInclude($params)
{
foreach ($params as $param_name => $param_value) {
$params[$param_name] = replaceModuleSection($param_value);
}
$m =& $this->Application->recallObject('m_TagProcessor');
return $m->ModuleInclude($params);
}
function TodayDate($params)
{
return date($params['format']);
}
function TreeEditWarrning($params)
{
$ret = $this->Application->Phrase($params['label']);
$ret = str_replace(Array('&lt;', '&gt;', 'br/', 'br /', "\n", "\r"), Array('<', '>', 'br', 'br', '', ''), $ret);
if (getArrayValue($params, 'escape')) {
$ret = addslashes($ret);
}
$ret = str_replace('<br>', '\n', $ret);
return $ret;
}
/**
* Draws section tabs using block name passed
*
* @param Array $params
*/
function ListTabs($params)
{
$sections_helper =& $this->Application->recallObject('SectionsHelper');
$section_data =& $sections_helper->getSectionData($params['section_name']);
$ret = '';
$block_params = Array('name' => $params['render_as']);
ksort($section_data['children'], SORT_NUMERIC);
foreach ($section_data['children'] as $priority => $section_name) {
if (!$this->Application->CheckPermission($section_name.'.view', 1)) continue;
$tab_data =& $sections_helper->getSectionData($section_name);
$block_params['t'] = $tab_data['url']['t'];
$block_params['title'] = $tab_data['label'];
$block_params['main_prefix'] = $section_data['SectionPrefix'];
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Returns list of module item tabs that have view permission in current category
*
* @param Array $params
*/
function ListCatalogTabs($params)
{
$ret = '';
$special = isset($params['special']) ? $params['special'] : '';
$replace_main = isset($params['replace_m']) && $params['replace_m'];
$skip_prefixes = isset($params['skip_prefixes']) ? explode(',', $params['skip_prefixes']) : Array();
$block_params = Array('name' => $params['render_as']);
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
$prefix = $module_info['Var'];
if (in_array($prefix, $skip_prefixes) || !$this->Application->prefixRegistred($prefix) || !$this->Application->getUnitOption($prefix, 'CatalogItem')) continue;
if ($prefix == 'm' && $replace_main) $prefix = 'c';
$label = $this->Application->getUnitOption($prefix, $params['title_property']);
$block_params['title'] = $label;
$block_params['prefix'] = $prefix;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
function FCKEditor($params)
{
if (file_exists(FULL_PATH.'/core/cmseditor/fckeditor.php')) {
$editor_path = 'core/cmseditor/';
}
else {
$editor_path = 'admin/editor/cmseditor/';
}
include_once(FULL_PATH.'/'.$editor_path.'/fckeditor.php');
$oFCKeditor = new FCKeditor($params['name']);
$oFCKeditor->BasePath = BASE_PATH.'/'.$editor_path;
$oFCKeditor->Width = $params['width'] ;
$oFCKeditor->Height = $params['height'] ;
$oFCKeditor->ToolbarSet = 'Advanced' ;
$oFCKeditor->Value = '' ;
if ($this->Application->isModuleEnabled('In-Portal')) {
$config_path = $this->Application->BaseURL().'kernel/admin_templates/incs/inp_fckconfig.js';
}
else {
$config_path = $this->Application->BaseURL().'core/admin_templates/js/inp_fckconfig.js';
}
$oFCKeditor->Config = Array(
// 'UserFilesPath' => FULL_PATH.'/kernel/user_files',
'ProjectPath' => BASE_PATH.'/',
'CustomConfigurationsPath' => $config_path,
// 'EditorAreaCSS' => $this->Application->BaseURL().'/themes/inportal_site/inc/inportal.css', //GetThemeCSS(),
//'StylesXmlPath' => '../../inp_styles.xml',
// 'Debug' => 1,
'Admin' => 1,
'K4' => 1,
);
return $oFCKeditor->CreateHtml();
}
/**
* Allows to construct link for opening any type of catalog item selector
*
* @param Array $params
* @return string
*/
function SelectorLink($params)
{
$mode = 'catalog';
if (isset($params['mode'])) { // {catalog, advanced_view}
$mode = $params['mode'];
unset($params['mode']);
}
$params['t'] = 'in-portal/item_selector/item_selector_'.$mode;
$default_params = Array('no_amp' => 1, 'pass' => 'all,'.$params['prefix']);
unset($params['prefix']);
$pass_through = Array();
if (isset($params['tabs_dependant'])) { // {yes, no}
$pass_through['td'] = $params['tabs_dependant'];
unset($params['tabs_dependant']);
}
if (isset($params['selection_mode'])) { // {single, multi}
$pass_through['tm'] = $params['selection_mode'];
unset($params['selection_mode']);
}
if (isset($params['tab_prefixes'])) { // {all, none, <comma separated prefix list}
$pass_through['tp'] = $params['tab_prefixes'];
unset($params['tab_prefixes']);
}
if ($pass_through) {
// add pass_through to selector url if any
$params['pass_through'] = implode(',', array_keys($pass_through));
$params = array_merge_recursive2($params, $pass_through);
}
// user can override default parameters (except pass_through of course)
$params = array_merge_recursive2($default_params, $params);
$main_processor =& $this->Application->recallObject('m_TagProcessor');
return $main_processor->T($params);
}
function TimeFrame($params)
{
$w = adodb_date('w');
$m = adodb_date('m');
$y = adodb_date('Y');
//FirstDayOfWeek is 0 for Sunday and 1 for Monday
$fdow = $this->Application->ConfigValue('FirstDayOfWeek');
if ($fdow && $w == 0) $w = 7;
$today_start = adodb_mktime(0,0,0,adodb_date('m'),adodb_date('d'),$y);
$first_day_of_this_week = $today_start - ($w - $fdow)*86400;
$first_day_of_this_month = adodb_mktime(0,0,0,$m,1,$y);
$this_quater = ceil($m/3);
$this_quater_start = adodb_mktime(0,0,0,$this_quater*3-2,1,$y);
switch ($params['type']) {
case 'last_week_start':
$timestamp = $first_day_of_this_week - 86400*7;
break;
case 'last_week_end':
$timestamp = $first_day_of_this_week - 1;
break;
case 'last_month_start':
$timestamp = $m == 1 ? adodb_mktime(0,0,0,12,1,$y-1) : adodb_mktime(0,0,0,$m-1,1,$y);
break;
case 'last_month_end':
$timestamp = $first_day_of_this_month = adodb_mktime(0,0,0,$m,1,$y) - 1;
break;
case 'last_quater_start':
$timestamp = $this_quater == 1 ? adodb_mktime(0,0,0,10,1,$y-1) : adodb_mktime(0,0,0,($this_quater-1)*3-2,1,$y);
break;
case 'last_quater_end':
$timestamp = $this_quater_start - 1;
break;
case 'last_6_months_start':
$timestamp = $m <= 6 ? adodb_mktime(0,0,0,$m+6,1,$y-1) : adodb_mktime(0,0,0,$m-6,1,$y);
break;
case 'last_year_start':
$timestamp = adodb_mktime(0,0,0,1,1,$y-1);
break;
case 'last_year_end':
$timestamp = adodb_mktime(23,59,59,12,31,$y-1);
break;
}
if (isset($params['format'])) {
$format = $params['format'];
if(preg_match("/_regional_(.*)/", $format, $regs))
{
$lang =& $this->Application->recallObject('lang.current');
$format = $lang->GetDBField($regs[1]);
}
return adodb_date($format, $timestamp);
}
return $timestamp;
}
function CheckPermCache($params)
{
if ($this->Conn->GetOne('SELECT Data FROM '.TABLE_PREFIX.'Cache WHERE VarName = \'ForcePermCacheUpdate\'')) {
$this->Application->Redirect($params['cache_update_t'], array('continue' => 1));
}
}
/**
* Checks if current protocol is SSL
*
* @param Array $params
* @return int
*/
function IsSSL($params)
{
return (PROTOCOL == 'https://')? 1 : 0;
}
function PrintColumns($params)
{
$picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
$picker_helper->SetGridName($this->Application->GetLinkedVar('grid_name'));
/* @var $picker_helper kColumnPickerHelper */
$main_prefix = $this->Application->RecallVar('main_prefix');
$cols = $picker_helper->LoadColumns($main_prefix);
$this->Application->Phrases->AddCachedPhrase('__FREEZER__', '-------------');
$o = '';
if (isset($params['hidden']) && $params['hidden']) {
foreach ($cols['hidden_fields'] as $col) {
$title = $this->Application->Phrase($cols['titles'][$col]);
$o .= "<option value='$col'>".$title;
}
}
else {
foreach ($cols['order'] as $col) {
if (in_array($col, $cols['hidden_fields'])) continue;
$title = $this->Application->Phrase($cols['titles'][$col]);
$o .= "<option value='$col'>".$title;
}
}
return $o;
}
/**
* Allows to set popup size (key - current template name)
*
* @param Array $params
*/
function SetPopupSize($params)
{
if (!$this->UsePopups($params)) return ;
$width = $params['width'];
$height = $params['height'];
if ($this->Application->GetVar('ajax') == 'yes') {
// during AJAX request just output size
die($width.'x'.$height);
}
$t = $this->Application->GetVar('t');
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'PopupSizes
WHERE TemplateName = '.$this->Conn->qstr($t);
$popup_info = $this->Conn->GetRow($sql);
if (!$popup_info) {
// create new popup size record
$fields_hash = Array (
'TemplateName' => $t,
'PopupWidth' => $width,
'PopupHeight' => $height,
);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX.'PopupSizes');
}
elseif ($popup_info['PopupWidth'] != $width || $popup_info['PopupHeight'] != $height) {
// popup found and size in tag differs from one in db -> update in db
$fields_hash = Array (
'PopupWidth' => $width,
'PopupHeight' => $height,
);
$this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'PopupSizes', 'PopupId = '.$popup_info['PopupId']);
}
}
/**
* Returns popup size (by template), if not cached, then parse template to get value
*
* @param Array $params
* @return string
*/
function GetPopupSize($params)
{
$t = $this->Application->GetVar('template_name');
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'PopupSizes
WHERE TemplateName = '.$this->Conn->qstr($t);
$popup_info = $this->Conn->GetRow($sql);
if (!$popup_info) {
$this->Application->InitParser();
$this->Application->ParseBlock(array('name' => $t)); // dies when SetPopupSize tag found & in ajax requrest
return '750x400'; // tag SetPopupSize not found in template -> use default size
}
return $popup_info['PopupWidth'].'x'.$popup_info['PopupHeight'];
}
function UsePopups($params)
{
return (int)$this->Application->ConfigValue('UsePopups');
}
function UseToolbarLabels($params)
{
return (int)$this->Application->ConfigValue('UseToolbarLabels');
}
/**
* Checks if debug mode enabled (optionally) and specified constant is on
*
* @param Array $params
* @return bool
*/
function ConstOn($params)
{
$constant_name = $this->SelectParam($params, 'name,const');
$debug_mode = isset($params['debug_mode']) && $params['debug_mode'] ? $this->Application->isDebugMode() : true;
return $debug_mode && constOn($constant_name);
}
/**
* Builds link to last template in main frame of admin
*
* @param Array $params
* @return string
*/
function MainFrameLink($params)
{
$persistent = isset($params['persistent']) && $params['persistent'];
if ($persistent) {
// check last_template in persistent session
$last_template = $this->Application->RecallPersistentVar('last_template_popup');
}
else {
// check last_template in session
$last_template = $this->Application->RecallVar('last_template_popup'); // because of m_opener=s there
}
if (!$last_template) {
$params['persistent'] = 1;
return $persistent ? false : $this->MainFrameLink($params);
}
list($index_file, $env) = explode('|', $last_template);
$vars = $this->Application->HttpQuery->processQueryString($env, 'pass');
$recursion_templates = Array ('login', 'index', 'no_permission');
if (isset($vars['admin']) && $vars['admin'] == 1) {
// index template doesn't begin recursion on front-end (in admin frame)
$vars['m_theme'] = '';
if (isset($params['m_opener']) && $params['m_opener'] == 'r') {
// front-end link for highlighting purposes
$vars['t'] = 'index';
$vars['m_cat_id'] = $this->Application->findModule('Name', 'Proj-CMS', 'RootCat');
}
unset($recursion_templates[ array_search('index', $recursion_templates)]);
}
if (in_array($vars['t'], $recursion_templates)) {
// prevents redirect recursion OR old in-portal pages
$params['persistent'] = 1;
return $persistent ? false : $this->MainFrameLink($params);
}
$vars = array_merge_recursive2($vars, $params);
$t = $vars['t'];
unset($vars['t'], $vars['persistent']);
return $this->Application->HREF($t, '', $vars, $index_file);
}
-
+ function MenuFrameWidth($params)
+ {
+ $w = $this->Application->ConfigValue('MenuFrameWidth');
+ if (!$w) $w = 200;
+ return $w;
+ }
function AdminSkin($params)
{
static $style;
if (!isset($style)) {
$style = $this->Conn->GetRow('SELECT * FROM '.TABLE_PREFIX.'Skins WHERE IsPrimary = 1');
}
$css_path = (defined('WRITEABLE') ? WRITEABLE : FULL_PATH.'/kernel').'/user_files';
$css_url = $this->Application->BaseURL(defined('WRITEBALE_BASE') ? WRITEBALE_BASE : '/kernel').'user_files/';
if (isset($params['type']) && $params['type'] == 'logo') {
return $style['Logo'] ? $css_url.$style['Logo'] : '';
}
$last_compiled = $style['LastCompiled'];
$style_name = strtolower( $style['Name'] );
if( file_exists($css_path.'/'.'admin-'.$style_name.'-'.$last_compiled.'.css') )
{
$ret = $css_url.'admin-'.$style_name.'-'.$last_compiled.'.css';
}
else
{
// search for previously compiled stylesheet
$last_compiled = 0;
if( $dh = opendir($css_path) )
{
while( ($file = readdir($dh)) !== false )
{
if( preg_match('/admin-(.*)-([\d]+).css/', $file, $rets) )
{
if( $rets[1] == $style_name && $rets[2] > $last_compiled ) $last_compiled = $rets[2];
}
}
closedir($dh);
}
if ($last_compiled) {
// found
$ret = $css_url.'admin-'.$style_name.'-'.$last_compiled.'.css';
}
else {
// not found (try to compile on the fly)
$object =& $this->Application->recallObject('skin.-item', null, Array ('skip_autoload' => true));
/* @var $object kDBItem */
$skin_eh =& $this->Application->recallObject('skin_EventHandler');
/* @var $skin_eh SkinEventHandler */
$object->Load(1, 'IsPrimary');
$skin_eh->Compile($object);
$ret = $css_url.'admin-'.$style_name.'-'.adodb_mktime().'.css';
}
}
if (isset($params['file_only'])) return $ret;
return '<link rel="stylesheet" rev="stylesheet" href="'.$ret.'" type="text/css" media="screen" />';
}
function PrintCompileErrors($params)
{
$errors = unserialize($this->Application->RecallVar('compile_errors'));
$o = '<table style="width: 100%;" border="1"><tr><td><b>File</b></td><td><b>Line</b></td><td><b>Message</b></td></tr>';
foreach ($errors as $an_error) {
$f = str_replace(FULL_PATH, '', $an_error['file']);
$o .= "<tr><td>{$f}</td><td>{$an_error['line']}</td><td>{$an_error['msg']}</td></tr>";
}
$o .= '</table>';
$this->Application->RemoveVar('compile_errors');
return $o;
}
+
+ function ExportData($params)
+ {
+ $export_helper =& $this->Application->recallObject('CSVHelper');
+ /* @var $export_helper kCSVHelper */
+ $result = $export_helper->ExportData( $this->SelectParam($params, 'var,name,field') );
+ return ($result === false) ? '' : $result;
+ }
+
+ function ImportData($params)
+ {
+ $import_helper =& $this->Application->recallObject('CSVHelper');
+ /* @var $import_helper kCSVHelper */
+ $result = $import_helper->ImportData( $this->SelectParam($params, 'var,name,field') );
+ return ($result === false) ? '' : $result;
+ }
+
+ function PrintCSVNotImportedLines($params)
+ {
+ $import_helper =& $this->Application->recallObject('CSVHelper');
+ /* @var $import_helper kCSVHelper */
+ return $import_helper->GetNotImportedLines();
+ }
+
+ /**
+ * Returns input field name to
+ * be placed on form (for correct
+ * event processing)
+ *
+ * @param Array $params
+ * @return string
+ * @access public
+ */
+ function InputName($params)
+ {
+ list($id, $field) = $this->prepareInputName($params);
+ $ret = $this->getPrefixSpecial().'[0]['.$field.']'; // 0 always, as has no idfield
+ if( getArrayValue($params, 'as_preg') ) $ret = preg_quote($ret, '/');
+ return $ret;
+ }
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/admin/admin_tag_processor.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.43.2.4
\ No newline at end of property
+1.43.2.5
\ No newline at end of property
Index: branches/RC/core/units/general/helpers/csv_helper.php
===================================================================
--- branches/RC/core/units/general/helpers/csv_helper.php (nonexistent)
+++ branches/RC/core/units/general/helpers/csv_helper.php (revision 9639)
@@ -0,0 +1,362 @@
+<?php
+
+ safeDefine('EXPORT_STEP', 100); // export by 100 items
+ safeDefine('IMPORT_STEP', 10);
+
+ class kCSVHelper extends kHelper {
+
+ var $PrefixSpecial;
+ var $grid;
+
+ var $delimiter_mapping = Array(0 => "\t", 1 => ',', 2 => ';', 3 => ' ', 4 => ':');
+ var $enclosure_mapping = Array(0 => '"', 1 => "'");
+ var $separator_mapping = Array(0 => "\n", 1 => "\r\n");
+
+ function ExportStep()
+ {
+ $export_data = $this->Application->RecallVar('export_data');
+ $export_rand = $this->Application->RecallVar('export_rand');
+ $get_rand = $this->Application->GetVar('export_rand');
+
+ if($export_data && $export_rand == $get_rand) {
+ $export_data = unserialize($export_data);
+ $first_step = false;
+ }
+ else {
+ // first step
+ $export_data = Array();
+ $export_data['prefix'] = $this->PrefixSpecial;
+ $export_data['grid'] = $this->grid;
+ $export_data['file_name'] = EXPORT_PATH.'/'.$this->ValidateFileName(EXPORT_PATH, 'export_'.$export_data['prefix'].'.csv');
+ $export_data['step'] = EXPORT_STEP;
+ $export_data['delimiter'] = $this->delimiter_mapping[(int)$this->Application->ConfigValue('CSVExportDelimiter')];
+ $export_data['enclosure'] = $this->enclosure_mapping[(int)$this->Application->ConfigValue('CSVExportEnclosure')];
+ $export_data['record_separator'] = $this->separator_mapping[(int)$this->Application->ConfigValue('CSVExportSeparator')];
+ $export_data['page'] = 1;
+
+ $lang_object =& $this->Application->recallObject('lang.current');
+ /* @var $lang_object LanguagesItem */
+ $export_data['source_encoding'] = strtoupper( $lang_object->GetDBField('Charset') );
+ $export_data['encoding'] = $this->Application->ConfigValue('CSVExportEncoding') ? false : 'UTF-16LE';
+
+ $this->Application->StoreVar('export_rand', $get_rand);
+
+ $first_step = true;
+ }
+
+ $file = fopen($export_data['file_name'], $first_step ? 'w' : 'a');
+
+ $prefix_elems = split('\.|_', $export_data['prefix']);
+ $grids = $this->Application->getUnitOption($prefix_elems[0], 'Grids');
+ $grid_config = $grids[ $export_data['grid'] ]['Fields'];
+
+ $list_params = Array('per_page' => $export_data['step'], 'grid' => $export_data['grid']);
+ $list =& $this->Application->recallObject(rtrim(implode('.', $prefix_elems), '.'), $prefix_elems[0].'_List', $list_params);
+ /* @var $list kDBList */
+ $list->SetPage($export_data['page']);
+
+ $list->Query();
+ $list->GoFirst();
+
+ $picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
+ /* @var $picker_helper kColumnPickerHelper */
+ $picker_helper->ApplyPicker(rtrim(implode('.', $prefix_elems), '.'), $grid_config, $export_data['grid']);
+
+ if($first_step) {
+ // if UTF-16, write Unicode marker
+ if($export_data['encoding'] == 'UTF-16LE') {
+ fwrite($file, chr(0xFF).chr(0xFE));
+ }
+
+ // inserting header line
+ $headers = Array();
+ foreach($grid_config as $field_name => $field_data) {
+ $header = $this->Application->Phrase( $field_data['title'] );
+ array_push($headers, $header);
+ }
+ $csv_line = getcsvline($headers, $export_data['delimiter'], $export_data['enclosure'], $export_data['record_separator']);
+ if($export_data['encoding']) {
+ $csv_line = mb_convert_encoding($csv_line, $export_data['encoding'], $export_data['source_encoding']);
+ }
+ fwrite($file, $csv_line);
+ }
+
+ while(!$list->EOL())
+ {
+ $data = Array();
+ foreach($grid_config as $field_name => $field_data) {
+ if(isset($field_data['export_field'])) {
+ $field_name = $field_data['export_field'];
+ }
+ $value = $list->GetField($field_name, isset($field_data['format']) ? $field_data['format'] : null);
+ $value = str_replace("\r\n", "\n", $value);
+ $value = str_replace("\r", "\n", $value);
+ array_push($data, $value);
+ }
+ if($export_data['encoding'] == 'UTF-16LE') {
+ fwrite($file, chr(0xFF).chr(0xFE));
+ }
+ $csv_line = getcsvline($data, $export_data['delimiter'], $export_data['enclosure'], $export_data['record_separator']);
+ if($export_data['encoding']) {
+ $csv_line = mb_convert_encoding($csv_line, $export_data['encoding'], $export_data['source_encoding']);
+ }
+ fwrite($file, $csv_line);
+
+ $list->GoNext();
+ }
+
+ $records_processed = $export_data['page'] * $export_data['step'];
+ $percent_complete = min(round($records_processed / $list->RecordsCount * 100), 100);
+
+ fclose($file);
+
+ if ($records_processed >= $list->RecordsCount) {
+ $this->Application->StoreVar('export_data', serialize($export_data));
+ $this->Application->Redirect($this->Application->GetVar('finish_template'));
+ }
+
+ echo $percent_complete;
+
+ $export_data['page']++;
+ $this->Application->StoreVar('export_data', serialize($export_data));
+ }
+
+ function ValidateFileName($path, $name)
+ {
+ $parts = pathinfo($name);
+ $ext = '.'.$parts['extension'];
+ $filename = substr($parts['basename'], 0, -strlen($ext));
+ $new_name = $filename.$ext;
+ while ( file_exists($path.'/'.$new_name) )
+ {
+ if ( preg_match('/('.preg_quote($filename, '/').'_)([0-9]*)('.preg_quote($ext, '/').')/', $new_name, $regs) ) {
+ $new_name = $regs[1].($regs[2]+1).$regs[3];
+ }
+ else {
+ $new_name = $filename.'_1'.$ext;
+ }
+ }
+ return $new_name;
+ }
+
+ function ExportData($name)
+ {
+ $export_data = unserialize($this->Application->RecallVar('export_data'));
+ return isset($export_data[$name]) ? $export_data[$name] : false;
+ }
+
+ function GetCSV()
+ {
+ safeDefine('DBG_SKIP_REPORTING', 1);
+
+ $export_data = unserialize($this->Application->RecallVar('export_data'));
+ header('Content-type: text/csv');
+ $filename = rtrim(basename($export_data['file_name']), '.csv').'.csv';
+ header('Content-Disposition: attachment; filename="'.$filename.'"');
+ readfile($export_data['file_name']);
+ die();
+ }
+
+ function ImportStart($filename)
+ {
+ if(!file_exists($filename) || !is_file($filename)) return 'cant_open_file';
+
+ $import_data = Array();
+
+ $lang_object =& $this->Application->recallObject('lang.current');
+ /* @var $lang_object LanguagesItem */
+ $import_data['source_encoding'] = strtoupper( $lang_object->GetDBField('Charset') );
+ $import_data['encoding'] = $this->Application->ConfigValue('CSVExportEncoding') ? false : 'UTF-16LE';
+ $import_data['errors'] = '';
+
+ // convert file in case of UTF-16LE
+ if($import_data['source_encoding'] != $import_data['encoding']) {
+ copy($filename, $filename.'.orginal');
+ $file_content = file_get_contents($filename);
+ $file = fopen($filename, 'w');
+ fwrite($file, mb_convert_encoding(str_replace(chr(0xFF).chr(0xFE), '', $file_content), $import_data['source_encoding'], $import_data['encoding']));
+ fclose($file);
+
+ }
+
+ $import_data['prefix'] = $this->PrefixSpecial;
+ $import_data['grid'] = $this->grid;
+ $import_data['file'] = $filename;
+ $import_data['total_lines'] = count(file($filename));
+ if(!$import_data['total_lines']) $import_data['total_lines'] = 1;
+ unset($file_content);
+ $import_data['lines_processed'] = 0;
+ $import_data['delimiter'] = $this->delimiter_mapping[(int)$this->Application->ConfigValue('CSVExportDelimiter')];
+ $import_data['enclosure'] = $this->enclosure_mapping[(int)$this->Application->ConfigValue('CSVExportEnclosure')];
+ $import_data['step'] = IMPORT_STEP;
+ $import_data['not_imported_lines'] = '';
+ $import_data['added'] = 0;
+ $import_data['updated'] = 0;
+
+ $file = fopen($filename, 'r');
+ // getting first line for headers
+ $headers = fgetcsv($file, 8192, $import_data['delimiter'], $import_data['enclosure']);
+ fclose($file);
+
+ $prefix_elems = split('\.|_', $import_data['prefix']);
+ $grids = $this->Application->getUnitOption($prefix_elems[0], 'Grids');
+ $grid_config = $grids[ $import_data['grid'] ]['Fields'];
+
+ $field_list = Array();
+ foreach($grid_config as $field_name => $field_data) {
+ if(isset($field_data['export_field'])) {
+ $field_name = $field_data['export_field'];
+ }
+ $field_label = $this->Application->Phrase( $field_data['title'] );
+ $field_pos = array_search($field_label, $headers);
+ if($field_pos !== false) {
+ $field_list[$field_pos] = $field_name;
+ }
+ }
+
+ if(!count($field_list)) return 'no_matching_columns';
+ $import_data['field_list'] = $field_list;
+
+ // getting key list
+ $field_positions = Array();
+ $config_key_list = $this->Application->getUnitOption($prefix_elems[0], 'ImportKeys');
+ if(!$config_key_list) $config_key_list = Array();
+ array_unshift($config_key_list, Array($this->Application->getUnitOption($prefix_elems[0], 'IDField')));
+
+ $key_list = Array();
+ foreach($config_key_list as $arr_key => $import_key) {
+ $key_list[$arr_key] = is_array($import_key) ? $import_key : Array($import_key);
+
+ foreach($key_list[$arr_key] as $key_field) {
+ $field_positions[$key_field] = array_search($key_field, $import_data['field_list']);
+ if($field_positions[$key_field] === false) {
+ // no such key field combination in imported file
+ unset($key_list[$arr_key]);
+ break;
+ }
+ }
+ }
+ $import_data['key_list'] = $key_list;
+ $import_data['field_positions'] = $field_positions;
+
+ $this->Application->StoreVar('import_data', serialize($import_data));
+ return true;
+ }
+
+ function ImportStep()
+ {
+ $import_data = unserialize($this->Application->RecallVar('import_data'));
+ $prefix_elems = split('\.|_', $import_data['prefix']);
+
+ $object =& $this->Application->recallObject($prefix_elems[0].'.-csvimport', $prefix_elems[0], Array('skip_autoload' => true, 'populate_ml_fields' => true));
+ /* @var $object kDBItem */
+
+ $file = fopen($import_data['file'], 'r');
+ $eof = false;
+ // skipping lines that has been already imported
+ for($i = 0; $i < $import_data['lines_processed'] + 1; $i++) {
+ if(feof($file)) break;
+ fgets($file, 8192);
+ }
+
+ $import_event = new kEvent($prefix_elems[0].'.-csvimport:OnBeforeCSVLineImport');
+
+ for($i = 0; $i < $import_data['step']; $i++) {
+ if(feof($file)) break;
+ $data = fgetcsv($file, 8192, $import_data['delimiter'], $import_data['enclosure']);
+ if(!$data) continue;
+
+ $object->Clear();
+ $action = 'Create';
+
+ // 1. trying to load object by keys
+ foreach($import_data['key_list'] as $key) {
+ $fail = false;
+ $key_array = Array();
+ foreach($key as $key_field) {
+ if(!isset($data[ $import_data['field_positions'][$key_field] ])) {
+ $fail = true;
+ break;
+ }
+ $key_array[$key_field] = $data[ $import_data['field_positions'][$key_field] ];
+ }
+ if($fail) continue;
+ if($object->Load($key_array)) {
+ $action = 'Update';
+ break;
+ }
+ }
+
+ // 2. set object fields
+ foreach($import_data['field_list'] as $position => $field_name) {
+ if(isset($data[$position])) {
+ $object->SetField($field_name, $data[$position]);
+ }
+ }
+
+ // 3. validate item and run event
+ $status = $object->Validate();
+ $import_event->status = $status ? erSUCCESS : erFAIL;
+ $this->Application->HandleEvent($import_event);
+
+ if($import_event->status == erSUCCESS && $object->$action()) {
+ $import_data[ ($action == 'Create') ? 'added' : 'updated' ]++;
+ }
+ else {
+ $msg = '';
+ foreach ($object->FieldErrors as $field => $info) {
+ if (!$info['pseudo']) continue;
+ $msg .= "$field: {$info['pseudo']} ";
+ }
+ $import_data['errors'] .= ($i + $import_data['lines_processed'] + 1).": $msg\n";
+ $import_data['not_imported_lines'] .= ','.($i + $import_data['lines_processed'] + 1);
+ }
+ }
+
+ $import_data['lines_processed'] += $import_data['step'];
+
+ $import_data['not_imported_lines'] = ltrim($import_data['not_imported_lines'], ',');
+ $this->Application->StoreVar('import_data', serialize($import_data));
+
+ $feof = feof($file);
+ fclose($file);
+
+ if($feof) {
+ $this->Application->Redirect($this->Application->GetVar('finish_template'));
+ }
+ else {
+ $percent_complete = floor($import_data['lines_processed'] / $import_data['total_lines'] * 100);
+ if($percent_complete > 99) $percent_complete = 99;
+ echo $percent_complete;
+ }
+ }
+
+ function ImportData($name)
+ {
+ $import_data = unserialize($this->Application->RecallVar('import_data'));
+ return isset($import_data[$name]) ? $import_data[$name] : false;
+ }
+
+ function GetNotImportedLines()
+ {
+ $import_data = unserialize($this->Application->RecallVar('import_data'));
+
+ if(!$import_data['not_imported_lines']) return false;
+ $line_numbers = explode(',', $import_data['not_imported_lines']);
+ $line_numbers[] = 0; // include header row in output
+
+ $file = fopen($import_data['file'], 'r');
+ $eof = false;
+ $result = '';
+ for($i = 0; $i <= max($line_numbers); $i++) {
+ if(feof($file)) break;
+ $line = fgets($file, 8192);
+ if(in_array($i, $line_numbers)) {
+ $result .= $i.':'.$line;
+ }
+ }
+ return $result."\n\n".$import_data['errors'];
+ }
+ }
+
+?>
\ No newline at end of file
Property changes on: branches/RC/core/units/general/helpers/csv_helper.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1.4.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: branches/RC/core/units/general/helpers/search_helper.php
===================================================================
--- branches/RC/core/units/general/helpers/search_helper.php (revision 9638)
+++ branches/RC/core/units/general/helpers/search_helper.php (revision 9639)
@@ -1,568 +1,568 @@
<?php
class kSearchHelper extends kHelper {
/**
* Splits search phrase into keyword using quotes,plus and minus sings and spaces as split criteria
*
* @param string $keyword
* @return string
*/
function splitKeyword($keyword)
{
$quotes_re = '/([+\-]?)"(.*?)"/';
$no_quotes_re = '/([+\-]?)([^ ]+)/';
$quoted_kw = preg_match_all($quotes_re, $keyword, $res);
foreach ($res[2] as $index => $kw) $final[$kw] = $res[1][$index];
$keyword = preg_replace($quotes_re, '', $keyword);
$not_quoted_kw = preg_match_all($no_quotes_re, $keyword, $res);
foreach ($res[2] as $index => $kw) $final[$kw] = $res[1][$index];
return $final;
}
function getPositiveKeywords($keyword)
{
$keywords = $this->splitKeyword($keyword);
$ret = Array();
foreach ($keywords as $keyword => $sign) {
if ($sign == '+' || $sign == '') {
$ret[] = $keyword;
}
}
return $ret;
}
function buildWhereClause($keyword, $fields)
{
$keywords = $this->splitKeyword($keyword);
$normal_conditions = Array();
$plus_conditions = Array();
$minus_conditions = Array();
foreach ($keywords as $keyword => $sign) {
switch ($sign) {
case '+':
$plus_conditions[] = implode(' LIKE "%'.$keyword.'%" OR ', $fields).' LIKE "%'.$keyword.'%"';
break;
case '-':
foreach ($fields as $field) {
$condition[] = $field.' NOT LIKE "%'.$keyword.'%" OR '.$field.' IS NULL';
}
$minus_conditions[] = '('.implode(') AND (', $condition).')';
break;
case '':
$keyword = str_replace('"', '\"', $keyword);
$normal_conditions[] = implode(' LIKE "%'.$keyword.'%" OR ', $fields).' LIKE "%'.$keyword.'%"';
break;
}
}
// building where clause
if ($normal_conditions) {
$where_clause = '('.implode(') OR (', $normal_conditions).')';
}
else {
$where_clause = '1';
}
if ($plus_conditions) {
$where_clause = '('.$where_clause.') AND ('.implode(') AND (', $plus_conditions).')';
}
if ($minus_conditions) {
$where_clause = '('.$where_clause.') AND ('.implode(') AND (', $minus_conditions).')';
}
return $where_clause;
}
/**
* Returns additional information about search field
*
* @param kDBList $object
* @param string $field_name
* @return Array
*/
function getFieldInformation(&$object, $field_name)
{
$sql_filter_type = isset($object->VirtualFields[$field_name]) ? 'having' : 'where';
$field_type = isset($object->Fields[$field_name]['type']) ? $object->Fields[$field_name]['type'] : 'string';
if (preg_match('/(.*)\.(.*)/', $field_name, $regs)) {
$table_name = '`'.$regs[1].'`.'; // field from external table
$field_name = $regs[2];
}
elseif ($sql_filter_type == 'where') {
$table_name = '`'.$object->TableName.'`.'; // field from local table
}
$table_name = ($sql_filter_type == 'where') ? $table_name : '';
// replace wid inside table name to WID_MARK constant value
$is_temp_table = preg_match('/(.*)'.TABLE_PREFIX.'ses_'.$this->Application->GetSID().'(_[\d]+){0,1}_edit_(.*)/', $table_name, $regs);
if ($is_temp_table) {
$table_name = $regs[1].TABLE_PREFIX.'ses_'.EDIT_MARK.'_edit_'.$regs[3]; // edit_mark will be replaced with sid[_main_wid] in AddFilters
}
return Array ('field_name' => $field_name, 'field_type' => $field_type, 'table_name' => $table_name, 'sql_filter_type' => $sql_filter_type);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function performSearch(&$event)
{
$object =& $event->getObject();
// process search keyword
$search_keyword = $this->Application->GetVar( $event->getPrefixSpecial(true).'_search_keyword');
$this->Application->StoreVar( $event->getPrefixSpecial().'_search_keyword', $search_keyword);
$search_keyword = str_replace('*', '%', $search_keyword);
$custom_filter = $this->processCustomFilters($event);
if(!$search_keyword && $custom_filter === false) {
$this->resetSearch($event);
return true;
}
if ($search_keyword) {
$this->processAutomaticFilters($event, $search_keyword, $custom_filter);
}
}
function processAutomaticFilters(&$event, $search_keyword, $custom_filter)
{
$grid_name = $this->Application->GetVar('grid_name');
$grids = $this->Application->getUnitOption($event->Prefix, 'Grids');
$search_fields = array_keys($grids[$grid_name]['Fields']);
$search_filter = Array();
$object =& $event->getObject();
foreach ($search_fields as $search_field) {
$custom_search = isset($custom_filter[$search_field]);
$filter_data = $this->getSearchClause($object, $search_field, $search_keyword, $custom_search);
if ($filter_data) {
$search_filter[$search_field] = $filter_data;
}
else {
unset($search_filter[$search_field]);
}
}
$this->Application->StoreVar($event->getPrefixSpecial().'_search_filter', serialize($search_filter) );
}
/**
* Returns search clause for any particular field
*
* @param kDBList $object
* @param string $search_field
* @param string $search_keyword what we are searching (false, when building custom filter clause)
* @param string $custom_search already found using custom filter
* @return Array
*/
function getSearchClause(&$object, $field_name, $search_keyword, $custom_search)
{
$search_keywords = $this->splitKeyword($search_keyword);
extract( $this->getFieldInformation($object, $field_name) ); // see getFieldInformation for more details
$filter_value = '';
// get field clause by formatter name and/or parameters
$formatter = getArrayValue($object->Fields[$field_name], 'formatter');
switch ($formatter) {
case 'kOptionsFormatter':
$search_keys = Array();
if ($custom_search === false) {
// if keywords passed through simple search filter (on each grid)
$use_phrases = getArrayValue($object->Fields[$field_name], 'use_phrases');
$field_options = $object->GetFieldOptions($field_name);
foreach ($field_options['options'] as $key => $val) {
foreach ($search_keywords as $keyword => $sign) {
$pattern = '#'.$keyword.'#i';
if (!preg_match($pattern, $use_phrases ? $this->Application->Phrase($val) : $val)) {
if ($sign == '+') {
$filter_value = $table_name.'`'.$field_name.'` = NULL';
break;
}
else {
continue;
}
}
if ($sign == '+' || $sign == '') {
$search_keys[$key] = $this->Conn->qstr($key);
}
elseif($sign == '-') {
// if same value if found as exclusive too, then remove from search result
unset($search_keys[$key]);
}
}
}
}
if ($search_keys) {
$filter_value = $table_name.'`'.$field_name.'` IN ('.implode(',', $search_keys).')';
}
$field_processed = true;
break;
case 'kDateFormatter':
// if date is searched using direct filter, then do nothing here, otherwise search using LIKE clause
$field_processed = ($custom_search !== false) ? true : false;
break;
default:
$field_processed = false;
break;
}
// if not already processed by formatter, then get clause by field type
if (!$field_processed && $search_keywords) {
switch($field_type)
{
case 'int':
case 'integer':
case 'numeric':
$search_keys = Array();
foreach ($search_keywords as $keyword => $sign) {
if (!is_numeric($keyword) || ($sign == '-')) continue;
$search_keys[] = $this->Conn->qstr($keyword);
}
if ($search_keys) {
$filter_value = $table_name.'`'.$field_name.'` IN ('.implode(',', $search_keys).')';
}
break;
case 'double':
case 'float':
case 'real':
$search_keys = Array();
foreach ($search_keywords as $keyword => $sign) {
$keyword = str_replace(',', '.', $keyword);
if (!is_numeric($keyword) || ($sign == '-')) continue;
$search_keys[] = 'ABS('.$table_name.'`'.$field_name.'` - '.$this->Conn->qstr($keyword).') <= 0.0001';
}
if ($search_keys) {
$filter_value = '('.implode(') OR (', $search_keys).')';
}
break;
case 'string':
$filter_value = $this->buildWhereClause($search_keyword, Array($table_name.'`'.$field_name.'`'));
break;
}
}
if ($filter_value) {
return Array('type' => $sql_filter_type, 'value' => $filter_value);
}
return false;
}
/**
* Processes custom filters from submit
*
* @param KEvent $event
* @return bool
*/
function processCustomFilters(&$event)
{
$grid_name = $this->Application->GetVar('grid_name');
// update "custom filter" with values from submit: begin
$view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view');
- $custom_filters = $this->Application->RecallPersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name);
+ $custom_filters = $this->Application->RecallPersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name, ALLOW_DEFAULT_SETTINGS);
if ($custom_filters) {
$custom_filters = unserialize($custom_filters);
$custom_filter = isset($custom_filters[$grid_name]) ? $custom_filters[$grid_name] : Array ();
}
else {
$custom_filter = Array ();
}
// submit format custom_filters[prefix_special][field]
$submit_filters = $this->Application->GetVar('custom_filters');
if ($submit_filters) {
$submit_filters = getArrayValue($submit_filters, $event->getPrefixSpecial(), $grid_name);
if ($submit_filters) {
foreach ($submit_filters as $field_name => $field_options) {
list ($filter_type, $field_value) = each($field_options);
$is_empty = strlen(is_array($field_value) ? implode('', $field_value) : $field_value) == 0;
if ($is_empty) {
if (isset($custom_filter[$field_name])) {
// use isset, because non-existing key will cause "php notice"!
unset($custom_filter[$field_name][$filter_type]); // remove filter
if (!$custom_filter[$field_name]) {
// if no filters left for field, then delete record at all
unset($custom_filter[$field_name]);
}
}
}
else {
$custom_filter[$field_name][$filter_type]['submit_value'] = $field_value;
}
}
}
}
if ($custom_filter) {
$custom_filters[$grid_name] = $custom_filter;
}
else {
unset($custom_filters[$grid_name]);
}
// update "custom filter" with values from submit: end
if (!$custom_filter) {
// in case when no filters specified, there are nothing to process
$this->Application->StorePersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name, serialize($custom_filters) );
return false;
}
$object =& $event->getObject(); // don't recall it each time in getCustomFilterSearchClause
$grid_info = $this->Application->getUnitOption($event->Prefix.'.'.$grid_name, 'Grids');
foreach ($custom_filter as $field_name => $field_options) {
list ($filter_type, $field_options) = each($field_options);
$field_options['grid_options'] = $grid_info['Fields'][$field_name];
$field_options = $this->getCustomFilterSearchClause($object, $field_name, $filter_type, $field_options);
if ($field_options['value']) {
unset($field_options['grid_options']);
$custom_filter[$field_name][$filter_type] = $field_options;
}
}
$custom_filters[$grid_name] = $custom_filter;
$this->Application->StorePersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name, serialize($custom_filters) );
return $custom_filter;
}
/**
* Return numeric range filter value + checking that it's number
*
* @param Array $value array containing range filter value
* @return unknown
*/
function getRangeValue($value)
{
return strlen($value) && is_numeric($value) ? $this->Conn->qstr($value) : false;
}
function getCustomFilterSearchClause(&$object, $field_name, $filter_type, $field_options)
{
// this is usually used for mutlilingual fields and date fields
if (isset($field_options['grid_options']['sort_field'])) {
$field_name = $field_options['grid_options']['sort_field'];
}
extract( $this->getFieldInformation($object, $field_name) ); // see getFieldInformation for more details
$filter_value = '';
switch ($filter_type) {
case 'range':
$from = $this->getRangeValue($field_options['submit_value']['from']);
$to = $this->getRangeValue($field_options['submit_value']['to']);
if ($from !== false && $to !== false) {
// add range filter
$filter_value = $table_name.'`'.$field_name.'` >= '.$from.' AND '.$table_name.'`'.$field_name.'` <= '.$to;
}
elseif ($from !== false) {
// add equals filter on $from
$filter_value = $table_name.'`'.$field_name.'` = '.$from;
}
elseif ($to !== false) {
// add equals filter on $to
$filter_value = $table_name.'`'.$field_name.'` = '.$to;
}
break;
case 'float_range':
// MySQL can't compare values in "float" type columns using "=" operator
$from = $this->getRangeValue($field_options['submit_value']['from']);
$to = $this->getRangeValue($field_options['submit_value']['to']);
if ($from !== false && $to !== false) {
// add range filter
$filter_value = $table_name.'`'.$field_name.'` >= '.$from.' AND '.$table_name.'`'.$field_name.'` <= '.$to;
}
elseif ($from !== false) {
// add equals filter on $from
$filter_value = 'ABS('.$table_name.'`'.$field_name.'` - '.$from.') <= 0.0001';
}
elseif ($to !== false) {
// add equals filter on $to
$filter_value = 'ABS('.$table_name.'`'.$field_name.'` - '.$to.') <= 0.0001';
}
break;
case 'date_range':
$from = $this->processRangeField($object, $field_name, $field_options['submit_value'], 'from');
$to = $this->processRangeField($object, $field_name, $field_options['submit_value'], 'to');
$day_seconds = 23 * 60 * 60 + 59 * 60 + 59;
if ($from !== false && $to === false) {
$from = strtotime(date('Y-m-d', $from).' 00:00:00', $from); // reset to morning
$to = $from + $day_seconds;
}
elseif ($from === false && $to !== false) {
$to = strtotime(date('Y-m-d', $to).' 23:59:59', $to); // reset to evening
$from = $to - $day_seconds;
}
if ($from !== false && $to !== false) {
$filter_value = $table_name.'`'.$field_name.'` >= '.$from.' AND '.$table_name.'`'.$field_name.'` <= '.$to;
}
break;
case 'equals':
case 'options':
$field_value = strlen($field_options['submit_value']) ? $this->Conn->qstr($field_options['submit_value']) : false;
if ($field_value) {
$filter_value = $table_name.'`'.$field_name.'` = '.$field_value;
}
break;
case 'like':
$filter_value = $this->buildWhereClause($field_options['submit_value'], Array($table_name.'`'.$field_name.'`'));
break;
default:
break;
}
$field_options['sql_filter_type'] = $sql_filter_type;
$field_options['value'] = $filter_value;
return $field_options;
}
/**
* Enter description here...
*
* @param kdbItem $object
* @param string $search_field
* @param string $value
* @param string $type
*/
function processRangeField(&$object, $search_field, $value, $type)
{
if (!strlen($value[$type])) {
return false;
}
$lang_current =& $this->Application->recallObject('lang.current');
$options = $object->GetFieldOptions($search_field);
$dt_separator = isset($options['date_time_separator']) ? $options['date_time_separator'] : ' ';
$tmp_value = explode($dt_separator, $value[$type], 2);
if (count($tmp_value) == 1) {
// time is missing, then guess it and add to date
$time = ($type == 'from') ? adodb_mktime(0, 0, 0) : adodb_mktime(23, 59, 59);
$time = adodb_date($lang_current->GetDBField('InputTimeFormat'), $time);
$value[$type] .= $dt_separator.$time;
}
$formatter =& $this->Application->recallObject($object->Fields[$search_field]['formatter']);
$value_ts = $formatter->Parse($value[$type], $search_field, $object);
$pseudo = getArrayValue($object->FieldErrors, $search_field, 'pseudo');
if ($pseudo) {
unset($object->FieldErrors[$search_field]); // remove error!
// invalid format -> ignore this date in search
return false;
}
return $value_ts;
}
/**
* Resets current search
*
* @param kEvent $event
*/
function resetSearch(&$event)
{
$this->Application->RemoveVar($event->getPrefixSpecial().'_search_filter');
$this->Application->RemoveVar($event->getPrefixSpecial().'_search_keyword');
$view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view');
$this->Application->RemovePersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name);
}
/**
* Creates filters based on "types" & "except" parameters from PrintList
*
* @param kEvent $event
* @param Array $type_clauses
* @param string $types
* @param string $except_types
*/
function SetComplexFilter(&$event, &$type_clauses, $types, $except_types)
{
$includes_or_filter =& $this->Application->makeClass('kMultipleFilter', FLT_TYPE_OR);
$excepts_and_filter =& $this->Application->makeClass('kMultipleFilter', FLT_TYPE_AND);
$includes_or_filter_h =& $this->Application->makeClass('kMultipleFilter', FLT_TYPE_OR);
$excepts_and_filter_h =& $this->Application->makeClass('kMultipleFilter', FLT_TYPE_AND);
if ($types) {
$types = explode(',', $types);
foreach ($types as $type) {
$type = trim($type);
if (isset($type_clauses[$type])) {
if ($type_clauses[$type]['having_filter']) {
$includes_or_filter_h->addFilter('filter_'.$type, $type_clauses[$type]['include']);
} else {
$includes_or_filter->addFilter('filter_'.$type, $type_clauses[$type]['include']);
}
}
}
}
if ($except_types) {
$except_types = explode(',', $except_types);
foreach ($except_types as $type) {
$type = trim($type);
if (isset($type_clauses[$type])) {
if ($type_clauses[$type]['having_filter']) {
$excepts_and_filter_h->addFilter('filter_'.$type, $type_clauses[$type]['except']);
} else {
$excepts_and_filter->addFilter('filter_'.$type, $type_clauses[$type]['except']);
}
}
}
}
$object =& $event->getObject();
$object->addFilter('includes_filter', $includes_or_filter);
$object->addFilter('excepts_filter', $excepts_and_filter);
$object->addFilter('includes_filter_h', $includes_or_filter_h, HAVING_FILTER);
$object->addFilter('excepts_filter_h', $excepts_and_filter_h, HAVING_FILTER);
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/general/helpers/search_helper.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.10
\ No newline at end of property
+1.10.2.1
\ No newline at end of property
Index: branches/RC/core/units/general/helpers/col_picker_helper.php
===================================================================
--- branches/RC/core/units/general/helpers/col_picker_helper.php (revision 9638)
+++ branches/RC/core/units/general/helpers/col_picker_helper.php (revision 9639)
@@ -1,182 +1,182 @@
<?php
class kColumnPickerHelper extends kHelper {
var $PickerData;
var $GridName;
function LoadColumns($prefix)
{
$view_name = $this->Application->RecallVar($prefix.'_current_view');
- $val = $this->Application->RecallPersistentVar($prefix.'_columns_.'.$view_name);
+ $val = $this->Application->RecallPersistentVar($prefix.'_columns_.'.$view_name, ALLOW_DEFAULT_SETTINGS);
if (!$val) {
$cols = $this->RebuildColumns($prefix);
}
else {
$cols = unserialize($val);
$current_cols = $this->GetColumns($prefix);
if ($cols === false || $cols['crc'] != $current_cols['crc'])
{
$cols = $this->RebuildColumns($prefix, $cols);
}
}
return $cols;
}
function PreparePicker($prefix, $grid_name)
{
$this->SetGridName($grid_name);
$this->PickerData = $this->LoadColumns($prefix);
}
function ApplyPicker($prefix, &$fields, $grid_name)
{
$this->PreparePicker($prefix, $grid_name);
uksort($fields, array($this, 'CmpElems'));
$this->RemoveHiddenColumns($fields);
}
function SetGridName($grid_name)
{
$this->GridName = $grid_name;
}
function CmpElems($a, $b)
{
$a_index = array_search($a, $this->PickerData['order']);
$b_index = array_search($b, $this->PickerData['order']);
if ($a_index == $b_index) {
return 0;
}
return ($a_index < $b_index) ? -1 : 1;
}
function RebuildColumns($prefix, $current=null)
{
$cols = $this->GetColumns($prefix);
if (is_array($current)) {
//get common fields both in db and xml
$common = array_intersect($current['order'], $cols['order']);
//get added columns - present in xml, but not in db
$added = array_diff($cols['order'], $current['order']);
if (in_array('__FREEZER__', $added)) {
array_unshift($common, '__FREEZER__');
unset($added[array_search('__FREEZER__', $added)]);
}
$cols['order'] = array_merge($common, $added);
$cols['hidden_fields'] = array_intersect($current['order'], $current['hidden_fields']);
foreach($common as $col) {
$cols['widths'][$col] = isset($current['widths'][$col]) ? $current['widths'][$col] : 100;
}
$this->SetCRC($cols);
}
$this->StoreCols($prefix, $cols);
return $cols;
}
function StoreCols($prefix, $cols)
{
$view_name = $this->Application->RecallVar($prefix.'_current_view');
$this->Application->StorePersistentVar($prefix.'_columns_.'.$view_name, serialize($cols));
}
function GetColumns($prefix)
{
$splited = $this->Application->processPrefix($prefix);
$grids = $this->Application->getUnitOption($splited['prefix'], 'Grids');
$conf_fields = array_merge_recursive(
array('__FREEZER__' => array('title' => '__FREEZER__')),
$grids[$this->GridName]['Fields']
);
// $conf_fields = $grids[$this->GridName]['Fields'];
// we NEED to recall dummy here to apply fields changes imposed by formatters,
// such as replacing multilingual field titles etc.
$dummy =& $this->Application->recallObject($prefix, null, array('skip_autoload'=>1));
$counter = 0;
$hidden = array();
$fields = array();
$titles = array();
$widths = array();
foreach ($conf_fields as $name => $options) {
$fields[$counter] = $name;
$titles[$name] = $options['title'];
$widths[$name] = 100;
if (isset($options['hidden']) && $options['hidden'])
{
$hidden[$counter] = $name;
}
$counter++;
}
$sorted_fields = $fields;
sort($sorted_fields);
$cols = array(
'order' => $fields,
'titles' => $titles,
'hidden_fields' => $hidden,
'widths' => $widths,
);
$this->SetCRC($cols);
return $cols;
}
function SetCRC(&$cols)
{
$sorted_fields = $cols['order'];
$sorted_titles = $cols['titles'];
asort($sorted_fields);
asort($sorted_titles);
$cols['crc'] = crc32(implode(',', $sorted_fields).implode(',', $sorted_titles));
}
function RemoveHiddenColumns(&$fields)
{
$to_remove = array();
foreach ($fields as $name => $options) {
if (array_search($name, $this->PickerData['hidden_fields']) !== false) {
$to_remove[] = $name;
}
}
foreach ($to_remove as $name) {
unset($fields[$name]);
}
}
function SaveColumns($prefix, $picked, $hidden)
{
$order = $picked ? explode('|', $picked) : array();
$hidden = $hidden ? explode('|', $hidden) : array();
$order = array_merge($order, $hidden);
$cols = $this->LoadColumns($prefix);
$cols['order'] = $order;
$cols['hidden_fields'] = $hidden;
$this->SetCRC($cols);
$this->StoreCols($prefix, $cols);
}
function SaveWidths($prefix, $widths)
{
if (!is_array($widths)) $widths = explode(':', $widths);
array_shift($widths); // removing first col (checkbox col) width
$i = 0;
foreach ($this->PickerData['order'] as $ord => $field) {
if ($field == '__FREEZER__') continue;
$this->PickerData['widths'][$field] = $widths[$i++];
}
$this->StoreCols($prefix, $this->PickerData);
}
function GetWidth($field)
{
return isset($this->PickerData['widths'][$field]) ? $this->PickerData['widths'][$field] : false;
}
}
\ No newline at end of file
Property changes on: branches/RC/core/units/general/helpers/col_picker_helper.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.2.2.1
\ No newline at end of property
+1.2.2.2
\ No newline at end of property
Index: branches/RC/core/units/general/helpers/priority_helper.php
===================================================================
--- branches/RC/core/units/general/helpers/priority_helper.php (revision 9638)
+++ branches/RC/core/units/general/helpers/priority_helper.php (revision 9639)
@@ -1,132 +1,145 @@
<?php
class kPriorityHelper extends kHelper {
/**
* Prepares options for priority dropdown
*
* @param kEvent $event
* @param bool $is_new for newly created items add new priority to the end
* @param string $constrain constrain for priority selection (if any)
*
*/
function preparePriorities(&$event, $is_new = false, $constrain = '')
{
$object =& $event->getObject();
$field_options = $object->GetFieldOptions('Priority');
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
$sql = 'SELECT COUNT(*)
FROM '.$table_name;
if ($constrain) {
$sql .= ' WHERE '.$constrain;
+ }
+ if (!isset($object->Fields['OldPriority'])) {
+ $object->VirtualFields['OldPriority'] = Array('type' => 'int', 'default' => 0);
}
$items_count = $this->Conn->GetOne($sql);
if ($is_new) {
// add new item to the end of list
$items_count++;
$object->SetDBField('Priority', -$items_count);
$object->SetDBField('OldPriority', -$items_count);
}
+ else {
+ $object->SetDBField('OldPriority', $object->GetDBField('Priority'));
+ }
for ($i = 1; $i <= $items_count; $i++) {
$field_options['options'][-$i] = $i;
}
$object->SetFieldOptions('Priority', $field_options);
+ // storing prioriry right after load for comparing when updating
}
/**
* Updates priorities for changed items
*
* @param kEvent $event
- * @param Array $changes = Array (CategoryID => Array ('parent' => ..., 'new' => ..., 'old' => ...), ...)
+ * @param Array $changes = Array (ID => Array ('parent' => ..., 'new' => ..., 'old' => ...), ...)
* @param Array $new_ids = Array (temp_id => live_id)
* @param string $constrain
*/
function updatePriorities(&$event, $changes, $new_ids, $constrain = '')
{
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
$not_processed = array_keys($changes);
+ $ids = array();
foreach ($changes as $id => $pair) {
- $constrain = 'ParentId = '.$pair['parent'].' AND ';
+ array_push($ids, $id);
+ $constrain = isset($pair['parent']) ? 'ParentId = '.$pair['parent'].' AND ' : '';
if ($pair['old'] == 'new') {
// replace 0 with newly created item id (from $new_ids mapping)
$not_processed[ array_search($id, $not_processed) ] = $new_ids[$id];
$id = $new_ids[$id];
$sql = 'SELECT MIN(Priority)
FROM '.$table_name.'
- WHERE '.$constrain.' CategoryId NOT IN ('.implode(',', $not_processed).')';
+ WHERE '.$constrain.' '.$id_field.' NOT IN ('.implode(',', $not_processed).')';
$min_priority = (int)$this->Conn->GetOne($sql) - 1;
if ($pair['new'] < $min_priority) {
$pair['new'] = $min_priority;
}
$pair['old'] = $min_priority;
}
if ($pair['new'] < $pair['old']) {
- $q = ' SET Priority = Priority + 1
- WHERE '.$constrain.'
+ $set = ' SET Priority = Priority + 1';
+ $where =' WHERE '.$constrain.'
Priority >= '.$pair['new'].'
AND
Priority < '.$pair['old'].'
AND
- CategoryId NOT IN ('.implode(',', $not_processed).')';
+ '.$id_field.' NOT IN ('.implode(',', $not_processed).')';
}
elseif ($pair['new'] > $pair['old']) {
- $q = ' SET Priority = Priority - 1
- WHERE '.$constrain.'
+ $set = ' SET Priority = Priority - 1';
+ $where =' WHERE '.$constrain.'
Priority > '.$pair['old'].'
AND
Priority <= '.$pair['new'].'
AND
- CategoryId NOT IN ('.implode(',', $not_processed).')';
+ '.$id_field.' NOT IN ('.implode(',', $not_processed).')';
}
else {
- $q = 'SET Priority = '.$pair['new'].' WHERE '.$id_field.' = '.$id;
+ $set = 'SET Priority = '.$pair['new'];
+ $where = ' WHERE '.$id_field.' = '.$id;
}
- $q = 'UPDATE '.$table_name.' '.$q;
+ $ids = array_merge($ids, $this->Conn->GetCol('SELECT '.$id_field.' FROM '.$table_name.$where));
+ $q = 'UPDATE '.$table_name.' '.$set.$where;
$this->Conn->Query($q);
unset( $not_processed[array_search($id, $not_processed)] );
}
+ return $ids;
}
/**
* Recalculates priorities
*
* @param kEvent $event
* @param string $constrain
*/
function recalculatePriorities(&$event, $constrain = '')
{
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
$sql = 'SELECT '.$id_field.'
FROM '.$table_name.
($constrain ? ' WHERE '.$constrain : '').'
ORDER BY Priority DESC';
$items = $this->Conn->GetCol($sql);
foreach ($items as $item_number => $item_id) {
$sql = 'UPDATE '.$table_name.'
SET Priority = '.-($item_number + 1).'
WHERE '.$id_field.' = '.$item_id;
$this->Conn->Query($sql);
}
+ return $items;
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/general/helpers/priority_helper.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.2
\ No newline at end of property
+1.2.2.1
\ No newline at end of property
Index: branches/RC/core/units/general/helpers/helpers_config.php
===================================================================
--- branches/RC/core/units/general/helpers/helpers_config.php (revision 9638)
+++ branches/RC/core/units/general/helpers/helpers_config.php (revision 9639)
@@ -1,27 +1,28 @@
<?php
$config = Array(
'Prefix' => 'helpers',
'EventHandlerClass' => Array('class' => 'kEventHandler', 'file' => '', 'build_event' => 'OnBuild'),
'RegisterClasses' => Array(
Array('pseudo'=>'kMultiLanguageHelper','class'=>'kMultiLanguageHelper','file'=>'multilanguage.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'SearchHelper','class'=>'kSearchHelper','file'=>'search_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'SectionsHelper','class'=>'kSectionsHelper','file'=>'sections_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'PermissionsHelper','class'=>'kPermissionsHelper','file'=>'permissions_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'ModulesHelper','class'=>'kModulesHelper','file'=>'modules.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'ModRewriteHelper','class'=>'kModRewriteHelper','file'=>'mod_rewrite_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'RecursiveHelper','class'=>'kRecursiveHelper','file'=>'recursive_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'FilenamesHelper','class'=>'kFilenamesHelper','file'=>'filenames_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'ClipboardHelper','class'=>'kClipboardHelper','file'=>'clipboard_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'ColumnPickerHelper','class'=>'kColumnPickerHelper','file'=>'col_picker_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'ThemesHelper','class'=>'kThemesHelper','file'=>'themes_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'CaptchaHelper','class'=>'kCaptchaHelper','file'=>'captcha_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'PriorityHelper','class'=>'kPriorityHelper','file'=>'priority_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo' => 'CurlHelper', 'class' => 'kCurlHelper','file' => 'curl_helper.php', 'build_event' => '', 'require_classes' => Array('kHelper')),
Array('pseudo'=>'CountHelper','class'=>'kCountHelper','file'=>'count_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'ImageHelper','class'=>'ImageHelper','file'=>'image_helper.php','build_event'=>'','require_classes'=>'kHelper'),
Array('pseudo'=>'CategoryHelper','class'=>'CategoryHelper','file'=>'category_helper.php','build_event'=>'','require_classes'=>'kHelper'),
+ Array('pseudo'=>'CSVHelper','class'=>'kCSVHelper','file'=>'csv_helper.php','build_event'=>'','require_classes'=>'kHelper'),
),
);
\ No newline at end of file
Property changes on: branches/RC/core/units/general/helpers/helpers_config.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.9
\ No newline at end of property
+1.9.2.1
\ No newline at end of property
Index: branches/RC/core/units/general/xml_helper.php
===================================================================
--- branches/RC/core/units/general/xml_helper.php (revision 9638)
+++ branches/RC/core/units/general/xml_helper.php (revision 9639)
@@ -1,206 +1,229 @@
<?php
class kXMLHelper extends kHelper {
var $RootElement = null;
/**
* Enter description here...
*
* @var kXMLNode
*/
var $CurrentElement = null;
/**
* Parses XML data specified and returns root node
*
* @param string $xml
* @return kXMLNode
*/
function &Parse($xml = null)
{
$this->Clear(); // in case if Parse method is called more then one time
$xml_parser = xml_parser_create();
xml_set_element_handler( $xml_parser, Array(&$this, 'startElement'), Array(&$this, 'endElement') );
xml_set_character_data_handler( $xml_parser, Array(&$this, 'characterData') );
if (!xml_parse($xml_parser, $xml, 1)) {
$this->RootElement = new kXMLNode('ERROR', array('code'=>xml_get_error_code($xml_parser),'message'=>xml_error_string(xml_get_error_code($xml_parser))));
trigger_error(sprintf('XML error: %s at line %d',
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)), E_USER_WARNING);
}
xml_parser_free($xml_parser);
$root_copy = $this->RootElement;
return $root_copy;
}
function startElement(&$Parser, &$Elem, $Attrs)
{
$parent =& $this->CurrentElement; // 1. $parent is now reference to $this->CurrentElement
$this->CurrentElement =& new kXMLNode($Elem, $Attrs); // 2. =& ensures, that new object won't be assigned to $parent as well (don't remove)
if (!isset($this->RootElement) || is_null($this->RootElement)) {
$this->RootElement =& $this->CurrentElement;
}
if (!is_null($parent)) {
$parent->AddChild($this->CurrentElement);
}
}
function characterData($Parser, $Line)
{
$this->CurrentElement->AppendData($Line);
}
function endElement($Parser, $Elem)
{
if ($this->CurrentElement->Parent != null) {
$this->CurrentElement =& $this->CurrentElement->Parent;
}
}
function Clear()
{
unset($this->RootElement);
unset($this->CurrentElement);
}
}
class kXMLNode {
var $Name = null;
var $Attributes = array();
var $Children = array();
var $Data = null;
var $firstChild = null;
var $lastChild = null;
/**
* Parent node
*
* @var kXMLNode
*/
var $Parent = null;
/**
* Node position relative to other nodes of it's parent
*
* @var int
*/
var $Position = 0;
function kXMLNode($name, $attrs = array())
{
$this->Name = $name;
$this->Attributes = $attrs;
}
function SetParent(&$elem)
{
$this->Parent =& $elem;
}
/**
* Adds new child to current node
*
* @param kXMLNode $a_child
*/
function AddChild(&$a_child)
{
$node_count = count($this->Children);
$a_child->Position = $node_count;
if ($node_count == 0) {
$this->firstChild =& $a_child;
$this->lastChild =& $a_child;
}
else {
$this->lastChild =& $a_child;
}
$this->Children[] =& $a_child;
$a_child->SetParent($this);
}
function AppendData($data)
{
$this->Data .= $data;
}
function &GetChild($path)
{
$entries = explode('/', strtoupper($path));
$cur = array_shift($entries);
if ($cur == $this->Name) $cur = array_shift($entries);
if (!$cur) return $this;
if (!isset($this->Children[$cur])) return false;
$left = implode('/', $entries);
if (!$left) return $this->Children[$cur];
return $this->Children[$cur]->GetChild($left);
}
function GetChildValue($path)
{
$child =& $this->GetChild($path);
if ($child !== false) {
return $child->Data;
}
}
function &GetChildByPosition($position)
{
if ($position < count($this->Children) ) {
return $this->Children[$position];
}
else {
$false = false;
return $false;
}
}
function &FindChild($name)
{
$name = strtoupper($name);
if ($this->Name == $name) return $this;
// if (isset($this->Children[$name])) return $this->Children[$name];
// $children = array_keys($this->Children);
foreach ($this->Children as $elem)
{
$child =& $elem->FindChild($name);
if ($child !== false)
{
return $child;
}
}
$false = false;
return $false;
}
function FindChildValue($name, $attr=null)
{
$child =& $this->FindChild($name);
if ($child !== false) {
if (isset($attr)) {
return $child->Attributes[strtoupper($attr)];
}
return $child->Data;
}
}
/**
* Returns next node to this, false in case of end list
*
* @return kXMLNode
*/
function &NextSibling()
{
if (!is_null($this->Parent)) {
$ret =& $this->Parent->GetChildByPosition($this->Position + 1);
return $ret;
}
else {
$false = false;
return $false;
}
}
+ /**
+ * Reconstructs XML of the node and subnodes
+ *
+ */
+ function GetXML()
+ {
+ $xml = '<'.$this->Name;
+ if (count($this->Attributes)) {
+ $xml .= ' ';
+ $att_contents = array();
+ foreach ($this->Attributes as $name => $value) {
+ $att_contents[] = $name.'="'.$value.'"';
+ }
+ $xml .= implode(' ', $att_contents);
+ }
+ $xml .= '>'.$this->Data;
+ foreach ($this->Children as $node)
+ {
+ $xml .= $node->GetXML();
+ }
+ $xml .= '</'.$this->Name.'>';
+ return $xml;
+ }
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/general/xml_helper.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.8.2.4
\ No newline at end of property
+1.8.2.5
\ No newline at end of property
Index: branches/RC/core/units/general/inp_ses_storage.php
===================================================================
--- branches/RC/core/units/general/inp_ses_storage.php (revision 9638)
+++ branches/RC/core/units/general/inp_ses_storage.php (revision 9639)
@@ -1,123 +1,134 @@
<?php
class InpSession extends Session
{
function Init($prefix,$special)
{
$this->SessionTimeout = $this->Application->ConfigValue('SessionTimeout');
$path = (BASE_PATH == '') ? '/' : BASE_PATH;
// if ( $this->Application->IsAdmin() ) $path = rtrim($path, '/').'/admin';
$this->SetCookiePath($path);
$cookie_name = $this->Application->ConfigValue('SessionCookieName');
if (!$cookie_name) $cookie_name = 'sid';
if (($this->Application->IsAdmin() && $special !== 'front') || $special == 'admin' ) { // || $this->Application->GetVar('admin') == 1
$cookie_name = 'adm_'.$cookie_name;
}
$this->SetCookieName($cookie_name);
$this->SetCookieDomain(SERVER_NAME);
if( $this->Application->IsAdmin()) { // && $this->Application->GetVar('admin') != 1
$mode = smAUTO;
}
elseif (constOn('IS_INSTALL')) {
$mode = smCOOKIES_ONLY;
}
else {
$ses_mode = $this->Application->ConfigValue('CookieSessions');
if ($ses_mode == 2) $mode = smAUTO;
if ($ses_mode == 1) $mode = smCOOKIES_ONLY;
if ($ses_mode == 0) $mode = smGET_ONLY;
}
$this->SetMode($mode);
parent::Init($prefix,$special);
if( !$this->Application->IsAdmin() && $this->GetField('PortalUserId') <= 0 )
{
$group_list = $this->Application->ConfigValue('User_GuestGroup').','.$this->Application->ConfigValue('User_LoggedInGroup');
$this->SetField('GroupId', $this->Application->ConfigValue('User_GuestGroup'));
$this->SetField('GroupList', $group_list);
}
}
+
+ function Destroy()
+ {
+ $this->Storage->DeleteSession($this);
+ $this->Storage->DeleteEditTables();
+ $this->Data =& new Params();
+ $this->SID = '';
+ if ($this->CookiesEnabled) $this->SetSessionCookie(); //will remove the cookie due to value (sid) is empty
+ $this->SetSession(); //will create a new session
+ }
+
}
class InpSessionStorage extends SessionStorage {
function Init($prefix,$special)
{
parent::Init($prefix,$special);
$this->setTableName(TABLE_PREFIX.'UserSession');
$this->SessionDataTable = TABLE_PREFIX.'SessionData';
$this->setIDField('SessionKey');
$this->TimestampField = 'LastAccessed';
$this->DataValueField = 'VariableValue';
$this->DataVarField = 'VariableName';
}
function LocateSession($sid)
{
$res = parent::LocateSession($sid);
if ($res) {
$this->Expiration += $this->SessionTimeout;
}
return $res;
}
function UpdateSession(&$session)
{
$time = adodb_mktime();
// Update LastAccessed only if it's newer than 1/10 of session timeout - perfomance optimization to eliminate needless updates on every click
if ($time - $this->DirectVars['LastAccessed'] > $this->SessionTimeout/10) {
$this->SetField($session, $this->TimestampField, $time);
}
}
function StoreSession(&$session, $additional_fields = Array())
{
$fields_hash = Array( 'PortalUserId' => $this->Application->IsAdmin() ? 0 : -2, // Guest
'Language' => $this->Application->GetDefaultLanguageId(),
'Theme' => $this->Application->GetDefaultThemeId(),
'IpAddress' => $_SERVER['REMOTE_ADDR'],
'GroupId' => $this->Application->ConfigValue('User_GuestGroup'),
'GroupList' => $this->Application->ConfigValue('User_GuestGroup'),
'CurrentTempKey'=> $session->SID,
);
parent::StoreSession($session, $fields_hash);
}
function GetExpiredSIDs()
{
$query = ' SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE '.$this->TimestampField.' < '.(adodb_mktime()-$this->SessionTimeout);
$ret = $this->Conn->GetCol($query);
if($ret) {
$this->DeleteEditTables();
}
return $ret;
}
function DeleteEditTables()
{
$tables = $this->Conn->GetCol('SHOW TABLES');
$mask_edit_table = '/'.TABLE_PREFIX.'ses_(.*)_edit_(.*)/';
$mask_search_table = '/'.TABLE_PREFIX.'ses_(.*?)_(.*)/';
$sql='SELECT COUNT(*) FROM '.$this->TableName.' WHERE '.$this->IDField.' = \'%s\'';
foreach($tables as $table)
{
if( preg_match($mask_edit_table,$table,$rets) || preg_match($mask_search_table,$table,$rets) )
{
$sid = preg_replace('/(.*)_(.*)/', '\\1', $rets[1]); // remove popup's wid from sid
$is_alive = $this->Conn->GetOne( sprintf($sql,$sid) );
if(!$is_alive) $this->Conn->Query('DROP TABLE IF EXISTS '.$table);
}
}
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/general/inp_ses_storage.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.23
\ No newline at end of property
+1.23.2.1
\ No newline at end of property
Index: branches/RC/core/admin_templates/tools/system_tools.tpl
===================================================================
--- branches/RC/core/admin_templates/tools/system_tools.tpl (revision 9638)
+++ branches/RC/core/admin_templates/tools/system_tools.tpl (revision 9639)
@@ -1,65 +1,87 @@
<inp2:m_RequireLogin permissions="in-portal:service.view" system="1"/>
<inp2:m_include t="incs/header"/>
<inp2:m_RenderElement name="section_header" icon="icon46_modules" title="!la_title_SystemTools!"/>
<inp2:m_RenderElement name="blue_bar" prefix="adm" title_preset="system_tools" module="in-portal" icon="icon46_modules"/>
<script type="text/javascript">
function show_structure($prefix, $event) {
var $form = document.getElementById($form_name);
openwin('about:blank', 'table_structure', 800, 575);
$form.target = 'table_structure';
submit_event($prefix, $event);
set_hidden_field('events[adm]', '');
}
+ function check_prefix_config() {
+ var $form = document.getElementById($form_name);
+ openwin('about:blank', 'config_check', 800, 575);
+ $form.target = 'config_check';
+ submit_event('adm', 'OnCheckPrefixConfig');
+ set_hidden_field('events[adm]', '');
+ }
+
function compile_templates()
{
openwin('<inp2:m_t t="tools/compile_templates" debug_ajax="1"/>', 'compile', 800, 575);
}
</script>
<inp2:m_DefineElement name="service_elem" event_prefix="adm">
<tr class="<inp2:m_odd_even odd="table-color1" even="table-color2"/>">
<inp2:m_inc param="tab_index" by="1"/>
<td class="text" style="width: 300px;">
<inp2:m_param name="title"/>:
</td>
<td valign="top" colspan="2">
<input class="button" type="button" onclick="submit_event('<inp2:m_param name="event_prefix"/>', '<inp2:m_param name="event_name"/>');" value="Go">
</td>
</tr>
</inp2:m_DefineElement>
<table width="100%" border="0" cellspacing="0" cellpadding="4" class="bordered" id="config_table">
<inp2:m_RenderElement name="subsection" title="la_section_General"/>
<inp2:m_RenderElement name="service_elem" title="Reset mod_rewrite Cache" event_name="OnResetModRwCache"/>
<inp2:m_RenderElement name="service_elem" title="Reset SMS Menu Cache" event_name="OnResetCMSMenuCache"/>
<inp2:m_RenderElement name="service_elem" title="Reset Sections Cache" event_name="OnResetSections"/>
<inp2:m_RenderElement name="service_elem" title="Reset Configs Cache" event_name="OnResetConfigsCache"/>
<inp2:m_RenderElement name="service_elem" title="Re-build Themes Files" event_name="OnRebuildThemes"/>
<inp2:m_RenderElement name="service_elem" title="Re-build Multilanguage Fields" event_prefix="lang" event_name="OnReflectMultiLingualFields"/>
<tr class="<inp2:m_odd_even odd="table-color1" even="table-color2"/>">
<inp2:m_inc param="tab_index" by="1"/>
<td class="text" style="width: 300px;">
Compile Templates (with NParser):
</td>
<td valign="top" colspan="2">
<input class="button" type="button" onclick="compile_templates();" value="Go">
</td>
</tr>
+
+ <tr class="<inp2:m_odd_even odd="table-color1" even="table-color2"/>">
+ <inp2:m_inc param="tab_index" by="1"/>
+ <td class="text" style="width: 300px;">
+ Prefix:
+ </td>
+ <td valign="top" colspan="2">
+ <input type="text" name="config_prefix" value="" size="30"/>
+ <input class="button" type="button" onclick="check_prefix_config();" value="Go">
+ <span class="small">Unit config prefix</span>
+ </td>
+ </tr>
+
+
<inp2:m_RenderElement name="subsection" title="la_section_Configs"/>
<tr class="<inp2:m_odd_even odd="table-color1" even="table-color2"/>">
<inp2:m_inc param="tab_index" by="1"/>
<td class="text" style="width: 300px;">
Table Structure:
</td>
<td valign="top" colspan="2">
<input type="text" name="table_name" value="" size="30"/>
<input class="button" type="button" onclick="show_structure('adm', 'OnGenerateTableStructure');" value="Go">
<span class="small">table name (prefix optional) OR unit config prefix</span>
</td>
</tr>
</table>
<inp2:m_include t="incs/footer"/>
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/tools/system_tools.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.9.2.1
\ No newline at end of property
+1.9.2.2
\ No newline at end of property
Index: branches/RC/core/admin_templates/users/admins_list.tpl
===================================================================
--- branches/RC/core/admin_templates/users/admins_list.tpl (revision 9638)
+++ branches/RC/core/admin_templates/users/admins_list.tpl (revision 9639)
@@ -1,52 +1,52 @@
<inp2:m_include t="incs/header"/>
-<inp2:m_RenderElement name="combined_header" section="proj-base:admins" pagination="1" prefix="u.admins" title_preset=""/>
+<inp2:m_RenderElement name="combined_header" section="proj-base:admins" pagination="1" prefix="u.admins" title_preset="" grid="Admins" />
<!-- ToolBar --->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td>
<script type="text/javascript">
//do not rename - this function is used in default grid for double click!
function edit()
{
set_hidden_field('remove_specials[u.admins]', 1);
std_edit_item('u.admins', 'proj-base/users/admins_edit');
}
var a_toolbar = new ToolBar();
a_toolbar.AddButton( new ToolBarButton('proj-base:new_user', '<inp2:m_phrase label="la_ToolTip_Add" escape="1"/>',
function() {
set_hidden_field('remove_specials[u.admins]', 1);
std_precreate_item('u.admins', 'proj-base/users/admins_edit')
} ) );
a_toolbar.AddButton( new ToolBarButton('edit', '<inp2:m_phrase label="la_ToolTip_Edit" escape="1"/>::<inp2:m_phrase label="la_ShortToolTip_Edit" escape="1"/>', edit) );
a_toolbar.AddButton( new ToolBarButton('delete', '<inp2:m_phrase label="la_ToolTip_Delete" escape="1"/>',
function() {
set_hidden_field('remove_specials[u.admins]', 1);
std_delete_items('u.admins')
} ) );
a_toolbar.AddButton( new ToolBarSeparator('sep1') );
a_toolbar.AddButton( new ToolBarButton('view', '<inp2:m_phrase label="la_ToolTip_View" escape="1"/>', function() {
show_viewmenu(a_toolbar,'view');
}
) );
a_toolbar.Render();
</script>
</td>
<inp2:m_RenderElement name="search_main_toolbar" prefix="u.admins" grid="Admins"/>
</tr>
</tbody>
</table>
<inp2:m_RenderElement name="grid" PrefixSpecial="u.admins" IdField="PortalUserId" grid="Admins" menu_filters="yes" grid_filters="1"/>
<script type="text/javascript">
Grids['u.admins'].SetDependantToolbarButtons( new Array('edit','delete') );
</script>
<inp2:m_include t="incs/footer"/>
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/users/admins_list.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.3
\ No newline at end of property
+1.3.2.1
\ No newline at end of property
Index: branches/RC/core/admin_templates/js/script.js
===================================================================
--- branches/RC/core/admin_templates/js/script.js (revision 9638)
+++ branches/RC/core/admin_templates/js/script.js (revision 9639)
@@ -1,1410 +1,1451 @@
if ( !( isset($init_made) && $init_made ) ) {
+ var Application = new kApplication();
var Grids = new Array();
var Toolbars = new Array();
var $Menus = new Array();
var $ViewMenus = new Array();
var $nls_menus = new Array();
var $MenuNames = new Array();
var $form_name = 'kernel_form';
if(!$fw_menus) var $fw_menus = new Array();
var $env = '';
var submitted = false;
+ var unload_legal = false;
var $edit_mode = false;
var $init_made = true; // in case of double inclusion of script.js :)
// hook processing
var hBEFORE = 1; // this is const, but including this twice causes errors
var hAFTER = 2; // this is const, but including this twice causes errors
var $hooks = new Array();
replaceFireBug();
}
function use_popups($prefix_special, $event) {
return $use_popups;
}
function getArrayValue()
{
var $value = arguments[0];
var $current_key = 0;
$i = 1;
while ($i < arguments.length) {
$current_key = arguments[$i];
if (isset($value[$current_key])) {
$value = $value[$current_key];
}
else {
return false;
}
$i++;
}
return $value;
}
function setArrayValue()
{
// first argument - array, other arguments - keys (arrays too), last argument - value
var $array = arguments[0];
var $current_key = 0;
$i = 1;
while ($i < arguments.length - 1) {
$current_key = arguments[$i];
if (!isset($array[$current_key])) {
$array[$current_key] = new Array();
}
$array = $array[$current_key];
$i++;
}
$array[$array.length] = arguments[arguments.length - 1];
}
function processHooks($function_name, $hook_type, $prefix_special)
{
var $i = 0;
var $local_hooks = getArrayValue($hooks, $function_name, $hook_type);
while($i < $local_hooks.length) {
$local_hooks[$i]($function_name, $prefix_special);
$i++;
}
}
function registerHook($function_name, $hook_type, $hook_body)
{
setArrayValue($hooks, $function_name, $hook_type, $hook_body);
}
function resort_grid($prefix_special, $field, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field($prefix_special + '_Sort1', $field);
submit_event($prefix_special, 'OnSetSorting', null, null, $ajax);
}
function direct_sort_grid($prefix_special, $field, $direction, $field_pos, $ajax)
{
if(!isset($field_pos)) $field_pos = 1;
set_form($prefix_special, $ajax);
set_hidden_field($prefix_special+'_Sort'+$field_pos,$field);
set_hidden_field($prefix_special+'_Sort'+$field_pos+'_Dir',$direction);
set_hidden_field($prefix_special+'_SortPos',$field_pos);
submit_event($prefix_special,'OnSetSortingDirect', null, null, $ajax);
}
function reset_sorting($prefix_special)
{
submit_event($prefix_special,'OnResetSorting');
}
function set_per_page($prefix_special, $per_page, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field($prefix_special + '_PerPage', $per_page);
submit_event($prefix_special, 'OnSetPerPage', null, null, $ajax);
}
function submit_event(prefix_special, event, t, form_action, $ajax)
{
+ if (!Application.processHooks(prefix_special + ':' + event)) {
+ return false;
+ }
if ($ajax) {
return $Catalog.submit_event(prefix_special, event, t);
}
if (event) {
set_hidden_field('events[' + prefix_special + ']', event);
}
if (t) set_hidden_field('t', t);
if (form_action) {
var old_env = '';
if (!form_action.match(/\?/)) {
document.getElementById($form_name).action.match(/.*(\?.*)/);
old_env = RegExp.$1;
}
document.getElementById($form_name).action = form_action + old_env;
}
submit_kernel_form();
}
function submit_action($url, $action)
{
$form = document.getElementById($form_name);
$form.action = $url;
set_hidden_field('Action', $action);
submit_kernel_form();
}
function show_form_data()
{
var $kf = document.getElementById($form_name);
$ret = '';
for(var i in $kf.elements)
{
$elem = $kf.elements[i];
$ret += $elem.id + ' = ' + $elem.value + "\n";
}
alert($ret);
}
function submit_kernel_form()
{
if (submitted) {
return;
}
submitted = true;
+ unload_legal = true;
var $form = document.getElementById($form_name);
processHooks('SubmitKF', hBEFORE);
if (typeof $form.onsubmit == "function") {
$form.onsubmit();
}
$form.submit();
processHooks('SubmitKF', hAFTER);
$form.target = '';
set_hidden_field('t', t);
window.setTimeout(function() {submitted = false}, 500);
}
function set_event(prefix_special, event)
{
var event_field=document.getElementById('events[' + prefix_special + ']');
if(isset(event_field))
{
event_field.value = event;
}
}
function isset(variable)
{
if(variable==null) return false;
return (typeof(variable)=='undefined')?false:true;
}
function in_array(needle, haystack)
{
return array_search(needle, haystack) != -1;
}
function array_search(needle, haystack)
{
for (var i=0; i<haystack.length; i++)
{
if (haystack[i] == needle) return i;
}
return -1;
}
function print_pre(variable, msg)
{
if (!isset(msg)) msg = '';
var s = msg;
for (prop in variable) {
s += prop+" => "+variable[prop] + "\n";
}
alert(s);
}
function go_to_page($prefix_special, $page, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field($prefix_special + '_Page', $page);
submit_event($prefix_special, null, null, null, $ajax);
}
function go_to_list(prefix_special, tab)
{
set_hidden_field(prefix_special+'_GoTab', tab);
submit_event(prefix_special,'OnUpdateAndGoToTab',null);
}
function go_to_tab(prefix_special, tab)
{
set_hidden_field(prefix_special+'_GoTab', tab);
submit_event(prefix_special,'OnPreSaveAndGoToTab',null);
}
function go_to_id(prefix_special, id)
{
set_hidden_field(prefix_special+'_GoId', id);
submit_event(prefix_special,'OnPreSaveAndGo')
}
// in-portal compatibility functions: begin
function getScriptURL($script_name, tpl)
{
tpl = tpl ? '-'+tpl : '';
var $asid = get_hidden_field('sid');
return base_url+$script_name+'?env='+( isset($env)&&$env?$env:$asid )+tpl+'&en=0';
}
function OpenEditor(extra_env,TargetForm,TargetField)
{
// var $url = getScriptURL('admin/editor/editor_new.php');
var $url = getScriptURL('admin/index.php', 'popups/editor');
// alert($url);
$url = $url+'&TargetForm='+TargetForm+'&TargetField='+TargetField+'&destform=popup';
if(extra_env.length>0) $url += extra_env;
openwin($url,'html_edit',800,575);
}
function OpenUserSelector(extra_env,TargetForm,TargetField)
{
var $url = getScriptURL('admin/users/user_select.php');
$url += '&destform='+TargetForm+'&Selector=radio&destfield='+TargetField+'&IdField=Login';
if(extra_env.length>0) $url += extra_env;
openwin($url,'user_select',800,575);
return false;
}
function OpenCatSelector(extra_env)
{
var $url = getScriptURL('admin/cat_select.php');
if(extra_env.length>0) $url += extra_env;
openwin($url,'catselect',750,400);
}
function OpenItemSelector(extra_env,$TargetForm)
{
var $url = getScriptURL('admin/relation_select.php') + '&destform='+$TargetForm;
if(extra_env.length>0) $url += extra_env;
openwin($url,'groupselect',750,400);
}
function OpenUserEdit($user_id, $extra_env)
{
var $url = getScriptURL('admin/users/adduser.php') + '&direct_id=' + $user_id;
if( isset($extra_env) ) $url += $extra_env;
window.location.href = $url;
}
function OpenLinkEdit($link_id, $extra_env)
{
var $url = getScriptURL('in-link/admin/addlink.php') + '&item=' + $link_id;
if( isset($extra_env) ) $url += $extra_env;
window.location.href = $url;
}
function OpenHelp($help_link)
{
// $help_link.match('http://(.*).lv/in-commerce/admin(.*)');
// alert(RegExp.$2);
openwin($help_link,'HelpPopup',750,400);
}
function openEmailSend($url, $type, $prefix_special)
{
var $kf = document.getElementById($form_name);
var $prev_action = $kf.action;
var $prev_opener = get_hidden_field('m_opener');
$kf.action = $url;
set_hidden_field('m_opener', 'p');
$kf.target = 'sendmail';
set_hidden_field('idtype', 'group');
set_hidden_field('idlist', Grids[$prefix_special].GetSelected().join(',') );
openwin('','sendmail',750,400);
submit_kernel_form();
$kf.action = $prev_action;
set_hidden_field('m_opener', $prev_opener);
}
// in-portal compatibility functions: end
function InitTranslator(prefix, field, t, multi_line)
{
var $kf = document.getElementById($form_name);
var $window_name = 'select_'+t.replace(/(\/|-)/g, '_');
var $regex = new RegExp('(.*)\?env=(' + document.getElementById('sid').value + ')?-(.*?):(m[^:]+)');
$regex = $regex.exec($kf.action);
// set_hidden_field('return_m', $regex[4]);
var $prev_opener = get_hidden_field('m_opener');
if (!isset(multi_line)) multi_line = 0;
openwin('', $window_name, 750, 400);
// set_hidden_field('return_template', $kf.elements['t'].value); // where should return after popup is done
set_hidden_field('m_opener', 'p');
set_hidden_field('translator_wnd_name', $window_name);
set_hidden_field('translator_field', field);
set_hidden_field('translator_t', t);
set_hidden_field('translator_prefixes', prefix);
set_hidden_field('translator_multi_line', multi_line);
$kf.target = $window_name;
return $prev_opener;
}
function PreSaveAndOpenTranslator(prefix, field, t, multi_line)
{
var $prev_opener = InitTranslator(prefix, field, t, multi_line);
var split_prefix = prefix.split(',');
submit_event(split_prefix[0], 'OnPreSaveAndOpenTranslator');
set_hidden_field('m_opener', $prev_opener);
}
function PreSaveAndOpenTranslatorCV(prefix, field, t, resource_id, multi_line)
{
var $prev_opener = InitTranslator(prefix, field, t, multi_line);
set_hidden_field('translator_resource_id', resource_id);
var split_prefix = prefix.split(',');
submit_event(split_prefix[0],'OnPreSaveAndOpenTranslator');
set_hidden_field('m_opener', $prev_opener);
}
function openTranslator(prefix,field,url,wnd)
{
var $kf = document.getElementById($form_name);
set_hidden_field('trans_prefix', prefix);
set_hidden_field('trans_field', field);
set_hidden_field('events[trans]', 'OnLoad');
var $regex = new RegExp('(.*)\?env=(' + document.getElementById('sid').value + ')?-(.*?):(.*)');
var $t = $regex.exec(url)[3];
$kf.target = wnd;
submit_event(prefix,'',$t,url);
}
function openwin($url,$name,$width,$height)
{
// prevent window from opening larger, then screen resolution on user's computer (to Kostja)
// alert('openwin: name = ['+$name+']');
var left = Math.round((screen.width - $width)/2);
var top = Math.round((screen.height - $height)/2);
cur_x = is.ie ? window.screenLeft : window.screenX;
cur_y = is.ie ? window.screenTop : window.screenY;
// alert('current X,Y: '+cur_x+','+cur_y+' target x,y: '+left+','+top);
var $window_params = 'left='+left+',top='+top+',width='+$width+',height='+$height+',status=yes,resizable=yes,menubar=no,scrollbars=yes,toolbar=no';
return window.open($url,$name,$window_params);
}
function OnResizePopup(e) {
if (!document.all) {
var $winW = window.innerWidth;
var $winH = window.innerHeight;
}
else {
var $winW = window.document.body.offsetWidth;
var $winH = window.document.body.offsetHeight;
}
window.status = '[width: ' + $winW + '; height: ' + $winH + ']';
}
function opener_action(new_action)
{
var $prev_opener = get_hidden_field('m_opener');
set_hidden_field('m_opener', new_action);
return $prev_opener;
}
function open_popup($prefix_special, $event, $t, $window_size) {
if (!$window_size) {
// if no size given, then query it from ajax
var $default_size = '750x400';
var $pm = getFrame('head').$popup_manager;
if ($pm) {
// popup manager was found in head frame
$pm.ResponceFunction = function ($responce) {
if (!$responce.match(/([\d]+)x([\d]+)/)) {
// invalid responce was received, may be php fatal error during AJAX request
$responce = $default_size;
}
open_popup($prefix_special, $event, $t, $responce);
}
$pm.GetSize($t);
return ;
}
$window_size = $default_size;
}
var $kf = document.getElementById($form_name);
var $window_name = $t.replace(/(\/|-)/g, '_'); // replace "/" and "-" with "_"
$window_size = $window_size.split('x');
openwin('', $window_name, $window_size[0], $window_size[1]);
$kf.target = $window_name;
var $prev_opener = opener_action('p');
event_bak = get_hidden_field('events[' + $prefix_special + ']')
if (!event_bak) event_bak = '';
submit_event($prefix_special, $event, $t);
opener_action($prev_opener); // restore opener in parent window
set_hidden_field('events[' + $prefix_special + ']', event_bak); // restore event
// AJAX popup size respoce is received after std_edit_item/std_precreate_item function exit
set_hidden_field($prefix_special + '_mode', null);
}
function openSelector($prefix, $url, $dst_field, $window_size, $event)
{
// if url has additional params - store it and make hidden fields from it (later, below)
var $additional = [];
if ($url.match('(.*?)&(.*)')) {
$url = RegExp.$1;
var tmp = RegExp.$2;
var pairs = tmp.split('&');
for (var i in pairs) {
var data = pairs[i].split('=');
$additional[data[0]] = data[1];
}
}
// get template name from url
var $regex = new RegExp('(.*)\?env=(' + document.getElementById('sid').value + ')?-(.*?):(m[^:]+)');
$regex = $regex.exec($url);
var $t = $regex[3];
// substitute form action with selector's url
var $kf = document.getElementById($form_name);
var $prev_action = $kf.action;
$kf.action = $url;
// check parameter values
if (!isset($event)) $event = '';
// set variables need for selector to work
processHooks('openSelector', hBEFORE);
set_hidden_field('main_prefix', $prefix);
set_hidden_field('dst_field', $dst_field);
for (var i in $additional)
{
set_hidden_field(i, $additional[i]);
}
open_popup($prefix, $event, $t);
// restore form action back
processHooks('openSelector', hAFTER);
$kf.action = $prev_action;
}
function translate_phrase($label, $template) {
set_hidden_field('phrases_label', $label);
open_popup('phrases', 'OnNew', $template);
}
function std_precreate_item(prefix_special, edit_template)
{
set_hidden_field(prefix_special+'_mode', 't');
if (use_popups(prefix_special, 'OnPreCreate')) {
open_popup(prefix_special, 'OnPreCreate', edit_template);
}
else {
opener_action('d');
submit_event(prefix_special,'OnPreCreate', edit_template);
}
// set_hidden_field(prefix_special+'_mode', '');
}
function std_new_item(prefix_special, edit_template)
{
if (use_popups(prefix_special, 'OnNew')) {
open_popup(prefix_special, 'OnNew', edit_template);
}
else {
opener_action('d');
submit_event(prefix_special,'OnNew', edit_template);
}
}
function std_edit_item(prefix_special, edit_template)
{
set_hidden_field(prefix_special+'_mode', 't');
if (use_popups(prefix_special, 'OnEdit')) {
open_popup(prefix_special, 'OnEdit', edit_template);
}
else {
opener_action('d');
submit_event(prefix_special,'OnEdit',edit_template);
}
// set_hidden_field(prefix_special+'_mode', '');
}
function std_edit_temp_item(prefix_special, edit_template)
{
if (use_popups(prefix_special, '')) {
open_popup(prefix_special, '', edit_template);
}
else {
opener_action('d');
submit_event(prefix_special,'',edit_template);
}
}
function std_delete_items(prefix_special, t, $ajax)
{
if (inpConfirm('Are you sure you want to delete selected items?')) {
submit_event(prefix_special, 'OnMassDelete', t, null, $ajax);
}
}
+function std_csv_export(prefix_special, grid, template)
+{
+ set_hidden_field('PrefixSpecial', prefix_special);
+ set_hidden_field('grid', grid);
+ if (use_popups(prefix_special, '')) {
+ open_popup(prefix_special, '', template);
+ }
+ else {
+ submit_event(prefix_special, '', template);
+ }
+}
+function std_csv_import(prefix_special, grid, template)
+{
+ set_hidden_field('PrefixSpecial', prefix_special);
+ set_hidden_field('grid', grid);
+ if (use_popups(prefix_special, '')) {
+ open_popup(prefix_special, '', template);
+ }
+ else {
+ submit_event(prefix_special, '', template);
+ }
+}
// set current form base on ajax
function set_form($prefix_special, $ajax)
{
if ($ajax) {
$form_name = $Catalog.queryTabRegistry('prefix', $prefix_special, 'tab_id') + '_form';
}
}
// sets hidden field value
// if the field does not exist - creates it
function set_hidden_field($field_id, $value)
{
var $kf = document.getElementById($form_name);
var $field = $kf.elements[$field_id];
if ($value === null) {
if ($field) {
$kf.removeChild($field);
}
return true;
}
if ($field) {
$field.value = $value;
return true;
}
$field = document.createElement('INPUT');
$field.type = 'hidden';
$field.name = $field_id;
$field.id = $field_id;
$field.value = $value;
$kf.appendChild($field);
return false;
}
// sets hidden field value
// if the field does not exist - creates it
function setInnerHTML($field_id, $value)
{
var $element = document.getElementById($field_id);
if (!$element) return false;
$element.innerHTML = $value;
}
function get_hidden_field($field)
{
var $kf = document.getElementById($form_name);
return $kf.elements[$field] ? $kf.elements[$field].value : false;
}
function search($prefix_special, $grid_name, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field('grid_name', $grid_name);
submit_event($prefix_special, 'OnSearch', null, null, $ajax);
}
function search_reset($prefix_special, $grid_name, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field('grid_name', $grid_name);
submit_event($prefix_special, 'OnSearchReset', null, null, $ajax);
}
function search_keydown($event, $prefix_special, $grid, $ajax)
{
$event = $event ? $event : event;
if (window.event) {// IE
var $key_code = $event.keyCode;
}
else if($event.which) { // Netscape/Firefox/Opera
var $key_code = $event.which;
}
switch ($key_code) {
case 13:
search($prefix_special, $grid, parseInt($ajax));
break;
case 27:
search_reset($prefix_special, $grid, parseInt($ajax));
break;
}
}
function getRealLeft(el)
{
if (typeof(el) == 'string') {
el = document.getElementById(el);
}
xPos = el.offsetLeft;
tempEl = el.offsetParent;
while (tempEl != null)
{
xPos += tempEl.offsetLeft;
tempEl = tempEl.offsetParent;
}
// if (obj.x) return obj.x;
return xPos;
}
function getRealTop(el)
{
if (typeof(el) == 'string') {
el = document.getElementById(el);
}
yPos = el.offsetTop;
tempEl = el.offsetParent;
while (tempEl != null)
{
yPos += tempEl.offsetTop;
tempEl = tempEl.offsetParent;
}
// if (obj.y) return obj.y;
return yPos;
}
function show_viewmenu_old($toolbar, $button_id)
{
var $img = $toolbar.GetButtonImage($button_id);
var $pos_x = getRealLeft($img) - ((document.all) ? 6 : -2);
var $pos_y = getRealTop($img) + 32;
var $prefix_special = '';
window.triedToWriteMenus = false;
if($ViewMenus.length == 1)
{
$prefix_special = $ViewMenus[$ViewMenus.length-1];
$fw_menus[$prefix_special+'_view_menu']();
$Menus[$prefix_special+'_view_menu'].writeMenus('MenuContainers['+$prefix_special+']');
window.FW_showMenu($Menus[$prefix_special+'_view_menu'], $pos_x, $pos_y);
}
else
{
// prepare menus
for(var $i in $ViewMenus)
{
$prefix_special = $ViewMenus[$i];
$fw_menus[$prefix_special+'_view_menu']();
}
$Menus['mixed'] = new Menu('ViewMenu_mixed');
// merge menus into new one
for(var $i in $ViewMenus)
{
$prefix_special = $ViewMenus[$i];
$Menus['mixed'].addMenuItem( $Menus[$prefix_special+'_view_menu'] );
}
$Menus['mixed'].writeMenus('MenuContainers[mixed]');
window.FW_showMenu($Menus['mixed'], $pos_x, $pos_y);
}
}
var nlsMenuRendered = false;
function show_viewmenu($toolbar, $button_id)
{
if($ViewMenus.length == 1) {
$prefix_special = $ViewMenus[$ViewMenus.length-1];
menu_to_show = $prefix_special+'_view_menu';
}
else
{
mixed_menu = menuMgr.createMenu(rs('mixed_menu'));
mixed_menu.applyBorder(false, false, false, false);
mixed_menu.dropShadow("none");
mixed_menu.showIcon = true;
// merge menus into new one
for(var $i in $ViewMenus)
{
$prefix_special = $ViewMenus[$i];
mixed_menu.addItem( rs($prefix_special+'.view.menu.mixed'),
$MenuNames[$prefix_special+'_view_menu'],
'javascript:void()', null, true, null,
rs($prefix_special+'.view.menu'),$MenuNames[$prefix_special+'_view_menu'] );
}
menu_to_show = 'mixed_menu';
}
renderMenus();
nls_showMenu(rs(menu_to_show), $toolbar.GetButtonImage($button_id))
}
function renderMenus()
{
menuMgr.renderMenus('nlsMenuPlace');
nlsMenuRendered = true;
}
function set_window_title($title)
{
var $window = window;
if($window.parent) $window = $window.parent;
$window.document.title = (main_title.length ? main_title + ' - ' : '') + $title;
}
function set_filter($prefix_special, $filter_id, $filter_value, $ajax)
{
set_form($prefix_special, $ajax);
set_hidden_field('filter_id', $filter_id);
set_hidden_field('filter_value', $filter_value);
submit_event($prefix_special, 'OnSetFilter', null, null, $ajax);
}
function filters_remove_all($prefix_special, $ajax)
{
set_form($prefix_special, $ajax);
submit_event($prefix_special,'OnRemoveFilters', null, null, $ajax);
}
function filters_apply_all($prefix_special, $ajax)
{
set_form($prefix_special, $ajax);
submit_event($prefix_special,'OnApplyFilters', null, null, $ajax);
}
function RemoveTranslationLink($string, $escaped)
{
if (!isset($escaped)) $escaped = true;
if ($escaped) {
return $string.replace(/&lt;a href=&quot;(.*?)&quot;&gt;(.*?)&lt;\/a&gt;/g, '$2');
}
return $string.replace(/<a href="(.*?)">(.*?)<\/a>/g, '$2');
}
function redirect($url)
{
window.location.href = $url;
}
function update_checkbox_options($cb_mask, $hidden_id)
{
var $kf = document.getElementById($form_name);
var $tmp = '';
for (var i = 0; i < $kf.elements.length; i++)
{
if ( $kf.elements[i].id.match($cb_mask) )
{
if ($kf.elements[i].checked) $tmp += '|'+$kf.elements[i].value;
}
}
if($tmp.length > 0) $tmp += '|';
document.getElementById($hidden_id).value = $tmp.replace(/,$/, '');
}
function update_multiple_options($hidden_id) {
var $select = document.getElementById($hidden_id + '_select');
var $result = '';
for (var $i = 0; $i < $select.options.length; $i++) {
if ($select.options[$i].selected) {
$result += $select.options[$i].value + '|';
}
}
document.getElementById($hidden_id).value = $result ? '|' + $result : '';
}
// related to lists operations (moving)
function move_selected($from_list, $to_list)
{
if (typeof($from_list) != 'object') $from_list = document.getElementById($from_list);
if (typeof($to_list) != 'object') $to_list = document.getElementById($to_list);
if (has_selected_options($from_list))
{
var $from_array = select_to_array($from_list);
var $to_array = select_to_array($to_list);
var $new_from = Array();
var $cur = null;
for (var $i = 0; $i < $from_array.length; $i++)
{
$cur = $from_array[$i];
if ($cur[2]) // If selected - add to To array
{
$to_array[$to_array.length] = $cur;
}
else //Else - keep in new From
{
$new_from[$new_from.length] = $cur;
}
}
$from_list = array_to_select($new_from, $from_list);
$to_list = array_to_select($to_array, $to_list);
}
else
{
alert('Please select items to perform moving!');
}
}
function select_to_array($aSelect)
{
var $an_array = new Array();
var $cur = null;
for (var $i = 0; $i < $aSelect.length; $i++)
{
$cur = $aSelect.options[$i];
$an_array[$an_array.length] = new Array($cur.text, $cur.value, $cur.selected);
}
return $an_array;
}
function array_to_select($anArray, $aSelect)
{
var $initial_length = $aSelect.length;
for (var $i = $initial_length - 1; $i >= 0; $i--)
{
$aSelect.options[$i] = null;
}
for (var $i = 0; $i < $anArray.length; $i++)
{
$cur = $anArray[$i];
$aSelect.options[$aSelect.length] = new Option($cur[0], $cur[1]);
}
}
function select_compare($a, $b)
{
if ($a[0] < $b[0])
return -1;
if ($a[0] > $b[0])
return 1;
return 0;
}
function select_to_string($aSelect)
{
var $result = '';
var $cur = null;
if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
for (var $i = 0; $i < $aSelect.length; $i++)
{
$result += $aSelect.options[$i].value + '|';
}
return $result.length ? '|' + $result : '';
}
function selected_to_string($aSelect)
{
var $result = '';
var $cur = null;
if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
for (var $i = 0; $i < $aSelect.length; $i++)
{
$cur = $aSelect.options[$i];
if ($cur.selected && $cur.value != '')
{
$result += $cur.value + '|';
}
}
return $result.length ? '|' + $result : '';
}
function string_to_selected($str, $aSelect)
{
var $cur = null;
for (var $i = 0; $i < $aSelect.length; $i++)
{
$cur = $aSelect.options[$i];
$aSelect.options[$i].selected = $str.match('\\|' + $cur.value + '\\|') ? true : false;
}
}
function set_selected($selected_options, $aSelect)
{
if (!$selected_options.length) return false;
for (var $i = 0; $i < $aSelect.length; $i++)
{
for (var $k = 0; $k < $selected_options.length; $k++)
{
if ($aSelect.options[$i].value == $selected_options[$k])
{
$aSelect.options[$i].selected = true;
}
}
}
}
function get_selected_count($theList)
{
var $count = 0;
var $cur = null;
for (var $i = 0; $i < $theList.length; $i++)
{
$cur = $theList.options[$i];
if ($cur.selected) $count++;
}
return $count;
}
function get_selected_index($aSelect, $typeIndex)
{
var $index = 0;
for (var $i = 0; $i < $aSelect.length; $i++)
{
if ($aSelect.options[$i].selected)
{
$index = $i;
if ($typeIndex == 'firstSelected') break;
}
}
return $index;
}
function has_selected_options($theList)
{
var $ret = false;
var $cur = null;
for (var $i = 0; $i < $theList.length; $i++)
{
$cur = $theList.options[$i];
if ($cur.selected) $ret = true;
}
return $ret;
}
function select_sort($aSelect)
{
if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
var $to_array = select_to_array($aSelect);
$to_array.sort(select_compare);
array_to_select($to_array, $aSelect);
}
function move_options_up($aSelect, $interval)
{
if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
if (has_selected_options($aSelect))
{
var $selected_options = Array();
var $first_selected = get_selected_index($aSelect, 'firstSelected');
for (var $i = 0; $i < $aSelect.length; $i++)
{
if ($aSelect.options[$i].selected && ($first_selected > 0) )
{
swap_options($aSelect, $i, $i - $interval);
$selected_options[$selected_options.length] = $aSelect.options[$i - $interval].value;
}
else if ($first_selected == 0)
{
//alert('Begin of list');
break;
}
}
set_selected($selected_options, $aSelect);
}
else
{
//alert('Check items from moving');
}
}
function move_options_down($aSelect, $interval)
{
if (typeof($aSelect) != 'object') $aSelect = document.getElementById($aSelect);
if (has_selected_options($aSelect))
{
var $last_selected = get_selected_index($aSelect, 'lastSelected');
var $selected_options = Array();
for (var $i = $aSelect.length - 1; $i >= 0; $i--)
{
if ($aSelect.options[$i].selected && ($aSelect.length - ($last_selected + 1) > 0))
{
swap_options($aSelect, $i, $i + $interval);
$selected_options[$selected_options.length] = $aSelect.options[$i + $interval].value;
}
else if ($last_selected + 1 == $aSelect.length)
{
//alert('End of list');
break;
}
}
set_selected($selected_options, $aSelect);
}
else
{
//alert('Check items from moving');
}
}
function swap_options($aSelect, $src_num, $dst_num)
{
var $src_html = $aSelect.options[$src_num].innerHTML;
var $dst_html = $aSelect.options[$dst_num].innerHTML;
var $src_value = $aSelect.options[$src_num].value;
var $dst_value = $aSelect.options[$dst_num].value;
var $src_option = document.createElement('OPTION');
var $dst_option = document.createElement('OPTION');
$aSelect.remove($src_num);
$aSelect.options.add($dst_option, $src_num);
$dst_option.innerText = $dst_html;
$dst_option.value = $dst_value;
$dst_option.innerHTML = $dst_html;
$aSelect.remove($dst_num);
$aSelect.options.add($src_option, $dst_num);
$src_option.innerText = $src_html;
$src_option.value = $src_value;
$src_option.innerHTML = $src_html;
}
function getXMLHTTPObject(content_type)
{
if (!isset(content_type)) content_type = 'text/plain';
var http_request = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType(content_type);
// See note below about this line
}
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
return http_request;
}
function str_repeat($symbol, $count)
{
var $i = 0;
var $ret = '';
while($i < $count) {
$ret += $symbol;
$i++;
}
return $ret;
}
function getDocumentFromXML(xml)
{
if (window.ActiveXObject) {
var doc = new ActiveXObject("Microsoft.XMLDOM");
doc.async=false;
doc.loadXML(xml);
}
else {
var parser = new DOMParser();
var doc = parser.parseFromString(xml,"text/xml");
}
return doc;
}
function set_persistant_var($var_name, $var_value, $t, $form_action)
{
set_hidden_field('field', $var_name);
set_hidden_field('value', $var_value);
submit_event('u', 'OnSetPersistantVariable', $t, $form_action);
}
/*functionremoveEvent(el, evname, func) {
if (Calendar.is_ie) {
el.detachEvent("on" + evname, func);
} else {
el.removeEventListener(evname, func, true);
}
};*/
function setCookie($Name, $Value)
{
// set cookie
if(getCookie($Name) != $Value)
{
document.cookie = $Name+'='+escape($Value)+'; path=' + $base_path + '/';
}
}
function getCookie($Name)
{
// get cookie
var $cookieString = document.cookie;
var $index = $cookieString.indexOf($Name+'=');
if($index == -1) return null;
$index = $cookieString.indexOf('=',$index)+1;
var $endstr = $cookieString.indexOf(';',$index);
if($endstr == -1) $endstr = $cookieString.length;
return unescape($cookieString.substring($index, $endstr));
}
function deleteCookie($Name)
{
// deletes cookie
if (getCookie($Name))
{
document.cookie = $Name+'=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/';
}
}
function addElement($dst_element, $tag_name) {
var $new_element = document.createElement($tag_name.toUpperCase());
$dst_element.appendChild($new_element);
return $new_element;
}
Math.sum = function($array) {
var $i = 0;
var $total = 0;
while ($i < $array.length) {
$total += $array[$i];
$i++;
}
return $total;
}
Math.average = function($array) {
return Math.sum($array) / $array.length;
}
// remove spaces and underscores from a string, used for nls_menu
function rs(str)
{
return str.replace(/[ _\']+/g, '.');
}
function getFrame($name)
{
var $main_window = window;
// 1. cycle through popups to get main window
try {
// will be error, when other site is opened in parent window
while ($main_window.opener) {
$main_window = $main_window.opener;
}
}
catch (err) {
// catch Access/Permission Denied error
// alert('getFrame.Error: [' + err.description + ']');
return window;
}
var $frameset = $main_window.parent.frames;
for ($i = 0; $i < $frameset.length; $i++) {
if ($frameset[$i].name == $name) {
return $frameset[$i];
}
}
return $main_window.parent;
}
function ClearBrowserSelection()
{
if (window.getSelection) {
// removeAllRanges will be supported by Opera from v 9+, do nothing by now
var selection = window.getSelection();
if (selection.removeAllRanges) { // Mozilla & Opera 9+
// alert('clearing FF')
window.getSelection().removeAllRanges();
}
} else if (document.selection && !is.opera) { // IE
// alert('clearing IE')
document.selection.empty();
}
}
function reset_form(prefix, event, msg)
{
if (confirm(RemoveTranslationLink(msg, true))) {
submit_event(prefix, event)
}
}
function cancel_edit(prefix, cancel_ev, save_ev, msg)
{
if (confirm(RemoveTranslationLink(msg, true))) {
submit_event(prefix, save_ev)
}
else {
submit_event(prefix, cancel_ev)
}
}
function execJS(node)
{
var bSaf = (navigator.userAgent.indexOf('Safari') != -1);
var bOpera = (navigator.userAgent.indexOf('Opera') != -1);
var bMoz = (navigator.appName == 'Netscape');
if (!node) return;
/* IE wants it uppercase */
var st = node.getElementsByTagName('SCRIPT');
var strExec;
for(var i=0;i<st.length; i++)
{
if (bSaf) {
strExec = st[i].innerHTML;
st[i].innerHTML = "";
} else if (bOpera) {
strExec = st[i].text;
st[i].text = "";
} else if (bMoz) {
strExec = st[i].textContent;
st[i].textContent = "";
} else {
strExec = st[i].text;
st[i].text = "";
}
try {
var x = document.createElement("script");
x.type = "text/javascript";
/* In IE we must use .text! */
if ((bSaf) || (bOpera) || (bMoz))
x.innerHTML = strExec;
else x.text = strExec;
document.getElementsByTagName("head")[0].appendChild(x);
} catch(e) {
alert(e);
}
}
};
function NumberFormatter() {}
NumberFormatter.ThousandsSep = '\'';
NumberFormatter.DecimalSep = '.';
NumberFormatter.Parse = function(num)
{
if (num == '') return 0;
return parseFloat( num.toString().replace(this.ThousandsSep, '').replace(this.DecimalSep, '.') );
}
NumberFormatter.Format = function(num)
{
num += '';
x = num.split('.');
x1 = x[0];
x2 = x.length > 1 ? this.DecimalSep + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + this.ThousandsSep + '$2');
}
return x1 + x2;
}
function getDimensions(obj) {
var style
if (obj.currentStyle) {
style = obj.currentStyle;
}
else {
style = getComputedStyle(obj,'');
}
padding = [parseInt(style.paddingTop), parseInt(style.paddingRight), parseInt(style.paddingBottom), parseInt(style.paddingLeft)]
border = [parseInt(style.borderTopWidth), parseInt(style.borderRightWidth), parseInt(style.borderBottomWidth), parseInt(style.borderLeftWidth)]
for (var i in padding) if ( isNaN( padding[i] ) ) padding[i] = 0
for (var i in border) if ( isNaN( border[i] ) ) border[i] = 0
var result = new Object();
result.innerHeight = obj.clientHeight - padding[0] - padding[2];
result.innerWidth = obj.clientWidth - padding[1] - padding[3];
result.padding = padding;
result.borders = border;
return result;
}
function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft
curtop = obj.offsetTop
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft
curtop += obj.offsetTop
}
}
return [curleft,curtop];
}
function addEvent(el, evname, func, traditional) {
if (traditional) {
eval('el.on'+evname+'='+func);
return;
}
if (is.ie) {
el.attachEvent("on" + evname, func);
} else {
el.addEventListener(evname, func, true);
}
};
function addLoadEvent(func, wnd) {
if (!wnd) wnd = window
var oldonload = wnd.onload;
if (typeof wnd.onload != 'function') {
wnd.onload = func;
} else {
wnd.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
function replaceFireBug() {
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
"group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i) {
window.console[names[i]] = function() {
alert('FireBug console object methods are not available outside Firefox!');
}
}
}
+}
+function runOnChange(elId) {
+ var evt;
+ var el = typeof(elId) == 'string' ? document.getElementById(elId) : elId
+ if (document.createEvent) {
+ evt = document.createEvent("HTMLEvents");
+ evt.initEvent("change", true, false);
+ (evt) ? el.dispatchEvent(evt) : (el.onchange && el.onchange());
+ return;
+ }
+ if (el.fireEvent) {
+ el.fireEvent('onchange');
+ }
}
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/js/script.js
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.11.2.1
\ No newline at end of property
+1.11.2.2
\ No newline at end of property
Index: branches/RC/core/admin_templates/js/ajax.js
===================================================================
--- branches/RC/core/admin_templates/js/ajax.js (revision 9638)
+++ branches/RC/core/admin_templates/js/ajax.js (revision 9639)
@@ -1,328 +1,443 @@
function preg_print_pre(obj, reg)
{
if (!reg) reg = /.*/;
var p = ''
for (var prop in obj) {
if (prop.match(reg) ) {
p += prop + ': '+obj[prop] + '\n'
}
}
alert(p)
}
// Main AJAX classs
function Request() {}
Request.timeout = 60000; //60 seconds
Request.method = 'GET';
Request.headers = new Array();
Request.params = null;
Request.makeRequest = function(p_url, p_busyReq, p_progId, p_successCallBack, p_errorCallBack, p_pass, p_object) {
//p_url: the web service url
//p_busyReq: is a request for this object currently in progress?
//p_progId: element id where progress HTML should be shown
//p_successCallBack: callback function for successful response
//p_errorCallBack: callback function for erroneous response
//p_pass: string of params to pass to callback functions
//p_object: object of params to pass to callback functions
if (p_busyReq) return;
var req = Request.getRequest();
if (req != null) {
p_busyReq = true;
Request.showProgress(p_progId);
req.onreadystatechange = function() {
if (req.readyState == 4) {
p_busyReq = false;
window.clearTimeout(toId);
try {
if (req.status == 200) {
// preg_print_pre(req)
p_successCallBack(req, p_pass, p_object);
} else {
p_errorCallBack(req, p_pass, p_object);
}
Request.hideProgress(p_progId);
}
catch (e) {
// alert('AJAX error')
}
}
}
var $ajax_mark = (p_url.indexOf('?') ? '&' : '?') + 'ajax=yes';
req.open(Request.method, p_url + $ajax_mark, true);
if (Request.method == 'POST') {
Request.headers['Content-type'] = 'application/x-www-form-urlencoded';
Request.headers['referer'] = p_url;
}
else {
Request.headers['If-Modified-Since'] = 'Sat, 1 Jan 2000 00:00:00 GMT';
}
Request.sendHeaders(req);
if (Request.method == 'POST') {
req.send(Request.params);
Request.method = 'GET'; // restore method back to GET
}
else {
req.send(null);
}
var toId = window.setTimeout( function() {if (p_busyReq) req.abort();}, Request.timeout );
}
}
+Request.processRedirect = function($request) {
+ var $match_redirect = new RegExp('^#redirect#(.*)').exec($request.responseText);
+ if ($match_redirect != null) {
+ // redirect to external template requested
+ window.location.href = $match_redirect[1];
+ return true;
+ }
+ return false;
+}
Request.sendHeaders = function($request) {
for (var $header_name in Request.headers) {
if (typeof Request.headers[$header_name] == 'function') {
continue;
}
$request.setRequestHeader($header_name, Request.headers[$header_name]);
}
Request.headers = new Array(); // reset header afterwards
}
Request.getRequest = function() {
var xmlHttp;
try { xmlHttp = new ActiveXObject('MSXML2.XMLHTTP'); return xmlHttp; } catch (e) {}
try { xmlHttp = new ActiveXObject('Microsoft.XMLHTTP'); return xmlHttp; } catch (e) {}
try { xmlHttp = new XMLHttpRequest(); return xmlHttp; } catch(e) {}
return null;
}
Request.showProgress = function(p_id) {
if (p_id != '') {
Request.setOpacity(20, p_id);
if (!document.getElementById(p_id + '_progress')) {
document.body.appendChild(Request.getProgressObject(p_id));
}
else {
var $progress_div = document.getElementById(p_id + '_progress');
$progress_div.style.top = getRealTop(p_id) + 'px';
$progress_div.style.height = document.getElementById(p_id).clientHeight;
$progress_div.style.display = 'block';
}
// document.getElementById(p_id).innerHTML = Request.getProgressHtml();
}
}
Request.hideProgress = function(p_id) {
if (p_id != '') {
document.getElementById(p_id + '_progress').style.display = 'none';
Request.setOpacity(100, p_id);
}
}
Request.setOpacity = function (opacity, id) {
var elem = typeof(id)=='string' ? document.getElementById(id) : id;
var object = elem.style;
object.opacity = (opacity / 100);
object.MozOpacity = (opacity / 100);
object.KhtmlOpacity = (opacity / 100);
object.filter = "alpha(opacity=" + opacity + ")";
}
Request.getProgressHtml = function() {
return "<p class='progress'>" + Request.progressText + "<br /><img src='img/ajax_progress.gif' align='absmiddle' width='100' height='7' alt='" + Request.progressText + "'/></p>";
}
Request.getProgressObject = function($id) {
var $div = document.createElement('DIV');
var $parent_div = document.getElementById($id);
$div.id = $id + '_progress';
$div.style.width = $parent_div.clientWidth + 'px';
$div.style.height = '150px'; // default height if div is empty (first ajax request for div)
$div.style.left = getRealLeft($parent_div) + 'px';
$div.style.top = getRealTop($parent_div) + 'px';
$div.style.position = 'absolute';
/*$div.style.border = '1px solid green';
$div.style.backgroundColor = '#FF0000';*/
$div.innerHTML = '<table style="width: 100%; height: 100%;"><tr><td style="text-align: center;">'+Request.progressText+'<br /><img src="img/ajax_progress.gif" align="absmiddle" width="100" height="7" alt="'+escape(Request.progressText)+'" /></td></tr></table>';
return $div;
}
Request.getErrorHtml = function(p_req) {
//TODO: implement accepted way to handle request error
return '[status: ' + p_req.status + '; status_text: ' + p_req.statusText + '; responce_text: ' + p_req.responseText + ']';
}
Request.serializeForm = function(theform) {
if (typeof(theform) == 'string') {
theform = document.getElementById(theform);
}
var els = theform.elements;
var len = els.length;
var queryString = '';
Request.addField = function(name, value) {
if (queryString.length > 0) queryString += '&';
queryString += encodeURIComponent(name) + '=' + encodeURIComponent(value);
};
for (var i = 0; i<len; i++) {
var el = els[i];
if (el.disabled) continue;
switch(el.type) {
case 'text':
case 'password':
case 'hidden':
case 'textarea':
Request.addField(el.name, el.value);
break;
case 'select-one':
if (el.selectedIndex >= 0) {
Request.addField(el.name, el.options[el.selectedIndex].value);
}
break;
case 'select-multiple':
for (var j = 0; j < el.options.length; j++) {
if (!el.options[j].selected) continue;
Request.addField(el.name, el.options[j].value);
}
break;
case 'checkbox':
case 'radio':
if (!el.checked) continue;
Request.addField(el.name,el.value);
break;
}
}
return queryString;
};
// AJAX ProgressBar class
function AjaxProgressBar($url) {
this.WindowTitle = this.GetWindow().document.title;
this.URL = $url;
this.BusyRequest = false;
this.LastResponceTime = this.GetMicroTime();
this.ProgressPercent = 0; // progress percent
this.ProgressTime = new Array();
this.Query();
}
AjaxProgressBar.prototype.GetWindow = function() {
return window.parent ? window.parent : window;
}
AjaxProgressBar.prototype.GetMicroTime = function() {
var $now = new Date();
return Math.round($now.getTime() / 1000); // because miliseconds are returned too
}
AjaxProgressBar.prototype.Query = function() {
// prompt('requestinng', this.URL);
Request.makeRequest(this.URL, this.BusyRequest, '', this.successCallback, this.errorCallback, '', this);
}
// return time needed for progress to finish
AjaxProgressBar.prototype.GetEstimatedTime = function() {
return Math.ceil((100 - this.ProgressPercent) * Math.sum(this.ProgressTime) / this.ProgressPercent);
}
AjaxProgressBar.prototype.successCallback = function($request, $params, $object) {
var $responce = $request.responseText;
var $match_redirect = new RegExp('^#redirect#(.*)').exec($responce);
if ($match_redirect != null) {
$object.showProgress(100);
// redirect to external template requested
window.location.href = $match_redirect[1];
return false;
}
if ($object.showProgress($responce)) {
$object.Query();
}
}
AjaxProgressBar.prototype.errorCallback = function($request, $params, $object) {
alert('AJAX Error; class: AjaxProgressBar; ' + Request.getErrorHtml($request));
}
AjaxProgressBar.prototype.FormatTime = function ($seconds) {
$seconds = parseInt($seconds);
var $minutes = Math.floor($seconds / 60);
if ($minutes < 10) $minutes = '0' + $minutes;
$seconds = $seconds % 60;
if ($seconds < 10) $seconds = '0' + $seconds;
return $minutes + ':' + $seconds;
}
AjaxProgressBar.prototype.showProgress = function ($percent) {
this.ProgressPercent = $percent;
var $now = this.GetMicroTime();
this.ProgressTime[this.ProgressTime.length] = $now - this.LastResponceTime;
this.LastResponceTime = $now;
var $display_progress = parseInt(this.ProgressPercent);
this.GetWindow().document.title = $display_progress + '% - ' + this.WindowTitle;
document.getElementById('progress_display[percents_completed]').innerHTML = $display_progress + '%';
document.getElementById('progress_display[elapsed_time]').innerHTML = this.FormatTime( Math.sum(this.ProgressTime) );
document.getElementById('progress_display[Estimated_time]').innerHTML = this.FormatTime( this.GetEstimatedTime() );
document.getElementById('progress_bar[done]').style.width = $display_progress + '%';
document.getElementById('progress_bar[left]').style.width = (100 - $display_progress) + '%';
return $percent < 100 ? true : false;
}
// AJAX PopupManager class
function AjaxPopupManager($url) {
this.URL = $url;
this.ResponceFunction = null;
this.PopupSizes = new Array();
}
AjaxPopupManager.prototype.GetSize = function ($template) {
if (this.ResponceFunction == null) {
alert ('Please define responce function first (type: '+typeof(this.ResponceFunction)+')');
}
if (!isset(this.PopupSizes[$template])) {
var $url = this.URL + '&type=GetPopupSize&template_name=' + $template;
// alert('from ajax: '+$url);
Request.makeRequest($url, this.BusyRequest, '', this.successCallback, this.errorCallback, ['GetSize', $template], this);
}
else {
// alert('from cache');
this.ResponceFunction(this.PopupSizes[$template]);
}
}
AjaxPopupManager.prototype.successCallback = function($request, $params, $object) {
var $responce = $request.responseText;
var $match_redirect = new RegExp('^#redirect#(.*)').exec($responce);
if ($match_redirect != null) {
// redirect to external template requested
window.location.href = $match_redirect[1];
return false;
}
switch ($params[0]) {
case 'GetSize':
// store responce to cache for future use
$object.PopupSizes[ $params[1] ] = $responce;
break;
}
$object.ResponceFunction($responce);
$object.ResponceFunction = null; // reset responce function
}
AjaxPopupManager.prototype.errorCallback = function($request, $params, $object) {
alert('AJAX Error; class: AjaxPopupManager; ' + Request.getErrorHtml($request));
+}
+// AJAX DropdownPreloader class
+function AjaxDropdownPreloader($url, $input_mask, $filter_field, $dependend_field, value) {
+ this.URL = $url;
+ this.InputMask = $input_mask;
+ this.FilterField = $filter_field;
+ this.DependendField = $dependend_field;
+ this.Titles = this.prepareTitles();
+ this.Value = value;
+ this.BusyRequest = false;
+}
+AjaxDropdownPreloader.prototype.prepareURL = function()
+{
+ return this.URL.replace('#DEPENDEND#', this.Dependend).replace('#FILTER_VALUE#', this.getValue(this.FilterField));
+}
+AjaxDropdownPreloader.prototype.prepareTitles = function() {
+ var $control = this.getControl(this.DependendField);
+ var $i = 0;
+ var $ret = new Array ();
+ while ($i < $control.options.length) {
+ $ret[$control.options[$i].value] = $control.options[$i].innerHTML;
+ $i++;
+ }
+ return $ret;
+}
+AjaxDropdownPreloader.prototype.getValue = function($field_name) {
+ var $control = this.getControl($field_name);
+ if ($control.tagName == 'INPUT') return $control.value;
+ return $control.selectedIndex > 0 ? $control.options[$control.selectedIndex].value : '';
+}
+AjaxDropdownPreloader.prototype.Query = function () {
+ var $url = this.prepareURL();
+ var $selected_value = this.Value || this.getValue(this.DependendField);
+ // remove all existing options
+ this.removeOptions();
+ Request.makeRequest($url, this.BusyRequest, '', this.successCallback, this.errorCallback, $selected_value, this);
+}
+AjaxDropdownPreloader.prototype.getControl = function($field) {
+ var $id = this.InputMask.replace('#FIELD#', $field);
+ return document.getElementById($id);
+}
+AjaxDropdownPreloader.prototype.successCallback = function($request, $params, $object) {
+ if (Request.processRedirect($request) === true) {
+ return ;
+ }
+ var control = $object.getControl($object.DependendField)
+ $object.ProcessXMLNode($request.responseXML, control, $params);
+ runOnChange(control);
+ $object.AfterProcess();
+}
+AjaxDropdownPreloader.prototype.ProcessXMLNode = function($node, $dst_field, $selected_value) {
+ for (var i = 0; i < $node.childNodes.length; i++) {
+ var $child = $node.childNodes.item(i);
+ switch ($child.tagName) {
+ case 'option':
+ var opt_value = $child.getAttribute('value');
+ var title;
+ if (opt_value) { // value is passed explicically
+ title = $child.firstChild.nodeValue
+ }
+ else {
+ opt_value = $child.firstChild.nodeValue;
+ title = this.Titles[$child.firstChild.nodeValue];
+ }
+ this.addOption($dst_field, opt_value, title, $child.attributes);
+ if (opt_value == $selected_value) {
+ $dst_field.options[$dst_field.options.length - 1].selected = true;
+ }
+ break;
+ case 'field_options':
+ this.addOption($dst_field, '', '');
+ // add new states
+ this.ProcessXMLNode($child, $dst_field, $selected_value);
+ if ($dst_field.options.length == 0 || $dst_field.options.length == 2) {
+ $dst_field.value = $dst_field.options[$dst_field.options.length - 1].value;
+ }
+ break;
+ }
+ }
+}
+AjaxDropdownPreloader.prototype.AfterProcess = function()
+{
+}
+AjaxDropdownPreloader.prototype.removeOptions = function($object) {
+ if (!$object) $object = this.getControl(this.DependendField);
+ if ($object.options.length > 0) {
+ while ($object.options.length > 0) {
+ $object.remove(0);
+ }
+ }
+}
+AjaxDropdownPreloader.prototype.addOption = function($object, $value, $title, attributes) {
+ var $option = document.createElement('OPTION');
+ $object.options.add($option, $object.options.length);
+ $option.innerText = $title;
+ $option.innerHTML = $title;
+ $option.value = $value;
+ if (attributes) {
+ for (var i=0; i<attributes.length; i++) {
+ if (attributes[i].nodeName == 'value') continue;
+ $option.setAttribute(attributes[i].nodeName, attributes[i].nodeValue);
+ }
+ }
+}
+AjaxDropdownPreloader.prototype.errorCallback = function($request, $params, $object) {
+ alert('AJAX Error; class: AjaxDropdownPreloader; ' + Request.getErrorHtml($request));
}
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/js/ajax.js
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.6.2.2
\ No newline at end of property
+1.6.2.3
\ No newline at end of property
Index: branches/RC/core/admin_templates/js/forms.js
===================================================================
--- branches/RC/core/admin_templates/js/forms.js (revision 9638)
+++ branches/RC/core/admin_templates/js/forms.js (revision 9639)
@@ -1,248 +1,277 @@
var last_shown_error = false;
var errors = new Object();
var first_error = new Object();
var fields = new Object();
function show_form_error(prefix, field, sticky)
{
if (isset(errors[prefix]) && isset(errors[prefix][field])) {
span = document.getElementById('error_msg_'+prefix);
span.innerHTML = fields[prefix][field] + ' - ' + errors[prefix][field];
if (sticky) last_shown_error = field;
}
}
function hide_form_error(prefix)
{
span = document.getElementById('error_msg_'+prefix);
if (!span) return;
span.innerHTML = '<br/>';
if (typeof(last_shown_error) != 'undefined' && last_shown_error) {
show_form_error(prefix, last_shown_error);
}
}
function add_form_error(prefix, field, element, error_msg) {
if (error_msg != '') {
if (typeof(errors[prefix]) == 'undefined') {
errors[prefix] = new Object();
}
errors[prefix][field] = error_msg;
addEvent(document.getElementById(element), 'focus', function() {
show_form_error(prefix, field, true)
} );
addEvent(document.getElementById(element), 'blur', function() {last_shown_error = false} )
if (typeof(first_error[prefix]) == 'undefined' || first_error[prefix] == false) {
first_error[prefix] = [field, element];
}
}
}
function Form() {}
Form = new Form();
Form.Controls = new Array();
Form.Div = false;
Form.MinControlsHeight = 0;
Form.Options = new Object();
Form.FlexibleCount = 0;
Form.ScrollerW = 17;
Form.ScrollerH = 17;
Form.Wrap = true;
Form.Init = function(id)
{
this.Div = document.getElementById(id);
for (var i in this.Controls) {
dim = getDimensions(document.getElementById(this.Controls[i]));
options = this.Options[this.Controls[i]];
if (options.height) { // fixed height
options.min_height = options.height;
options.max_height = options.height;
}
if (!options.min_height) options.min_height = dim.innerHeight;
this.MinControlsHeight += options.min_height;
if (dim.innerHeight < options.min_height) {
document.getElementById(this.Controls[i]).style.height = options.min_height+'px';
}
// alert('adding element '+this.Controls[i]+' height: '+options.min_height+' total: '+this.MinControlsHeight)
}
/*alert('one more time');
document.body.style.height = '100%';
document.body.style.overflow = 'hidden';
document.body.scroll = 'no'
alert('done');*/
var a_div = document.createElement('DIV');
a_div.style.position = 'relative';
a_div.style.overflow = 'auto';
a_div.style.width = '100%';
// a_div.style.height = '100%';
// a_div.style.backgroundColor = 'yellow';
a_div.appendChild(this.Div.parentNode.replaceChild(a_div, this.Div));
this.Table = this.Div.getElementsByTagName('table')[0];
this.Table.style.height = 'auto';
// this.Table.style.width = 'auto';
this.MinHeight = this.Table.offsetHeight;
this.MinWidth = this.Table.offsetWidth;
// alert('Measuring min width now')
addEvent(window, 'resize', function() {Form.Resize()})
this.Resize()
if (isset(first_error)) {
for (var i in first_error) {
if (first_error[i] != false) {
document.getElementById(first_error[i][1]).focus();
show_form_error(i, first_error[i][0], true);
// alert('focused on '+first_error[i][1])
}
}
}
+
+ addEvent(window, 'unload', function() {
+ if (!unload_legal) { // it's set in submit_kernel_form - if we are submitting form, the unload is already handled
+ // if we got here, it means that we are closing window ilegally (through OS interace X button)
+// alert('closing window');
+ // we need to clear temp tables then
+
+ var req = Request.getRequest();
+ var $ajax_mark = (_DropTempUrl.indexOf('?') ? '&' : '?') + 'ajax=yes';
+ req.open('GET', _DropTempUrl + $ajax_mark, false); //!!!SYNCRONIOUS!!! REQUEST (3rd param = false!!!)
+ req.send(null);
+
+// window.opener.EditWindowClosed(_DropTempUrl);
+// alert('request sent, closing widow');
+ }
+ });
+
+ // we need to set unload_legal to true if we are refreshing current window, because onunload will still fire
+ addEvent(document, 'keydown', function(e) {
+ var code;
+ if (!e) var e = window.event;
+ if (e.keyCode) code = e.keyCode;
+ else if (e.which) code = e.which;
+ if (code == 116 || (e.ctrlKey && code == 82)) unload_legal = true; //F5 or Ctrl+R
+ });
+
+ if (_Simultanious_Edit_Message != '') {
+ alert(_Simultanious_Edit_Message);
+ }
}
Form.addControl = function(id, options) {
this.Controls.push(id);
if (!options) {
options = {coeff: 1, max_height: 0, min_height: 0};
}
else {
if (typeof(options['coeff']) == 'undefined') options['coeff'] = 1;
if (typeof(options['max_height']) == 'undefined') options['max_height'] = 0;
if (typeof(options['min_height']) == 'undefined') options['min_height'] = 0;
}
options['real_height'] = 0;
this.Options[id] = options; // for future use
// print_pre(this.Options[id]);
}
Form.Resize = function()
{
var h = (document.all ? window.document.body.offsetHeight : window.innerHeight);
var pos = findPos(this.Div);
var dim = getDimensions(this.Div);
h -= pos[1] + dim.padding[0] + dim.padding[2] + dim.borders[0] + dim.borders[2];
// alert('h after correction is '+h);
window.document.body.style.width = '100%';
var w = (document.all ? window.document.body.offsetWidth : window.innerWidth);
w -= pos[0] + dim.padding[1] + dim.padding[3] + dim.borders[1] + dim.borders[3];
scroller_height = this.MinWidth > w ? this.ScrollerH : 0;
scroller_width = this.MinHeight > h - scroller_height ? this.ScrollerW : 0;
scroller_height = this.MinWidth > w - scroller_width ? this.ScrollerH : 0;
var st = document.getElementById('width_status');
if (st) st.innerHTML = 'minWdith: '+this.MinWidth+' minHeight: '+this.MinHeight+' w: '+w+' h: '+h+' scroll_w: '+scroller_width+' scroll_h: '+scroller_height;
// alert('scroller W x H = '+scroller_width+' x '+scroller_height);
// alert('resize: '+w+'x'+h)
// h -= 100;
this.Table.style.width = (w-scroller_width) + 'px';
this.Div.parentNode.style.width = (w)+'px';
this.Div.style.width = (w-scroller_width)+'px';
this.Div.parentNode.style.height = (h)+'px';
var count = this.Controls.length;
// -count here is adjustment - 1px for each control
var split = h - count*2 - this.MinHeight + this.MinControlsHeight;
if (split < this.MinControlsHeight) split = this.MinControlsHeight;
this.ResetHeights();
var used = this.SetMinHeights();
split -= used;
var cur_diff = 0;
var iterations = 0;
do {
var prev_diff = cur_diff;
var cur_diff = this.SplitExtra(split);
split = cur_diff;
iterations++;
} while (cur_diff != 0 && cur_diff != prev_diff && iterations < 10);
for (var i in this.Controls) {
document.getElementById(this.Controls[i]).style.height = this.Options[this.Controls[i]]['real_height'] + 'px';
// document.getElementById(this.Controls[i]).value = this.Options[this.Controls[i]]['real_height'];
}
// alert('h is: '+h+' min height is '+this.MinHeight+' MinControlsHeight is '+this.MinControlsHeight+' -> '+split+' to split between '+count+' new height is '+new_height);
// print_pre(this.Controls)
}
Form.ResetHeights = function()
{
for (var i in this.Controls) {
var options = this.Options[this.Controls[i]]
options['real_height'] = 0;
options.fixed = false;
}
this.FlexibleCount = this.Controls.length;
}
// Enlarge heights when possible
// Return any not split pixels number
Form.SplitExtra = function(split)
{
var number = 0;
for (var i in this.Controls) {
var options = this.Options[this.Controls[i]]
if (options['max_height'] ==0 || options['real_height'] < options.max_height) {
number++;
}
}
if (number == 0) return 0;
var delta = Math.floor(split / number);
// alert('splitting '+split+' between '+number+' delta is '+delta)
var added = 0;
for (var i in this.Controls) {
var options = this.Options[this.Controls[i]];
var to_add;
if (options['max_height'] != 0 && options['real_height']+delta > options['max_height']) {
to_add = options['max_height']-options['real_height'];
}
else {
to_add = delta;
}
// alert('delta: '+delta+' current real: '+options['real_height']+' min: '+options['min_height']+' max:'+options['max_height']+' to_add: '+to_add)
options['real_height'] = options['real_height']+to_add;
added += to_add;
}
// alert('added total '+added)
// removing extra added from the last (any) control
if (added > split) {
extra = added-split;
options['real_height'] -= extra;
added -= extra;
}
return split - added;
}
Form.SetMinHeights = function()
{
var used = 0;
for (var i in this.Controls) {
var options = this.Options[this.Controls[i]]
if (options['real_height'] < options['min_height']) {
options['real_height'] = options.min_height;
used += options.min_height;
}
}
return used;
}
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/js/forms.js
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.4.2.1
\ No newline at end of property
+1.4.2.2
\ No newline at end of property
Index: branches/RC/core/admin_templates/js/simple_grid.js
===================================================================
--- branches/RC/core/admin_templates/js/simple_grid.js (nonexistent)
+++ branches/RC/core/admin_templates/js/simple_grid.js (revision 9639)
@@ -0,0 +1,144 @@
+function SimpleGrid($id_prefix, $field_mask, $show_order) {
+ this.ItemIDs = new Array ();
+ this.NextNumber = 0;
+ this.IDPrefix = $id_prefix;
+ this.FieldMask = $field_mask;
+ this.Container = this.getControl('container');
+ this.ShowOrder = $show_order;
+}
+
+SimpleGrid.prototype.registerRecord = function ($id) {
+ var $prev_id = this.lastID();
+ if ($prev_id !== false) {
+ this.getControl('button_' + $prev_id).value = '-';
+ }
+
+ $id = parseInt($id);
+ this.ItemIDs.push($id);
+
+ if ($id < 0 && Math.abs($id) > Math.abs(this.NextNumber)) {
+ this.NextNumber = $id;
+ }
+
+ if (this.ShowOrder) {
+ this.getControl('number_'+$id).innerHTML = this.ItemIDs.length;
+ }
+
+ this.processRecordDependancies($id);
+}
+
+SimpleGrid.prototype.renumberRecords = function () {
+ if (!this.ShowOrder) {
+ return ;
+ }
+
+ var $i = 0;
+ while ($i < this.ItemIDs.length) {
+ this.getControl('number_' + this.ItemIDs[$i]).innerHTML = $i + 1;
+ $i++;
+ }
+}
+
+SimpleGrid.prototype.nextNumber = function () {
+ return --this.NextNumber;
+}
+
+SimpleGrid.prototype.lastID = function () {
+ return this.ItemIDs.length ? this.ItemIDs.slice(this.ItemIDs.length - 1)[0] : false;
+}
+
+SimpleGrid.prototype.toggleRecord = function ($item_id) {
+ if (this.lastID() == $item_id) {
+ this.addRecord();
+ }
+ else {
+ this.removeRecord($item_id);
+ }
+}
+
+SimpleGrid.prototype.getControl = function ($name) {
+ return document.getElementById(this.IDPrefix + '_' + $name);
+}
+
+SimpleGrid.prototype.getField = function ($id, $field_name, $prepend, $append) {
+ $prepend = isset($prepend) ? $prepend + '_' : '';
+ $append = isset($append) ? '_' + $append : '';
+
+ return document.getElementById($prepend + this.FieldMask.replace('#FIELD#', $field_name).replace('#ID#', $id) + $append);
+}
+
+SimpleGrid.prototype.markError = function ($item_id, $field_name, $error_found) {
+ if (!isset($error_found)) {
+ $error_found = true;
+ }
+
+ var $field = this.getField($item_id, $field_name);
+ if ($error_found) {
+ $field.style.backgroundColor = '#EF2C2C';
+
+ // TODO: duplicate focus events possible on one element, fix this later
+ addEvent($field, 'focus',
+ function($e) {
+ if (!$e) {
+ $e = window.event;
+ }
+
+ var $element = document.all ? $e.srcElement : $e.currentTarget;
+ $element.style.backgroundColor = '';
+ }
+
+ );
+ }
+ else {
+ $field.style.backgroundColor = '';
+ }
+}
+
+SimpleGrid.prototype.validateRecord = function ($item_id) {
+ return true;
+}
+
+SimpleGrid.prototype.validate = function () {
+ var $i = 0;
+ var $is_valid = true;
+ while ($i < this.ItemIDs.length) {
+ if (!this.validateRecord(this.ItemIDs[$i])) {
+ $is_valid = false;
+ }
+ $i++;
+ }
+
+ return $is_valid;
+}
+
+SimpleGrid.prototype.addRecord = function () {
+ var new_item_number = this.nextNumber();
+
+ var $item_mask = this.getControl('mask').value;
+ var $result_html = $item_mask.replace(/#NUMBER#/g, new_item_number);
+
+ var $div = document.createElement('DIV');
+ $div.id = this.IDPrefix + '_' + new_item_number;
+ this.getControl('container').appendChild($div);
+ $div.innerHTML = $result_html;
+
+ var $js_mask = this.getControl('js_mask').value;
+ var result_js = $js_mask.replace(/#NUMBER#/g, new_item_number);
+ eval(result_js);
+}
+
+SimpleGrid.prototype.removeRecord = function ($number) {
+ this.getControl('container').removeChild( this.getControl($number) );
+ var $index = array_search($number, this.ItemIDs);
+ this.ItemIDs.splice($index, 1);
+ this.renumberRecords();
+ this.updateTotals();
+}
+
+SimpleGrid.prototype.updateTotals = function () {
+ // prototype
+}
+
+SimpleGrid.prototype.processRecordDependancies = function ($id) {
+ // prototype
+}
Property changes on: branches/RC/core/admin_templates/js/simple_grid.js
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1.4.1
\ No newline at end of property
Index: branches/RC/core/admin_templates/js/ajax_dropdown.js
===================================================================
--- branches/RC/core/admin_templates/js/ajax_dropdown.js (revision 9638)
+++ branches/RC/core/admin_templates/js/ajax_dropdown.js (revision 9639)
@@ -1,277 +1,278 @@
/*
(c) Intechnic Europe 2007 http://www.intechnic.lv
Author: Konstantin Tjuterev
The class adds a dynamic drop-down to the edit-box
Usage:
<input type="text" id="combo_input" style="width: 200px"><br/>
<input type="text" id="combo_input1" style="width: 200px"><br/>
<script type="text/javascript">
new AJAXDropDown('combo_input', function(cur_value) {return 'items.xml?'}, function(item) {
var val = item.getAttribute('a');
return val ? val : item.innerHTML;
});
new AJAXDropDown('combo_input1', function(cur_value) {return 'items1.xml?cur='+escape(cur_value)});
new AJAXDropDown('curr_search_keyword', function(cur_value) {
var $url = '<inp2:m_Link template="dummy" pass="m,curr" curr_event="OnSuggestValues" field="Name" cur_value="#CUR_VALUE#" no_amp="1"/>';
return $url.replace('#CUR_VALUE#', escape(cur_value));
}
);
</script>
The AJAXDropDown constructor takes the following arguments:
input_id - id of textbox to attach to
suggest_url_callback - function which should return URL which returns XML of suggested values,
function takes one argument - it is current value of the text_box
[get_value_callback] - optional argument - function which returns the value to be set in the textbox,
based on currently selected item (out of suggested). If the argument is skipped - the node value of
<item> element will be used as the value
<item> element in the suggestions XML may have unlimited number of attribuets, all the attributes will be set
to the corresponding DIV element and this DIV element will be passed as argument to the get_value_callback,
so one may use the argument to alter the value set into textbox as in the example above
Response XML structure:
The script will look for ALL elements with tagname = 'item', so basically the structure should look like this:
<suggestions>
<item>Suggestion 1</item>
<item>Suggestion 2</item>
<item>Suggestion 3</item>
</suggestions>
Design & CSS
The script will automatically display a div which width will match the width of the text-box
You may control the div look by changing .suggest-box CSS selector
The items inside the box will have .suggest-item and .suggest-item-over
The default styles which may be used is:
<style type="text/css">
.suggest-box {
border: 1px solid #999;
background-color: #fff;
}
.suggest-item, .suggest-item-over {
padding: 1px 2px 0px 2px;
font-family: arial,verdana;
font-size: 12px;
}
.suggest-item-over {
background-color: #3366CC;
color: #fff;
}
</style>
*/
function AJAXDropDown(input_id, suggest_url_callback, get_value_callback)
{
this.Input = document.getElementById(input_id);
this.KeyUpWaiting = false;
this.KeyUpTimer = false;
this.Box = '';
this.SuggestURLCallback = suggest_url_callback;
if (!get_value_callback) get_value_callback = this.GetValue;
this.GetValueCallback = get_value_callback;
this.BoxOpen = false;
this.SelectedItem = false;
var obj = this;
addLoadEvent(function() {obj.Init()});
}
AJAXDropDown.prototype.Init = function()
{
// draw box
this.Box = document.createElement('DIV');
document.body.appendChild(this.Box);
// this.Box = addElement(this.Input.parentNode, 'div');
this.Box.style.display = 'none';
this.Box.style.zIndex = 99;
this.Box.style.position = 'absolute';
this.Box.style.overflow = 'auto';
this.Box.className = 'suggest-box'
+ this.Input.setAttribute('autocomplete', 'off');
// add onkeyup
var obj = this;
addEvent(this.Input, 'keyup', function(ev) {obj.KeyUp(ev)})
addEvent(this.Input, 'blur', function(ev) {obj.Blur(ev)})
addEvent(this.Box, 'scroll', function(ev) {if (obj.BlurWaiting) {window.clearTimeout(obj.BlurTimer);}});
addEvent(this.Box, 'mouseup', function(ev) {obj.BlurWaiting = false});
}
AJAXDropDown.prototype.Blur = function(ev)
{
if (this.BlurWaiting) return;
this.BlurWaiting = true;
var obj = this;
this.BlurTimer = window.setTimeout(function() {
obj.CloseBox();
this.BlurWaiting = false;
}, 300)
}
AJAXDropDown.prototype.KeyUp = function(ev)
{
var e = !is.ie ? ev : window.event;
switch (e.keyCode) {
case 38: //arrow up
if (!this.BoxOpen) break;
this.SelectPrev();
break;
case 40: //arrow down
if (!this.BoxOpen) break;
this.SelectNext();
break;
case 27: //Enter
this.Input.value = this.OriginalValue;
this.CloseBox();
break;
case 13: //Escape
this.CloseBox();
break;
default:
if (this.Input.value == '') return;
var obj = this;
if (this.KeyUpWaiting && this.KeyUpTimer) {
window.clearTimeout(this.KeyUpTimer);
this.KeyUpTimer = false;
}
this.KeyUpWaiting = true;
this.KeyUpTimer = window.setTimeout(function() {
obj.RequestSuggestions();
}, 300)
}
}
AJAXDropDown.prototype.RequestSuggestions = function()
{
Request.makeRequest(this.SuggestURLCallback(this.Input.value), false, '', this.successCallback, this.errorCallback, 'reload', this);
}
AJAXDropDown.prototype.successCallback = function (request, params, object) {
object.OriginalValue = object.Input.value;
object.OpenBox();
object.KeyUpWaiting = false;
var items = request.responseXML.getElementsByTagName('item');
object.ClearItems();
for (var i=0; i<items.length; i++)
{
object.AddItem(items[i].firstChild.nodeValue, items[i].attributes);
}
}
AJAXDropDown.prototype.errorCallback = function (request, params, object) {
this.KeyUpWaiting = false;
}
AJAXDropDown.prototype.ClearItems = function()
{
this.Box.scrollTop = 0;
this.UnselectItem();
for (var i=this.Box.childNodes.length-1; i>=0; i--)
{
this.Box.removeChild(this.Box.childNodes[i]);
}
}
AJAXDropDown.prototype.OpenBox = function()
{
var pos = findPos(this.Input);
var dim = getDimensions(this.Input);
this.Box.style.left = pos[0] + 'px';
this.Box.style.top = (pos[1] + dim.innerHeight + dim.borders[0] + dim.borders[2]) + 'px';
this.Box.style.width = (dim.innerWidth + dim.borders[1] + (is.ie ? dim.borders[3] : 0 ) ) + 'px';
this.Box.style.display = 'block';
// alert('box opened at '+this.Box.style.left+','+this.Box.style.top+' pos x:'+pos[0])
this.BoxOpen = true;
}
AJAXDropDown.prototype.CloseBox = function()
{
if (!this.BoxOpen) return;
this.Box.style.display = 'none';
this.BoxOpen = false;
}
AJAXDropDown.prototype.AddItem = function(value, attributes)
{
var item = addElement(this.Box, 'div');
for (var i=0; i<attributes.length; i++) {
item.setAttribute(attributes[i].nodeName, attributes[i].nodeValue)
}
item.className = 'suggest-item';
item.innerHTML = value;
var obj = this;
addEvent(item, 'mousemove', function() {obj.SelectItem(item)});
addEvent(item, 'mousedown', function() {obj.ClickItem(item)});
}
AJAXDropDown.prototype.ClickItem = function(item)
{
this.Input.value = this.GetValueCallback(item);
this.CloseBox();
}
AJAXDropDown.prototype.SelectNext = function()
{
if (!this.SelectedItem) {
this.SelectItem(this.Box.firstChild, true);
return;
}
if (isset(this.SelectedItem.nextSibling)) {
this.SelectItem(this.SelectedItem.nextSibling, true)
}
else { // down from last
this.UnselectItem();
this.Input.value = this.OriginalValue;
}
}
AJAXDropDown.prototype.SelectPrev = function()
{
if (!this.SelectedItem) {
this.SelectItem(this.Box.lastChild, true);
return;
}
if (isset(this.SelectedItem.previousSibling)) {
this.SelectItem(this.SelectedItem.previousSibling, true)
}
else { // up from first
this.UnselectItem();
this.Input.value = this.OriginalValue;
}
}
AJAXDropDown.prototype.UnselectItem = function(item)
{
if (!item) item = this.SelectedItem;
if (!item) return;
item.className = 'suggest-item';
this.SelectedItem = false;
}
AJAXDropDown.prototype.SelectItem = function(item, setvalue)
{
if (this.SelectedItem) {
this.UnselectItem(this.SelectedItem);
}
item.className = 'suggest-item-over';
this.SelectedItem = item;
item.scrollIntoView(false);
if (setvalue) {
this.Input.value = this.GetValueCallback(item);
}
}
AJAXDropDown.prototype.GetValue = function(item)
{
return item.innerHTML;
}
Property changes on: branches/RC/core/admin_templates/js/ajax_dropdown.js
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.4
\ No newline at end of property
+1.1.2.5
\ No newline at end of property
Index: branches/RC/core/admin_templates/js/dropdown_mapper.js
===================================================================
--- branches/RC/core/admin_templates/js/dropdown_mapper.js (nonexistent)
+++ branches/RC/core/admin_templates/js/dropdown_mapper.js (revision 9639)
@@ -0,0 +1,129 @@
+function DropDownMapper(map, request, input_mask) {
+ this.Map = map;
+ this.Request = request;
+ this.InputMask = input_mask;
+ this.Objects = new Object();
+ this.WatchFields = [];
+ this.UpdateFields = {};
+ this.Init()
+}
+
+DropDownMapper.prototype.Init = function()
+{
+ this.AssignDrills(this.Map);
+ this.DrillDownRequests(this.Map,'root');
+ for (var i in this.WatchFields) {
+ var elem = document.getElementById(this.InputMask.replace('#FIELD#', this.WatchFields[i]));
+ elem.fieldName = this.WatchFields[i];
+ addEvent(elem, 'change', function(ev) {
+ var el = !is.ie ? ev.currentTarget : window.event.srcElement;
+ mapper.Changed(el.fieldName);
+ })
+ }
+}
+
+DropDownMapper.prototype.GetFilters = function(map, o)
+{
+ if (!map) map = this.Map;
+ if (!o) o = '';
+ for (var i in map) {
+ if (map[i].Field) o += escape(map[i].Field+'='+this.GetValue(map[i].Field)+'&');
+ if (map[i].Pass) { // additional fields to pass to the ajax query
+ for (var x in map[i].Pass) {
+ o += escape(map[i].Pass[x]+'='+this.GetValue(map[i].Pass[x])+'&');
+ }
+ }
+ if (map[i].SubNodes) {
+ o += this.GetFilters(map[i].SubNodes)
+ }
+ }
+ return o;
+}
+
+DropDownMapper.prototype.GetValue = function(field)
+{
+ elem = document.getElementById(this.InputMask.replace('#FIELD#', field));
+ if (elem.type && elem.type == 'checkbox') return elem.checked ? 1:0;
+ return elem.value;
+}
+
+DropDownMapper.prototype.Changed = function(field)
+{
+ var branch = this.FindBranch(field);
+ this.DrillDownRequests(branch, field);
+ if (this.UpdateFields[field]) {
+ for (var i in this.UpdateFields[field]) {
+ this.Objects[this.UpdateFields[field][i]].Query();
+ }
+ }
+}
+
+DropDownMapper.prototype.AssignDrills = function(map)
+{
+ var mapper = this;
+ for (var i in map) {
+ if ( map[i].Field ) {
+ this.WatchFields.push(map[i].Field);
+ if ( map[i].Pass ) {
+ for (var p in map[i].Pass) {
+ if (!in_array(map[i].Pass[p], this.WatchFields)) {
+ this.WatchFields.push(map[i].Pass[p]);
+ }
+ if (!this.UpdateFields[map[i].Pass[p]]) this.UpdateFields[map[i].Pass[p]] = new Array();
+ if (!in_array(map[i].Field, this.UpdateFields[map[i].Pass[p]])) {
+ this.UpdateFields[map[i].Pass[p]].push(map[i].Field);
+ }
+ }
+ }
+ }
+ if ( typeof(map[i].Dependent) == 'undefined' || i.Dependent ) {
+ var val = map[i].Value ? map[i].Value : null
+ var obj = new AjaxDropdownPreloader(this.Request, this.InputMask, null, map[i].Field, val );
+ obj.prepareURL = function()
+ {
+ return this.URL.replace('#QUESTIONED#', this.DependendField).replace('#FILTERS#', mapper.GetFilters().replace(/%26$/, ''))
+ }
+ this.Objects[map[i].Field] = obj;
+ }
+
+ if (typeof(map[i].SubNodes) == 'object') {
+ if ( typeof(map[i].Dependent) == 'undefined' || i.Dependent ) {
+ var ii = i; // we need this, otherwise AfterProcess will use the wrong i (be reference)
+ obj.AfterProcess = function() {
+// mapper.DrillDownRequests(map[ii].SubNodes, ii);
+ }
+ }
+ this.AssignDrills(map[i].SubNodes);
+ }
+ }
+}
+
+DropDownMapper.prototype.FindBranch = function(branch, map)
+{
+ if (!map) map = this.Map;
+ for (var i in map) {
+ if (typeof(map[i].SubNodes) == 'object') {
+ if (map[i].Field == branch) return map[i].SubNodes;
+ var res = this.FindBranch(branch, map[i].SubNodes);
+ if (res) return res;
+ }
+ }
+ return false;
+}
+
+DropDownMapper.prototype.DrillDownRequests = function(map,item)
+{
+ for (var i in map) {
+ if (map[i].Field && this.Objects[map[i].Field]) {
+ this.Objects[map[i].Field].Query();
+ }
+ else {
+ this.DrillDownRequests(map[i].SubNodes,item); //if there is no object for current item, try its children
+ }
+ }
+}
+
+DropDownMapper.prototype.QueryByField = function(field)
+{
+ this.Objects[field].Query();
+}
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/js/dropdown_mapper.js
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1.4.1
\ No newline at end of property
Index: branches/RC/core/admin_templates/js/application.js
===================================================================
--- branches/RC/core/admin_templates/js/application.js (nonexistent)
+++ branches/RC/core/admin_templates/js/application.js (revision 9639)
@@ -0,0 +1,72 @@
+function kApplication() {
+ this.Hooks = new Array ();
+
+ addLoadEvent(
+ function () {
+ Application.processHooks('m:OnAfterWindowLoad');
+ }
+ );
+
+}
+
+kApplication.prototype.SetVar = function ($name, $value) {
+ set_hidden_field($name, $value);
+}
+
+// hidden fields are printed in footer, that's why use this in m:OnAfterWindowLoad hook
+kApplication.prototype.GetVar = function ($name) {
+ return get_hidden_field($name);
+}
+
+kApplication.prototype.setHook = function ($hook_to, $do_code, $hook_mode) {
+ if (!isset($hook_mode)) {
+ $hook_mode = hBEFORE;
+ }
+ if (typeof $hook_to == 'string') {
+ setArrayValue(this.Hooks, $hook_to, $hook_mode, $do_code);
+ }
+ else {
+ var $i = 0;
+ while ($i < $hook_to.length) {
+ this.setHook($hook_to[$i], $do_code, $hook_mode);
+ $i++;
+ }
+ }
+}
+
+kApplication.prototype.processHooks = function ($hook_to, $hook_mode) {
+ if (!isset($hook_mode)) {
+ $hook_mode = hBEFORE;
+ }
+
+ var $i = 0;
+ var $defined_hooks = getArrayValue(this.Hooks, $hook_to, $hook_mode);
+
+ while($i < $defined_hooks.length) {
+ var $do_event = new kEvent($hook_to);
+ $defined_hooks[$i]($do_event);
+ if (!$do_event.status) {
+ return false;
+ break;
+ }
+ $i++;
+ }
+ return true;
+}
+
+// =======================================
+
+function kEvent($params) {
+ if ($params.match(/([^.:]*)[.]{0,1}([^:]*):(.*)/, $params)) {
+ this.Prefix = RegExp.$1;
+ this.Special = RegExp.$2;
+ this.Name = RegExp.$3;
+ }
+ else {
+ this.Prefix = '';
+ this.Special = '';
+ this.Name = '';
+ }
+
+ this.status = true;
+}
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/js/application.js
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1.4.1
\ No newline at end of property
Index: branches/RC/core/admin_templates/img/toolbar/tool_export_f2.gif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/RC/core/admin_templates/img/toolbar/tool_export_f2.gif
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1.4.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: branches/RC/core/admin_templates/img/toolbar/tool_import_f3.gif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/RC/core/admin_templates/img/toolbar/tool_import_f3.gif
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1.4.1
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: branches/RC/core/admin_templates/img/toolbar/tool_export.gif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/RC/core/admin_templates/img/toolbar/tool_export.gif
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1.4.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: branches/RC/core/admin_templates/img/toolbar/tool_export_f3.gif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/RC/core/admin_templates/img/toolbar/tool_export_f3.gif
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1.4.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: branches/RC/core/admin_templates/img/toolbar/tool_import_f2.gif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/RC/core/admin_templates/img/toolbar/tool_import_f2.gif
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1.4.1
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: branches/RC/core/admin_templates/img/toolbar/tool_import.gif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/RC/core/admin_templates/img/toolbar/tool_import.gif
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1.4.1
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: branches/RC/core/admin_templates/incs/footer.tpl
===================================================================
--- branches/RC/core/admin_templates/incs/footer.tpl (revision 9638)
+++ branches/RC/core/admin_templates/incs/footer.tpl (revision 9639)
@@ -1,28 +1,30 @@
<inp2:m_if check="adm_UsePopups">
<script type="text/javascript">
var o = '';
var el = document.getElementById('scroll_container');
if (el) {
document.body.style.height = '100%';
document.body.style.overflow = 'hidden';
document.body.scroll = 'no'
+ var _Simultanious_Edit_Message = '<inp2:m_Get var="_simultanious_edit_message" js_escape="1"/>';
+ var _DropTempUrl = '<inp2:m_t pass="m,adm" adm_event="OnDropTempTablesByWID" js_escape="1"/>';
addLoadEvent(function() {Form.Init('scroll_container')});
}
</script>
<inp2:m_else/>
<inp2:m_if check="adm_TemplateMatches" templates="head,tree" inverse="inverse">
<br /><br />
</inp2:m_if>
</inp2:m_if>
<inp2:adm_AfterScript/>
<inp2:m_if check="m_ParamEquals" name="noform" value="yes" inverse="inverse">
<inp2:m_RenderElement name="kernel_form_end"/>
</inp2:m_if>
<div id="nlsMenuPlace"></div>
</body>
</html>
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/incs/footer.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.6
\ No newline at end of property
+1.6.2.1
\ No newline at end of property
Index: branches/RC/core/admin_templates/index.tpl
===================================================================
--- branches/RC/core/admin_templates/index.tpl (revision 9638)
+++ branches/RC/core/admin_templates/index.tpl (revision 9639)
@@ -1,47 +1,47 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<inp2:m_CheckSSL mode="required" condition="Require_AdminSSL" />
<inp2:m_CheckSSL/>
<inp2:m_RequireLogin login_template="login"/>
<inp2:m_Set skip_last_template="1"/>
<inp2:m_NoDebug/>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=<inp2:lang_GetCharset/>">
<title><inp2:m_GetConfig var="Site_Name"/> - <inp2:m_Phrase label="la_AdministrativeConsole"/></title>
<inp2:m_base_ref/>
<link rel="icon" href="img/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" rev="stylesheet" href="incs/style.css" type="text/css" />
<script type="text/javascript">
window.name = 'main_frame';
var $top_height = 94;
if (navigator.appName == 'Netscape') {
$top_height = navigator.appVersion.substring(0, 1) != '5' ? 96 : 95;
}
<inp2:m_if check="m_RecallEquals" name="ShowAdminMenu" value="0" persistent="1">
document.write('<frameset id="top_frameset" rows="' + $top_height + ',*" framespacing="0" scrolling="no" frameborder="0">');
<inp2:m_else/>
document.write('<frameset id="top_frameset" rows="25,*" framespacing="0" scrolling="no" frameborder="0">');
</inp2:m_if>
</script>
</head>
<frame src="<inp2:m_t t="head" pass="m" m_cat_id="0" m_opener="s" no_pass_through="1"/>" name="head" scrolling="no" noresize="noresize">
- <frameset id="sub_frameset" cols="<inp2:m_if check="m_RecallEquals" name="ShowAdminMenu" value="0" persistent="1">200<inp2:m_else/>0</inp2:m_if>,*" border="0">
+ <frameset id="sub_frameset" cols="<inp2:m_if check="m_RecallEquals" name="ShowAdminMenu" value="0" persistent="1"><inp2:adm_MenuFrameWidth/>,<inp2:m_else/>0</inp2:m_if>,*" border="0">
<frame src="<inp2:m_t t="tree" pass="m" m_cat_id="0" m_opener="s" no_pass_through="1"/>" name="menu" target="main" noresize scrolling="auto" marginwidth="0" marginheight="0">
<inp2:m_DefineElement name="root_node">
<frame src="<inp2:m_if check="adm_MainFrameLink"><inp2:adm_MainFrameLink/><inp2:m_else/><inp2:m_param name="section_url"/></inp2:m_if>" name="main" marginwidth="0" marginheight="0" frameborder="no" noresize scrolling="auto">
</inp2:m_DefineElement>
<inp2:adm_PrintSection render_as="root_node" section_name="in-portal:root"/>
</frameset>
</frameset>
<noframes>
<body bgcolor="#FFFFFF">
<p></p>
</body>
</noframes>
</html>
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/index.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.7.2.2
\ No newline at end of property
+1.7.2.3
\ No newline at end of property
Index: branches/RC/core/install/utf.php
===================================================================
--- branches/RC/core/install/utf.php (revision 9638)
+++ branches/RC/core/install/utf.php (revision 9639)
@@ -1,144 +1,144 @@
<?php
// comment out this line to run the script
-die(' Should be enabled by the administrator! ');
+//die(' Should be enabled by the administrator! ');
$start = getmicrotime();
define('FULL_PATH', realpath(dirname(__FILE__)).'/../../');
define('REL_PATH', '/core/install');
include_once(FULL_PATH.'/core/kernel/startup.php');
$application =& kApplication::Instance();
$application->Init();
header('Content-type: text/html; charset: utf-8');
if (!defined('DEBUG_MODE') || !DEBUG_MODE) exit;
$target_charset = 'utf8';
$target_collation = 'utf8_general_ci';
//$target_charset = 'latin1';
//$target_collation = 'latin1_swedish_ci';
ini_set('max_execution_time', 0);
// Convert language translation
$langs = $application->Conn->Query('SELECT * FROM '.TABLE_PREFIX.'Language', 'LanguageId');
foreach ($langs as $lang_id => $a_lang) {
switch ( strtoupper($a_lang['Charset']) ) {
case 'WINDOWS-1251':
$langs[$lang_id]['mysql_charset'] = 'cp1251';
break;
case 'WINDOWS-1257':
$langs[$lang_id]['mysql_charset'] = 'cp1257';
break;
case 'UTF-8':
// when column have latin1 collation, but it's data is encoded to utf8 (from web browser)
$langs[$lang_id]['mysql_charset'] = 'utf8';
break;
default:
$langs[$lang_id]['mysql_charset'] = 'latin1';
}
}
print_pre($langs);
//die();
$query = 'ALTER DATABASE `'.SQL_DB.'` DEFAULT CHARACTER SET '.$target_charset.' COLLATE '.$target_collation;
$application->Conn->Query($query);
$query = 'SHOW TABLE STATUS';
$tables = $application->Conn->Query($query);
foreach ($tables as $table_status)
{
$table = $table_status['Name'];
if (!preg_match('/^'.preg_quote(TABLE_PREFIX, '/').'/', $table)) {
continue;
}
if ($table_status['Collation'] != $target_collation) {
$sql = 'ALTER TABLE '.$table.' COLLATE '.$application->Conn->qstr($target_collation);
echo "$sql<br>\n";
$application->Conn->Query($sql);
}
echo "scanning $table<br>";
$columns = $application->Conn->Query('SHOW FULL COLUMNS FROM '.$table);
foreach ($columns as $a_column) {
- if ($a_column['Collation'] != 'NULL') {
+ if ($a_column['Collation'] && $a_column['Collation'] != 'NULL') {
if ($a_column['Collation'] == $target_collation) {
echo "skipping ".$a_column['Field'].'<br>';
continue;
}
echo 'processing column '.$a_column['Field'].' ('.$a_column['Collation'].')<br>';
// ALTER TABLE `inp_Addresses` ADD `utf_To` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL AFTER `To` ;
// adding temporary UTF column
$new_def = $a_column['Type'].' CHARACTER SET '.$target_charset.' COLLATE '.$target_collation.' '.($a_column['Null'] == 'YES' ? 'NULL':'NOT NULL');
$q = 'ALTER TABLE `'.$table.'` ADD `utf_'.$a_column['Field'].'` '.$new_def.' AFTER `'.$a_column['Field'].'`;';
echo "$q<br>";
$application->Conn->Query($q);
// copying value to utf
if ($table == TABLE_PREFIX.'Phrase' && $a_column['Field'] == 'Translation') {
foreach ($langs as $lang_id => $a_lang) {
$cast = $a_lang['mysql_charset'];
if (!$cast) $cast = 'latin1';
$copy_def = 'CONVERT( CAST(BINARY('.$a_column['Field'].') AS CHAR CHARACTER SET '.$cast.') USING '.$target_charset.')';
$q = 'UPDATE `'.$table.'` SET `utf_'.$a_column['Field'].'` = '.$copy_def.' WHERE LanguageId = '.$lang_id;
echo "$q<br>";
$application->Conn->Query($q);
}
}
elseif (preg_match('/l([0-9]+)_.*/', $a_column['Field'], $matches)) {
$cast = $langs[$matches[1]]['mysql_charset'];
if (!$cast) $cast = 'latin1';
$copy_def = 'CONVERT( CAST(BINARY('.$a_column['Field'].') AS CHAR CHARACTER SET '.$cast.') USING '.$target_charset.')';
$q = 'UPDATE `'.$table.'` SET `utf_'.$a_column['Field'].'` = '.$copy_def;
echo "$q<br>";
$application->Conn->Query($q);
}
else {
$copy_def = 'BINARY(`'.$a_column['Field'].'`);';
$q = 'UPDATE `'.$table.'` SET `utf_'.$a_column['Field'].'` = '.$copy_def;
echo "$q<br>";
$application->Conn->Query($q);
}
// altering orignal field to utf
$q = 'ALTER TABLE `'.$table.'` CHANGE `'.$a_column['Field'].'` `'.$a_column['Field'].'` '.$new_def.';';
echo "$q<br>";
$application->Conn->Query($q);
// copying utf value back
$q = 'UPDATE `'.$table.'` SET `'.$a_column['Field'].'` = `utf_'.$a_column['Field'].'`;';
echo "$q<br>";
$application->Conn->Query($q);
// removing temporary UTF column
$q = 'ALTER TABLE `'.$table.'` DROP `utf_'.$a_column['Field'].'`;';
echo "$q<br>";
$application->Conn->Query($q);
}
}
}
$application->Conn->Query('UPDATE '.TABLE_PREFIX.'Language SET Charset = \''.$target_charset.'\'');
function getmicrotime()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/install/utf.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.2.2.4
\ No newline at end of property
+1.2.2.5
\ No newline at end of property
Index: branches/RC/core/install/upgrades.sql
===================================================================
--- branches/RC/core/install/upgrades.sql (revision 9638)
+++ branches/RC/core/install/upgrades.sql (revision 9639)
@@ -1,140 +1,150 @@
# ===== v 4.0.1 =====
ALTER TABLE EmailLog ADD EventParams TEXT NOT NULL;
INSERT INTO ConfigurationAdmin VALUES ('MailFunctionHeaderSeparator', 'la_Text_smtp_server', 'la_config_MailFunctionHeaderSeparator', 'radio', NULL, '1=la_Linux,2=la_Windows', 30.08, 0, 0);
INSERT INTO ConfigurationValues VALUES (0, 'MailFunctionHeaderSeparator', 1, 'In-Portal', 'in-portal:configure_general');
ALTER TABLE PersistantSessionData DROP PRIMARY KEY ;
ALTER TABLE PersistantSessionData ADD INDEX ( `PortalUserId` ) ;
# ===== v 4.1.0 =====
ALTER TABLE EmailMessage ADD ReplacementTags TEXT AFTER Template;
ALTER TABLE Phrase
CHANGE Translation Translation TEXT NOT NULL,
CHANGE Module Module VARCHAR(30) NOT NULL DEFAULT 'In-Portal';
ALTER TABLE Category
CHANGE Description Description TEXT,
CHANGE l1_Description l1_Description TEXT,
CHANGE l2_Description l2_Description TEXT,
CHANGE l3_Description l3_Description TEXT,
CHANGE l4_Description l4_Description TEXT,
CHANGE l5_Description l5_Description TEXT,
CHANGE CachedNavbar CachedNavbar text,
CHANGE l1_CachedNavbar l1_CachedNavbar text,
CHANGE l2_CachedNavbar l2_CachedNavbar text,
CHANGE l3_CachedNavbar l3_CachedNavbar text,
CHANGE l4_CachedNavbar l4_CachedNavbar text,
CHANGE l5_CachedNavbar l5_CachedNavbar text,
CHANGE ParentPath ParentPath TEXT NULL DEFAULT NULL,
CHANGE NamedParentPath NamedParentPath TEXT NULL DEFAULT NULL;
ALTER TABLE ConfigurationAdmin CHANGE ValueList ValueList TEXT;
ALTER TABLE EmailQueue
CHANGE `Subject` `Subject` TEXT,
CHANGE toaddr toaddr TEXT,
CHANGE fromaddr fromaddr TEXT;
ALTER TABLE Category DROP Pop;
ALTER TABLE PortalUser
CHANGE CreatedOn CreatedOn INT DEFAULT NULL,
CHANGE dob dob INT(11) NULL DEFAULT NULL,
CHANGE PassResetTime PassResetTime INT(11) UNSIGNED NULL DEFAULT NULL,
CHANGE PwRequestTime PwRequestTime INT(11) UNSIGNED NULL DEFAULT NULL,
CHANGE `Password` `Password` VARCHAR(255) NULL DEFAULT 'd41d8cd98f00b204e9800998ecf8427e';
ALTER TABLE Modules
CHANGE BuildDate BuildDate INT UNSIGNED NULL DEFAULT NULL,
CHANGE Version Version VARCHAR(10) NOT NULL DEFAULT '0.0.0',
CHANGE `Var` `Var` VARCHAR(100) NOT NULL DEFAULT '';
ALTER TABLE Language
CHANGE Enabled Enabled INT(11) NOT NULL DEFAULT '1',
CHANGE InputDateFormat InputDateFormat VARCHAR(50) NOT NULL DEFAULT 'm/d/Y',
CHANGE InputTimeFormat InputTimeFormat VARCHAR(50) NOT NULL DEFAULT 'g:i:s A',
CHANGE DecimalPoint DecimalPoint VARCHAR(10) NOT NULL DEFAULT '',
CHANGE ThousandSep ThousandSep VARCHAR(10) NOT NULL DEFAULT '';
ALTER TABLE Events CHANGE FromUserId FromUserId INT(11) NOT NULL DEFAULT '-1';
ALTER TABLE StdDestinations CHANGE DestAbbr2 DestAbbr2 CHAR(2) NULL DEFAULT NULL;
ALTER TABLE PermCache DROP DACL;
ALTER TABLE PortalGroup CHANGE CreatedOn CreatedOn INT UNSIGNED NULL DEFAULT NULL;
ALTER TABLE UserSession
CHANGE SessionKey SessionKey INT UNSIGNED NULL DEFAULT NULL ,
CHANGE CurrentTempKey CurrentTempKey INT UNSIGNED NULL DEFAULT NULL ,
CHANGE PrevTempKey PrevTempKey INT UNSIGNED NULL DEFAULT NULL ,
CHANGE LastAccessed LastAccessed INT UNSIGNED NOT NULL DEFAULT '0',
CHANGE PortalUserId PortalUserId INT(11) NOT NULL DEFAULT '-2',
CHANGE Language Language INT(11) NOT NULL DEFAULT '1',
CHANGE Theme Theme INT(11) NOT NULL DEFAULT '1';
CREATE TABLE Counters (
CounterId int(10) unsigned NOT NULL auto_increment,
Name varchar(100) NOT NULL default '',
CountQuery text,
CountValue text,
LastCounted int(10) unsigned default NULL,
LifeTime int(10) unsigned NOT NULL default '3600',
IsClone tinyint(3) unsigned NOT NULL default '0',
TablesAffected text,
PRIMARY KEY (CounterId),
UNIQUE KEY Name (Name)
);
CREATE TABLE Skins (
`SkinId` int(11) NOT NULL auto_increment,
`Name` varchar(255) default NULL,
`CSS` text,
`Logo` varchar(255) default NULL,
`Options` text,
`LastCompiled` int(11) NOT NULL default '0',
`IsPrimary` int(1) NOT NULL default '0',
PRIMARY KEY (`SkinId`)
);
INSERT INTO Skins VALUES (DEFAULT, 'Default', '/* General elements */\r\n\r\nhtml {\r\n height: 100%;\r\n}\r\n\r\nbody {\r\n font-family: verdana,arial,helvetica,sans-serif;\r\n font-size: 9pt;\r\n color: #000000;\r\n overflow-x: auto; overflow-y: auto;\r\n margin: 0px 0px 0px 0px;\r\n text-decoration: none;\r\n}\r\n\r\na {\r\n color: #006699;\r\n text-decoration: none;\r\n}\r\n\r\na:hover {\r\n color: #009ff0;\r\n text-decoration: none;\r\n}\r\n\r\nform {\r\n display: inline;\r\n}\r\n\r\nimg { border: 0px; }\r\n\r\nbody.height-100 {\r\n height: 100%;\r\n}\r\n\r\nbody.regular-body {\r\n margin: 0px 10px 5px 10px;\r\n color: #000000;\r\n background-color: @@SectionBgColor@@;\r\n}\r\n\r\nbody.edit-popup {\r\n margin: 0px 0px 0px 0px;\r\n}\r\n\r\ntable.collapsed {\r\n border-collapse: collapse;\r\n}\r\n\r\n.bordered, table.bordered, .bordered-no-bottom {\r\n border: 1px solid #000000;\r\n border-collapse: collapse;\r\n}\r\n\r\n.bordered-no-bottom {\r\n border-bottom: none;\r\n}\r\n\r\n.login-table td {\r\n padding: 1px;\r\n}\r\n\r\n.disabled {\r\n background-color: #ebebeb;\r\n}\r\n\r\n/* Head frame */\r\n.head-table tr td {\r\n background-color: @@HeadBgColor@@;\r\n color: @@HeadColor@@\r\n}\r\n\r\ntd.kx-block-header, .head-table tr td.kx-block-header{\r\n color: @@HeadBarColor@@;\r\n background-color: @@HeadBarBgColor@@;\r\n padding-left: 7px;\r\n padding-right: 7px;\r\n}\r\n\r\na.kx-header-link {\r\n text-decoration: underline;\r\n color: #FFFFFF;\r\n}\r\n\r\na.kx-header-link:hover {\r\n color: #FFCB05;\r\n text-decoration: none;\r\n}\r\n\r\n.kx-secondary-foreground {\r\n color: @@HeadBarColor@@;\r\n background-color: @@HeadBarBgColor@@;\r\n}\r\n\r\n.kx-login-button {\r\n background-color: #2D79D6;\r\n color: #FFFFFF;\r\n}\r\n\r\n/* General form button (yellow) */\r\n.button {\r\n font-size: 12px;\r\n font-weight: normal;\r\n color: #000000;\r\n background: url(@@base_url@@/proj-base/admin_templates/img/button_back.gif) #f9eeae repeat-x;\r\n text-decoration: none;\r\n}\r\n\r\n/* Disabled (grayed-out) form button */\r\n.button-disabled {\r\n font-size: 12px;\r\n font-weight: normal;\r\n color: #676767;\r\n background: url(@@base_url@@/proj-base/admin_templates/img/button_back_disabled.gif) #f9eeae repeat-x;\r\n text-decoration: none;\r\n}\r\n\r\n/* Tabs bar */\r\n\r\n.tab, .tab-active {\r\n background-color: #F0F1EB;\r\n padding: 3px 7px 2px 7px;\r\n border-top: 1px solid black;\r\n border-left: 1px solid black;\r\n border-right: 1px solid black;\r\n}\r\n\r\n.tab-active {\r\n background-color: #2D79D6;\r\n border-bottom: 1px solid #2D79D6;\r\n}\r\n\r\n.tab a {\r\n color: #00659C;\r\n font-weight: bold;\r\n}\r\n\r\n.tab-active a {\r\n color: #fff;\r\n font-weight: bold;\r\n}\r\n\r\n\r\n/* Toolbar */\r\n\r\n.toolbar {\r\n font-size: 8pt;\r\n border: 1px solid #000000;\r\n border-width: 0px 1px 1px 1px;\r\n background-color: @@ToolbarBgColor@@;\r\n border-collapse: collapse;\r\n}\r\n\r\n.toolbar td {\r\n height: 100%;\r\n}\r\n\r\n.toolbar-button, .toolbar-button-disabled, .toolbar-button-over {\r\n float: left;\r\n text-align: center;\r\n font-size: 8pt;\r\n padding: 5px 5px 5px 5px;\r\n vertical-align: middle;\r\n color: #006F99;\r\n}\r\n\r\n.toolbar-button-over {\r\n color: #000;\r\n}\r\n\r\n.toolbar-button-disabled {\r\n color: #444;\r\n}\r\n\r\n/* Scrollable Grids */\r\n\r\n\r\n/* Main Grid class */\r\n.grid-scrollable {\r\n padding: 0px;\r\n border: 1px solid black !important;\r\n border-top: none !important;\r\n}\r\n\r\n/* Div generated by js, which contains all the scrollable grid elements, affects the style of scrollable area without data (if there are too few rows) */\r\n.grid-container {\r\n background-color: #fff;\r\n}\r\n\r\n.grid-container table {\r\n border-collapse: collapse;\r\n}\r\n\r\n/* Inner div generated in each data-cell */\r\n.grid-cell-div {\r\n overflow: hidden;\r\n height: auto;\r\n}\r\n\r\n/* Main row definition */\r\n.grid-data-row td, .grid-data-row-selected td, .grid-data-row-even-selected td, .grid-data-row-mouseover td, .table-color1, .table-color2 {\r\n font-weight: normal;\r\n color: @@OddColor@@;\r\n background-color: @@OddBgColor@@;\r\n padding: 3px 5px 3px 5px;\r\n height: 30px;\r\n overflow: hidden;\r\n /* border-right: 1px solid black; */\r\n}\r\n.grid-data-row-even td, .table-color2 {\r\n background-color: @@EvenBgColor@@;\r\n color: @@EvenColor@@;\r\n}\r\n.grid-data-row td a, .grid-data-row-selected td a, .grid-data-row-mouseover td a {\r\n text-decoration: underline;\r\n}\r\n\r\n/* mouse-over rows */\r\n.grid-data-row-mouseover td {\r\n background: #FFFDF4;\r\n}\r\n\r\n/* Selected row, applies to both checkbox and data areas */\r\n.grid-data-row-selected td {\r\n background: #FEF2D6;\r\n}\r\n\r\n.grid-data-row-even-selected td {\r\n background: #FFF7E0;\r\n}\r\n\r\n/* General header cell definition */\r\n.grid-header-row td {\r\n font-weight: bold;\r\n background-color: @@ColumnTitlesBgColor@@;\r\n text-decoration: none;\r\n padding: 3px 5px 3px 5px;\r\n color: @@ColumnTitlesColor@@;\r\n border-right: none;\r\n text-align: left;\r\n vertical-align: middle !important;\r\n white-space: nowrap;\r\n /* border-right: 1px solid black; */\r\n}\r\n\r\n/* Filters row */\r\ntr.grid-header-row-0 td {\r\n background-color: @@FiltersBgColor@@;\r\n border-bottom: 1px solid black;\r\n}\r\n\r\n/* Grid Filters */\r\ntable.range-filter {\r\n width: 100%;\r\n}\r\n\r\n.range-filter td {\r\n padding: 0px 0px 2px 2px !important;\r\n border: none !important;\r\n font-size: 8pt !important;\r\n font-weight: normal !important;\r\n text-align: left;\r\n color: #000000 !important;\r\n}\r\n\r\ninput.filter, select.filter {\r\n margin-bottom: 0px;\r\n width: 85%;\r\n}\r\n\r\ninput.filter-active {\r\n background-color: #FFFF00;\r\n}\r\n\r\nselect.filter-active {\r\n background-color: #FFFF00;\r\n}\r\n\r\n/* Column titles row */\r\ntr.grid-header-row-1 td {\r\n height: 25px;\r\n font-weight: bold;\r\n background-color: @@ColumnTitlesBgColor@@;\r\n color: @@ColumnTitlesColor@@;\r\n}\r\n\r\ntr.grid-header-row-1 td a {\r\n color: @@ColumnTitlesColor@@;\r\n}\r\n\r\ntr.grid-header-row-1 td a:hover {\r\n color: #FFCC00;\r\n}\r\n\r\n\r\n.grid-footer-row td {\r\n background-color: #D7D7D7;\r\n font-weight: bold;\r\n border-right: none;\r\n padding: 3px 5px 3px 5px;\r\n}\r\n\r\ntd.grid-header-last-cell, td.grid-data-last-cell, td.grid-footer-last-cell {\r\n border-right: none !important;\r\n}\r\n\r\ntd.grid-data-col-0, td.grid-data-col-0 div {\r\n text-align: center;\r\n vertical-align: middle !important;\r\n}\r\n\r\ntr.grid-header-row-0 td.grid-header-col-0 {\r\n text-align: center;\r\n vertical-align: middle !important;\r\n}\r\n\r\ntr.grid-header-row-0 td.grid-header-col-0 div {\r\n display: table-cell;\r\n vertical-align: middle;\r\n}\r\n\r\n.grid-status-bar {\r\n border: 1px solid black;\r\n border-top: none;\r\n padding: 0px;\r\n width: 100%;\r\n border-collapse: collapse;\r\n height: 30px;\r\n}\r\n\r\n.grid-status-bar td {\r\n background-color: @@TitleBarBgColor@@;\r\n color: @@TitleBarColor@@;\r\n font-size: 11pt;\r\n font-weight: normal;\r\n padding: 2px 8px 2px 8px;\r\n}\r\n\r\n/* /Scrollable Grids */\r\n\r\n\r\n/* Forms */\r\ntable.edit-form {\r\n border: none;\r\n border-top-width: 0px;\r\n border-collapse: collapse;\r\n width: 100%;\r\n}\r\n\r\n.edit-form-odd, .edit-form-even {\r\n padding: 0px;\r\n}\r\n\r\n.subsectiontitle {\r\n font-size: 10pt;\r\n font-weight: bold;\r\n background-color: #4A92CE;\r\n color: #fff;\r\n height: 25px;\r\n border-top: 1px solid black;\r\n}\r\n\r\n.label-cell {\r\n background: #DEE7F6 url(@@base_url@@/proj-base/admin_templates/img/bgr_input_name_line.gif) no-repeat right bottom;\r\n font: 12px arial, sans-serif;\r\n padding: 4px 20px;\r\n width: 150px;\r\n}\r\n\r\n.control-mid {\r\n width: 13px;\r\n border-left: 1px solid #7A95C2;\r\n background: #fff url(@@base_url@@/proj-base/admin_templates/img/bgr_mid.gif) repeat-x left bottom;\r\n}\r\n\r\n.control-cell {\r\n font: 11px arial, sans-serif;\r\n padding: 4px 10px 5px 5px;\r\n background: #fff url(@@base_url@@/proj-base/admin_templates/img/bgr_input_line.gif) no-repeat left bottom;\r\n width: auto;\r\n vertical-align: middle;\r\n}\r\n\r\n.label-cell-filler {\r\n background: #DEE7F6 none;\r\n}\r\n.control-mid-filler {\r\n background: #fff none;\r\n border-left: 1px solid #7A95C2;\r\n}\r\n.control-cell-filler {\r\n background: #fff none;\r\n}\r\n\r\n\r\n.error-cell {\r\n background-color: #fff;\r\n color: red;\r\n}\r\n\r\n.form-warning {\r\n color: red;\r\n}\r\n\r\n.req-note {\r\n font-style: italic;\r\n color: #333;\r\n}\r\n\r\n#scroll_container table.tableborder {\r\n border-collapse: separate\r\n}\r\n\r\n\r\n/* Uploader */\r\n\r\n.uploader-main {\r\n position: absolute;\r\n display: none;\r\n z-index: 10;\r\n border: 1px solid #777;\r\n padding: 10px;\r\n width: 350px;\r\n height: 120px;\r\n overflow: hidden;\r\n background-color: #fff;\r\n}\r\n\r\n.uploader-percent {\r\n width: 100%;\r\n padding-top: 3px;\r\n text-align: center;\r\n position: relative;\r\n z-index: 20;\r\n float: left;\r\n font-weight: bold;\r\n}\r\n\r\n.uploader-left {\r\n width: 100%;\r\n border: 1px solid black;\r\n height: 20px;\r\n background: #fff url(@@base_url@@/core/admin_templates/img/progress_left.gif);\r\n}\r\n\r\n.uploader-done {\r\n width: 0%;\r\n background-color: green;\r\n height: 20px;\r\n background: #4A92CE url(@@base_url@@/core/admin_templates/img/progress_done.gif);\r\n}\r\n\r\n\r\n/* To be sorted */\r\n\r\n\r\n/* Section title, right to the big icon */\r\n.admintitle {\r\n font-size: 16pt;\r\n font-weight: bold;\r\n color: @@SectionColor@@;\r\n text-decoration: none;\r\n}\r\n\r\n/* Left sid of bluebar */\r\n.header_left_bg {\r\n background-color: @@TitleBarBgColor@@;\r\n background-image: none;\r\n padding-left: 5px;\r\n}\r\n\r\n/* Right side of bluebar */\r\n.tablenav, tablenav a {\r\n font-size: 11pt;\r\n font-weight: bold;\r\n color: @@TitleBarColor@@;\r\n\r\n text-decoration: none;\r\n background-color: @@TitleBarBgColor@@;\r\n background-image: none;\r\n}\r\n\r\n/* Section title in the bluebar * -- why ''link''? :S */\r\n.tablenav_link {\r\n font-size: 11pt;\r\n font-weight: bold;\r\n color: @@TitleBarColor@@;\r\n text-decoration: none;\r\n}\r\n\r\n/* Active page in top and bottom bluebars pagination */\r\n.current_page {\r\n font-size: 10pt;\r\n font-weight: bold;\r\n background-color: #fff;\r\n color: #2D79D6;\r\n padding: 3px 2px 3px 3px;\r\n}\r\n\r\n/* Other pages and arrows in pagination on blue */\r\n.nav_url {\r\n font-size: 10pt;\r\n font-weight: bold;\r\n color: #fff;\r\n padding: 3px 2px 3px 3px;\r\n}\r\n\r\n/* Tree */\r\n.tree-body {\r\n background-color: @@TreeBgColor@@;\r\n height: 100%\r\n}\r\n\r\n.tree_head.td, .tree_head, .tree_head:hover {\r\n font-weight: bold;\r\n font-size: 10px;\r\n color: #FFFFFF;\r\n font-family: Verdana, Arial;\r\n text-decoration: none;\r\n}\r\n\r\n.tree {\r\n padding: 0px;\r\n border: none;\r\n border-collapse: collapse;\r\n}\r\n\r\n.tree tr td {\r\n padding: 0px;\r\n margin: 0px;\r\n font-family: helvetica, arial, verdana,;\r\n font-size: 11px;\r\n white-space: nowrap;\r\n}\r\n\r\n.tree tr td a {\r\n font-size: 11px;\r\n color: @@TreeColor@@;\r\n font-family: Helvetica, Arial, Verdana;\r\n text-decoration: none;\r\n padding: 2px 0px 2px 2px;\r\n}\r\n\r\n.tree tr.highlighted td a {\r\n background-color: @@TreeHighBgColor@@;\r\n color: @@TreeHighColor@@;\r\n}\r\n\r\n.tree tr.highlighted td a:hover {\r\n color: #fff;\r\n}\r\n\r\n.tree tr td a:hover {\r\n color: #000000;\r\n}', 'just_logo.gif', 'a:20:{s:11:"HeadBgColor";a:2:{s:11:"Description";s:27:"Head frame background color";s:5:"Value";s:7:"#1961B8";}s:9:"HeadColor";a:2:{s:11:"Description";s:21:"Head frame text color";s:5:"Value";s:7:"#CCFF00";}s:14:"SectionBgColor";a:2:{s:11:"Description";s:28:"Section bar background color";s:5:"Value";s:7:"#FFFFFF";}s:12:"SectionColor";a:2:{s:11:"Description";s:22:"Section bar text color";s:5:"Value";s:7:"#2D79D6";}s:12:"HeadBarColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:14:"HeadBarBgColor";a:1:{s:5:"Value";s:7:"#1961B8";}s:13:"TitleBarColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:15:"TitleBarBgColor";a:1:{s:5:"Value";s:7:"#2D79D6";}s:14:"ToolbarBgColor";a:1:{s:5:"Value";s:7:"#F0F1EB";}s:14:"FiltersBgColor";a:1:{s:5:"Value";s:7:"#D7D7D7";}s:17:"ColumnTitlesColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:19:"ColumnTitlesBgColor";a:1:{s:5:"Value";s:7:"#999999";}s:8:"OddColor";a:1:{s:5:"Value";s:7:"#000000";}s:10:"OddBgColor";a:1:{s:5:"Value";s:7:"#F6F6F6";}s:9:"EvenColor";a:1:{s:5:"Value";s:7:"#000000";}s:11:"EvenBgColor";a:1:{s:5:"Value";s:7:"#EBEBEB";}s:9:"TreeColor";a:1:{s:5:"Value";s:7:"#006F99";}s:11:"TreeBgColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:13:"TreeHighColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:15:"TreeHighBgColor";a:1:{s:5:"Value";s:7:"#4A92CE";}}', 1178706881, 1);
INSERT INTO Permissions VALUES (0, 'in-portal:skins.view', 11, 1, 1, 0), (0, 'in-portal:skins.add', 11, 1, 1, 0), (0, 'in-portal:skins.edit', 11, 1, 1, 0), (0, 'in-portal:skins.delete', 11, 1, 1, 0);
# ===== v 4.1.1 =====
DROP TABLE EmailQueue;
CREATE TABLE EmailQueue (
EmailQueueId int(10) unsigned NOT NULL auto_increment,
ToEmail varchar(255) NOT NULL default '',
`Subject` varchar(255) NOT NULL default '',
MessageHeaders text,
MessageBody longtext,
Queued int(10) unsigned NOT NULL default '0',
SendRetries int(10) unsigned NOT NULL default '0',
LastSendRetry int(10) unsigned NOT NULL default '0',
PRIMARY KEY (EmailQueueId),
KEY LastSendRetry (LastSendRetry),
KEY SendRetries (SendRetries)
);
ALTER TABLE Events ADD ReplacementTags TEXT AFTER Event;
# ===== v 4.2.0 =====
ALTER TABLE CustomField ADD MultiLingual TINYINT UNSIGNED NOT NULL DEFAULT '1' AFTER FieldLabel;
ALTER TABLE Category
ADD TreeLeft BIGINT NOT NULL AFTER ParentPath,
ADD TreeRight BIGINT NOT NULL AFTER TreeLeft;
ALTER TABLE Category ADD INDEX (TreeLeft);
ALTER TABLE Category ADD INDEX (TreeRight);
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CategoriesRebuildSerial', '0', 'In-Portal', '');
UPDATE ConfigurationAdmin SET `element_type` = 'textarea' WHERE `VariableName` IN ('Category_MetaKey', 'Category_MetaDesc');
ALTER TABLE PortalUser
CHANGE FirstName FirstName VARCHAR(255) NOT NULL DEFAULT '',
CHANGE LastName LastName VARCHAR(255) NOT NULL DEFAULT '';
# ===== v 4.2.1 =====
INSERT INTO ConfigurationAdmin VALUES ('UseSmallHeader', 'la_Text_Website', 'la_config_UseSmallHeader', 'checkbox', '', '', 10.21, 0, 0);
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseSmallHeader', '0', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationAdmin VALUES ('User_Default_Registration_Country', 'la_Text_General', 'la_config_DefaultRegistrationCountry', 'select', NULL , '=+,<SQL>SELECT DestName AS OptionName, DestId AS OptionValue FROM <PREFIX>StdDestinations WHERE DestParentId IS NULL Order BY OptionName</SQL>', 10.111, 0, 0);
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_Default_Registration_Country', '', 'In-Portal:Users', 'in-portal:configure_users');
ALTER TABLE Category ADD SymLinkCategoryId INT UNSIGNED NULL DEFAULT NULL AFTER `Type`, ADD INDEX (SymLinkCategoryId);
ALTER TABLE ConfigurationValues CHANGE VariableValue VariableValue TEXT NULL DEFAULT NULL;
ALTER TABLE Language
ADD AdminInterfaceLang TINYINT UNSIGNED NOT NULL AFTER PrimaryLang,
ADD Priority INT NOT NULL AFTER AdminInterfaceLang;
DELETE FROM PersistantSessionData WHERE VariableName = 'lang_columns_.';
-ALTER TABLE SessionData CHANGE VariableValue VariableValue longtext NOT NULL;
\ No newline at end of file
+ALTER TABLE SessionData CHANGE VariableValue VariableValue longtext NOT NULL;
+
+REPLACE INTO ConfigurationAdmin VALUES ('CSVExportDelimiter', 'la_Text_CSV_Export', 'la_config_CSVExportDelimiter', 'select', NULL, '0=la_Tab,1=la_Comma,2=la_Semicolon,3=la_Space,4=la_Colon', 40.1, 0, 1);
+REPLACE INTO ConfigurationAdmin VALUES ('CSVExportEnclosure', 'la_Text_CSV_Export', 'la_config_CSVExportEnclosure', 'radio', NULL, '0=la_Doublequotes,1=la_Quotes', 40.2, 0, 1);
+REPLACE INTO ConfigurationAdmin VALUES ('CSVExportSeparator', 'la_Text_CSV_Export', 'la_config_CSVExportSeparator', 'radio', NULL, '0=la_Linux,1=la_Windows', 40.3, 0, 1);
+REPLACE INTO ConfigurationAdmin VALUES ('CSVExportEncoding', 'la_Text_CSV_Export', 'la_config_CSVExportEncoding', 'radio', NULL, '0=la_Unicode,1=la_Regular', 40.4, 0, 1);
+
+REPLACE INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportDelimiter', '0', 'In-Portal', 'in-portal:configure_general');
+REPLACE INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportEnclosure', '0', 'In-Portal', 'in-portal:configure_general');
+REPLACE INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportSeparator', '0', 'In-Portal', 'in-portal:configure_general');
+REPLACE INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportEncoding', '0', 'In-Portal', 'in-portal:configure_general');
Property changes on: branches/RC/core/install/upgrades.sql
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.19.2.12
\ No newline at end of property
+1.19.2.13
\ No newline at end of property
Index: branches/RC/core/install/install_data.sql
===================================================================
--- branches/RC/core/install/install_data.sql (revision 9638)
+++ branches/RC/core/install/install_data.sql (revision 9639)
@@ -1,593 +1,602 @@
INSERT INTO ConfigurationAdmin VALUES ('Site_Name', 'la_Text_Website', 'la_config_website_name', 'text', '', '', 10.02, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Site_Path', 'la_Text_Website', 'la_config_web_address', 'text', '', '', 10.01, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Backup_Path', 'la_Text_BackupPath', 'la_config_backup_path', 'text', '', '', 40.01, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Domain_Detect', 'la_Text_Website', 'la_config_detect_domain', 'text', '', '', 8, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Category_Sortfield', 'la_Text_General', 'la_category_sortfield_prompt', 'select', '', 'Name=la_Category_Name,Description=la_Category_Description,CreatedOn=la_Category_Date,EditorsPick=la_Category_Pick,<SQL>SELECT Prompt AS OptionName, CONCAT("cust_", FieldName) AS OptionValue FROM <PREFIX>CustomField WHERE (Type = 1) AND (IsSystem = 0)</SQL>', 10.01, 1, 1);
INSERT INTO ConfigurationAdmin VALUES ('Category_Sortorder', 'la_Text_General', 'la_category_sortfield_prompt', 'select', '', 'asc=la_common_ascending,desc=la_common_descending', 10.01, 2, 1);
INSERT INTO ConfigurationAdmin VALUES ('Category_Sortfield2', 'la_Text_General', 'la_category_sortfield2_prompt', 'select', '', 'Name=la_Category_Name,Description=la_Category_Description,CreatedOn=la_Category_Date,EditorsPick=la_Category_Pick,<SQL>SELECT Prompt AS OptionName, CONCAT("cust_", FieldName) AS OptionValue FROM <PREFIX>CustomField WHERE (Type = 1) AND (IsSystem = 0)</SQL>', 10.02, 1, 1);
INSERT INTO ConfigurationAdmin VALUES ('Category_Sortorder2', 'la_Text_General', 'la_category_sortfield2_prompt', 'select', '', 'asc=la_common_ascending,desc=la_common_descending', 10.02, 2, 1);
INSERT INTO ConfigurationAdmin VALUES ('Perpage_Category', 'la_Text_General', 'la_category_perpage_prompt', 'text', '', '', 10.03, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Category_DaysNew', 'la_Text_General', 'la_category_daysnew_prompt', 'text', '', '', 10.05, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Category_ShowPick', 'la_Text_General', 'la_category_showpick_prompt', 'checkbox', '', '', 10.06, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Category_MetaKey', 'la_Text_MetaInfo', 'la_category_metakey', 'textarea', '', '', 20.01, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Category_MetaDesc', 'la_Text_MetaInfo', 'la_category_metadesc', 'textarea', '', '', 20.02, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('User_NewGroup', 'la_Text_General', 'la_users_new_group', 'select', NULL, '0=lu_none,<SQL+>SELECT GroupId as OptionValue, Name as OptionName FROM <PREFIX>PortalGroup WHERE Enabled=1 AND Personal=0</SQL>', 10.08, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('User_GuestGroup', 'la_Text_General', 'la_users_guest_group', 'select', NULL, '0=lu_none,<SQL+>SELECT GroupId as OptionValue, Name as OptionName FROM <PREFIX>PortalGroup WHERE Enabled=1 AND Personal=0</SQL>', 10.1, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('RootPass', 'la_Text_General', 'la_prompt_root_pass', 'password', NULL, NULL, 10.12, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('Users_AllowReset', 'la_Text_General', 'la_prompt_allow_reset', 'text', NULL, NULL, 10.05, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('User_Allow_New', 'la_Text_General', 'la_users_allow_new', 'radio', '', '1=la_User_Instant,2=la_User_Not_Allowed,3=la_User_Upon_Approval', 10.01, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('User_Password_Auto', 'la_Text_General', 'la_users_password_auto', 'checkbox', '', '', 10.06, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('User_Votes_Deny', 'la_Text_Restrictions', 'la_users_votes_deny', 'text', '', '', 20.01, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('User_MembershipExpirationReminder', 'la_Text_General', 'la_MembershipExpirationReminder', 'text', NULL, '', 10.07, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('User_Review_Deny', 'la_Text_Restrictions', 'la_users_review_deny', 'text', '', '', 20.02, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Server_Name', 'la_Text_Website', 'la_config_server_name', 'text', '', '', 4, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('Config_Server_Time', 'la_Text_Date_Time_Settings', 'la_config_time_server', 'select', '', '1=la_m12,2=la_m11,3=la_m10,5=la_m9,6=la_m8,7=la_m7,8=la_m6,9=la_m5,10=la_m4,11=la_m3,12=la_m2,13=la_m1,14=la_m0,15=la_p1,16=la_p2,17=la_p3,18=la_p4,19=la_p5,20=la_p6,21=la_p7,22=la_p8,23=la_p9,24=la_p10,25=la_p11,26=la_p12,27=la_p13', 20.01, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Config_Site_Time', 'la_Text_Date_Time_Settings', 'la_config_site_zone', 'select', '', '1=la_m12,2=la_m11,3=la_m10,5=la_m9,6=la_m8,7=la_m7,8=la_m6,9=la_m5,10=la_m4,11=la_m3,12=la_m2,13=la_m1,14=la_m0,15=la_p1,16=la_p2,17=la_p3,18=la_p4,19=la_p5,20=la_p6,21=la_p7,22=la_p8,23=la_p9,24=la_p10,25=la_p11,26=la_p12,27=la_p13', 20.02, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Smtp_Server', 'la_Text_smtp_server', 'la_prompt_mailserver', 'text', NULL, NULL, 30.01, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Smtp_Port', 'la_Text_smtp_server', 'la_prompt_mailport', 'text', NULL, NULL, 30.02, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Smtp_Authenticate', 'la_Text_smtp_server', 'la_prompt_mailauthenticate', 'checkbox', NULL, NULL, 30.03, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Smtp_User', 'la_Text_smtp_server', 'la_prompt_smtp_user', 'text', NULL, NULL, 30.04, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Smtp_Pass', 'la_Text_smtp_server', 'la_prompt_smtp_pass', 'text', NULL, NULL, 30.05, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Smtp_DefaultHeaders', 'la_Text_smtp_server', 'la_prompt_smtpheaders', 'textarea', NULL, 'COLS=40 ROWS=5', 30.06, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('Smtp_AdminMailFrom', 'la_Text_smtp_server', 'la_prompt_AdminMailFrom', 'text', NULL, NULL, 30.07, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Perpage_Category_Short', 'la_Text_General', 'la_category_perpage__short_prompt', 'text', '', '', 10.04, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('CookieSessions', 'la_Text_Website', 'la_prompt_session_management', 'select', NULL, '0=lu_query_string,1=lu_cookies,2=lu_auto', 10.03, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('SearchRel_Keyword_category', 'la_config_SearchRel_DefaultKeyword', 'la_text_keyword', 'text', NULL, NULL, 0, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('SearchRel_Pop_category', 'la_config_DefaultPop', 'la_text_popularity', 'text', NULL, NULL, 0, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('SearchRel_Rating_category', 'la_config_DefaultRating', 'la_prompt_Rating', 'text', NULL, NULL, 0, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('SearchRel_Increase_category', 'la_config_DefaultIncreaseImportance', 'la_text_increase_importance', 'text', NULL, NULL, 0, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('SessionTimeout', 'la_Text_Website', 'la_prompt_session_timeout', 'text', '', '', 10.05, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('SystemTagCache', 'la_Text_Website', 'la_prompt_syscache_enable', 'checkbox', NULL, NULL, 10.07, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('User_SubscriberGroup', 'la_Text_General', 'la_users_subscriber_group', 'select', NULL, '0=lu_none,<SQL+>SELECT GroupId as OptionValue, Name as OptionName FROM <PREFIX>PortalGroup WHERE Enabled=1 AND Personal=0</SQL>', 10.11, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Root_Name', 'la_Text_General', 'la_prompt_root_name', 'text', '', '', 10.07, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('SocketBlockingMode', 'la_Text_Website', 'la_prompt_socket_blocking_mode', 'checkbox', NULL, NULL, 10.08, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('Min_UserName', 'la_Text_General', 'la_text_min_username', 'text', '', '', 10.03, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('Min_Password', 'la_Text_General', 'la_text_min_password', 'text', '', '', 10.04, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('Email_As_Login', 'la_Text_General', 'la_use_emails_as_login', 'checkbox', NULL, NULL, 10.02, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('RegistrationCaptcha', 'la_Text_General', 'la_registration_captcha', 'checkbox', NULL, NULL, 10.025, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('User_LoggedInGroup', 'la_Text_General', 'la_users_assign_all_to', 'select', NULL, '0=lu_none,<SQL+>SELECT GroupId as OptionValue, Name as OptionName FROM <PREFIX>PortalGroup WHERE Enabled=1 AND Personal=0</SQL>', 10.09, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('FirstDayOfWeek', 'la_Text_Date_Time_Settings', 'la_config_first_day_of_week', 'select', '', '0=la_sunday,1=la_monday', 20.03, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('SSL_URL', 'la_Text_Website', 'la_config_ssl_url', 'text', '', '', 10.09, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Require_SSL', 'la_Text_Website', 'la_config_require_ssl', 'checkbox', '', '', 10.1, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('Force_HTTP_When_SSL_Not_Required', 'la_Text_Website', 'la_config_force_http', 'checkbox', '', '', 10.11, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('SessionCookieName', 'la_Text_Website', 'la_prompt_session_cookie_name', 'text', '', '', 10.04, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('SessionReferrerCheck', 'la_Text_Website', 'la_promt_ReferrerCheck', 'checkbox', NULL, NULL, 10.06, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('UseModRewrite', 'la_Text_Website', 'la_config_use_modrewrite', 'checkbox', '', '', 10.12, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('UseModRewriteWithSSL', 'la_Text_Website', 'la_config_use_modrewrite_with_ssl', 'checkbox', '', '', 10.13, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('ErrorTemplate', 'la_Text_Website', 'la_config_error_template', 'text', '', '', 10.16, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('UseJSRedirect', 'la_Text_Website', 'la_config_use_js_redirect', 'checkbox', '', '', 10.14, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('MaxImportCategoryLevels', 'la_Text_General', 'la_prompt_max_import_category_levels', 'text', '', '', 10.08, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('UseCronForRegularEvent', 'la_Text_Website', 'la_UseCronForRegularEvent', 'checkbox', NULL, NULL, 10.15, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('NoPermissionTemplate', 'la_Text_Website', 'la_config_nopermission_template', 'text', '', '', 10.17, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('UseOutputCompression', 'la_Text_Website', 'la_config_UseOutputCompression', 'checkbox', '', '', 10.18, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('OutputCompressionLevel', 'la_Text_Website', 'la_config_OutputCompressionLevel', 'text', '', '', 10.19, 0, 1);
INSERT INTO ConfigurationAdmin VALUES ('MailFunctionHeaderSeparator', 'la_Text_smtp_server', 'la_config_MailFunctionHeaderSeparator', 'radio', NULL, '1=la_Linux,2=la_Windows', 30.08, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('UseToolbarLabels', 'la_Text_Website', 'la_config_UseToolbarLabels', 'checkbox', NULL , NULL , 10.20, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('UseSmallHeader', 'la_Text_Website', 'la_config_UseSmallHeader', 'checkbox', '', '', 10.21, 0, 0);
INSERT INTO ConfigurationAdmin VALUES ('User_Default_Registration_Country', 'la_Text_General', 'la_config_DefaultRegistrationCountry', 'select', NULL , '=+,<SQL>SELECT DestName AS OptionName, DestId AS OptionValue FROM <PREFIX>StdDestinations WHERE DestParentId IS NULL Order BY OptionName</SQL>', 10.111, 0, 0);
+INSERT INTO ConfigurationAdmin VALUES ('CSVExportDelimiter', 'la_Text_CSV_Export', 'la_config_CSVExportDelimiter', 'select', NULL, '0=la_Tab,1=la_Comma,2=la_Semicolon,3=la_Space,4=la_Colon', 40.1, 0, 1);
+INSERT INTO ConfigurationAdmin VALUES ('CSVExportEnclosure', 'la_Text_CSV_Export', 'la_config_CSVExportEnclosure', 'radio', NULL, '0=la_Doublequotes,1=la_Quotes', 40.2, 0, 1);
+INSERT INTO ConfigurationAdmin VALUES ('CSVExportSeparator', 'la_Text_CSV_Export', 'la_config_CSVExportSeparator', 'radio', NULL, '0=la_Linux,1=la_Windows', 40.3, 0, 1);
+INSERT INTO ConfigurationAdmin VALUES ('CSVExportEncoding', 'la_Text_CSV_Export', 'la_config_CSVExportEncoding', 'radio', NULL, '0=la_Unicode,1=la_Regular', 40.4, 0, 1);
+
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Columns_Category', '2', 'In-Portal', 'Categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'DomainSelect','1','In-Portal','in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Site_Path', '/', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Archive', '25', 'inportal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'debug', '1', 'inportal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_User', '100', 'inportal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_LangEmail', '20', 'inportal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Default_FromAddr', '', 'inportal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'email_replyto', '', 'inportal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'email_footer', 'message footer goes here', 'inportal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Default_Theme', 'default', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Default_Language', 'English', 'inportal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SessionTimeout', '3600', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_SortOrder', 'asc', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Suggest_MinInterval', '3600', 'inportal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SubCat_ListCount', '3', 'inportal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Timeout_Rating', '3600', 'In-Portal', 'System');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_SortField', 'u.CreatedOn', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Relations', '10', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Group_SortField', 'GroupName', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Group_SortOrder', 'asc', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Default_FromName', 'Webmaster', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Category', '20', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Category_Sortfield', 'Name', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Category_Sortorder', 'asc', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'MetaKeywords', DEFAULT, 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Relation_LV_Sortfield', 'ItemType', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'ampm_time', '1', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Template', '10', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Phrase', '40', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Sessionlist', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Category_Sortfield2', 'Description', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Category_Sortorder2', 'asc', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Category_DaysNew', '8', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Category_ShowPick', '', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Category_MetaKey', '', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Category_MetaDesc', '', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'MetaDescription', DEFAULT, 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_NewGroup', '13', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_Allow_New', '3', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_Password_Auto', '0', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_Votes_Deny', '5', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_Review_Deny', '5', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Config_Name', '', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Config_Company', '', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Config_Reg_Number', '', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Config_Website_Name', '', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Config_Web_Address', '', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Config_Server_Time', '14', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Config_Site_Time', '14', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Site_Name', 'In-Portal', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Backup_Path', '', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Items', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'GuestSessions', '1', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Smtp_Server', DEFAULT, 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Smtp_Port', DEFAULT, 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Smtp_User', DEFAULT, 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Smtp_Pass', DEFAULT, 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Smtp_SendHTML', '1', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Smtp_Authenticate', '0', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Email', '10', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Smtp_DefaultHeaders', 'X-Priority: 1\r\nX-MSMail-Priority: High\r\nX-Mailer: In-Portal', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Smtp_AdminMailFrom', 'portal@user.domain.name', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Category_Highlight_OpenTag', '<span class="match">', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Category_Highlight_CloseTag', '</span>', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_GuestGroup', '14', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'RootPass', '', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Category_Short', '3', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CookieSessions', '2', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SearchRel_Increase_category', '30', 'In-Portal', 'in-portal:configuration_search');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SearchRel_Keyword_category', '90', 'In-Portal', 'in-portal:configuration_search');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SearchRel_Pop_category', '5', 'In-Portal', 'in-portal:configuration_search');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SearchRel_Rating_category', '5', 'In-Portal', 'in-portal:configuration_search');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SearchRel_DefaultIncrease', '30', 'In-Portal', 'inportal:configure_searchdefault');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SearchRel_DefaultKeyword', '80', 'In-Portal', 'SearchRel_DefaultKeyword');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SearchRel_DefaultPop', '10', 'In-Portal', 'inportal:configuration_searchdefault');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SearchRel_DefaultRating', '10', 'In-Portal', 'inportal:configure_searchdefault');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SystemTagCache', '0', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Root_Name', 'lu_rootcategory_name', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_SubscriberGroup', '12', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SocketBlockingMode', '0', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Min_UserName', '3', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Min_Password', '5', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'LinksValidation_LV_Sortfield', 'ValidationTime', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CustomConfig_LV_Sortfield', 'FieldName', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Event_LV_SortField', 'Description', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Theme_LV_SortField', 'Name', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Template_LV_SortField', 'FileName', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Lang_LV_SortField', 'PackName', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Phrase_LV_SortField', 'Phrase', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'LangEmail_LV_SortField', 'Description', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CustomData_LV_SortField', 'FieldName', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Summary_SortField', 'Module', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Session_SortField', 'UserName', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SearchLog_SortField', 'Keyword', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_StatItem', '10', 'inportal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Groups', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Event', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_BanRules', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_SearchLog', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_LV_lang', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_LV_Themes', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_LV_Catlist', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Reviews', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Modules', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Grouplist', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Images', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'EmailsL_SortField', 'time_sent', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_EmailsL', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_CustomData', '20', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Perpage_Review', '10', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Search_MinKeyword_Length', '3', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Users_AllowReset', '180', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Email_As_Login', '0', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'RegistrationCaptcha', '0', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_LoggedInGroup', '15', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_MembershipExpirationReminder', '10', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'FirstDayOfWeek', '1', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SSL_URL', '', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Require_SSL', '', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Force_HTTP_When_SSL_Not_Required', '1', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SessionCookieName', 'sid', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseModRewrite', '0', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseModRewriteWithSSL', '0', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'SessionReferrerCheck', '1', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'ErrorTemplate', 'error_notfound', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseJSRedirect', '0', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'MaxImportCategoryLevels', '10', 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseCronForRegularEvent', '0', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'NoPermissionTemplate', 'no_permission', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseOutputCompression', '0', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'OutputCompressionLevel', '7', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'MailFunctionHeaderSeparator', 1, 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CategoriesRebuildSerial', '0', 'In-Portal', '');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseToolbarLabels', '1', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseSmallHeader', '0', 'In-Portal', 'in-portal:configure_general');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_Default_Registration_Country', '', 'In-Portal:Users', 'in-portal:configure_users');
+INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportDelimiter', '0', 'In-Portal', 'in-portal:configure_general');
+INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportEnclosure', '0', 'In-Portal', 'in-portal:configure_general');
+INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportSeparator', '0', 'In-Portal', 'in-portal:configure_general');
+INSERT INTO ConfigurationValues VALUES (DEFAULT, 'CSVExportEncoding', '0', 'In-Portal', 'in-portal:configure_general');
INSERT INTO Events VALUES (DEFAULT, 'USER.ADD', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.add', 0);
INSERT INTO Events VALUES (DEFAULT, 'USER.ADD', NULL, 2, 0, 'In-Portal:Users', 'la_event_user.add', 1);
INSERT INTO Events VALUES (DEFAULT, 'USER.APPROVE', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.approve', 0);
INSERT INTO Events VALUES (DEFAULT, 'USER.APPROVE', NULL, 2, 0, 'In-Portal:Users', 'la_event_user.approve', 1);
INSERT INTO Events VALUES (DEFAULT, 'USER.VALIDATE', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.validate', 0);
INSERT INTO Events VALUES (DEFAULT, 'USER.VALIDATE', NULL, 2, 0, 'In-Portal:Users', 'la_event_user.validate', 1);
INSERT INTO Events VALUES (DEFAULT, 'USER.DENY', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.deny', 0);
INSERT INTO Events VALUES (DEFAULT, 'USER.DENY', NULL, 2, 0, 'In-Portal:Users', 'la_event_user.deny', 1);
INSERT INTO Events VALUES (DEFAULT, 'USER.PSWD', NULL, 2, 0, 'In-Portal:Users', 'la_event_user.forgotpw', 1);
INSERT INTO Events VALUES (DEFAULT, 'USER.PSWD', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.forgotpw', 0);
INSERT INTO Events VALUES (DEFAULT, 'USER.ADD.PENDING', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.add.pending', 0);
INSERT INTO Events VALUES (DEFAULT, 'USER.ADD.PENDING', NULL, 2, 0, 'In-Portal:Users', 'la_event_user.add.pending', 1);
INSERT INTO Events VALUES (DEFAULT, 'CATEGORY.ADD', NULL, 1, 0, 'In-Portal:Category', 'la_event_category.add', 0);
INSERT INTO Events VALUES (DEFAULT, 'CATEGORY.ADD.PENDING', NULL, 1, 0, 'In-Portal:Category', 'la_event_category.add.pending', 0);
INSERT INTO Events VALUES (DEFAULT, 'CATEGORY.ADD.PENDING', NULL, 2, 0, 'In-Portal:Category', 'la_event_category.add.pending', 1);
INSERT INTO Events VALUES (DEFAULT, 'CATEGORY.ADD', NULL, 2, 0, 'In-Portal:Category', 'la_event_category.add', 1);
INSERT INTO Events VALUES (DEFAULT, 'CATEGORY.DELETE', NULL, 1, 0, 'In-Portal:Category', 'la_event_category_delete', 0);
INSERT INTO Events VALUES (DEFAULT, 'CATEGORY.DELETE', NULL, 2, 0, 'In-Portal:Category', 'la_event_category_delete', 1);
INSERT INTO Events VALUES (DEFAULT, 'CATEGORY.MODIFY', NULL, 1, 0, 'In-Portal:Category', 'la_event_category.modify', 0);
INSERT INTO Events VALUES (DEFAULT, 'CATEGORY.MODIFY', NULL, 2, 0, 'In-Portal:Category', 'la_event_category.modify', 1);
INSERT INTO Events VALUES (DEFAULT, 'CATEGORY.APPROVE', NULL, 1, 0, 'In-Portal:Category', 'la_event_category.approve', 0);
INSERT INTO Events VALUES (DEFAULT, 'CATEGORY.APPROVE', NULL, 2, 0, 'In-Portal:Category', 'la_event_category.approve', 1);
INSERT INTO Events VALUES (DEFAULT, 'CATEGORY.DENY', NULL, 1, 0, 'In-Portal:Category', 'la_event_category.deny', 0);
INSERT INTO Events VALUES (DEFAULT, 'CATEGORY.DENY', NULL, 2, 0, 'In-Portal:Category', 'la_event_category.deny', 1);
INSERT INTO Events VALUES (DEFAULT, 'USER.SUBSCRIBE', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.subscribe', 0);
INSERT INTO Events VALUES (DEFAULT, 'USER.SUBSCRIBE', NULL, 2, 0, 'In-Portal:Users', 'la_event_user.subscribe', 1);
INSERT INTO Events VALUES (DEFAULT, 'USER.UNSUBSCRIBE', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.unsubscribe', 0);
INSERT INTO Events VALUES (DEFAULT, 'USER.UNSUBSCRIBE', NULL, 2, 0, 'In-Portal:Users', 'la_event_user.unsubscribe', 1);
INSERT INTO Events VALUES (DEFAULT, 'USER.SUGGEST', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.suggest', '0');
INSERT INTO Events VALUES (DEFAULT, 'USER.SUGGEST', NULL, 2, 0, 'In-Portal:Users', 'la_event_user.suggest', '1');
INSERT INTO Events VALUES (DEFAULT, 'USER.PSWDC', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.pswd_confirm', '0');
INSERT INTO Events VALUES (DEFAULT, 'USER.MEMBERSHIP.EXPIRED', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.membership_expired', '0');
INSERT INTO Events VALUES (DEFAULT, 'USER.MEMBERSHIP.EXPIRED', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.membership_expired', '1');
INSERT INTO Events VALUES (DEFAULT, 'USER.MEMBERSHIP.EXPIRATION.NOTICE', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.membership_expiration_notice', '0');
INSERT INTO Events VALUES (DEFAULT, 'USER.MEMBERSHIP.EXPIRATION.NOTICE', NULL, 1, 0, 'In-Portal:Users', 'la_event_user.membership_expiration_notice', '1');
INSERT INTO Events VALUES (DEFAULT, 'COMMON.FOOTER', NULL, 1, 0, 'In-Portal', 'la_event_common.footer', 1);
INSERT INTO IdGenerator VALUES ('100');
INSERT INTO PortalGroup VALUES (15, 'Everyone', 'Everyone', 0, 1, 0, 1, 15);
INSERT INTO PortalGroup VALUES (13, 'Member', '', '1054738682', 0, 0, 1, 13);
INSERT INTO PortalGroup VALUES (12, 'Subscribers', '', '1054738670', 0, 0, 1, 12);
INSERT INTO PortalGroup VALUES (14, 'Guest', 'Guest User', '0', 1, 0, 1, 14);
INSERT INTO PortalGroup VALUES (11, 'admin', '', '1054738405', 0, 0, 1, 11);
INSERT INTO StdDestinations VALUES (1, 1, DEFAULT, 'la_country_AFG', 'AFG', 'AF');
INSERT INTO StdDestinations VALUES (2, 1, DEFAULT, 'la_country_ALB', 'ALB', 'AL');
INSERT INTO StdDestinations VALUES (3, 1, DEFAULT, 'la_country_DZA', 'DZA', 'DZ');
INSERT INTO StdDestinations VALUES (4, 1, DEFAULT, 'la_country_ASM', 'ASM', 'AS');
INSERT INTO StdDestinations VALUES (5, 1, DEFAULT, 'la_country_AND', 'AND', 'AD');
INSERT INTO StdDestinations VALUES (6, 1, DEFAULT, 'la_country_AGO', 'AGO', 'AO');
INSERT INTO StdDestinations VALUES (7, 1, DEFAULT, 'la_country_AIA', 'AIA', 'AI');
INSERT INTO StdDestinations VALUES (8, 1, DEFAULT, 'la_country_ATA', 'ATA', 'AQ');
INSERT INTO StdDestinations VALUES (9, 1, DEFAULT, 'la_country_ATG', 'ATG', 'AG');
INSERT INTO StdDestinations VALUES (10, 1, DEFAULT, 'la_country_ARG', 'ARG', 'AR');
INSERT INTO StdDestinations VALUES (11, 1, DEFAULT, 'la_country_ARM', 'ARM', 'AM');
INSERT INTO StdDestinations VALUES (12, 1, DEFAULT, 'la_country_ABW', 'ABW', 'AW');
INSERT INTO StdDestinations VALUES (13, 1, DEFAULT, 'la_country_AUS', 'AUS', 'AU');
INSERT INTO StdDestinations VALUES (14, 1, DEFAULT, 'la_country_AUT', 'AUT', 'AT');
INSERT INTO StdDestinations VALUES (15, 1, DEFAULT, 'la_country_AZE', 'AZE', 'AZ');
INSERT INTO StdDestinations VALUES (16, 1, DEFAULT, 'la_country_BHS', 'BHS', 'BS');
INSERT INTO StdDestinations VALUES (17, 1, DEFAULT, 'la_country_BHR', 'BHR', 'BH');
INSERT INTO StdDestinations VALUES (18, 1, DEFAULT, 'la_country_BGD', 'BGD', 'BD');
INSERT INTO StdDestinations VALUES (19, 1, DEFAULT, 'la_country_BRB', 'BRB', 'BB');
INSERT INTO StdDestinations VALUES (20, 1, DEFAULT, 'la_country_BLR', 'BLR', 'BY');
INSERT INTO StdDestinations VALUES (21, 1, DEFAULT, 'la_country_BEL', 'BEL', 'BE');
INSERT INTO StdDestinations VALUES (22, 1, DEFAULT, 'la_country_BLZ', 'BLZ', 'BZ');
INSERT INTO StdDestinations VALUES (23, 1, DEFAULT, 'la_country_BEN', 'BEN', 'BJ');
INSERT INTO StdDestinations VALUES (24, 1, DEFAULT, 'la_country_BMU', 'BMU', 'BM');
INSERT INTO StdDestinations VALUES (25, 1, DEFAULT, 'la_country_BTN', 'BTN', 'BT');
INSERT INTO StdDestinations VALUES (26, 1, DEFAULT, 'la_country_BOL', 'BOL', 'BO');
INSERT INTO StdDestinations VALUES (27, 1, DEFAULT, 'la_country_BIH', 'BIH', 'BA');
INSERT INTO StdDestinations VALUES (28, 1, DEFAULT, 'la_country_BWA', 'BWA', 'BW');
INSERT INTO StdDestinations VALUES (29, 1, DEFAULT, 'la_country_BVT', 'BVT', 'BV');
INSERT INTO StdDestinations VALUES (30, 1, DEFAULT, 'la_country_BRA', 'BRA', 'BR');
INSERT INTO StdDestinations VALUES (31, 1, DEFAULT, 'la_country_IOT', 'IOT', 'IO');
INSERT INTO StdDestinations VALUES (32, 1, DEFAULT, 'la_country_BRN', 'BRN', 'BN');
INSERT INTO StdDestinations VALUES (33, 1, DEFAULT, 'la_country_BGR', 'BGR', 'BG');
INSERT INTO StdDestinations VALUES (34, 1, DEFAULT, 'la_country_BFA', 'BFA', 'BF');
INSERT INTO StdDestinations VALUES (35, 1, DEFAULT, 'la_country_BDI', 'BDI', 'BI');
INSERT INTO StdDestinations VALUES (36, 1, DEFAULT, 'la_country_KHM', 'KHM', 'KH');
INSERT INTO StdDestinations VALUES (37, 1, DEFAULT, 'la_country_CMR', 'CMR', 'CM');
INSERT INTO StdDestinations VALUES (38, 1, DEFAULT, 'la_country_CAN', 'CAN', 'CA');
INSERT INTO StdDestinations VALUES (39, 1, DEFAULT, 'la_country_CPV', 'CPV', 'CV');
INSERT INTO StdDestinations VALUES (40, 1, DEFAULT, 'la_country_CYM', 'CYM', 'KY');
INSERT INTO StdDestinations VALUES (41, 1, DEFAULT, 'la_country_CAF', 'CAF', 'CF');
INSERT INTO StdDestinations VALUES (42, 1, DEFAULT, 'la_country_TCD', 'TCD', 'TD');
INSERT INTO StdDestinations VALUES (43, 1, DEFAULT, 'la_country_CHL', 'CHL', 'CL');
INSERT INTO StdDestinations VALUES (44, 1, DEFAULT, 'la_country_CHN', 'CHN', 'CN');
INSERT INTO StdDestinations VALUES (45, 1, DEFAULT, 'la_country_CXR', 'CXR', 'CX');
INSERT INTO StdDestinations VALUES (46, 1, DEFAULT, 'la_country_CCK', 'CCK', 'CC');
INSERT INTO StdDestinations VALUES (47, 1, DEFAULT, 'la_country_COL', 'COL', 'CO');
INSERT INTO StdDestinations VALUES (48, 1, DEFAULT, 'la_country_COM', 'COM', 'KM');
INSERT INTO StdDestinations VALUES (49, 1, DEFAULT, 'la_country_COD', 'COD', 'CD');
INSERT INTO StdDestinations VALUES (50, 1, DEFAULT, 'la_country_COG', 'COG', 'CG');
INSERT INTO StdDestinations VALUES (51, 1, DEFAULT, 'la_country_COK', 'COK', 'CK');
INSERT INTO StdDestinations VALUES (52, 1, DEFAULT, 'la_country_CRI', 'CRI', 'CR');
INSERT INTO StdDestinations VALUES (53, 1, DEFAULT, 'la_country_CIV', 'CIV', 'CI');
INSERT INTO StdDestinations VALUES (54, 1, DEFAULT, 'la_country_HRV', 'HRV', 'HR');
INSERT INTO StdDestinations VALUES (55, 1, DEFAULT, 'la_country_CUB', 'CUB', 'CU');
INSERT INTO StdDestinations VALUES (56, 1, DEFAULT, 'la_country_CYP', 'CYP', 'CY');
INSERT INTO StdDestinations VALUES (57, 1, DEFAULT, 'la_country_CZE', 'CZE', 'CZ');
INSERT INTO StdDestinations VALUES (58, 1, DEFAULT, 'la_country_DNK', 'DNK', 'DK');
INSERT INTO StdDestinations VALUES (59, 1, DEFAULT, 'la_country_DJI', 'DJI', 'DJ');
INSERT INTO StdDestinations VALUES (60, 1, DEFAULT, 'la_country_DMA', 'DMA', 'DM');
INSERT INTO StdDestinations VALUES (61, 1, DEFAULT, 'la_country_DOM', 'DOM', 'DO');
INSERT INTO StdDestinations VALUES (62, 1, DEFAULT, 'la_country_TLS', 'TLS', 'TL');
INSERT INTO StdDestinations VALUES (63, 1, DEFAULT, 'la_country_ECU', 'ECU', 'EC');
INSERT INTO StdDestinations VALUES (64, 1, DEFAULT, 'la_country_EGY', 'EGY', 'EG');
INSERT INTO StdDestinations VALUES (65, 1, DEFAULT, 'la_country_SLV', 'SLV', 'SV');
INSERT INTO StdDestinations VALUES (66, 1, DEFAULT, 'la_country_GNQ', 'GNQ', 'GQ');
INSERT INTO StdDestinations VALUES (67, 1, DEFAULT, 'la_country_ERI', 'ERI', 'ER');
INSERT INTO StdDestinations VALUES (68, 1, DEFAULT, 'la_country_EST', 'EST', 'EE');
INSERT INTO StdDestinations VALUES (69, 1, DEFAULT, 'la_country_ETH', 'ETH', 'ET');
INSERT INTO StdDestinations VALUES (70, 1, DEFAULT, 'la_country_FLK', 'FLK', 'FK');
INSERT INTO StdDestinations VALUES (71, 1, DEFAULT, 'la_country_FRO', 'FRO', 'FO');
INSERT INTO StdDestinations VALUES (72, 1, DEFAULT, 'la_country_FJI', 'FJI', 'FJ');
INSERT INTO StdDestinations VALUES (73, 1, DEFAULT, 'la_country_FIN', 'FIN', 'FI');
INSERT INTO StdDestinations VALUES (74, 1, DEFAULT, 'la_country_FRA', 'FRA', 'FR');
INSERT INTO StdDestinations VALUES (75, 1, DEFAULT, 'la_country_FXX', 'FXX', 'FX');
INSERT INTO StdDestinations VALUES (76, 1, DEFAULT, 'la_country_GUF', 'GUF', 'GF');
INSERT INTO StdDestinations VALUES (77, 1, DEFAULT, 'la_country_PYF', 'PYF', 'PF');
INSERT INTO StdDestinations VALUES (78, 1, DEFAULT, 'la_country_ATF', 'ATF', 'TF');
INSERT INTO StdDestinations VALUES (79, 1, DEFAULT, 'la_country_GAB', 'GAB', 'GA');
INSERT INTO StdDestinations VALUES (80, 1, DEFAULT, 'la_country_GMB', 'GMB', 'GM');
INSERT INTO StdDestinations VALUES (81, 1, DEFAULT, 'la_country_GEO', 'GEO', 'GE');
INSERT INTO StdDestinations VALUES (82, 1, DEFAULT, 'la_country_DEU', 'DEU', 'DE');
INSERT INTO StdDestinations VALUES (83, 1, DEFAULT, 'la_country_GHA', 'GHA', 'GH');
INSERT INTO StdDestinations VALUES (84, 1, DEFAULT, 'la_country_GIB', 'GIB', 'GI');
INSERT INTO StdDestinations VALUES (85, 1, DEFAULT, 'la_country_GRC', 'GRC', 'GR');
INSERT INTO StdDestinations VALUES (86, 1, DEFAULT, 'la_country_GRL', 'GRL', 'GL');
INSERT INTO StdDestinations VALUES (87, 1, DEFAULT, 'la_country_GRD', 'GRD', 'GD');
INSERT INTO StdDestinations VALUES (88, 1, DEFAULT, 'la_country_GLP', 'GLP', 'GP');
INSERT INTO StdDestinations VALUES (89, 1, DEFAULT, 'la_country_GUM', 'GUM', 'GU');
INSERT INTO StdDestinations VALUES (90, 1, DEFAULT, 'la_country_GTM', 'GTM', 'GT');
INSERT INTO StdDestinations VALUES (91, 1, DEFAULT, 'la_country_GIN', 'GIN', 'GN');
INSERT INTO StdDestinations VALUES (92, 1, DEFAULT, 'la_country_GNB', 'GNB', 'GW');
INSERT INTO StdDestinations VALUES (93, 1, DEFAULT, 'la_country_GUY', 'GUY', 'GY');
INSERT INTO StdDestinations VALUES (94, 1, DEFAULT, 'la_country_HTI', 'HTI', 'HT');
INSERT INTO StdDestinations VALUES (95, 1, DEFAULT, 'la_country_HMD', 'HMD', 'HM');
INSERT INTO StdDestinations VALUES (96, 1, DEFAULT, 'la_country_HND', 'HND', 'HN');
INSERT INTO StdDestinations VALUES (97, 1, DEFAULT, 'la_country_HKG', 'HKG', 'HK');
INSERT INTO StdDestinations VALUES (98, 1, DEFAULT, 'la_country_HUN', 'HUN', 'HU');
INSERT INTO StdDestinations VALUES (99, 1, DEFAULT, 'la_country_ISL', 'ISL', 'IS');
INSERT INTO StdDestinations VALUES (100, 1, DEFAULT, 'la_country_IND', 'IND', 'IN');
INSERT INTO StdDestinations VALUES (101, 1, DEFAULT, 'la_country_IDN', 'IDN', 'ID');
INSERT INTO StdDestinations VALUES (102, 1, DEFAULT, 'la_country_IRN', 'IRN', 'IR');
INSERT INTO StdDestinations VALUES (103, 1, DEFAULT, 'la_country_IRQ', 'IRQ', 'IQ');
INSERT INTO StdDestinations VALUES (104, 1, DEFAULT, 'la_country_IRL', 'IRL', 'IE');
INSERT INTO StdDestinations VALUES (105, 1, DEFAULT, 'la_country_ISR', 'ISR', 'IL');
INSERT INTO StdDestinations VALUES (106, 1, DEFAULT, 'la_country_ITA', 'ITA', 'IT');
INSERT INTO StdDestinations VALUES (107, 1, DEFAULT, 'la_country_JAM', 'JAM', 'JM');
INSERT INTO StdDestinations VALUES (108, 1, DEFAULT, 'la_country_JPN', 'JPN', 'JP');
INSERT INTO StdDestinations VALUES (109, 1, DEFAULT, 'la_country_JOR', 'JOR', 'JO');
INSERT INTO StdDestinations VALUES (110, 1, DEFAULT, 'la_country_KAZ', 'KAZ', 'KZ');
INSERT INTO StdDestinations VALUES (111, 1, DEFAULT, 'la_country_KEN', 'KEN', 'KE');
INSERT INTO StdDestinations VALUES (112, 1, DEFAULT, 'la_country_KIR', 'KIR', 'KI');
INSERT INTO StdDestinations VALUES (113, 1, DEFAULT, 'la_country_PRK', 'PRK', 'KP');
INSERT INTO StdDestinations VALUES (114, 1, DEFAULT, 'la_country_KOR', 'KOR', 'KR');
INSERT INTO StdDestinations VALUES (115, 1, DEFAULT, 'la_country_KWT', 'KWT', 'KW');
INSERT INTO StdDestinations VALUES (116, 1, DEFAULT, 'la_country_KGZ', 'KGZ', 'KG');
INSERT INTO StdDestinations VALUES (117, 1, DEFAULT, 'la_country_LAO', 'LAO', 'LA');
INSERT INTO StdDestinations VALUES (118, 1, DEFAULT, 'la_country_LVA', 'LVA', 'LV');
INSERT INTO StdDestinations VALUES (119, 1, DEFAULT, 'la_country_LBN', 'LBN', 'LB');
INSERT INTO StdDestinations VALUES (120, 1, DEFAULT, 'la_country_LSO', 'LSO', 'LS');
INSERT INTO StdDestinations VALUES (121, 1, DEFAULT, 'la_country_LBR', 'LBR', 'LR');
INSERT INTO StdDestinations VALUES (122, 1, DEFAULT, 'la_country_LBY', 'LBY', 'LY');
INSERT INTO StdDestinations VALUES (123, 1, DEFAULT, 'la_country_LIE', 'LIE', 'LI');
INSERT INTO StdDestinations VALUES (124, 1, DEFAULT, 'la_country_LTU', 'LTU', 'LT');
INSERT INTO StdDestinations VALUES (125, 1, DEFAULT, 'la_country_LUX', 'LUX', 'LU');
INSERT INTO StdDestinations VALUES (126, 1, DEFAULT, 'la_country_MAC', 'MAC', 'MO');
INSERT INTO StdDestinations VALUES (127, 1, DEFAULT, 'la_country_MKD', 'MKD', 'MK');
INSERT INTO StdDestinations VALUES (128, 1, DEFAULT, 'la_country_MDG', 'MDG', 'MG');
INSERT INTO StdDestinations VALUES (129, 1, DEFAULT, 'la_country_MWI', 'MWI', 'MW');
INSERT INTO StdDestinations VALUES (130, 1, DEFAULT, 'la_country_MYS', 'MYS', 'MY');
INSERT INTO StdDestinations VALUES (131, 1, DEFAULT, 'la_country_MDV', 'MDV', 'MV');
INSERT INTO StdDestinations VALUES (132, 1, DEFAULT, 'la_country_MLI', 'MLI', 'ML');
INSERT INTO StdDestinations VALUES (133, 1, DEFAULT, 'la_country_MLT', 'MLT', 'MT');
INSERT INTO StdDestinations VALUES (134, 1, DEFAULT, 'la_country_MHL', 'MHL', 'MH');
INSERT INTO StdDestinations VALUES (135, 1, DEFAULT, 'la_country_MTQ', 'MTQ', 'MQ');
INSERT INTO StdDestinations VALUES (136, 1, DEFAULT, 'la_country_MRT', 'MRT', 'MR');
INSERT INTO StdDestinations VALUES (137, 1, DEFAULT, 'la_country_MUS', 'MUS', 'MU');
INSERT INTO StdDestinations VALUES (138, 1, DEFAULT, 'la_country_MYT', 'MYT', 'YT');
INSERT INTO StdDestinations VALUES (139, 1, DEFAULT, 'la_country_MEX', 'MEX', 'MX');
INSERT INTO StdDestinations VALUES (140, 1, DEFAULT, 'la_country_FSM', 'FSM', 'FM');
INSERT INTO StdDestinations VALUES (141, 1, DEFAULT, 'la_country_MDA', 'MDA', 'MD');
INSERT INTO StdDestinations VALUES (142, 1, DEFAULT, 'la_country_MCO', 'MCO', 'MC');
INSERT INTO StdDestinations VALUES (143, 1, DEFAULT, 'la_country_MNG', 'MNG', 'MN');
INSERT INTO StdDestinations VALUES (144, 1, DEFAULT, 'la_country_MSR', 'MSR', 'MS');
INSERT INTO StdDestinations VALUES (145, 1, DEFAULT, 'la_country_MAR', 'MAR', 'MA');
INSERT INTO StdDestinations VALUES (146, 1, DEFAULT, 'la_country_MOZ', 'MOZ', 'MZ');
INSERT INTO StdDestinations VALUES (147, 1, DEFAULT, 'la_country_MMR', 'MMR', 'MM');
INSERT INTO StdDestinations VALUES (148, 1, DEFAULT, 'la_country_NAM', 'NAM', 'NA');
INSERT INTO StdDestinations VALUES (149, 1, DEFAULT, 'la_country_NRU', 'NRU', 'NR');
INSERT INTO StdDestinations VALUES (150, 1, DEFAULT, 'la_country_NPL', 'NPL', 'NP');
INSERT INTO StdDestinations VALUES (151, 1, DEFAULT, 'la_country_NLD', 'NLD', 'NL');
INSERT INTO StdDestinations VALUES (152, 1, DEFAULT, 'la_country_ANT', 'ANT', 'AN');
INSERT INTO StdDestinations VALUES (153, 1, DEFAULT, 'la_country_NCL', 'NCL', 'NC');
INSERT INTO StdDestinations VALUES (154, 1, DEFAULT, 'la_country_NZL', 'NZL', 'NZ');
INSERT INTO StdDestinations VALUES (155, 1, DEFAULT, 'la_country_NIC', 'NIC', 'NI');
INSERT INTO StdDestinations VALUES (156, 1, DEFAULT, 'la_country_NER', 'NER', 'NE');
INSERT INTO StdDestinations VALUES (157, 1, DEFAULT, 'la_country_NGA', 'NGA', 'NG');
INSERT INTO StdDestinations VALUES (158, 1, DEFAULT, 'la_country_NIU', 'NIU', 'NU');
INSERT INTO StdDestinations VALUES (159, 1, DEFAULT, 'la_country_NFK', 'NFK', 'NF');
INSERT INTO StdDestinations VALUES (160, 1, DEFAULT, 'la_country_MNP', 'MNP', 'MP');
INSERT INTO StdDestinations VALUES (161, 1, DEFAULT, 'la_country_NOR', 'NOR', 'NO');
INSERT INTO StdDestinations VALUES (162, 1, DEFAULT, 'la_country_OMN', 'OMN', 'OM');
INSERT INTO StdDestinations VALUES (163, 1, DEFAULT, 'la_country_PAK', 'PAK', 'PK');
INSERT INTO StdDestinations VALUES (164, 1, DEFAULT, 'la_country_PLW', 'PLW', 'PW');
INSERT INTO StdDestinations VALUES (165, 1, DEFAULT, 'la_country_PSE', 'PSE', 'PS');
INSERT INTO StdDestinations VALUES (166, 1, DEFAULT, 'la_country_PAN', 'PAN', 'PA');
INSERT INTO StdDestinations VALUES (167, 1, DEFAULT, 'la_country_PNG', 'PNG', 'PG');
INSERT INTO StdDestinations VALUES (168, 1, DEFAULT, 'la_country_PRY', 'PRY', 'PY');
INSERT INTO StdDestinations VALUES (169, 1, DEFAULT, 'la_country_PER', 'PER', 'PE');
INSERT INTO StdDestinations VALUES (170, 1, DEFAULT, 'la_country_PHL', 'PHL', 'PH');
INSERT INTO StdDestinations VALUES (171, 1, DEFAULT, 'la_country_PCN', 'PCN', 'PN');
INSERT INTO StdDestinations VALUES (172, 1, DEFAULT, 'la_country_POL', 'POL', 'PL');
INSERT INTO StdDestinations VALUES (173, 1, DEFAULT, 'la_country_PRT', 'PRT', 'PT');
INSERT INTO StdDestinations VALUES (174, 1, DEFAULT, 'la_country_PRI', 'PRI', 'PR');
INSERT INTO StdDestinations VALUES (175, 1, DEFAULT, 'la_country_QAT', 'QAT', 'QA');
INSERT INTO StdDestinations VALUES (176, 1, DEFAULT, 'la_country_REU', 'REU', 'RE');
INSERT INTO StdDestinations VALUES (177, 1, DEFAULT, 'la_country_ROU', 'ROU', 'RO');
INSERT INTO StdDestinations VALUES (178, 1, DEFAULT, 'la_country_RUS', 'RUS', 'RU');
INSERT INTO StdDestinations VALUES (179, 1, DEFAULT, 'la_country_RWA', 'RWA', 'RW');
INSERT INTO StdDestinations VALUES (180, 1, DEFAULT, 'la_country_KNA', 'KNA', 'KN');
INSERT INTO StdDestinations VALUES (181, 1, DEFAULT, 'la_country_LCA', 'LCA', 'LC');
INSERT INTO StdDestinations VALUES (182, 1, DEFAULT, 'la_country_VCT', 'VCT', 'VC');
INSERT INTO StdDestinations VALUES (183, 1, DEFAULT, 'la_country_WSM', 'WSM', 'WS');
INSERT INTO StdDestinations VALUES (184, 1, DEFAULT, 'la_country_SMR', 'SMR', 'SM');
INSERT INTO StdDestinations VALUES (185, 1, DEFAULT, 'la_country_STP', 'STP', 'ST');
INSERT INTO StdDestinations VALUES (186, 1, DEFAULT, 'la_country_SAU', 'SAU', 'SA');
INSERT INTO StdDestinations VALUES (187, 1, DEFAULT, 'la_country_SEN', 'SEN', 'SN');
INSERT INTO StdDestinations VALUES (188, 1, DEFAULT, 'la_country_SYC', 'SYC', 'SC');
INSERT INTO StdDestinations VALUES (189, 1, DEFAULT, 'la_country_SLE', 'SLE', 'SL');
INSERT INTO StdDestinations VALUES (190, 1, DEFAULT, 'la_country_SGP', 'SGP', 'SG');
INSERT INTO StdDestinations VALUES (191, 1, DEFAULT, 'la_country_SVK', 'SVK', 'SK');
INSERT INTO StdDestinations VALUES (192, 1, DEFAULT, 'la_country_SVN', 'SVN', 'SI');
INSERT INTO StdDestinations VALUES (193, 1, DEFAULT, 'la_country_SLB', 'SLB', 'SB');
INSERT INTO StdDestinations VALUES (194, 1, DEFAULT, 'la_country_SOM', 'SOM', 'SO');
INSERT INTO StdDestinations VALUES (195, 1, DEFAULT, 'la_country_ZAF', 'ZAF', 'ZA');
INSERT INTO StdDestinations VALUES (196, 1, DEFAULT, 'la_country_SGS', 'SGS', 'GS');
INSERT INTO StdDestinations VALUES (197, 1, DEFAULT, 'la_country_ESP', 'ESP', 'ES');
INSERT INTO StdDestinations VALUES (198, 1, DEFAULT, 'la_country_LKA', 'LKA', 'LK');
INSERT INTO StdDestinations VALUES (199, 1, DEFAULT, 'la_country_SHN', 'SHN', 'SH');
INSERT INTO StdDestinations VALUES (200, 1, DEFAULT, 'la_country_SPM', 'SPM', 'PM');
INSERT INTO StdDestinations VALUES (201, 1, DEFAULT, 'la_country_SDN', 'SDN', 'SD');
INSERT INTO StdDestinations VALUES (202, 1, DEFAULT, 'la_country_SUR', 'SUR', 'SR');
INSERT INTO StdDestinations VALUES (203, 1, DEFAULT, 'la_country_SJM', 'SJM', 'SJ');
INSERT INTO StdDestinations VALUES (204, 1, DEFAULT, 'la_country_SWZ', 'SWZ', 'SZ');
INSERT INTO StdDestinations VALUES (205, 1, DEFAULT, 'la_country_SWE', 'SWE', 'SE');
INSERT INTO StdDestinations VALUES (206, 1, DEFAULT, 'la_country_CHE', 'CHE', 'CH');
INSERT INTO StdDestinations VALUES (207, 1, DEFAULT, 'la_country_SYR', 'SYR', 'SY');
INSERT INTO StdDestinations VALUES (208, 1, DEFAULT, 'la_country_TWN', 'TWN', 'TW');
INSERT INTO StdDestinations VALUES (209, 1, DEFAULT, 'la_country_TJK', 'TJK', 'TJ');
INSERT INTO StdDestinations VALUES (210, 1, DEFAULT, 'la_country_TZA', 'TZA', 'TZ');
INSERT INTO StdDestinations VALUES (211, 1, DEFAULT, 'la_country_THA', 'THA', 'TH');
INSERT INTO StdDestinations VALUES (212, 1, DEFAULT, 'la_country_TGO', 'TGO', 'TG');
INSERT INTO StdDestinations VALUES (213, 1, DEFAULT, 'la_country_TKL', 'TKL', 'TK');
INSERT INTO StdDestinations VALUES (214, 1, DEFAULT, 'la_country_TON', 'TON', 'TO');
INSERT INTO StdDestinations VALUES (215, 1, DEFAULT, 'la_country_TTO', 'TTO', 'TT');
INSERT INTO StdDestinations VALUES (216, 1, DEFAULT, 'la_country_TUN', 'TUN', 'TN');
INSERT INTO StdDestinations VALUES (217, 1, DEFAULT, 'la_country_TUR', 'TUR', 'TR');
INSERT INTO StdDestinations VALUES (218, 1, DEFAULT, 'la_country_TKM', 'TKM', 'TM');
INSERT INTO StdDestinations VALUES (219, 1, DEFAULT, 'la_country_TCA', 'TCA', 'TC');
INSERT INTO StdDestinations VALUES (220, 1, DEFAULT, 'la_country_TUV', 'TUV', 'TV');
INSERT INTO StdDestinations VALUES (221, 1, DEFAULT, 'la_country_UGA', 'UGA', 'UG');
INSERT INTO StdDestinations VALUES (222, 1, DEFAULT, 'la_country_UKR', 'UKR', 'UA');
INSERT INTO StdDestinations VALUES (223, 1, DEFAULT, 'la_country_ARE', 'ARE', 'AE');
INSERT INTO StdDestinations VALUES (224, 1, DEFAULT, 'la_country_GBR', 'GBR', 'GB');
INSERT INTO StdDestinations VALUES (225, 1, DEFAULT, 'la_country_USA', 'USA', 'US');
INSERT INTO StdDestinations VALUES (226, 1, DEFAULT, 'la_country_UMI', 'UMI', 'UM');
INSERT INTO StdDestinations VALUES (227, 1, DEFAULT, 'la_country_URY', 'URY', 'UY');
INSERT INTO StdDestinations VALUES (228, 1, DEFAULT, 'la_country_UZB', 'UZB', 'UZ');
INSERT INTO StdDestinations VALUES (229, 1, DEFAULT, 'la_country_VUT', 'VUT', 'VU');
INSERT INTO StdDestinations VALUES (230, 1, DEFAULT, 'la_country_VAT', 'VAT', 'VA');
INSERT INTO StdDestinations VALUES (231, 1, DEFAULT, 'la_country_VEN', 'VEN', 'VE');
INSERT INTO StdDestinations VALUES (232, 1, DEFAULT, 'la_country_VNM', 'VNM', 'VN');
INSERT INTO StdDestinations VALUES (233, 1, DEFAULT, 'la_country_VGB', 'VGB', 'VG');
INSERT INTO StdDestinations VALUES (234, 1, DEFAULT, 'la_country_VIR', 'VIR', 'VI');
INSERT INTO StdDestinations VALUES (235, 1, DEFAULT, 'la_country_WLF', 'WLF', 'WF');
INSERT INTO StdDestinations VALUES (236, 1, DEFAULT, 'la_country_ESH', 'ESH', 'EH');
INSERT INTO StdDestinations VALUES (237, 1, DEFAULT, 'la_country_YEM', 'YEM', 'YE');
INSERT INTO StdDestinations VALUES (238, 1, DEFAULT, 'la_country_YUG', 'YUG', 'YU');
INSERT INTO StdDestinations VALUES (239, 1, DEFAULT, 'la_country_ZMB', 'ZMB', 'ZM');
INSERT INTO StdDestinations VALUES (240, 1, DEFAULT, 'la_country_ZWE', 'ZWE', 'ZW');
INSERT INTO StdDestinations VALUES (370, 2, 38, 'la_state_YT', 'YT', DEFAULT);
INSERT INTO StdDestinations VALUES (369, 2, 38, 'la_state_SK', 'SK', DEFAULT);
INSERT INTO StdDestinations VALUES (368, 2, 38, 'la_state_QC', 'QC', DEFAULT);
INSERT INTO StdDestinations VALUES (367, 2, 38, 'la_state_PE', 'PE', DEFAULT);
INSERT INTO StdDestinations VALUES (366, 2, 38, 'la_state_ON', 'ON', DEFAULT);
INSERT INTO StdDestinations VALUES (365, 2, 38, 'la_state_NU', 'NU', DEFAULT);
INSERT INTO StdDestinations VALUES (364, 2, 38, 'la_state_NS', 'NS', DEFAULT);
INSERT INTO StdDestinations VALUES (363, 2, 38, 'la_state_NT', 'NT', DEFAULT);
INSERT INTO StdDestinations VALUES (362, 2, 38, 'la_state_NL', 'NL', DEFAULT);
INSERT INTO StdDestinations VALUES (361, 2, 38, 'la_state_NB', 'NB', DEFAULT);
INSERT INTO StdDestinations VALUES (360, 2, 38, 'la_state_MB', 'MB', DEFAULT);
INSERT INTO StdDestinations VALUES (359, 2, 38, 'la_state_BC', 'BC', DEFAULT);
INSERT INTO StdDestinations VALUES (358, 2, 38, 'la_state_AB', 'AB', DEFAULT);
INSERT INTO StdDestinations VALUES (357, 2, 225, 'la_state_DC', 'DC', DEFAULT);
INSERT INTO StdDestinations VALUES (356, 2, 225, 'la_state_WY', 'WY', DEFAULT);
INSERT INTO StdDestinations VALUES (355, 2, 225, 'la_state_WI', 'WI', DEFAULT);
INSERT INTO StdDestinations VALUES (354, 2, 225, 'la_state_WV', 'WV', DEFAULT);
INSERT INTO StdDestinations VALUES (353, 2, 225, 'la_state_WA', 'WA', DEFAULT);
INSERT INTO StdDestinations VALUES (352, 2, 225, 'la_state_VA', 'VA', DEFAULT);
INSERT INTO StdDestinations VALUES (351, 2, 225, 'la_state_VT', 'VT', DEFAULT);
INSERT INTO StdDestinations VALUES (350, 2, 225, 'la_state_UT', 'UT', DEFAULT);
INSERT INTO StdDestinations VALUES (349, 2, 225, 'la_state_TX', 'TX', DEFAULT);
INSERT INTO StdDestinations VALUES (348, 2, 225, 'la_state_TN', 'TN', DEFAULT);
INSERT INTO StdDestinations VALUES (347, 2, 225, 'la_state_SD', 'SD', DEFAULT);
INSERT INTO StdDestinations VALUES (346, 2, 225, 'la_state_SC', 'SC', DEFAULT);
INSERT INTO StdDestinations VALUES (345, 2, 225, 'la_state_RI', 'RI', DEFAULT);
INSERT INTO StdDestinations VALUES (344, 2, 225, 'la_state_PR', 'PR', DEFAULT);
INSERT INTO StdDestinations VALUES (343, 2, 225, 'la_state_PA', 'PA', DEFAULT);
INSERT INTO StdDestinations VALUES (342, 2, 225, 'la_state_OR', 'OR', DEFAULT);
INSERT INTO StdDestinations VALUES (341, 2, 225, 'la_state_OK', 'OK', DEFAULT);
INSERT INTO StdDestinations VALUES (340, 2, 225, 'la_state_OH', 'OH', DEFAULT);
INSERT INTO StdDestinations VALUES (339, 2, 225, 'la_state_ND', 'ND', DEFAULT);
INSERT INTO StdDestinations VALUES (338, 2, 225, 'la_state_NC', 'NC', DEFAULT);
INSERT INTO StdDestinations VALUES (337, 2, 225, 'la_state_NY', 'NY', DEFAULT);
INSERT INTO StdDestinations VALUES (336, 2, 225, 'la_state_NM', 'NM', DEFAULT);
INSERT INTO StdDestinations VALUES (335, 2, 225, 'la_state_NJ', 'NJ', DEFAULT);
INSERT INTO StdDestinations VALUES (334, 2, 225, 'la_state_NH', 'NH', DEFAULT);
INSERT INTO StdDestinations VALUES (333, 2, 225, 'la_state_NV', 'NV', DEFAULT);
INSERT INTO StdDestinations VALUES (332, 2, 225, 'la_state_NE', 'NE', DEFAULT);
INSERT INTO StdDestinations VALUES (331, 2, 225, 'la_state_MT', 'MT', DEFAULT);
INSERT INTO StdDestinations VALUES (330, 2, 225, 'la_state_MO', 'MO', DEFAULT);
INSERT INTO StdDestinations VALUES (329, 2, 225, 'la_state_MS', 'MS', DEFAULT);
INSERT INTO StdDestinations VALUES (328, 2, 225, 'la_state_MN', 'MN', DEFAULT);
INSERT INTO StdDestinations VALUES (327, 2, 225, 'la_state_MI', 'MI', DEFAULT);
INSERT INTO StdDestinations VALUES (326, 2, 225, 'la_state_MA', 'MA', DEFAULT);
INSERT INTO StdDestinations VALUES (325, 2, 225, 'la_state_MD', 'MD', DEFAULT);
INSERT INTO StdDestinations VALUES (324, 2, 225, 'la_state_ME', 'ME', DEFAULT);
INSERT INTO StdDestinations VALUES (323, 2, 225, 'la_state_LA', 'LA', DEFAULT);
INSERT INTO StdDestinations VALUES (322, 2, 225, 'la_state_KY', 'KY', DEFAULT);
INSERT INTO StdDestinations VALUES (321, 2, 225, 'la_state_KS', 'KS', DEFAULT);
INSERT INTO StdDestinations VALUES (320, 2, 225, 'la_state_IA', 'IA', DEFAULT);
INSERT INTO StdDestinations VALUES (319, 2, 225, 'la_state_IN', 'IN', DEFAULT);
INSERT INTO StdDestinations VALUES (318, 2, 225, 'la_state_IL', 'IL', DEFAULT);
INSERT INTO StdDestinations VALUES (317, 2, 225, 'la_state_ID', 'ID', DEFAULT);
INSERT INTO StdDestinations VALUES (316, 2, 225, 'la_state_HI', 'HI', DEFAULT);
INSERT INTO StdDestinations VALUES (315, 2, 225, 'la_state_GA', 'GA', DEFAULT);
INSERT INTO StdDestinations VALUES (314, 2, 225, 'la_state_FL', 'FL', DEFAULT);
INSERT INTO StdDestinations VALUES (313, 2, 225, 'la_state_DE', 'DE', DEFAULT);
INSERT INTO StdDestinations VALUES (312, 2, 225, 'la_state_CT', 'CT', DEFAULT);
INSERT INTO StdDestinations VALUES (311, 2, 225, 'la_state_CO', 'CO', DEFAULT);
INSERT INTO StdDestinations VALUES (310, 2, 225, 'la_state_CA', 'CA', DEFAULT);
INSERT INTO StdDestinations VALUES (309, 2, 225, 'la_state_AR', 'AR', DEFAULT);
INSERT INTO StdDestinations VALUES (308, 2, 225, 'la_state_AZ', 'AZ', DEFAULT);
INSERT INTO StdDestinations VALUES (307, 2, 225, 'la_state_AK', 'AK', DEFAULT);
INSERT INTO StdDestinations VALUES (306, 2, 225, 'la_state_AL', 'AL', DEFAULT);
INSERT INTO PermissionConfig VALUES (DEFAULT, 'CATEGORY.VIEW', 'lu_PermName_Category.View_desc', 'lu_PermName_Category.View_error', 'In-Portal');
INSERT INTO PermCache VALUES (DEFAULT, 0, 1, '11,12,13,14,15');
INSERT INTO Permissions VALUES (DEFAULT, 'LOGIN', 13, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'LOGIN', 11, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'ADMIN', 11, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:root.view', 11, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:system.view', 11, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:user_list.view', 11, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:user_list.add', 11, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:user_list.edit', 11, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:user_list.delete', 11, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:configure_lang.view', 11, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:configure_lang.add', 11, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:configure_lang.edit', 11, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:configure_lang.delete', 11, 1, 1, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'CATEGORY.VIEW', 11, 1, 0, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'CATEGORY.ADD', 11, 1, 0, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'CATEGORY.DELETE', 11, 1, 0, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'CATEGORY.MODIFY', 11, 1, 0, 0);
INSERT INTO Permissions VALUES (DEFAULT, 'in-portal:service.view', 11, 1, 1, 0);
INSERT INTO Skins VALUES (DEFAULT, 'Default', '/* General elements */\r\n\r\nhtml {\r\n height: 100%;\r\n}\r\n\r\nbody {\r\n font-family: verdana,arial,helvetica,sans-serif;\r\n font-size: 9pt;\r\n color: #000000;\r\n overflow-x: auto; overflow-y: auto;\r\n margin: 0px 0px 0px 0px;\r\n text-decoration: none;\r\n}\r\n\r\na {\r\n color: #006699;\r\n text-decoration: none;\r\n}\r\n\r\na:hover {\r\n color: #009ff0;\r\n text-decoration: none;\r\n}\r\n\r\nform {\r\n display: inline;\r\n}\r\n\r\nimg { border: 0px; }\r\n\r\nbody.height-100 {\r\n height: 100%;\r\n}\r\n\r\nbody.regular-body {\r\n margin: 0px 10px 5px 10px;\r\n color: #000000;\r\n background-color: @@SectionBgColor@@;\r\n}\r\n\r\nbody.edit-popup {\r\n margin: 0px 0px 0px 0px;\r\n}\r\n\r\ntable.collapsed {\r\n border-collapse: collapse;\r\n}\r\n\r\n.bordered, table.bordered, .bordered-no-bottom {\r\n border: 1px solid #000000;\r\n border-collapse: collapse;\r\n}\r\n\r\n.bordered-no-bottom {\r\n border-bottom: none;\r\n}\r\n\r\n.login-table td {\r\n padding: 1px;\r\n}\r\n\r\n.disabled {\r\n background-color: #ebebeb;\r\n}\r\n\r\n/* Head frame */\r\n.head-table tr td {\r\n background-color: @@HeadBgColor@@;\r\n color: @@HeadColor@@\r\n}\r\n\r\ntd.kx-block-header, .head-table tr td.kx-block-header{\r\n color: @@HeadBarColor@@;\r\n background-color: @@HeadBarBgColor@@;\r\n padding-left: 7px;\r\n padding-right: 7px;\r\n}\r\n\r\na.kx-header-link {\r\n text-decoration: underline;\r\n color: #FFFFFF;\r\n}\r\n\r\na.kx-header-link:hover {\r\n color: #FFCB05;\r\n text-decoration: none;\r\n}\r\n\r\n.kx-secondary-foreground {\r\n color: @@HeadBarColor@@;\r\n background-color: @@HeadBarBgColor@@;\r\n}\r\n\r\n.kx-login-button {\r\n background-color: #2D79D6;\r\n color: #FFFFFF;\r\n}\r\n\r\n/* General form button (yellow) */\r\n.button {\r\n font-size: 12px;\r\n font-weight: normal;\r\n color: #000000;\r\n background: url(@@base_url@@/proj-base/admin_templates/img/button_back.gif) #f9eeae repeat-x;\r\n text-decoration: none;\r\n}\r\n\r\n/* Disabled (grayed-out) form button */\r\n.button-disabled {\r\n font-size: 12px;\r\n font-weight: normal;\r\n color: #676767;\r\n background: url(@@base_url@@/proj-base/admin_templates/img/button_back_disabled.gif) #f9eeae repeat-x;\r\n text-decoration: none;\r\n}\r\n\r\n/* Tabs bar */\r\n\r\n.tab, .tab-active {\r\n background-color: #F0F1EB;\r\n padding: 3px 7px 2px 7px;\r\n border-top: 1px solid black;\r\n border-left: 1px solid black;\r\n border-right: 1px solid black;\r\n}\r\n\r\n.tab-active {\r\n background-color: #2D79D6;\r\n border-bottom: 1px solid #2D79D6;\r\n}\r\n\r\n.tab a {\r\n color: #00659C;\r\n font-weight: bold;\r\n}\r\n\r\n.tab-active a {\r\n color: #fff;\r\n font-weight: bold;\r\n}\r\n\r\n\r\n/* Toolbar */\r\n\r\n.toolbar {\r\n font-size: 8pt;\r\n border: 1px solid #000000;\r\n border-width: 0px 1px 1px 1px;\r\n background-color: @@ToolbarBgColor@@;\r\n border-collapse: collapse;\r\n}\r\n\r\n.toolbar td {\r\n height: 100%;\r\n}\r\n\r\n.toolbar-button, .toolbar-button-disabled, .toolbar-button-over {\r\n float: left;\r\n text-align: center;\r\n font-size: 8pt;\r\n padding: 5px 5px 5px 5px;\r\n vertical-align: middle;\r\n color: #006F99;\r\n}\r\n\r\n.toolbar-button-over {\r\n color: #000;\r\n}\r\n\r\n.toolbar-button-disabled {\r\n color: #444;\r\n}\r\n\r\n/* Scrollable Grids */\r\n\r\n\r\n/* Main Grid class */\r\n.grid-scrollable {\r\n padding: 0px;\r\n border: 1px solid black !important;\r\n border-top: none !important;\r\n}\r\n\r\n/* Div generated by js, which contains all the scrollable grid elements, affects the style of scrollable area without data (if there are too few rows) */\r\n.grid-container {\r\n background-color: #fff;\r\n}\r\n\r\n.grid-container table {\r\n border-collapse: collapse;\r\n}\r\n\r\n/* Inner div generated in each data-cell */\r\n.grid-cell-div {\r\n overflow: hidden;\r\n height: auto;\r\n}\r\n\r\n/* Main row definition */\r\n.grid-data-row td, .grid-data-row-selected td, .grid-data-row-even-selected td, .grid-data-row-mouseover td, .table-color1, .table-color2 {\r\n font-weight: normal;\r\n color: @@OddColor@@;\r\n background-color: @@OddBgColor@@;\r\n padding: 3px 5px 3px 5px;\r\n height: 30px;\r\n overflow: hidden;\r\n /* border-right: 1px solid black; */\r\n}\r\n.grid-data-row-even td, .table-color2 {\r\n background-color: @@EvenBgColor@@;\r\n color: @@EvenColor@@;\r\n}\r\n.grid-data-row td a, .grid-data-row-selected td a, .grid-data-row-mouseover td a {\r\n text-decoration: underline;\r\n}\r\n\r\n/* mouse-over rows */\r\n.grid-data-row-mouseover td {\r\n background: #FFFDF4;\r\n}\r\n\r\n/* Selected row, applies to both checkbox and data areas */\r\n.grid-data-row-selected td {\r\n background: #FEF2D6;\r\n}\r\n\r\n.grid-data-row-even-selected td {\r\n background: #FFF7E0;\r\n}\r\n\r\n/* General header cell definition */\r\n.grid-header-row td {\r\n font-weight: bold;\r\n background-color: @@ColumnTitlesBgColor@@;\r\n text-decoration: none;\r\n padding: 3px 5px 3px 5px;\r\n color: @@ColumnTitlesColor@@;\r\n border-right: none;\r\n text-align: left;\r\n vertical-align: middle !important;\r\n white-space: nowrap;\r\n /* border-right: 1px solid black; */\r\n}\r\n\r\n/* Filters row */\r\ntr.grid-header-row-0 td {\r\n background-color: @@FiltersBgColor@@;\r\n border-bottom: 1px solid black;\r\n}\r\n\r\n/* Grid Filters */\r\ntable.range-filter {\r\n width: 100%;\r\n}\r\n\r\n.range-filter td {\r\n padding: 0px 0px 2px 2px !important;\r\n border: none !important;\r\n font-size: 8pt !important;\r\n font-weight: normal !important;\r\n text-align: left;\r\n color: #000000 !important;\r\n}\r\n\r\ninput.filter, select.filter {\r\n margin-bottom: 0px;\r\n width: 85%;\r\n}\r\n\r\ninput.filter-active {\r\n background-color: #FFFF00;\r\n}\r\n\r\nselect.filter-active {\r\n background-color: #FFFF00;\r\n}\r\n\r\n/* Column titles row */\r\ntr.grid-header-row-1 td {\r\n height: 25px;\r\n font-weight: bold;\r\n background-color: @@ColumnTitlesBgColor@@;\r\n color: @@ColumnTitlesColor@@;\r\n}\r\n\r\ntr.grid-header-row-1 td a {\r\n color: @@ColumnTitlesColor@@;\r\n}\r\n\r\ntr.grid-header-row-1 td a:hover {\r\n color: #FFCC00;\r\n}\r\n\r\n\r\n.grid-footer-row td {\r\n background-color: #D7D7D7;\r\n font-weight: bold;\r\n border-right: none;\r\n padding: 3px 5px 3px 5px;\r\n}\r\n\r\ntd.grid-header-last-cell, td.grid-data-last-cell, td.grid-footer-last-cell {\r\n border-right: none !important;\r\n}\r\n\r\ntd.grid-data-col-0, td.grid-data-col-0 div {\r\n text-align: center;\r\n vertical-align: middle !important;\r\n}\r\n\r\ntr.grid-header-row-0 td.grid-header-col-0 {\r\n text-align: center;\r\n vertical-align: middle !important;\r\n}\r\n\r\ntr.grid-header-row-0 td.grid-header-col-0 div {\r\n display: table-cell;\r\n vertical-align: middle;\r\n}\r\n\r\n.grid-status-bar {\r\n border: 1px solid black;\r\n border-top: none;\r\n padding: 0px;\r\n width: 100%;\r\n border-collapse: collapse;\r\n height: 30px;\r\n}\r\n\r\n.grid-status-bar td {\r\n background-color: @@TitleBarBgColor@@;\r\n color: @@TitleBarColor@@;\r\n font-size: 11pt;\r\n font-weight: normal;\r\n padding: 2px 8px 2px 8px;\r\n}\r\n\r\n/* /Scrollable Grids */\r\n\r\n\r\n/* Forms */\r\ntable.edit-form {\r\n border: none;\r\n border-top-width: 0px;\r\n border-collapse: collapse;\r\n width: 100%;\r\n}\r\n\r\n.edit-form-odd, .edit-form-even {\r\n padding: 0px;\r\n}\r\n\r\n.subsectiontitle {\r\n font-size: 10pt;\r\n font-weight: bold;\r\n background-color: #4A92CE;\r\n color: #fff;\r\n height: 25px;\r\n border-top: 1px solid black;\r\n}\r\n\r\n.label-cell {\r\n background: #DEE7F6 url(@@base_url@@/proj-base/admin_templates/img/bgr_input_name_line.gif) no-repeat right bottom;\r\n font: 12px arial, sans-serif;\r\n padding: 4px 20px;\r\n width: 150px;\r\n}\r\n\r\n.control-mid {\r\n width: 13px;\r\n border-left: 1px solid #7A95C2;\r\n background: #fff url(@@base_url@@/proj-base/admin_templates/img/bgr_mid.gif) repeat-x left bottom;\r\n}\r\n\r\n.control-cell {\r\n font: 11px arial, sans-serif;\r\n padding: 4px 10px 5px 5px;\r\n background: #fff url(@@base_url@@/proj-base/admin_templates/img/bgr_input_line.gif) no-repeat left bottom;\r\n width: auto;\r\n vertical-align: middle;\r\n}\r\n\r\n.label-cell-filler {\r\n background: #DEE7F6 none;\r\n}\r\n.control-mid-filler {\r\n background: #fff none;\r\n border-left: 1px solid #7A95C2;\r\n}\r\n.control-cell-filler {\r\n background: #fff none;\r\n}\r\n\r\n.error {\r\n color: red;\r\n}\r\n\r\n.error-cell {\r\n background-color: #fff;\r\n color: red;\r\n}\r\n\r\n.form-warning {\r\n color: red;\r\n}\r\n\r\n.req-note {\r\n font-style: italic;\r\n color: #333;\r\n}\r\n\r\n#scroll_container table.tableborder {\r\n border-collapse: separate\r\n}\r\n\r\n\r\n/* Uploader */\r\n\r\n.uploader-main {\r\n position: absolute;\r\n display: none;\r\n z-index: 10;\r\n border: 1px solid #777;\r\n padding: 10px;\r\n width: 350px;\r\n height: 120px;\r\n overflow: hidden;\r\n background-color: #fff;\r\n}\r\n\r\n.uploader-percent {\r\n width: 100%;\r\n padding-top: 3px;\r\n text-align: center;\r\n position: relative;\r\n z-index: 20;\r\n float: left;\r\n font-weight: bold;\r\n}\r\n\r\n.uploader-left {\r\n width: 100%;\r\n border: 1px solid black;\r\n height: 20px;\r\n background: #fff url(@@base_url@@/core/admin_templates/img/progress_left.gif);\r\n}\r\n\r\n.uploader-done {\r\n width: 0%;\r\n background-color: green;\r\n height: 20px;\r\n background: #4A92CE url(@@base_url@@/core/admin_templates/img/progress_done.gif);\r\n}\r\n\r\n\r\n/* To be sorted */\r\n\r\n\r\n/* Section title, right to the big icon */\r\n.admintitle {\r\n font-size: 16pt;\r\n font-weight: bold;\r\n color: @@SectionColor@@;\r\n text-decoration: none;\r\n}\r\n\r\n/* Left sid of bluebar */\r\n.header_left_bg {\r\n background-color: @@TitleBarBgColor@@;\r\n background-image: none;\r\n padding-left: 5px;\r\n}\r\n\r\n/* Right side of bluebar */\r\n.tablenav, tablenav a {\r\n font-size: 11pt;\r\n font-weight: bold;\r\n color: @@TitleBarColor@@;\r\n\r\n text-decoration: none;\r\n background-color: @@TitleBarBgColor@@;\r\n background-image: none;\r\n}\r\n\r\n/* Section title in the bluebar * -- why ''link''? :S */\r\n.tablenav_link {\r\n font-size: 11pt;\r\n font-weight: bold;\r\n color: @@TitleBarColor@@;\r\n text-decoration: none;\r\n}\r\n\r\n/* Active page in top and bottom bluebars pagination */\r\n.current_page {\r\n font-size: 10pt;\r\n font-weight: bold;\r\n background-color: #fff;\r\n color: #2D79D6;\r\n padding: 3px 2px 3px 3px;\r\n}\r\n\r\n/* Other pages and arrows in pagination on blue */\r\n.nav_url {\r\n font-size: 10pt;\r\n font-weight: bold;\r\n color: #fff;\r\n padding: 3px 2px 3px 3px;\r\n}\r\n\r\n/* Tree */\r\n.tree-body {\r\n background-color: @@TreeBgColor@@;\r\n height: 100%\r\n}\r\n\r\n.tree_head.td, .tree_head, .tree_head:hover {\r\n font-weight: bold;\r\n font-size: 10px;\r\n color: #FFFFFF;\r\n font-family: Verdana, Arial;\r\n text-decoration: none;\r\n}\r\n\r\n.tree {\r\n padding: 0px;\r\n border: none;\r\n border-collapse: collapse;\r\n}\r\n\r\n.tree tr td {\r\n padding: 0px;\r\n margin: 0px;\r\n font-family: helvetica, arial, verdana,;\r\n font-size: 11px;\r\n white-space: nowrap;\r\n}\r\n\r\n.tree tr td a {\r\n font-size: 11px;\r\n color: @@TreeColor@@;\r\n font-family: Helvetica, Arial, Verdana;\r\n text-decoration: none;\r\n padding: 2px 0px 2px 2px;\r\n}\r\n\r\n.tree tr.highlighted td a {\r\n background-color: @@TreeHighBgColor@@;\r\n color: @@TreeHighColor@@;\r\n}\r\n\r\n.tree tr.highlighted td a:hover {\r\n color: #fff;\r\n}\r\n\r\n.tree tr td a:hover {\r\n color: #000000;\r\n}', 'just_logo.gif', 'a:20:{s:11:"HeadBgColor";a:2:{s:11:"Description";s:27:"Head frame background color";s:5:"Value";s:7:"#1961B8";}s:9:"HeadColor";a:2:{s:11:"Description";s:21:"Head frame text color";s:5:"Value";s:7:"#CCFF00";}s:14:"SectionBgColor";a:2:{s:11:"Description";s:28:"Section bar background color";s:5:"Value";s:7:"#FFFFFF";}s:12:"SectionColor";a:2:{s:11:"Description";s:22:"Section bar text color";s:5:"Value";s:7:"#2D79D6";}s:12:"HeadBarColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:14:"HeadBarBgColor";a:1:{s:5:"Value";s:7:"#1961B8";}s:13:"TitleBarColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:15:"TitleBarBgColor";a:1:{s:5:"Value";s:7:"#2D79D6";}s:14:"ToolbarBgColor";a:1:{s:5:"Value";s:7:"#F0F1EB";}s:14:"FiltersBgColor";a:1:{s:5:"Value";s:7:"#D7D7D7";}s:17:"ColumnTitlesColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:19:"ColumnTitlesBgColor";a:1:{s:5:"Value";s:7:"#999999";}s:8:"OddColor";a:1:{s:5:"Value";s:7:"#000000";}s:10:"OddBgColor";a:1:{s:5:"Value";s:7:"#F6F6F6";}s:9:"EvenColor";a:1:{s:5:"Value";s:7:"#000000";}s:11:"EvenBgColor";a:1:{s:5:"Value";s:7:"#EBEBEB";}s:9:"TreeColor";a:1:{s:5:"Value";s:7:"#006F99";}s:11:"TreeBgColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:13:"TreeHighColor";a:1:{s:5:"Value";s:7:"#FFFFFF";}s:15:"TreeHighBgColor";a:1:{s:5:"Value";s:7:"#4A92CE";}}', 1183202859, 1);
INSERT INTO Modules VALUES ('Core', 'core/', 'adm', DEFAULT, 1, 1, '', 0, '0');
Property changes on: branches/RC/core/install/install_data.sql
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.10.2.9
\ No newline at end of property
+1.10.2.10
\ No newline at end of property

Event Timeline