Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Tue, Jun 24, 11:27 PM

in-portal

Index: branches/unlabeled/unlabeled-1.23.2/kernel/units/visits/visits_config.php
===================================================================
--- branches/unlabeled/unlabeled-1.23.2/kernel/units/visits/visits_config.php (nonexistent)
+++ branches/unlabeled/unlabeled-1.23.2/kernel/units/visits/visits_config.php (revision 7645)
@@ -0,0 +1,140 @@
+<?php
+
+$config = Array(
+ 'Prefix' => 'visits',
+ 'ItemClass' => Array('class'=>'kDBItem','file'=>'','build_event'=>'OnItemBuild'),
+ 'ListClass' => Array('class'=>'VisitsList','file'=>'visits_list.php','build_event'=>'OnListBuild'),
+ 'EventHandlerClass' => Array('class'=>'VisitsEventHandler','file'=>'visits_event_handler.php','build_event'=>'OnBuild'),
+ 'TagProcessorClass' => Array('class'=>'VisitsTagProcessor','file'=>'visits_tag_processor.php','build_event'=>'OnBuild'),
+ 'AutoLoad' => true,
+
+ 'QueryString' => Array(
+ 1 => 'id',
+ 2 => 'Page',
+ 3 => 'event',
+ 4 => 'mode',
+ ),
+
+ 'Hooks' => Array(
+ Array(
+ 'Mode' => hBEFORE,
+ 'Conditional' => false,
+ 'HookToPrefix' => 'adm',
+ 'HookToSpecial' => '',
+ 'HookToEvent' => Array( 'OnStartup' ),
+ 'DoPrefix' => '',
+ 'DoSpecial' => '',
+ 'DoEvent' => 'OnRegisterVisit',
+ ),
+
+ Array(
+ 'Mode' => hAFTER,
+ 'Conditional' => false,
+ 'HookToPrefix' => 'u',
+ 'HookToSpecial' => '*',
+ 'HookToEvent' => Array( 'OnLogin' ),
+ 'DoPrefix' => '',
+ 'DoSpecial' => '',
+ 'DoEvent' => 'OnUserLogin',
+ ),
+ ),
+
+ 'IDField' => 'VisitId',
+ 'TableName' => TABLE_PREFIX.'Visits',
+ 'TitlePresets' => Array(
+ 'default' => Array(),
+ 'visits_list' => Array('prefixes' => Array('visits_List'), 'format' => "!la_title_Visits! (#visits_recordcount#)"),
+ 'visits.incommerce_list' => Array('prefixes' => Array('visits.incommerce_List'), 'format' => "!la_title_Visits! (#visits.incommerce_recordcount#)"),
+ ),
+ 'CalculatedFields' => Array(
+ '' => Array (
+ 'UserName' => 'IF( ISNULL(u.Login), IF (%1$s.PortalUserId = -1, \'root\', IF (%1$s.PortalUserId = -2, \'Guest\', \'n/a\')), u.Login)',
+ ),
+ 'incommerce' => Array (
+ 'UserName' => 'IF( ISNULL(u.Login), IF (%1$s.PortalUserId = -1, \'root\', IF (%1$s.PortalUserId = -2, \'Guest\', \'n/a\')), u.Login)',
+ 'AffiliateUser' => 'IF( LENGTH(au.Login),au.Login,\'!la_None!\')',
+ 'AffiliatePortalUserId' => 'af.PortalUserId',
+ 'OrderTotalAmount' => 'IF(ord.Status = 4, ord.SubTotal+ord.ShippingCost+ord.VAT, 0)',
+ 'OrderAffiliateCommission' => 'IF(ord.Status = 4, ord.AffiliateCommission, 0)',
+ 'OrderNumber' => 'CONCAT(LPAD(Number,6,"0"),\'-\',LPAD(SubNumber,3,"0") )',
+ 'OrderId' => 'ord.OrderId',
+ ),
+ ),
+
+ 'ListSQLs' => Array( ''=>' SELECT %1$s.* %2$s
+ FROM %1$s
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser u ON %1$s.PortalUserId = u.PortalUserId',
+ 'incommerce'=>'
+ SELECT %1$s.* %2$s
+ FROM %1$s
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser u ON %1$s.PortalUserId = u.PortalUserId
+ LEFT JOIN '.TABLE_PREFIX.'Affiliates af ON %1$s.AffiliateId = af.AffiliateId
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser au ON af.PortalUserId = au.PortalUserId
+ LEFT JOIN '.TABLE_PREFIX.'Orders ord ON %1$s.VisitId = ord.VisitId',
+ ),
+
+
+ 'ItemSQLs' => Array( ''=>' SELECT %1$s.* %2$s
+ FROM %1$s
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser u ON %1$s.PortalUserId = u.PortalUserId',
+ 'incommerce'=>' SELECT %1$s.* %2$s
+ FROM %1$s
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser u ON %1$s.PortalUserId = u.PortalUserId
+ LEFT JOIN '.TABLE_PREFIX.'Affiliates af ON %1$s.AffiliateId = af.AffiliateId
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser au ON af.PortalUserId = au.PortalUserId
+ LEFT JOIN '.TABLE_PREFIX.'Orders ord ON %1$s.VisitId = ord.VisitId',
+ ),
+
+ 'ListSortings' => Array(
+ '' => Array(
+ 'Sorting' => Array('VisitDate' => 'desc'),
+ )
+ ),
+
+ 'Fields' => Array(
+ 'VisitId' => Array('type' => 'int'),
+ 'VisitDate' => Array('type' => 'int', 'formatter'=>'kDateFormatter', 'custom_filter' => 'date_range', 'not_null' => '1','default' => '0'),
+ 'Referer' => Array('type' => 'string','not_null' => '1','default' => ''),
+ 'IPAddress' => Array('type' => 'string','not_null' => '1','default' => ''),
+ 'AffiliateId' => Array('type'=>'int','formatter'=>'kLEFTFormatter','options'=>Array(0=>'lu_none'),'left_sql'=>'SELECT %s FROM '.TABLE_PREFIX.'Affiliates af LEFT JOIN '.TABLE_PREFIX.'PortalUser pu ON pu.PortalUserId = af.PortalUserId WHERE `%s` = \'%s\'','left_key_field'=>'AffiliateId','left_title_field'=>'Login','not_null'=>1,'default'=>0),
+ 'PortalUserId' => Array('type' => 'int','not_null' => '1','default' => -2),
+ ),
+
+ 'VirtualFields' => Array(
+ 'UserName' => Array('type'=>'string'),
+ 'AffiliateUser' => Array('type'=>'string'),
+ 'AffiliatePortalUserId' => Array('type'=>'int'),
+ 'OrderTotalAmount' => Array('type' => 'float', 'formatter'=>'kFormatter', 'format'=>'%01.2f', 'not_null' => '1','default' => '0.00', 'totals' => 'SUM'),
+ 'OrderTotalAmountSum' => Array('type' => 'float', 'formatter'=>'kFormatter', 'format'=>'%01.2f', 'not_null' => '1','default' => '0.00'),
+ 'OrderAffiliateCommission' => Array('type' => 'double', 'formatter'=>'kFormatter','format'=>'%.02f', 'not_null' => '1','default' => '0.0000', 'totals' => 'SUM'),
+ 'OrderAffiliateCommissionSum' => Array('type' => 'double', 'formatter'=>'kFormatter','format'=>'%.02f', 'not_null' => '1','default' => '0.0000'),
+ 'OrderId' => Array('type' => 'int', 'default' => '0'),
+ ),
+
+ 'Grids' => Array(
+ 'Default' => Array(
+ 'Icons' => Array('default'=>'icon16_custom.gif'), // icons for each StatusField values, if no matches or no statusfield selected, then "default" icon is used
+ 'Fields' => Array(
+ 'VisitDate' => Array( 'title'=>'la_col_VisitDate', 'data_block' => 'grid_checkbox_td' ),
+ 'IPAddress' => Array( 'title'=>'la_col_IPAddress' ),
+ 'Referer' => Array( 'title'=>'la_col_Referer', 'data_block' => 'grid_referer_td' ),
+ 'UserName' => Array('title' => 'la_col_Username', 'data_block' => 'grid_userlink_td', 'user_field' => 'PortalUserId'),
+ ),
+ ),
+ 'visitsincommerce' => Array(
+ 'Icons' => Array('default'=>'icon16_custom.gif'), // icons for each StatusField values, if no matches or no statusfield selected, then "default" icon is used
+ 'Fields' => Array(
+ 'VisitDate' => Array( 'title'=>'la_col_VisitDate', 'data_block' => 'grid_checkbox_td' ),
+ 'IPAddress' => Array( 'title'=>'la_col_IPAddress' ),
+ 'Referer' => Array( 'title'=>'la_col_Referer', 'data_block' => 'grid_referer_td' ),
+ 'UserName' => Array('title' => 'la_col_Username', 'data_block' => 'grid_userlink_td', 'user_field' => 'PortalUserId'),
+ 'AffiliateUser' => Array( 'title' => 'la_col_AffiliateUser', 'data_block' => 'grid_userlink_td', 'user_field' => 'AffiliatePortalUserId'),
+ 'OrderTotalAmountSum' => Array( 'title' => 'la_col_OrderTotal'),
+ 'OrderAffiliateCommissionSum' => Array( 'title' => 'la_col_Commission'),
+ ),
+ ),
+ ),
+
+ );
+
+?>
\ No newline at end of file
Property changes on: branches/unlabeled/unlabeled-1.23.2/kernel/units/visits/visits_config.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.23
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.23.2/kernel/include/theme.php
===================================================================
--- branches/unlabeled/unlabeled-1.23.2/kernel/include/theme.php (nonexistent)
+++ branches/unlabeled/unlabeled-1.23.2/kernel/include/theme.php (revision 7645)
@@ -0,0 +1,829 @@
+<?php
+define('THEME_ERROR_1', 'Theme folder not writable');
+define('THEME_ERROR_2', 'Template File Not Found');
+
+class clsThemeFile extends clsItem
+{
+ var $Contents;
+ var $Root;
+ var $Errors = Array(); // global template error messages (not db related)
+
+ function clsThemeFile($id=NULL)
+ {
+ $this->clsItem();
+ $this->tablename = GetTablePrefix()."ThemeFiles";
+ $this->id_field = "FileId";
+ $this->NoResourceId=1;
+ $this->Root = "";
+ $this->Contents = '';
+ if($id) $this->LoadFromDatabase($id);
+ }
+
+ function DetectChanges($name, $value)
+ {
+ global $objSession;
+
+ if (!isset($this->Data[$name]) ) return false;
+
+ if ( $this->Data[$name] != $value) {
+ //echo "$name Modified tt ".$this->Data[$name]." tt $value<br>";
+ if (!stristr($name, 'File') && !stristr($name, 'Theme')) {
+ if ($objSession->GetVariable("HasChanges") != 1) {
+ $objSession->SetVariable("HasChanges", 2);
+ }
+ }
+ }
+ }
+
+ function ThemeRoot()
+ {
+ if( !$this->Root )
+ {
+ $t = new clsTheme( $this->Get("ThemeId") );
+ $this->Root = $t->Get("Name");
+ }
+ return $this->Root;
+ }
+
+ function FullPath()
+ {
+ // need to rewrite (by Alex)
+ global $objConfig, $pathchar,$pathtoroot;
+
+ $template_path = Array();
+ $template_path[] = FULL_PATH.'/themes/'.$this->ThemeRoot();
+ $sub_folder = trim( $this->Get('FilePath'), ' /');
+ if($sub_folder) $template_path[] = $sub_folder;
+ $template_path[] = trim( $this->Get('FileName'), '/');
+
+ //echo "Full Path is $path <br>\n";
+ return implode('/', $template_path);
+ }
+
+ function Get($name)
+ {
+ if($name == 'Contents')
+ return $this->Contents;
+ else
+ return parent::Get($name);
+ }
+
+ function Set($name, $value)
+ {
+ if( !is_array($name) )
+ {
+ $name = Array($name);
+ $value = Array($value);
+ }
+
+ $i = 0; $field_count = count($name);
+ while($i < $field_count)
+ {
+ if($name[$i] == 'Contents')
+ $this->Contents = $value[$i];
+ else
+ parent::Set($name[$i], $value[$i]);
+ $i++;
+ }
+ }
+ /*
+ function LoadFromDatabase($Id)
+ {
+ global $Errors;
+
+ if(!isset($Id))
+ {
+ $Errors->AddError("error.AppError",NULL,'Internal error: LoadFromDatabase id',"",get_class($this),"LoadFromDatabase");
+ return false;
+ }
+ $sql = sprintf("SELECT * FROM ".$this->tablename." WHERE ".$this->IdField()." = '%s'",$Id);
+ $result = $this->adodbConnection->Execute($sql);
+ if ($result === false)
+ {
+ $Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"LoadFromDatabase");
+ return false;
+ }
+
+ $data = $result->fields;
+
+ $this->SetFromArray($data);
+ $this->Clean();
+ return true;
+ }
+ */
+
+ function Delete()
+ {
+ $path = $this->FullPath();
+ if($this->debuglevel) echo "Trying to delete file [$path]<br>";
+ if( file_exists($path) ) @unlink($path);
+ parent::Delete();
+ }
+
+ function LoadFileContents($want_return = true)
+ {
+ global $objConfig,$pathchar;
+
+ $this->Contents = '';
+ $path = $this->FullPath();
+
+ if( file_exists($path) )
+ $this->Contents = file_get_contents($path);
+ else
+ $this->SetError(THEME_ERROR_2, 2); // template not found
+ if($want_return) return $this->Contents;
+ }
+
+ function SetError($msg, $code, $field = 'global_error')
+ {
+ $this->Errors[$field]['msg'] = $msg;
+ $this->Errors[$field]['code'] = $code;
+ }
+
+ function HasError()
+ {
+ return count($this->Errors) ? 1 : 0;
+ }
+
+ function ErrorMsg()
+ {
+ return $this->Errors['global_error']['msg'];
+ }
+
+ function SaveFileContents($filecontents, $new_file = false)
+ {
+ $path = $this->FullPath();
+ if( is_array($filecontents) ) $filecontents = implode("\n",$filecontents);
+
+ if( $this->IsWriteablePath($new_file) )
+ {
+ $fp = fopen($path,"w");
+ if($fp)
+ {
+ fwrite($fp,$filecontents);
+ fclose($fp);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function IsWriteablePath($new_file = false)
+ {
+
+ $path = $this->FullPath();
+// $path = str_replace('//','/',$path);
+ $ret = $new_file ? is_writable(dirname($path)): is_writable($path);
+
+ if(!$ret)
+ {
+ $this->SetError(THEME_ERROR_1, 1);
+ return false;
+ }
+ return $ret;
+ }
+}
+
+class clsThemeFileList extends clsItemCollection
+{
+ var $Page;
+ var $PerPageVar;
+ var $ThemeId;
+
+ function clsThemeFileList($theme_id=NULL)
+ {
+ global $m_var_list;
+ $this->clsItemCollection();
+ $this->classname = "clsThemeFile";
+ $this->Page=(int)$m_var_list["p"];
+ $this->PerPageVar = "Perpage_ThemeFiles";
+ $this->SourceTable = GetTablePrefix()."ThemeFiles";
+ $this->AdminSearchFields = array("FileName","FilePath","Description");
+
+
+ $this->ThemeId=$theme_id;
+ //if($theme_id)
+ // $this->LoadFiles($theme_id);
+ }
+
+ function LoadFiles($id,$where="",$orderBy="",$limit="")
+ {
+ global $objConfig;
+
+ $this->Clear();
+ $this->ThemeId=$id;
+ $sql = "SELECT * FROM ".$this->SourceTable. " WHERE ThemeId=$id ";
+ if(strlen(trim($where))) $sql .= ' AND '.$where." ";
+ if(strlen(trim($orderBy))) $sql .= "ORDER BY $orderBy";
+ if(strlen(trim($limit))) $sql .= $limit;
+
+ if(strlen($this->PerPageVar))
+ {
+ $sql .= GetLimitSQL($this->Page,$objConfig->Get($this->PerPageVar));
+ }
+ //echo $sql;
+ return $this->Query_Item($sql);
+ }
+
+ function GetFileByName($path,$name,$LoadFromDB=TRUE)
+ {
+ $found = FALSE;
+ $f = FALSE;
+ //echo "Looking through ".$this->NumItems()." Files <br>\n";
+ if($this->NumItems()>0)
+ {
+ foreach($this->Items as $f)
+ {
+ if(($f->Get("FilePath")== $path) && ($f->Get("FileName")==$name))
+ {
+ $found = TRUE;
+ break;
+ }
+ }
+ }
+
+ if(!$found && $LoadFromDB)
+ {
+ $sql = "SELECT * FROM ".$this->SourceTable." WHERE ThemeId=".$this->ThemeId." AND FileName LIKE '$name' AND FilePath LIKE '$path'";
+ $rs = $this->adodbConnection->Execute($sql);
+ //echo $sql."<br>\n";
+ if($rs && !$rs->EOF)
+ {
+ $data = $rs->fields;
+ $f =& $this->AddItemFromArray($data);
+ }
+ else
+ $f = FALSE;
+ }
+ return $f;
+ }
+
+ function AddFile($Path,$Name,$ThemeId,$Type,$Description,$contents=NULL)
+ {
+ $f = new clsThemeFile();
+ $f->Set(array("FilePath","FileName","ThemeId","FileType","Description"),
+ array($Path,$Name,$ThemeId,$Type,$Description));
+ $f->Create();
+ if($contents!==NULL)
+ {
+ $f->SaveFileContents($contents,$Name);
+ }
+ //echo $f->Get("FilePath")."/".$f->Get("FileName")."<br>\n";
+ return $f;
+ }
+
+ function EditFile($FileId,$Path,$Name,$ThemeId,$Type,$Description,$contents=NULL)
+ {
+ $f = $this->GetItem($FileId);
+ $f->Set(array("FilePath","FileName","ThemeId","FileType","Description"),
+ array($Path,$Name,$ThemeId,$Type,$Description));
+ $f->Update();
+ if($Contents!=NULL)
+ $f->SaveFileContents($Contents);
+
+ return $f;
+ }
+
+ function DeleteFile($FileId)
+ {
+ $f = $this->GetItem($FileId);
+ $f->Delete();
+ }
+
+ function DeleteAll()
+ {
+ $this->Clear();
+ $this->LoadFiles($this->ThemeId);
+ foreach($this->Items as $f)
+ $f->Delete();
+ $this->Clear();
+ }
+
+ function SetFileContents($FileId,$Contents)
+ {
+ $f = $this->GetItem($FileId);
+ $f->SaveFileContents($Contents);
+ }
+
+ function GetFileContents($FileId)
+ {
+ $f = $this->GetItem($FileId);
+ return $f->LoadFileContents();
+ }
+
+ function FindMissingFiles($path, $where = null, $OrderBy = null, $limit = null)
+ {
+ global $pathtoroot;
+ $this->Clear();
+ $fullpath = $pathtoroot.'themes/'.$path;
+ // get all templates from database
+ $sql = 'SELECT FileId AS i,CONCAT(FilePath,"/",FileName) AS f FROM '.$this->SourceTable. ' WHERE ThemeId='.$this->ThemeId;
+ $DBfiles=Array();
+ if($rs = $this->adodbConnection->Execute($sql))
+ {
+ while(!$rs->EOF)
+ {
+ $DBfiles[$rs->fields['i']] = $fullpath.$rs->fields['f'];
+ $rs->MoveNext();
+ }
+ $rs->Free();
+ }
+ // get all templates file from disk
+ $HDDfiles = filelist($fullpath, NULL, "tpl");
+
+ $missingFiles=array_diff($HDDfiles,$DBfiles);
+ $orphanFiles=array_diff($DBfiles,$HDDfiles);
+ if($orphanFiles)
+ {
+ $sql = 'DELETE FROM '.$this->SourceTable.' WHERE FileId IN('.join(',',array_keys($orphanFiles)).')';
+ $this->adodbConnection->Execute($sql);
+ }
+ $l=strlen($fullpath);
+ foreach($missingFiles as $file)
+ $this->AddFile(substr(dirname($file),$l),basename($file),$this->ThemeId,0,'');
+ }
+}
+
+RegisterPrefix("clsTheme","theme","kernel/include/theme.php");
+
+class clsTheme extends clsParsedItem
+{
+ var $Files;
+ var $FileCache;
+ var $IdCache;
+ var $ParseCacheDate;
+ var $ParseCacheTimeout;
+
+ function clsTheme($Id = NULL)
+ {
+ $this->clsParsedItem($Id);
+ $this->tablename = GetTablePrefix()."Theme";
+ $this->id_field = "ThemeId";
+ $this->NoResourceId=1;
+ $this->TagPrefix="theme";
+
+ $this->Files = new clsThemeFileList($Id);
+ $this->FileCache = array();
+ $this->IdCache = array();
+ $this->ParseCacheDate=array();
+ $this->ParseCacheTimeout = array();
+
+ if($Id)
+ $this->LoadFromDatabase($Id);
+ }
+
+ function ThemeDirectory()
+ {
+ global $objConfig, $pathchar, $pathtoroot;
+
+ $path = $pathtoroot."themes/".strtolower($this->Get("Name"));
+ return $path;
+ }
+
+ function UpdateFileCacheData($id,$CacheDate)
+ {
+ $sql = "UPDATE ".GetTablePrefix()."ThemeFiles SET CacheDate=$CacheDate WHERE FileId=$id";
+ $this->adodbConnection->Execute($sql);
+ }
+
+ function LoadFileCache()
+ {
+ if(!is_numeric($id=$this->Get("ThemeId")))return;
+ $sql = "SELECT * FROM ".GetTablePrefix()."ThemeFiles WHERE ThemeId=".$id;
+ $rs = $this->adodbConnection->Execute($sql);
+ while($rs && ! $rs->EOF)
+ {
+ //$this->Files->AddItemFromArray($rs->fields,TRUE);
+ $f = $rs->fields["FileName"];
+ $t = $rs->fields["FilePath"];
+ if(strlen($t))
+ $t .= "/";
+ $parts = pathinfo($f);
+ $fname = substr($f,0,(strlen($parts["extension"])+1)*-1);
+ // echo "Name: $fname<br>\n";
+ $t .= $fname;
+
+ $this->FileCache[$t] = $rs->fields["FileId"];
+ $this->IdCache[$rs->fields["FileId"]] = $t;
+ /*
+ if($rs->fields["EnableCache"]) // no such field in this table (commented by Alex)
+ {
+ $this->ParseCacheDate[$rs->fields["FileId"]] = $rs->fields["CacheDate"];
+ $this->ParseCacheTimeout[$rs->fields["FileId"]] = $rs->fields["CacheTimeout"];
+ }
+ */
+ if( defined('ADODB_EXTENSION') && constant('ADODB_EXTENSION') > 0 )
+ adodb_movenext($rs);
+ else
+ $rs->MoveNext();
+ }
+ //echo "<PRE>"; print_r($this->IdCache); echo "</PRE>";
+ }
+
+ function GetTemplateById($FileId)
+ {
+ if(count($this->FileCache)==0)
+ $this->LoadFileCache();
+ $f = $this->IdCache[$FileId];
+
+ return $f;
+ }
+
+ function GetTemplateId($t)
+ {
+ if( count($this->IdCache) == 0 ) $this->LoadFileCache();
+ $f = isset( $this->FileCache[$t] ) ? $this->FileCache[$t] : '';
+ return is_numeric($f) ? $f : $t;
+ }
+
+ function LoadFromDatabase($Id)
+ {
+ global $Errors;
+
+ if(!isset($Id))
+ {
+ $Errors->AddError("error.AppError",NULL,'Internal error: LoadFromDatabase id',"",get_class($this),"LoadFromDatabase");
+ return false;
+ }
+ $sql = sprintf("SELECT * FROM ".$this->tablename." WHERE ".$this->IdField()." = '%s'",$Id);
+ $result = $this->adodbConnection->Execute($sql);
+ if ($result === false)
+ {
+ $Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"LoadFromDatabase");
+ return false;
+ }
+
+ $data = $result->fields;
+
+ $this->SetFromArray($data);
+ $this->Clean();
+ $this->Files = new clsThemeFileList($Id);
+ return true;
+ }
+
+ function GetFileList($where,$OrderBy)
+ {
+ global $objConfig, $pathchar;
+
+ $this->Files->PerPageVar="";
+ $this->Files->ThemeId = $this->Get("ThemeId");
+ $this->Files->LoadFiles($this->Get("ThemeId"),$where,$OrderBy);
+ }
+
+ function VerifyTemplates($where = null,$OrderBy = null,$limit = null)
+ {
+ if(!is_object($this->Files))
+ $this->Files = new clsThemeFileList($this->Get("ThemeId"));
+ $this->Files->ThemeId = $this->Get("ThemeId");
+
+ $this->Files->FindMissingFiles(strtolower($this->Get("Name")),$where,$OrderBy,$limit);
+ }
+
+ function EditTemplateContents($FileId,$Contents)
+ {
+ $this->Files->SetFileContents($FileId,$Contents);
+ }
+
+ function ReadTemplateContents($FileId)
+ {
+ return $this->Files->GetFileContents($FileId);
+ }
+
+ function CreateDirectory()
+ {
+ $dir = $this->ThemeDirectory();
+ if(!is_dir($dir))
+ mkdir($dir);
+ if(is_dir($dir))
+ {
+ $fp = fopen($dir.'/index.tpl',"w");
+ if($fp)
+ {
+ fwrite($fp,'');
+ fclose($fp);
+// $this->Files->FindMissingFiles($this->Get('name'));
+ /* $theme_id = $this->Get('ThemeId');
+ $db_dir = '/'.strtolower($this->Get('Name'));
+ $sql = 'INSERT INTO '.GetTablePrefix().'ThemeFiles
+ (ThemeId, FileName, FilePath, Description, FileType) VALUES
+ ('.$theme_id.', "index.tpl", "'.$db_dir.'", "", 0)';
+ $conn = &GetADODBConnection();
+ $conn->Execute($sql);*/
+ }
+ }
+ }
+
+ function Delete()
+ {
+ $this->Files->DeleteAll();
+ $dir = $this->ThemeDirectory();
+ if(is_writable($dir)) {
+ $files = filelist($dir);
+ foreach ($files as $file) {
+ @unlink($file);
+ }
+ @rmdir($dir);
+ }
+ parent::Delete();
+ }
+
+ function AdminIcon()
+ {
+ global $imagesURL;
+
+ $file = $imagesURL."/itemicons/icon16_theme";
+ if($this->Get("PrimaryTheme")==1)
+ {
+ $file .= "_primary.gif";
+ }
+ else
+ {
+ if($this->Get("Enabled")==0)
+ {
+ $file .= "_disabled";
+ }
+ $file .= ".gif";
+ }
+ return $file;
+ }
+
+ function ParseObject($element)
+ {
+ global $var_list_update, $objSession;
+
+ $extra_attribs = ExtraAttributes($element->attributes);
+ if(strtolower($element->name)==$this->TagPrefix)
+ {
+ $field = strtolower($element->attributes["_field"]);
+ switch($field)
+ {
+ case "id":
+ $ret = $this->Get("ThemeId");
+ break;
+ case "name": // was "nane"
+ $ret = $this->Get("Name");
+ break;
+ case "description":
+ $ret = $this->Get("Description");
+ break;
+ case "adminicon":
+ $ret = $this->AdminIcon();
+ break;
+ case "directory":
+ $ret = $this->ThemeDirectory();
+ break;
+ case "select_url":
+ $var_list_update["t"] = "index";
+ $ret = HREF_Wrapper('', Array('Action' => 'm_set_theme', 'ThemeId' => $this->Get('ThemeId') ) );
+ break;
+ case "selected":
+ $ret = "";
+ if($this->Get("Name")==$objSession->Get("Theme"))
+ $ret = "SELECTED";
+ break;
+ default:
+ $tag = $this->TagPrefix."_".$field;
+ $ret = ""; $this->parsetag($tag);
+ break;
+ }
+ }
+ return $ret;
+ }
+}
+
+class clsThemeList extends clsItemCollection
+{
+ var $Page;
+ var $PerPageVar;
+
+ function clsThemeList($id=NULL)
+ {
+ $this->clsItemCollection();
+ $this->classname="clsTheme";
+ $this->SourceTable=GetTablePrefix()."Theme";
+ $this->PerPageVar = "Perpage_Themes";
+ $this->AdminSearchFields = array("Name","Description");
+ }
+
+ function LoadThemes($where='',$orderBy='')
+ {
+ global $objConfig;
+
+ $this->Clear();
+ $sql = "SELECT * FROM ".$this->SourceTable." ";
+ if(trim($where))
+ $sql .= "WHERE ".$where." ";
+ if(trim($orderBy))
+ $sql .= "ORDER BY $orderBy";
+
+ $sql .= GetLimitSQL($this->Page,$objConfig->Get($this->PerPageVar));
+ return $this->Query_Item($sql);
+ }
+
+ function AddTheme($Name,$Description,$Enabled,$Primary,$CacheTimeout=3600,$StylesheetId=1)
+ {
+ $t = new clsTheme();
+ $t->tablename = $this->SourceTable;
+ $t->Set(array("Name","Description","Enabled","PrimaryTheme","CacheTimeout",'StylesheetId'),
+ array($Name,$Description,$Enabled,$Primary,$CacheTimeout,$StylesheetId));
+ $t->Create();
+ $t->Files->ThemeId=$t->Get("ThemeId");
+ if($Primary==1)
+ {
+ $sql = "UPDATE ".$this->SourceTable." SET PrimaryTheme=0 WHERE ThemeId != ".$t->Get("ThemeId");
+ $this->adodbConnection->Execute($sql);
+ }
+ return $t;
+ }
+
+ function EditTheme($ThemeId,$Name,$Description,$Enabled,$Primary, $CacheTimeout, $StylesheetId)
+ {
+ $t = $this->GetItem($ThemeId);
+ $oldName = $t->Get("Name");
+ if($oldName!=$Name)
+ {
+ $dir=dirname($t->ThemeDirectory());
+ if(!rename($dir.'/'.$oldName,$dir.'/'.$Name))
+ $Name=$oldName;
+ }
+ $t->Set(array("Name","Description","Enabled","PrimaryTheme","CacheTimeout", 'StylesheetId'),
+ array($Name, $Description, $Enabled, $Primary, $CacheTimeout,$StylesheetId));
+ $t->Dirty();
+ $t->Update();
+ if($Primary==1)
+ {
+ $sql = "UPDATE ".$this->SourceTable." SET PrimaryTheme=0 WHERE ThemeId!=$ThemeId";
+ $this->adodbConnection->Execute($sql);
+ }
+ return $t;
+ }
+
+ function DeleteTheme($ThemeId)
+ {
+ $t = $this->GetItem($ThemeId);
+ if (!$t->Get('PrimaryTheme'))
+ {
+ $t->Delete();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function SetPrimaryTheme($ThemeId)
+ {
+ $theme = $this->GetItem($ThemeId);
+ $theme->Dirty();
+ if($theme->Get("Enabled")==1)
+ {
+ $sql = "UPDATE ".$this->SourceTable." SET PrimaryTheme=0";
+ $this->adodbConnection->Execute($sql);
+ $theme->Set("PrimaryTheme","1");
+ $theme->Update();
+ }
+ }
+
+ function GetPrimaryTheme($field = 'ThemeId')
+ {
+ static $primary_theme = 0, $skip_quering = false;
+ if ($skip_quering) return $primary_theme;
+
+ if (!$primary_theme)
+ {
+ $sql = 'SELECT '.$field.' FROM '.$this->SourceTable.' WHERE PrimaryTheme = 1';
+ $primary_theme = $this->adodbConnection->GetOne($sql);
+ $skip_quering = true;
+ }
+ return $primary_theme;
+ }
+
+ function CreateMissingThemes($compile_css = false)
+ {
+ global $objConfig,$pathchar, $pathtoroot;
+
+ $path = $pathtoroot."themes";
+
+ $themes = array();
+ $HDDThemes=Array();
+ if ($dir = @opendir($path))
+ {
+ while (($file = readdir($dir)) !== false)
+ {
+ if($file !="." && $file !=".." && substr($file,0,1)!="_")
+ {
+ if(is_dir($path."/".$file)&&file_exists($path."/".$file.'/index.tpl'))
+ {
+ $file = strtolower($file);
+ $themes[$file]=0;
+ $HDDThemes[]=$file;
+ }
+ }
+ }
+ }
+ closedir($dir);
+
+ $sql = 'SELECT ThemeId AS i,Name AS n FROM '.$this->SourceTable;
+ $DBThemes=Array();
+ if($rs = $this->adodbConnection->Execute($sql))
+ {
+ while(!$rs->EOF)
+ {
+ $DBThemes[$rs->fields['i']] = $fullpath.$rs->fields['n'];
+ $rs->MoveNext();
+ }
+ $rs->Free();
+ }
+
+ $missingThemes = array_udiff($HDDThemes, $DBThemes, 'stricmp');
+ $orphanThemes = array_udiff($DBThemes, $HDDThemes, 'stricmp');
+
+ if($orphanThemes)
+ {
+ $sql = 'DELETE FROM '.$this->SourceTable.' WHERE ThemeId IN('.join(',',array_keys($orphanThemes)).')';
+ $this->adodbConnection->Execute($sql);
+ $sql = 'DELETE FROM '.GetTablePrefix().'ThemeFiles WHERE ThemeId IN('.join(',',array_keys($orphanThemes)).')';
+ $this->adodbConnection->Execute($sql);
+ }
+
+ // make stylesheet/theme hash
+ $css_hash = Array();
+ $css_rs = $this->adodbConnection->Execute('SELECT Name, StylesheetId FROM '.GetTablePrefix().'Stylesheets');
+ while($css_rs && !$css_rs->EOF)
+ {
+ $css_hash[ strtolower($css_rs->fields['Name']) ] = $css_rs->fields['StylesheetId'];
+ $css_rs->MoveNext();
+ }
+
+ if($compile_css)
+ {
+ $application =& kApplication::Instance();
+ $css_table = $application->getUnitOption('css','TableName');
+ $css_idfield = $application->getUnitOption('css','IDField');
+
+ foreach($css_hash as $stylesheet_id)
+ {
+ $css_item =& $application->recallObject('css', null, Array('skip_autoload' => true) );
+ $css_item->Load($stylesheet_id);
+ $css_item->Compile();
+ }
+ $application->Done();
+ }
+
+ $this->Clear();
+ foreach($missingThemes as $theme)
+ {
+ $t=$this->AddTheme($theme,"New Theme",0,0, 3600, getArrayValue($css_hash, $theme) );
+ $t->Files->FindMissingFiles($t->Get('Name'));
+ }
+ }
+
+ function CopyFromEditTable()
+ {
+ global $objSession;
+ $GLOBALS['_CopyFromEditTable']=1;
+
+ $edit_table = $objSession->GetEditTable($this->SourceTable);
+ $idlist = array();
+ $sql = "SELECT * FROM $edit_table";
+ $this->Clear();
+ $rs = $this->adodbConnection->Execute($sql);
+ while($rs && !$rs->EOF)
+ {
+ $data = $rs->fields;
+ $c = $this->AddItemFromArray($data);
+
+ $c->Dirty();
+ if($data["ThemeId"]>0)
+ {
+ $c->Update();
+ }
+ else
+ {
+ $c->UnsetIdField();
+ $c->Create();
+ $GLOBALS['m_var_list']['theme_id']=$c->Get('ThemeId');
+ $c->CreateDirectory();
+ }
+ if($c->Get("PrimaryTheme"))
+ {
+ $this->SetPrimaryTheme($c->Get("ThemeId"));
+ }
+ $rs->MoveNext();
+ }
+ $this->adodbConnection->Execute($sql);
+ unset($GLOBALS['_CopyFromEditTable']);
+ }
+
+ function PurgeEditTable()
+ {
+ global $objSession;
+
+ $edit_table = $objSession->GetEditTable($this->SourceTable);
+ $this->adodbConnection->Execute("DROP TABLE IF EXISTS $edit_table");
+ }
+
+
+}
+?>
Property changes on: branches/unlabeled/unlabeled-1.23.2/kernel/include/theme.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.23
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.23.2/admin/editor/cmseditor/editor/filemanager/browser/default/frmresourceslist.html
===================================================================
--- branches/unlabeled/unlabeled-1.23.2/admin/editor/cmseditor/editor/filemanager/browser/default/frmresourceslist.html (nonexistent)
+++ branches/unlabeled/unlabeled-1.23.2/admin/editor/cmseditor/editor/filemanager/browser/default/frmresourceslist.html (revision 7645)
@@ -0,0 +1,501 @@
+<!--
+ * FCKeditor - The text editor for internet
+ * Copyright (C) 2003-2004 Frederico Caldeira Knabben
+ *
+ * Licensed under the terms of the GNU Lesser General Public License:
+ * http://www.opensource.org/licenses/lgpl-license.php
+ *
+ * For further information visit:
+ * http://www.fckeditor.net/
+ *
+ * File Name: frmresourceslist.html
+ * This page shows all resources available in a folder in the File Browser.
+ *
+ * Version: 2.0 RC3
+ * Modified: 2005-02-25 22:01:23
+ *
+ * File Authors:
+ * Frederico Caldeira Knabben (fredck@fckeditor.net)
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <link href="Browser.css" type="text/css" rel="stylesheet">
+
+ <script type="text/javascript" src="js/common.js"></script>
+ <script language="javascript">
+
+var oListManager = new Object() ;
+var current_sort_order = '_asc';
+var current_sort_by = 'name';
+oListManager.Init = function()
+{
+ this.Table = document.getElementById('tableFiles') ;
+}
+
+oListManager.Clear = function()
+{
+ // Remove all other rows available.
+ while ( this.Table.rows.length > 0 )
+ this.Table.deleteRow(0) ;
+}
+
+function is_msie()
+{
+ var browser = "";
+ browser = navigator.appName;
+ if (browser == 'Microsoft Internet Explorer')
+ return 1;
+ else
+ return 0;
+}
+
+oListManager.AddFolder = function( folderName, folderPath )
+{
+ // Create the new row.
+ var oRow = this.Table.insertRow(-1) ;
+ // Build the link to view the folder.
+ var sLink = '<a href="#" onclick="OpenFolder(\'' + folderPath + '\');return false;">' ;
+ var oCell = oRow.insertCell(-1);
+ oCell.width = 16;
+ // Add the folder icon cell.
+ var oCell = oRow.insertCell(-1) ;
+ oCell.width = 16 ;
+ oCell.innerHTML = sLink + '<img alt="" src="images/Folder.gif" width="16" height="16" border="0"></a>' ;
+ // Add the folder name cell.
+ oCell = oRow.insertCell(-1) ;
+ oCell.noWrap = true ;
+ oCell.colSpan = 4 ;
+ oCell.innerHTML = '&nbsp;' + sLink + folderName + '</a>' ;
+}
+
+oListManager.AddFile = function( fileName, fileUrl, fileSize, fileDate )
+{
+ // Create the new row.
+ var oRow = this.Table.insertRow(-1) ;
+ // Build the link to view the folder.
+ var sLink = '<a href="#" onclick="OpenFile(\'' + fileUrl + '\',\''+fileSize+'\'); return false;">' ;
+ // Get the file icon.
+ var sIcon = oIcons.GetIcon( fileName ) ;
+ // Add the checkbox cell
+ var oCell = oRow.insertCell(-1);
+ oCell.width = 25;
+ oCell.innerHTML = '<input type="checkbox" name="file_checkbox" value='+fileName+' onclick="HandleCheckboxes();"/>';
+ // Add the file icon cell.
+ var oCell = oRow.insertCell(-1) ;
+ oCell.width = 16 ;
+ oCell.innerHTML = sLink + ' <img alt="" src="images/icons/' + sIcon + '.gif" width="16" height="16" border="0"></a>' ;
+ // Add the file name cell.
+ oCell = oRow.insertCell(-1) ;
+ oCell.innerHTML = '&nbsp;' + sLink + '<span id=\'' + fileName + '\'oncontextmenu="ShowContextMenu(event);">' + fileName + '</span></a>' ;
+ // Add the file size cell.
+ oCell = oRow.insertCell(-1) ;
+ oCell.width = 50;
+ oCell.noWrap = true ;
+ oCell.align = 'right' ;
+ oCell.innerHTML = '&nbsp;' + fileSize + ' KB' ;
+
+ oCell = oRow.insertCell(-1) ;
+ oCell.width = 10;
+ oCell.noWrap = true ;
+ oCell.innerHTML = "&nbsp;" ;
+ //Add the file date cell.
+ oCell = oRow.insertCell(-1) ;
+ oCell.width = 120;
+ oCell.noWrap = true ;
+ oCell.innerHTML = fileDate ;
+}
+
+oListManager.AddEmptyRow = function()
+{
+ var oRow = this.Table.insertRow(-1) ;
+ var oCell = oRow.insertCell(-1);
+
+ oCell.width = 25;
+ oCell.innerHTML = '&nbsp;';
+ oCell = oRow.insertCell(-1) ;
+ oCell.width = 16 ;
+ oCell.innerHTML = '&nbsp;';
+ oCell = oRow.insertCell(-1) ;
+ oCell.innerHTML = '&nbsp;';
+ oCell = oRow.insertCell(-1) ;
+ oCell.width = 50;
+ oCell.innerHTML = '&nbsp;';
+ oCell = oRow.insertCell(-1) ;
+ oCell.width = 10;
+ oCell.innerHTML = '&nbsp;';
+ oCell = oRow.insertCell(-1) ;
+ oCell.width = 120;
+ oCell.innerHTML = '&nbsp;';
+}
+
+function GetCheckedFileName(method)
+{
+ var files = '';
+ checkboxes = document.getElementsByName('file_checkbox');
+ for (var i = 0; i< checkboxes.length; i++) {
+ if (checkboxes[i].checked && checkboxes[i].value) {
+ if (method == 'first')
+ return checkboxes[i].value;
+ if (method == 'cnt') {
+ files++;
+ } else
+ files = files+checkboxes[i].value+'|';
+ }
+ }
+ return files;
+}
+
+
+function HandleCheckboxes() {
+ var checked_num = 0, i, count = 0;
+ checkboxes = document.getElementsByName('file_checkbox');
+ for (var i = 0; i< checkboxes.length; i++)
+ {
+ if (checkboxes[i].checked && checkboxes[i].value)
+ checked_num++;
+ }
+
+ if (checked_num == 0) {
+ document.getElementById("selector").checked = false;
+ }
+ if (checked_num > 0) {
+ window.parent.frames['frmUpload'].SetElementVisibility("none", "");
+ if (checked_num > 1) {
+ window.parent.frames['frmUpload'].SetButtonAvalability("rename", false);
+ }
+ else {
+ window.parent.frames['frmUpload'].SetButtonAvalability("rename", true);
+ }
+ }
+ else {
+ window.parent.frames['frmUpload'].SetElementVisibility("", "none");
+ }
+}
+
+function ShowContextMenu(event) {
+ if (event.target) {
+ var targ = event.target;
+ }
+ else if (event.srcElement) {
+ var targ = event.srcElement;
+ }
+ if (targ.nodeType == 3) {
+ targ = targ.parentNode; // defeat Safari bug
+ }
+ document.getElementById("context_menu").style.display = "";
+ document.getElementById("context_menu").style.top = event.clientY;
+ document.getElementById("context_menu").style.left = event.clientX;
+ id = targ.id;
+ document.getElementById("context_menu_file").value = id;
+}
+
+function HideContextMenu() {
+ document.getElementById("context_menu").style.display = "none";
+}
+
+function RenameFromContextMenu(old_name) {
+ if (old_name)
+ file_name = old_name;
+ else
+ file_name = document.getElementById("context_menu_file").value;
+ f=prompt('Rename file "'+file_name+'"?',file_name);
+ if (f) {
+ RenameFile(file_name,f);
+ }
+}
+
+
+function DeleteFromContextMenu() {
+ file_name = document.getElementById("context_menu_file").value;
+ f=confirm('Delete file "'+file_name+'"?',file_name);
+ if (f) {
+ oConnector.PostCommand( 'DeleteFiles', 'files='+file_name, DeleteCallBack );
+ }
+}
+
+function UncheckSelector() {
+ document.getElementById("selector").checked = false;
+}
+
+function ToggleSelectAll() {
+ checkboxes = document.getElementsByName('file_checkbox');
+ if (document.getElementById('selector').checked)
+ {
+ for (var i = 0; i< checkboxes.length; i++)
+ checkboxes[i].checked = true;
+ } else {
+ for (var i = 0; i < checkboxes.length; i++)
+ checkboxes[i].checked = false;
+ }
+ HandleCheckboxes();
+}
+
+function OpenFolder( folderPath )
+{
+ // Load the resources list for this folder.
+ window.parent.frames['frmFolders'].LoadFolders( folderPath ) ;
+}
+
+function OpenFile( fileUrl, fileSize)
+{
+ window.top.opener.SetUrl( fileUrl, '', '', '', fileSize);
+ window.close() ;
+ window.top.close() ;
+ window.top.opener.focus() ;
+}
+
+
+function ValidateFileName(file_name)
+{
+ var sp = file_name.replace(/\\/g, '\/');
+ sp=sp.split("/");
+ file_name = sp[sp.length-1];
+ var re = /^([\/a-zA-Z0-9\(\)_\.-]+)$/
+
+ if (!re.test(file_name)) {
+ alert('Please name your files to be web-friendly. We recommend using only these characters in file names:'+"\n"+
+ 'Letters a-z, A-Z, Numbers 0-9, "_" (underscore), "-" (dash), " " (space), "." (period)'+"\n"+
+ 'Please avoid using any other characters like quotes, brackets, quotation marks, "?", "!", "=", foreign symbols, etc.');
+ return false;
+ } else
+ return true;
+}
+
+function RenameFile(old_name,new_name)
+{
+ if (ValidateFileName(new_name))
+ oConnector.SendCommand( 'RenameFile_'+old_name+'|'+new_name, null, RenameCallBack );
+ else
+ RenameFromContextMenu(old_name);
+}
+
+function DeleteFiles(confirm)
+{
+ var files = GetCheckedFileName('All');
+ oConnector.PostCommand( 'DeleteFiles', 'files='+files+'&confirm='+confirm, DeleteCallBack );
+}
+
+function DeleteCallBack(fckXml)
+{
+ var oNodes = fckXml.SelectNodes( 'Connector/Error' );
+ var msg = '';
+ if (oNodes.length > 0) {
+ for ( var i = 0 ; i < oNodes.length ; i++ )
+ {
+ var iErrorNumber = parseInt( oNodes[i].attributes.getNamedItem('number').value ) ;
+ if (iErrorNumber == '100') {
+ Refresh();
+ return;
+ }
+ msg = msg + oNodes[i].attributes.getNamedItem('originalDescription').value+"\n" ;
+ }
+ if (oNodes.length > 1)
+ $base_msg = "Selected Files used in Your SMS "+"\n"+msg+"Delete All Selected Files";
+ if (oNodes.length == 1)
+ $base_msg = "Selected File used in Your SMS "+"\n"+msg+"Delete All Selected File?";
+ if (confirm($base_msg)) {
+ DeleteFiles(1);
+ }
+ }
+
+}
+
+function RenameCallBack(fckXml)
+{
+ var oNode = fckXml.SelectSingleNode( 'Connector/Error' ) ;
+ var iErrorNumber = parseInt( oNode.attributes.getNamedItem('number').value ) ;
+ switch ( iErrorNumber )
+ {
+ case 0 :
+ window.parent.frames['frmResourcesList'].Refresh() ;
+ break ;
+ case 203 :
+ alert( 'Invalid file type for this foder' ) ;
+ break ;
+ case 204 :
+ alert( 'A file with the same name is already available' ) ;
+ break ;
+ default :
+ alert( 'Error on file upload. Error number: ' + errorNumber ) ;
+ break ;
+ }
+
+}
+
+function LoadResources( resourceType, folderPath )
+{
+ oListManager.Clear() ;
+ oConnector.ResourceType = resourceType ;
+ oConnector.CurrentFolder = folderPath
+ oConnector.SendCommand( 'GetFoldersAndFiles_'+current_sort_by+current_sort_order, null, GetFoldersAndFilesCallBack ) ;
+}
+
+function Refresh()
+{
+ LoadResources( oConnector.ResourceType, oConnector.CurrentFolder ) ;
+ window.parent.frames['frmUpload'].SetElementVisibility("", "none");
+}
+
+function GetFoldersAndFilesCallBack( fckXml )
+{
+ // Get the current folder path.
+ var oNode = fckXml.SelectSingleNode( 'Connector/CurrentFolder' ) ;
+ var sCurrentFolderPath = oNode.attributes.getNamedItem('path').value ;
+ var sCurrentFolderUrl = oNode.attributes.getNamedItem('url').value ;
+
+ if (current_sort_order == '_asc') {
+ // Add the Folders.
+ var oNodes = fckXml.SelectNodes( 'Connector/Folders/Folder' ) ;
+ for ( var i = 0 ; i < oNodes.length ; i++ )
+ {
+ var sFolderName = oNodes[i].attributes.getNamedItem('name').value ;
+ oListManager.AddFolder( sFolderName, sCurrentFolderPath + sFolderName + "/" ) ;
+ }
+ // Add the Files.
+ var oNodes = fckXml.SelectNodes( 'Connector/Files/File' ) ;
+ for ( var i = 0 ; i < oNodes.length ; i++ )
+ {
+ var sFileName = oNodes[i].attributes.getNamedItem('name').value ;
+ var sFileSize = oNodes[i].attributes.getNamedItem('size').value ;
+ var sFileDate = oNodes[i].attributes.getNamedItem('date').value;
+ oListManager.AddFile( sFileName, sCurrentFolderUrl + sFileName, sFileSize, sFileDate) ;
+ }
+
+ } else {
+ // Add the Files.
+ var oNodes = fckXml.SelectNodes( 'Connector/Files/File' ) ;
+ for ( var i = 0 ; i < oNodes.length ; i++ )
+ {
+ var sFileName = oNodes[i].attributes.getNamedItem('name').value ;
+ var sFileSize = oNodes[i].attributes.getNamedItem('size').value ;
+ var sFileDate = oNodes[i].attributes.getNamedItem('date').value;
+ oListManager.AddFile( sFileName, sCurrentFolderUrl + sFileName, sFileSize, sFileDate) ;
+ }
+ // Add the Folders.
+ var oNodes = fckXml.SelectNodes( 'Connector/Folders/Folder' ) ;
+ for ( var i = 0 ; i < oNodes.length ; i++ )
+ {
+ var sFolderName = oNodes[i].attributes.getNamedItem('name').value ;
+ oListManager.AddFolder( sFolderName, sCurrentFolderPath + sFolderName + "/" ) ;
+ }
+
+ }
+ oListManager.AddEmptyRow();
+ if (document.getElementById('selector'))
+ document.getElementById('selector').checked=false;
+ UpdateDivSize();
+}
+
+function UpdateDivSize()
+{
+ table_height = document.getElementById('tableFiles').clientHeight;
+ if(is_msie())
+ window_height = document.body.clientHeight - 20;
+ else
+ window_height = window.outerHeight - 165;
+ if (document.getElementById('data_div')) {
+ document.getElementById('data_div').style.height = window_height;
+ if (window_height < table_height) {
+ document.getElementById('data_div').scroll = 'yes';
+ document.getElementById('sortFiles').style.width = document.getElementById('tableFiles').clientWidth;
+ } else {
+ document.getElementById('data_div').scroll = 'yes';
+ document.getElementById('sortFiles').style.width = document.getElementById('tableFiles').clientWidth;
+ }
+ }
+}
+
+window.onload = function()
+{
+ oListManager.Init() ;
+ window.top.IsLoadedResourcesList = true ;
+ UncheckSelector();
+}
+
+function sortBy(sort_by)
+{
+ if (sort_by == current_sort_by)
+ current_sort_order = (current_sort_order == '_asc')?'_desc':'_asc';
+ else {
+ document.getElementById('sort_'+current_sort_by).src = document.getElementById('_no').src;
+ current_sort_by = sort_by;
+ current_sort_order = '_asc';
+ }
+ document.getElementById('sort_'+current_sort_by).src = document.getElementById(current_sort_order).src;
+ //alert('GetFoldersAndFiles_'+current_sort_by+current_sort_order);
+ LoadResources( oConnector.ResourceType, oConnector.CurrentFolder ) ;
+}
+
+window.onresize = UpdateDivSize;
+
+</script>
+ </head>
+ <body class="FileArea" bottomMargin="10" leftMargin="10" topMargin="3" rightMargin="10" onclick="HideContextMenu();" oncontextmenu="return false;">
+ <div id="sort_div" style="padding: 0; border: none; overflow: hidden; width: 100%; position: relative;">
+ <table id="sortFiles" border="0" cellSpacing="1" cellPadding="0" width="100%" border="0" style="border-bottom:1px solid #000000; margin-bottom:0px; padding-bottom:0px;">
+ <tr>
+ <td width="25">
+ <input type="checkbox" id="selector" value="unchecked" onclick="ToggleSelectAll();" />
+ </td>
+ <td>
+ <table border="0" cellSpacing="0" cellPadding="0"border="0">
+ <tr>
+ <td><a href="javascript:sortBy('name');"><img id="sort_name" src="images/sort_asc.gif" alt="" border="0"></a></td>
+ <td><a href="javascript:sortBy('name');" class='order-link'>&nbsp;File Name</a></td>
+ </tr>
+ </table>
+ </td>
+ <td width="50" align="center">
+ <table border="0" cellSpacing="0" cellPadding="0"border="0">
+ <tr>
+ <td><a href="javascript:sortBy('size');"><img id="sort_size" src="images/sort_no.gif" alt="" border="0"></a></td>
+ <td><a href="javascript:sortBy('size');" class='order-link'>&nbsp;Size</a></td>
+ </tr>
+ </table>
+ </td>
+ <td width="10"> </td>
+ <td width="120">
+ <table border="0" cellSpacing="0" cellPadding="0"border="0">
+ <tr>
+ <td><a href="javascript:sortBy('date');"><img id="sort_date" src="images/sort_no.gif" alt="" border="0"></a></td>
+ <td><a href="javascript:sortBy('date');" class='order-link'>&nbsp;Date</a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </div>
+
+ <div id="data_div" style="padding: 0; border: none; overflow: auto; width: 100%; position: relative;">
+ <img src="images/s.gif" width="1" height="3"><br />
+ <table id="tableFiles" border="0" cellSpacing="1" cellPadding="0" width="100%" border="0" style="padding-top:0px;">
+ </table>
+ </div>
+ <div style="display:none">
+ <img id='_desc' src="images/sort_desc.gif" alt="" border="0">
+ <img id='_asc' src="images/sort_asc.gif" alt="" border="0">
+ <img id='_no' src="images/sort_no.gif" alt="" border="0">
+
+ </div>
+ <table id="context_menu" cellpadding="0" cellspacing="2" style="position: absolute; background-color: #FFFFFF; border: 1px solid #000000; display: none">
+ <tr>
+ <td>
+ <table id="context_menu" cellpadding="0" cellspacing="0">
+ <tr style="height:18px;" onmouseover="document.getElementById('rename').bgColor = '#8f8f73'; document.getElementById('rename_dot').bgColor = '#737357';" onmouseout="document.getElementById('rename').bgColor = '#FFFFFF'; document.getElementById('rename_dot').bgColor = '#E3E3C7';">
+ <td id="rename_dot" bgcolor="#E3E3C7" align="center" valign="middle" width="15"><img src="images/blackpix.gif" style="width: 5; height: 5" /></td>
+ <td id="rename" align="left" style="font-size: 11px; font-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana" onclick="RenameFromContextMenu();">&nbsp;<a href="#" style="text-decoration: none; color: #000000">Rename</a>&nbsp;&nbsp;</td>
+ </tr>
+ <tr style="height:18px;" onmouseover="document.getElementById('delete').bgColor = '#8f8f73'; document.getElementById('delete_dot').bgColor = '#737357';" onmouseout="document.getElementById('delete').bgColor = '#FFFFFF'; document.getElementById('delete_dot').bgColor = '#E3E3C7';">
+ <td id="delete_dot" bgcolor="#E3E3C7" align="center" valign="middle" width="15"><img src="images/blackpix.gif" style="width: 5; height: 5" /></td>
+ <td id="delete" align="left" style="font-size: 11px; font-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana" onclick="DeleteFromContextMenu();">
+ &nbsp;<a href="#" style="text-decoration: none; color: #000000">Delete</a>&nbsp;&nbsp;
+ <input type="hidden" value="" id="context_menu_file">
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </body>
+</html>
Property changes on: branches/unlabeled/unlabeled-1.23.2/admin/editor/cmseditor/editor/filemanager/browser/default/frmresourceslist.html
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.23
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.23.2/core/kernel/db/dblist.php
===================================================================
--- branches/unlabeled/unlabeled-1.23.2/core/kernel/db/dblist.php (nonexistent)
+++ branches/unlabeled/unlabeled-1.23.2/core/kernel/db/dblist.php (revision 7645)
@@ -0,0 +1,831 @@
+<?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);
+ }
+
+ /**
+ * 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 getCountSQL($sql)
+ {
+ if ( preg_match("/DISTINCT(.*?)FROM(?!_)/is",$sql,$regs ) )
+ {
+ return preg_replace("/^.*SELECT DISTINCT(.*?)FROM(?!_)/is", "SELECT COUNT(DISTINCT ".$regs[1].") AS count FROM", $sql);
+ }
+ else
+ {
+ return preg_replace("/^.*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);
+ $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
+ if (getArrayValue($this->Fields, $field, 'formatter') == 'kMultiLanguage' && !getArrayValue($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 = 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();
+ }
+
+ 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
+ }
+ }
+}
+
+?>
\ No newline at end of file
Property changes on: branches/unlabeled/unlabeled-1.23.2/core/kernel/db/dblist.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.23
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.23.2/core/units/visits/visits_config.php
===================================================================
--- branches/unlabeled/unlabeled-1.23.2/core/units/visits/visits_config.php (nonexistent)
+++ branches/unlabeled/unlabeled-1.23.2/core/units/visits/visits_config.php (revision 7645)
@@ -0,0 +1,140 @@
+<?php
+
+$config = Array(
+ 'Prefix' => 'visits',
+ 'ItemClass' => Array('class'=>'kDBItem','file'=>'','build_event'=>'OnItemBuild'),
+ 'ListClass' => Array('class'=>'VisitsList','file'=>'visits_list.php','build_event'=>'OnListBuild'),
+ 'EventHandlerClass' => Array('class'=>'VisitsEventHandler','file'=>'visits_event_handler.php','build_event'=>'OnBuild'),
+ 'TagProcessorClass' => Array('class'=>'VisitsTagProcessor','file'=>'visits_tag_processor.php','build_event'=>'OnBuild'),
+ 'AutoLoad' => true,
+
+ 'QueryString' => Array(
+ 1 => 'id',
+ 2 => 'Page',
+ 3 => 'event',
+ 4 => 'mode',
+ ),
+
+ 'Hooks' => Array(
+ Array(
+ 'Mode' => hBEFORE,
+ 'Conditional' => false,
+ 'HookToPrefix' => 'adm',
+ 'HookToSpecial' => '',
+ 'HookToEvent' => Array( 'OnStartup' ),
+ 'DoPrefix' => '',
+ 'DoSpecial' => '',
+ 'DoEvent' => 'OnRegisterVisit',
+ ),
+
+ Array(
+ 'Mode' => hAFTER,
+ 'Conditional' => false,
+ 'HookToPrefix' => 'u',
+ 'HookToSpecial' => '*',
+ 'HookToEvent' => Array( 'OnLogin' ),
+ 'DoPrefix' => '',
+ 'DoSpecial' => '',
+ 'DoEvent' => 'OnUserLogin',
+ ),
+ ),
+
+ 'IDField' => 'VisitId',
+ 'TableName' => TABLE_PREFIX.'Visits',
+ 'TitlePresets' => Array(
+ 'default' => Array(),
+ 'visits_list' => Array('prefixes' => Array('visits_List'), 'format' => "!la_title_Visits! (#visits_recordcount#)"),
+ 'visits.incommerce_list' => Array('prefixes' => Array('visits.incommerce_List'), 'format' => "!la_title_Visits! (#visits.incommerce_recordcount#)"),
+ ),
+ 'CalculatedFields' => Array(
+ '' => Array (
+ 'UserName' => 'IF( ISNULL(u.Login), IF (%1$s.PortalUserId = -1, \'root\', IF (%1$s.PortalUserId = -2, \'Guest\', \'n/a\')), u.Login)',
+ ),
+ 'incommerce' => Array (
+ 'UserName' => 'IF( ISNULL(u.Login), IF (%1$s.PortalUserId = -1, \'root\', IF (%1$s.PortalUserId = -2, \'Guest\', \'n/a\')), u.Login)',
+ 'AffiliateUser' => 'IF( LENGTH(au.Login),au.Login,\'!la_None!\')',
+ 'AffiliatePortalUserId' => 'af.PortalUserId',
+ 'OrderTotalAmount' => 'IF(ord.Status = 4, ord.SubTotal+ord.ShippingCost+ord.VAT, 0)',
+ 'OrderAffiliateCommission' => 'IF(ord.Status = 4, ord.AffiliateCommission, 0)',
+ 'OrderNumber' => 'CONCAT(LPAD(Number,6,"0"),\'-\',LPAD(SubNumber,3,"0") )',
+ 'OrderId' => 'ord.OrderId',
+ ),
+ ),
+
+ 'ListSQLs' => Array( ''=>' SELECT %1$s.* %2$s
+ FROM %1$s
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser u ON %1$s.PortalUserId = u.PortalUserId',
+ 'incommerce'=>'
+ SELECT %1$s.* %2$s
+ FROM %1$s
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser u ON %1$s.PortalUserId = u.PortalUserId
+ LEFT JOIN '.TABLE_PREFIX.'Affiliates af ON %1$s.AffiliateId = af.AffiliateId
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser au ON af.PortalUserId = au.PortalUserId
+ LEFT JOIN '.TABLE_PREFIX.'Orders ord ON %1$s.VisitId = ord.VisitId',
+ ),
+
+
+ 'ItemSQLs' => Array( ''=>' SELECT %1$s.* %2$s
+ FROM %1$s
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser u ON %1$s.PortalUserId = u.PortalUserId',
+ 'incommerce'=>' SELECT %1$s.* %2$s
+ FROM %1$s
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser u ON %1$s.PortalUserId = u.PortalUserId
+ LEFT JOIN '.TABLE_PREFIX.'Affiliates af ON %1$s.AffiliateId = af.AffiliateId
+ LEFT JOIN '.TABLE_PREFIX.'PortalUser au ON af.PortalUserId = au.PortalUserId
+ LEFT JOIN '.TABLE_PREFIX.'Orders ord ON %1$s.VisitId = ord.VisitId',
+ ),
+
+ 'ListSortings' => Array(
+ '' => Array(
+ 'Sorting' => Array('VisitDate' => 'desc'),
+ )
+ ),
+
+ 'Fields' => Array(
+ 'VisitId' => Array('type' => 'int'),
+ 'VisitDate' => Array('type' => 'int', 'formatter'=>'kDateFormatter', 'custom_filter' => 'date_range', 'not_null' => '1','default' => '0'),
+ 'Referer' => Array('type' => 'string','not_null' => '1','default' => ''),
+ 'IPAddress' => Array('type' => 'string','not_null' => '1','default' => ''),
+ 'AffiliateId' => Array('type'=>'int','formatter'=>'kLEFTFormatter','options'=>Array(0=>'lu_none'),'left_sql'=>'SELECT %s FROM '.TABLE_PREFIX.'Affiliates af LEFT JOIN '.TABLE_PREFIX.'PortalUser pu ON pu.PortalUserId = af.PortalUserId WHERE `%s` = \'%s\'','left_key_field'=>'AffiliateId','left_title_field'=>'Login','not_null'=>1,'default'=>0),
+ 'PortalUserId' => Array('type' => 'int','not_null' => '1','default' => -2),
+ ),
+
+ 'VirtualFields' => Array(
+ 'UserName' => Array('type'=>'string'),
+ 'AffiliateUser' => Array('type'=>'string'),
+ 'AffiliatePortalUserId' => Array('type'=>'int'),
+ 'OrderTotalAmount' => Array('type' => 'float', 'formatter'=>'kFormatter', 'format'=>'%01.2f', 'not_null' => '1','default' => '0.00', 'totals' => 'SUM'),
+ 'OrderTotalAmountSum' => Array('type' => 'float', 'formatter'=>'kFormatter', 'format'=>'%01.2f', 'not_null' => '1','default' => '0.00'),
+ 'OrderAffiliateCommission' => Array('type' => 'double', 'formatter'=>'kFormatter','format'=>'%.02f', 'not_null' => '1','default' => '0.0000', 'totals' => 'SUM'),
+ 'OrderAffiliateCommissionSum' => Array('type' => 'double', 'formatter'=>'kFormatter','format'=>'%.02f', 'not_null' => '1','default' => '0.0000'),
+ 'OrderId' => Array('type' => 'int', 'default' => '0'),
+ ),
+
+ 'Grids' => Array(
+ 'Default' => Array(
+ 'Icons' => Array('default'=>'icon16_custom.gif'), // icons for each StatusField values, if no matches or no statusfield selected, then "default" icon is used
+ 'Fields' => Array(
+ 'VisitDate' => Array( 'title'=>'la_col_VisitDate', 'data_block' => 'grid_checkbox_td' ),
+ 'IPAddress' => Array( 'title'=>'la_col_IPAddress' ),
+ 'Referer' => Array( 'title'=>'la_col_Referer', 'data_block' => 'grid_referer_td' ),
+ 'UserName' => Array('title' => 'la_col_Username', 'data_block' => 'grid_userlink_td', 'user_field' => 'PortalUserId'),
+ ),
+ ),
+ 'visitsincommerce' => Array(
+ 'Icons' => Array('default'=>'icon16_custom.gif'), // icons for each StatusField values, if no matches or no statusfield selected, then "default" icon is used
+ 'Fields' => Array(
+ 'VisitDate' => Array( 'title'=>'la_col_VisitDate', 'data_block' => 'grid_checkbox_td' ),
+ 'IPAddress' => Array( 'title'=>'la_col_IPAddress' ),
+ 'Referer' => Array( 'title'=>'la_col_Referer', 'data_block' => 'grid_referer_td' ),
+ 'UserName' => Array('title' => 'la_col_Username', 'data_block' => 'grid_userlink_td', 'user_field' => 'PortalUserId'),
+ 'AffiliateUser' => Array( 'title' => 'la_col_AffiliateUser', 'data_block' => 'grid_userlink_td', 'user_field' => 'AffiliatePortalUserId'),
+ 'OrderTotalAmountSum' => Array( 'title' => 'la_col_OrderTotal'),
+ 'OrderAffiliateCommissionSum' => Array( 'title' => 'la_col_Commission'),
+ ),
+ ),
+ ),
+
+ );
+
+?>
\ No newline at end of file
Property changes on: branches/unlabeled/unlabeled-1.23.2/core/units/visits/visits_config.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.23
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.23.2/core/units/languages/import_xml.php
===================================================================
--- branches/unlabeled/unlabeled-1.23.2/core/units/languages/import_xml.php (nonexistent)
+++ branches/unlabeled/unlabeled-1.23.2/core/units/languages/import_xml.php (revision 7645)
@@ -0,0 +1,438 @@
+<?php
+
+ define('LANG_OVERWRITE_EXISTING', 1);
+ define('LANG_SKIP_EXISTING', 2);
+
+ class LangXML_Parser extends kBase {
+
+ /**
+ * Path to current node beeing processed
+ *
+ * @var Array
+ */
+ var $path = Array();
+
+ /**
+ * Connection to database
+ *
+ * @var kDBConnection
+ */
+ var $Conn = null;
+
+ /**
+ * Fields of language currently beeing processed
+ *
+ * @var Array
+ */
+ var $current_language = Array();
+
+ /**
+ * Fields of phrase currently beeing processed
+ *
+ * @var Array
+ */
+ var $current_phrase = Array();
+
+ /**
+ * Fields of event currently beeing processed
+ *
+ * @var Array
+ */
+ var $current_event = Array();
+
+ /**
+ * Event type + name mapping to id (from system)
+ *
+ * @var Array
+ */
+ var $events_hash = Array();
+
+
+ /**
+ * Phrase types allowed for import/export operations
+ *
+ * @var Array
+ */
+ var $phrase_types_allowed = Array();
+
+ /**
+ * Modules allowed for export (import in development)
+ *
+ * @var Array
+ */
+ var $modules_allowed = Array();
+
+ /**
+ * Current Language in import
+ *
+ * @var LanguagesItem
+ */
+ var $lang_object = null;
+
+ var $tables = Array();
+
+ var $ip_address = '';
+
+ var $import_mode = LANG_SKIP_EXISTING;
+
+ var $Encoding = 'base64';
+
+ function LangXML_Parser($temp_mode = true)
+ {
+ parent::kBase();
+ $this->Conn =& $this->Application->GetADODBConnection();
+
+ if ($temp_mode) {
+ $this->Application->SetVar('lang_mode', 't');
+ $this->tables['lang'] = $this->prepareTempTable('lang');
+ $this->tables['phrases'] = $this->prepareTempTable('phrases');
+ $this->tables['emailmessages'] = $this->prepareTempTable('emailmessages');
+ }
+ else {
+ $this->tables['lang'] = $this->Application->getUnitOption('lang', 'TableName');
+ $this->tables['phrases'] = $this->Application->getUnitOption('phrases', 'TableName');
+ $this->tables['emailmessages'] = $this->Application->getUnitOption('emailmessages', 'TableName');
+ }
+
+ $this->lang_object =& $this->Application->recallObject('lang.imp', null, Array('skip_autoload' => true));
+
+ $sql = 'SELECT EventId, CONCAT(Event,"_",Type) AS EventMix FROM '.TABLE_PREFIX.'Events';
+ $this->events_hash = $this->Conn->GetCol($sql, 'EventMix');
+
+ $this->ip_address = getenv('HTTP_X_FORWARDED_FOR') ? getenv('HTTP_X_FORWARDED_FOR') : getenv('REMOTE_ADDR');
+ }
+
+ function SetEncoding($enc)
+ {
+ $this->Encoding = $enc;
+ }
+
+ function renameTable($table_prefix, $new_name)
+ {
+ $this->Conn->Query('ALTER TABLE '.$this->tables[$table_prefix].' RENAME '.$new_name);
+ $this->tables[$table_prefix] = $new_name;
+ }
+
+ /**
+ * Create temp table for prefix, if table already exists, then delete it and create again
+ *
+ * @param string $prefix
+ */
+ function prepareTempTable($prefix)
+ {
+ $idfield = $this->Application->getUnitOption($prefix, 'IDField');
+ $table = $this->Application->getUnitOption($prefix,'TableName');
+ $temp_table = $this->Application->GetTempName($table);
+
+ $sql = 'DROP TABLE IF EXISTS %s';
+ $this->Conn->Query( sprintf($sql, $temp_table) );
+
+ $sql = 'CREATE TABLE %s SELECT * FROM %s WHERE 0';
+ $this->Conn->Query( sprintf($sql, $temp_table, $table) );
+
+ $sql = 'ALTER TABLE %1$s CHANGE %2$s %2$s INT(11) NOT NULL';
+ $this->Conn->Query( sprintf($sql, $temp_table, $idfield) );
+
+ return $temp_table;
+ }
+
+ function Parse($filename, $phrase_types, $module_ids, $import_mode = LANG_SKIP_EXISTING)
+ {
+ // define the XML parsing routines/functions to call based on the handler path
+ if( !file_exists($filename) || !$phrase_types /*|| !$module_ids*/ ) return false;
+
+ $phrase_types = explode('|', substr($phrase_types, 1, -1) );
+// $module_ids = explode('|', substr($module_ids, 1, -1) );
+
+ $this->phrase_types_allowed = array_flip($phrase_types);
+ $this->import_mode = $import_mode;
+
+ //if (in_array('In-Portal',)
+
+ $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') );
+
+ $fdata = file_get_contents($filename);
+
+ $ret = xml_parse($xml_parser, $fdata);
+ xml_parser_free($xml_parser); // clean up the parser object
+
+ $this->Application->SetVar('lang_mode', '');
+ return $ret;
+ }
+
+ function startElement(&$parser, $element, $attributes)
+ {
+ array_push($this->path, $element);
+ $path = implode(' ',$this->path);
+ //check what path we are in
+
+ $this->LastLine = xml_get_current_line_number($parser);
+ $this->SecondData = false;
+
+ switch($path)
+ {
+ case 'LANGUAGES LANGUAGE':
+ $this->current_language = Array('PackName' => $attributes['PACKNAME'], 'LocalName' => $attributes['PACKNAME'], 'Encoding' => $attributes['ENCODING']);
+
+ $sql = 'SELECT %s FROM %s WHERE PackName = %s';
+ $sql = sprintf( $sql,
+ $this->lang_object->IDField,
+ $this->Application->GetLiveName($this->lang_object->TableName),
+ $this->Conn->qstr($this->current_language['PackName']) );
+ $language_id = $this->Conn->GetOne($sql);
+ if($language_id)
+ {
+ $this->current_language['LanguageId'] = $language_id;
+ $this->lang_object->SwitchToLive();
+ $this->lang_object->Load($language_id);
+ }
+ break;
+
+ case 'LANGUAGES LANGUAGE PHRASES':
+ case 'LANGUAGES LANGUAGE EVENTS':
+ if( !getArrayValue($this->current_language,'Charset') ) $this->current_language['Charset'] = 'iso-8859-1';
+ $this->lang_object->SetFieldsFromHash($this->current_language);
+
+ if( !getArrayValue($this->current_language,'LanguageId') )
+ {
+ $this->lang_object->SetDBField('Enabled', STATUS_ACTIVE);
+ if( $this->lang_object->Create() ) $this->current_language['LanguageId'] = $this->lang_object->GetID();
+ }
+ elseif($this->import_mode == LANG_OVERWRITE_EXISTING)
+ {
+ $this->lang_object->TableName = $this->Application->getUnitOption($this->lang_object->Prefix, 'TableName');
+ $this->lang_object->Update();
+ }
+ break;
+
+ case 'LANGUAGES LANGUAGE PHRASES PHRASE':
+ $phrase_module = getArrayValue($attributes,'MODULE');
+ if(!$phrase_module) $phrase_module = 'In-Portal';
+
+ $this->current_phrase = Array( 'LanguageId' => $this->current_language['LanguageId'],
+ 'Phrase' => $attributes['LABEL'],
+ 'PhraseType' => $attributes['TYPE'],
+ 'Module' => $phrase_module,
+ 'LastChanged' => adodb_mktime(),
+ 'LastChangeIP' => $this->ip_address,
+ 'Translation' => '');
+ break;
+
+ case 'LANGUAGES LANGUAGE EVENTS EVENT':
+ $this->current_event = Array( 'LanguageId' => $this->current_language['LanguageId'],
+ 'EventId' => $this->events_hash[ $attributes['EVENT'].'_'.$attributes['TYPE'] ],
+ 'MessageType' => $attributes['MESSAGETYPE'],
+ 'Template' => '');
+ break;
+
+
+ }
+
+ // if($path == 'SHIPMENT PACKAGE')
+ }
+
+ function characterData(&$parser, $line)
+ {
+ $line = trim($line);
+ if(!$line) return ;
+
+ $path = join (' ',$this->path);
+
+ $language_nodes = Array('DATEFORMAT','TIMEFORMAT','INPUTDATEFORMAT','INPUTTIMEFORMAT','DECIMAL','THOUSANDS','CHARSET','UNITSYSTEM');
+
+
+ $node_field_map = Array('LANGUAGES LANGUAGE DATEFORMAT' => 'DateFormat',
+ 'LANGUAGES LANGUAGE TIMEFORMAT' => 'TimeFormat',
+
+ 'LANGUAGES LANGUAGE INPUTDATEFORMAT'=> 'InputDateFormat',
+ 'LANGUAGES LANGUAGE INPUTTIMEFORMAT'=> 'InputTimeFormat',
+
+ 'LANGUAGES LANGUAGE DECIMAL' => 'DecimalPoint',
+ 'LANGUAGES LANGUAGE THOUSANDS' => 'ThousandSep',
+ 'LANGUAGES LANGUAGE CHARSET' => 'Charset',
+ 'LANGUAGES LANGUAGE UNITSYSTEM' => 'UnitSystem');
+
+ if( in_array( end($this->path), $language_nodes) )
+ {
+ $this->current_language[ $node_field_map[$path] ] = $line;
+ }
+ else
+ {
+ switch($path)
+ {
+ case 'LANGUAGES LANGUAGE PHRASES PHRASE':
+ if( isset($this->phrase_types_allowed[ $this->current_phrase['PhraseType'] ]) )
+ {
+ $this->current_phrase['Translation'] .= $line;
+ }
+ break;
+
+ case 'LANGUAGES LANGUAGE EVENTS EVENT':
+ $cur_line = xml_get_current_line_number($parser);
+ if ($cur_line != $this->LastLine) {
+ $this->current_event['Template'] .= str_repeat("\r\n", ($cur_line - $this->LastLine) );
+ $this->LastLine = $cur_line;
+ }
+ $this->current_event['Template'] .= $line;
+
+ $this->SecondData = true;
+ break;
+ }
+ }
+ }
+
+ function endElement(&$parser, $element)
+ {
+ $path = implode(' ',$this->path);
+
+ switch($path)
+ {
+ case 'LANGUAGES LANGUAGE PHRASES PHRASE':
+ if( isset($this->phrase_types_allowed[ $this->current_phrase['PhraseType'] ]) )
+ {
+ if ($this->current_language['Encoding'] == 'plain') {
+ // nothing to decode!
+ }
+ else {
+ $this->current_phrase['Translation'] = base64_decode($this->current_phrase['Translation']);
+ }
+ $this->insertRecord($this->tables['phrases'], $this->current_phrase);
+ }
+ break;
+
+ case 'LANGUAGES LANGUAGE EVENTS EVENT':
+ if ($this->current_language['Encoding'] == 'plain') {
+ $this->current_event['Template'] = rtrim($this->current_event['Template']);
+ // nothing to decode!
+ }
+ else {
+ $this->current_event['Template'] = base64_decode($this->current_event['Template']);
+ }
+ $this->insertRecord($this->tables['emailmessages'],$this->current_event);
+ break;
+ }
+
+ array_pop($this->path);
+ }
+
+ function insertRecord($table, $fields_hash)
+ {
+ $fields = '';
+ $values = '';
+
+ foreach($fields_hash as $field_name => $field_value)
+ {
+ $fields .= '`'.$field_name.'`,';
+ $values .= $this->Conn->qstr($field_value).',';
+ }
+
+ $fields = preg_replace('/(.*),$/', '\\1', $fields);
+ $values = preg_replace('/(.*),$/', '\\1', $values);
+
+ $sql = 'INSERT INTO `'.$table.'` ('.$fields.') VALUES ('.$values.')';
+ $this->Conn->Query($sql);
+
+// return $this->Conn->getInsertID(); // no need because of temp table without auto_increment column at all
+ }
+
+ /**
+ * Creates XML file with exported language data
+ *
+ * @param string $filename filename to export into
+ * @param Array $phrase_types phrases types to export from modules passed in $module_ids
+ * @param Array $language_ids IDs of languages to export
+ * @param Array $module_ids IDs of modules to export phrases from
+ */
+ function Create($filename, $phrase_types, $language_ids, $module_ids)
+ {
+ $fp = fopen($filename,'w');
+ if(!$fp || !$phrase_types || !$module_ids || !$language_ids) return false;
+
+ $phrase_types = explode('|', substr($phrase_types, 1, -1) );
+ $module_ids = explode('|', substr($module_ids, 1, -1) );
+
+ $this->events_hash = array_flip($this->events_hash);
+
+ $lang_table = $this->Application->getUnitOption('lang','TableName');
+ $phrases_table = $this->Application->getUnitOption('phrases','TableName');
+ $emailevents_table = $this->Application->getUnitOption('emailmessages','TableName');
+ $mainevents_table = $this->Application->getUnitOption('emailevents','TableName');
+
+ $phrase_tpl = "\t\t\t".'<PHRASE Label="%s" Module="%s" Type="%s">%s</PHRASE>'."\n";
+ $event_tpl = "\t\t\t".'<EVENT MessageType="%s" Event="%s" Type="%s">%s</EVENT>'."\n";
+ $sql = 'SELECT * FROM %s WHERE LanguageId = %s';
+ $ret = '<LANGUAGES>'."\n";
+ foreach($language_ids as $language_id)
+ {
+ // languages
+ $row = $this->Conn->GetRow( sprintf($sql, $lang_table, $language_id) );
+ $ret .= "\t".'<LANGUAGE PackName="'.$row['PackName'].'" Encoding="'.$this->Encoding.'"><DATEFORMAT>'.$row['DateFormat'].'</DATEFORMAT>';
+ $ret .= '<TIMEFORMAT>'.$row['TimeFormat'].'</TIMEFORMAT><INPUTDATEFORMAT>'.$row['InputDateFormat'].'</INPUTDATEFORMAT>';
+ $ret .= '<INPUTTIMEFORMAT>'.$row['InputTimeFormat'].'</INPUTTIMEFORMAT><DECIMAL>'.$row['DecimalPoint'].'</DECIMAL>';
+ $ret .= '<THOUSANDS>'.$row['ThousandSep'].'</THOUSANDS><CHARSET>'.$row['Charset'].'</CHARSET>';
+ $ret .= '<UNITSYSTEM>'.$row['UnitSystem'].'</UNITSYSTEM>'."\n";
+
+ // phrases
+ $phrases_sql = 'SELECT * FROM '.$phrases_table.' WHERE LanguageId = %s AND PhraseType IN (%s) AND Module IN (%s) ORDER BY Phrase';
+ if( in_array('In-Portal',$module_ids) ) array_push($module_ids, ''); // for old language packs
+ $rows = $this->Conn->Query( sprintf($phrases_sql,$language_id, implode(',',$phrase_types), '\''.implode('\',\'',$module_ids).'\'' ) );
+ if($rows)
+ {
+ $ret .= "\t\t".'<PHRASES>'."\n";
+ foreach($rows as $row)
+ {
+ $data = $this->Encoding == 'base64' ? base64_encode($row['Translation']) : '<![CDATA['.$row['Translation'].']]>';
+ $ret .= sprintf($phrase_tpl, $row['Phrase'], $row['Module'], $row['PhraseType'], $data );
+ }
+ $ret .= "\t\t".'</PHRASES>'."\n";
+ }
+
+ // email events
+ if( in_array('In-Portal',$module_ids) ) unset( $module_ids[array_search('',$module_ids)] ); // for old language packs
+ $module_sql = preg_replace('/(.*) OR $/', '\\1', preg_replace('/(.*),/U', 'INSTR(Module,\'\\1\') OR ', implode(',', $module_ids).',' ) );
+
+ $sql = 'SELECT EventId FROM '.$mainevents_table.' WHERE '.$module_sql;
+ $event_ids = $this->Conn->GetCol($sql);
+
+ if($event_ids)
+ {
+ $ret .= "\t\t".'<EVENTS>'."\n";
+ $event_sql = ' SELECT em.*
+ FROM '.$emailevents_table.' em
+ LEFT JOIN '.$mainevents_table.' e ON e.EventId = em.EventId
+ WHERE em.LanguageId = %s AND em.EventId IN (%s)
+ ORDER BY e.Event, e.Type';
+ $rows = $this->Conn->Query( sprintf($event_sql,$language_id, $event_ids ? implode(',',$event_ids) : '' ) );
+ foreach($rows as $row)
+ {
+ list($event_name, $event_type) = explode('_', $this->events_hash[ $row['EventId'] ] );
+ $data = $this->Encoding == 'base64' ? base64_encode($row['Template']) : '<![CDATA['.$row['Template'].']]>';
+ $ret .= sprintf($event_tpl, $row['MessageType'], $event_name, $event_type, $data );
+ }
+ $ret .= "\t\t".'</EVENTS>'."\n";
+ }
+ $ret .= "\t".'</LANGUAGE>'."\n";
+ }
+
+ $ret .= '</LANGUAGES>';
+ fwrite($fp, $ret);
+ fclose($fp);
+ return true;
+ }
+
+ /**
+ * Creates new instance of LangXML_Parser class
+ *
+ * @param int $type
+ * @return LangXML_Parser
+ */
+ function &makeClass($temp_mode = true)
+ {
+ $result = new LangXML_Parser($temp_mode);
+ return $result;
+ }
+ }
+
+?>
\ No newline at end of file
Property changes on: branches/unlabeled/unlabeled-1.23.2/core/units/languages/import_xml.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.23
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.23.2/core/units/general/cat_dbitem_export.php
===================================================================
--- branches/unlabeled/unlabeled-1.23.2/core/units/general/cat_dbitem_export.php (nonexistent)
+++ branches/unlabeled/unlabeled-1.23.2/core/units/general/cat_dbitem_export.php (revision 7645)
@@ -0,0 +1,1388 @@
+<?php
+
+ define('EXPORT_STEP', 100); // export by 200 items (e.g. links)
+ define('IMPORT_STEP', 20); // export by 200 items (e.g. links)
+ define('IMPORT_CHUNK', 10240); // 10240); //30720); //50120); // 5 KB
+
+ define('IMPORT_TEMP', 1);
+ define('IMPORT_LIVE', 2);
+
+ class kCatDBItemExportHelper extends kHelper {
+
+ var $false = false;
+
+ var $cache = Array();
+
+ /**
+ * Allows to find out what items are new in cache
+ *
+ * @var Array
+ */
+ var $cacheStatus = Array();
+
+ var $cacheTable = '';
+
+ var $exportFields = Array();
+
+ /**
+ * Export options
+ *
+ * @var Array
+ */
+ var $exportOptions = Array();
+
+ /**
+ * Item beeing currenly exported
+ *
+ * @var kCatDBItem
+ */
+ var $curItem = null;
+
+ /**
+ * Dummy category object
+ *
+ * @var CategoriesItem
+ */
+ var $dummyCategory = null;
+
+ /**
+ * Pointer to opened file
+ *
+ * @var resource
+ */
+ var $filePointer = null;
+
+ /**
+ * Custom fields definition of current item
+ *
+ * @var Array
+ */
+ var $customFields = Array();
+
+ function kCatDBItemExportHelper()
+ {
+ parent::kHelper();
+ $this->cacheTable = TABLE_PREFIX.'ImportCache';
+ }
+
+ /**
+ * Returns value from cache if found or false otherwise
+ *
+ * @param string $type
+ * @param int $key
+ * @return mixed
+ */
+ function getFromCache($type, $key)
+ {
+ return getArrayValue($this->cache, $type, $key);
+ }
+
+ /**
+ * Adds value to be cached
+ *
+ * @param string $type
+ * @param int $key
+ * @param mixed $value
+ */
+ function addToCache($type, $key, $value, $is_new = true)
+ {
+// if (!isset($this->cache[$type])) $this->cache[$type] = Array();
+ $this->cache[$type][$key] = $value;
+ if ($is_new) {
+ $this->cacheStatus[$type][$key] = true;
+ }
+ }
+
+ function storeCache($cache_types)
+ {
+ $cache_types = explode(',', $cache_types);
+
+ $values_sql = '';
+ foreach ($cache_types as $cache_type) {
+ $sql_mask = '('.$this->Conn->qstr($cache_type).',%s,%s),';
+ $cache = getArrayValue($this->cacheStatus, $cache_type);
+ if (!$cache) $cache = Array();
+ foreach ($cache as $var_name => $cache_status) {
+ $var_value = $this->cache[$cache_type][$var_name];
+ $values_sql .= sprintf($sql_mask, $this->Conn->qstr($var_name), $this->Conn->qstr($var_value) );
+ }
+ }
+ $values_sql = preg_replace('/(.*),$/', '\\1', $values_sql);
+ if ($values_sql) {
+ $sql = 'INSERT INTO '.$this->cacheTable.'(`CacheName`,`VarName`,`VarValue`) VALUES '.$values_sql;
+ $this->Conn->Query($sql);
+ }
+
+ }
+
+ function loadCache()
+ {
+ $sql = 'SELECT * FROM '.$this->cacheTable;
+ $records = $this->Conn->Query($sql);
+
+ $this->cache = Array();
+ foreach ($records as $record) {
+ $this->addToCache($record['CacheName'], $record['VarName'], $record['VarValue'], false);
+ }
+ }
+
+ /**
+ * Fill required fields with dummy values
+ *
+ * @param kEvent $event
+ */
+ function fillRequiredFields(&$event, &$object, $set_status = false)
+ {
+ if ($object == $this->false) {
+ $object =& $event->getObject();
+ }
+
+ $has_empty = false;
+ $fields = array_keys($object->Fields);
+ foreach ($fields as $field_name)
+ {
+ $field_options =& $object->Fields[$field_name];
+ if (isset($object->VirtualFields[$field_name]) || !getArrayValue($field_options, 'required') ) continue;
+ if ( $object->GetDBField($field_name) ) continue;
+
+ $formatter_class = getArrayValue($field_options, 'formatter');
+ if ($formatter_class) // not tested
+ {
+ $formatter =& $this->Application->recallObject($formatter_class);
+ $sample_value = $formatter->GetSample($field_name, $field_options, $object);
+ }
+
+ $has_empty = true;
+ $object->SetField($field_name, isset($sample_value) && $sample_value ? $sample_value : 'no value');
+ }
+ $object->UpdateFormattersSubFields();
+
+ if ($set_status && $has_empty) {
+ $object->SetDBField('Status', 0);
+ }
+ }
+
+ /**
+ * Verifies that all user entered export params are correct
+ *
+ * @param kEvent $event
+ */
+ function verifyOptions(&$event)
+ {
+ if ($this->Application->RecallVar($event->getPrefixSpecial().'_ForceNotValid'))
+ {
+ $this->Application->StoreVar($event->getPrefixSpecial().'_ForceNotValid', 0);
+ return false;
+ }
+
+ $this->fillRequiredFields($event, $this->false);
+
+ $object =& $event->getObject();
+ $cross_unique_fields = Array('FieldsSeparatedBy', 'FieldsEnclosedBy');
+ if (($object->GetDBField('CategoryFormat') == 1) || ($event->Special == 'import')) // in one field
+ {
+ $object->setRequired('CategorySeparator', true);
+ $cross_unique_fields[] = 'CategorySeparator';
+ }
+
+ $ret = $object->Validate();
+
+ // check if cross unique fields has no same values
+ foreach ($cross_unique_fields as $field_index => $field_name)
+ {
+ if (getArrayValue($object->FieldErrors, $field_name, 'pseudo') == 'required') continue;
+
+ $check_fields = $cross_unique_fields;
+ unset($check_fields[$field_index]);
+
+ foreach ($check_fields as $check_field)
+ {
+ if ($object->GetDBField($field_name) == $object->GetDBField($check_field))
+ {
+ $object->SetError($check_field, 'unique');
+ }
+ }
+ }
+
+ if ($event->Special == 'import')
+ {
+ $this->exportOptions = $this->loadOptions($event);
+
+ $automatic_fields = ($object->GetDBField('FieldTitles') == 1);
+ $object->setRequired('ExportColumns', !$automatic_fields);
+ $category_prefix = '__CATEGORY__';
+ if ( $automatic_fields && ($this->exportOptions['SkipFirstRow']) ) {
+ $this->openFile($event);
+ $this->exportOptions['ExportColumns'] = $this->readRecord();
+ $this->closeFile();
+
+ // remove additional (non-parseble columns)
+ foreach ($this->exportOptions['ExportColumns'] as $field_index => $field_name) {
+ if (!$this->validateField($field_name, $object)) {
+ unset($this->exportOptions['ExportColumns'][$field_index]);
+ }
+ }
+ $category_prefix = '';
+ }
+
+ // 1. check, that we have column definitions
+ if (!$this->exportOptions['ExportColumns']) {
+ $object->setError('ExportColumns', 'required');
+ $ret = false;
+ }
+ else {
+ // 1.1. check that all required fields are present in imported file
+ $missing_columns = Array();
+ foreach ($object->Fields as $field_name => $field_options) {
+ if ($object->SkipField($field_name)) continue;
+ if (getArrayValue($field_options, 'required') && !in_array($field_name, $this->exportOptions['ExportColumns']) ) {
+ $missing_columns[] = $field_name;
+ $object->setError('ExportColumns', 'required_fields_missing', 'la_error_RequiredColumnsMissing');
+ $ret = false;
+ }
+ }
+
+ if (!$ret && $this->Application->isDebugMode()) {
+ $this->Application->Debugger->appendHTML('Missing required for import/export:');
+ $this->Application->Debugger->dumpVars($missing_columns);
+ }
+ }
+
+
+ // 2. check, that we have only mixed category field or only separated category fields
+ $category_found['mixed'] = false;
+ $category_found['separated'] = false;
+
+ foreach ($this->exportOptions['ExportColumns'] as $import_field) {
+ if (preg_match('/^'.$category_prefix.'Category(Path|[0-9]+)/', $import_field, $rets)) {
+ $category_found[$rets[1] == 'Path' ? 'mixed' : 'separated'] = true;
+ }
+ }
+ if ($category_found['mixed'] && $category_found['separated']) {
+ $object->SetError('ExportColumns', 'unique_category', 'la_error_unique_category_field');
+ $ret = false;
+ }
+
+ // 3. check, that duplicates check fields are selected & present in imported fields
+ if ($this->exportOptions['ReplaceDuplicates']) {
+ if ($this->exportOptions['CheckDuplicatesMethod'] == 1) {
+ $check_fields = Array($object->IDField);
+ }
+ else {
+ $check_fields = $this->exportOptions['DuplicateCheckFields'] ? explode('|', substr($this->exportOptions['DuplicateCheckFields'], 1, -1)) : Array();
+ $object =& $event->getObject();
+
+ $language_id = $this->Application->GetDefaultLanguageId();
+ foreach ($check_fields as $index => $check_field) {
+ foreach ($object->Fields as $field_name => $field_options) {
+ if ($field_name == 'l'.$language_id.'_'.$check_field) {
+ $check_fields[$index] = 'l'.$language_id.'_'.$check_field;
+ break;
+ }
+ }
+ }
+ }
+ $this->exportOptions['DuplicateCheckFields'] = $check_fields;
+
+ if (!$check_fields) {
+ $object->setError('CheckDuplicatesMethod', 'required');
+ $ret = false;
+ }
+ else {
+ foreach ($check_fields as $check_field) {
+ $check_field = preg_replace('/^cust_(.*)/', 'Custom_\\1', $check_field);
+ if (!in_array($check_field, $this->exportOptions['ExportColumns'])) {
+ $object->setError('ExportColumns', 'required');
+ $ret = false;
+ break;
+ }
+ }
+ }
+ }
+ $this->saveOptions($event);
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Returns filename to read import data from
+ *
+ * @return string
+ */
+ function getImportFilename()
+ {
+ if ($this->exportOptions['ImportSource'] == 1)
+ {
+ $ret = $this->exportOptions['ImportFilename']; // ['name']; commented by Kostja
+ }
+ else {
+ $ret = $this->exportOptions['ImportLocalFilename'];
+ }
+ return EXPORT_PATH.'/'.$ret;
+ }
+
+ /**
+ * Returns filename to write export data to
+ *
+ * @return string
+ */
+ function getExportFilename()
+ {
+ return EXPORT_PATH.'/'.$this->exportOptions['ExportFilename'].'.'.$this->getFileExtension();
+ }
+
+ /**
+ * Opens file required for export/import operations
+ *
+ * @param kEvent $event
+ */
+ function openFile(&$event)
+ {
+ if ($event->Special == 'export') {
+ $write_mode = ($this->exportOptions['start_from'] == 0) ? 'w' : 'a';
+ $this->filePointer = fopen($this->getExportFilename(), $write_mode);
+ }
+ else {
+ $this->filePointer = fopen($this->getImportFilename(), 'r');
+ }
+
+ // skip UTF-8 BOM Modifier
+ $first_chars = fread($this->filePointer, 3);
+ if (bin2hex($first_chars) != 'efbbbf') {
+ fseek($this->filePointer, 0);
+ }
+ }
+
+ /**
+ * Closes opened file
+ *
+ */
+ function closeFile()
+ {
+ fclose($this->filePointer);
+ }
+
+ function getCustomSQL()
+ {
+ $ml_formatter =& $this->Application->recallObject('kMultiLanguage');
+
+ $custom_sql = '';
+ foreach ($this->customFields as $custom_id => $custom_name) {
+ $custom_sql .= 'custom_data.'.$ml_formatter->LangFieldName('cust_'.$custom_id).' AS cust_'.$custom_name.', ';
+ }
+
+ return preg_replace('/(.*), /', '\\1', $custom_sql);
+ }
+
+ function getPlainExportSQL($count_only = false) {
+ if ($count_only && isset($this->exportOptions['ForceCountSQL'])) {
+ $sql = $this->exportOptions['ForceCountSQL'];
+ }
+ elseif (!$count_only && isset($this->exportOptions['ForceSelectSQL'])) {
+ $sql = $this->exportOptions['ForceSelectSQL'];
+ }
+ else {
+ $items_list =& $this->Application->recallObject($this->curItem->Prefix.'.export-items-list', $this->curItem->Prefix.'_List');
+ $items_list->SetPerPage(-1);
+
+ if ($options['export_ids'] != '') {
+ $items_list->AddFilter('export_ids', $items_list->TableName.'.'.$items_list->IDField.' IN ('.implode(',',$options['export_ids']).')');
+ }
+
+ if ($count_only) {
+ $sql = $items_list->getCountSQL( $items_list->GetSelectSQL(true,false) );
+ }
+ else {
+ $sql = $items_list->GetSelectSQL();
+ }
+ }
+
+ if (!$count_only)
+ {
+ $sql .= ' LIMIT '.$this->exportOptions['start_from'].','.EXPORT_STEP;
+ }
+// else {
+// $sql = preg_replace("/^.*SELECT(.*?)FROM(?!_)/is", "SELECT COUNT(*) AS count FROM ", $sql);
+// }
+
+ return $sql;
+ }
+
+ function getExportSQL($count_only = false)
+ {
+ if (!$this->Application->getUnitOption($this->curItem->Prefix, 'CatalogItem')) {
+ return $this->GetPlainExportSQL($count_only); // in case this is not a CategoryItem
+ }
+
+ if ($this->exportOptions['export_ids'] === false)
+ {
+ // get links from current category & all it's subcategories
+ $join_clauses = Array();
+
+ $custom_sql = $this->getCustomSQL();
+ if ($custom_sql) {
+ $custom_table = $this->Application->getUnitOption($this->curItem->Prefix.'-cdata', 'TableName');
+ $join_clauses[$custom_table.' custom_data'] = 'custom_data.ResourceId = item_table.ResourceId';
+ }
+
+ $join_clauses[TABLE_PREFIX.'CategoryItems ci'] = 'ci.ItemResourceId = item_table.ResourceId';
+ $join_clauses[TABLE_PREFIX.'Category c'] = 'c.CategoryId = ci.CategoryId';
+
+ $sql = 'SELECT item_table.*, ci.CategoryId'.($custom_sql ? ', '.$custom_sql : '').'
+ FROM '.$this->curItem->TableName.' item_table';
+
+ foreach ($join_clauses as $table_name => $join_expression) {
+ $sql .= ' LEFT JOIN '.$table_name.' ON '.$join_expression;
+ }
+ $sql .= ' WHERE ';
+
+ if ($this->exportOptions['export_cats_ids'][0] == 0)
+ {
+ $sql .= '1';
+ }
+ else {
+ foreach ($this->exportOptions['export_cats_ids'] as $category_id) {
+ $sql .= '(c.ParentPath LIKE "%|'.$category_id.'|%") OR ';
+ }
+ $sql = preg_replace('/(.*) OR $/', '\\1', $sql);
+ }
+
+ $sql .= ' ORDER BY ci.PrimaryCat DESC'; // NEW
+ }
+ else {
+ // get only selected links
+ $sql = 'SELECT item_table.*, '.$this->exportOptions['export_cats_ids'][0].' AS CategoryId
+ FROM '.$this->curItem->TableName.' item_table
+ WHERE '.$this->curItem->IDField.' IN ('.implode(',', $this->exportOptions['export_ids']).')';
+ }
+
+ if (!$count_only)
+ {
+ $sql .= ' LIMIT '.$this->exportOptions['start_from'].','.EXPORT_STEP;
+ }
+ else {
+ $sql = preg_replace("/^.*SELECT(.*?)FROM(?!_)/is", "SELECT COUNT(*) AS count FROM ", $sql);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param kEvent $event
+ */
+ function performExport(&$event)
+ {
+ $this->exportOptions = $this->loadOptions($event);
+ $this->exportFields = $this->exportOptions['ExportColumns'];
+ $this->curItem =& $event->getObject( Array('skip_autoload' => true) );
+ $this->customFields = $this->Application->getUnitOption($event->Prefix, 'CustomFields');
+ $this->openFile($event);
+
+ if ($this->exportOptions['start_from'] == 0) // first export step
+ {
+ if (!getArrayValue($this->exportOptions, 'IsBaseCategory')) {
+ $this->exportOptions['IsBaseCategory'] = 0;
+ }
+
+ if ($this->exportOptions['IsBaseCategory'] ) {
+ $sql = 'SELECT ParentPath
+ FROM '.TABLE_PREFIX.'Category
+ WHERE CategoryId = '.$this->Application->GetVar('m_cat_id');
+ $this->exportOptions['BaseLevel'] = substr_count($this->Conn->GetOne($sql), '|') - 1; // level to cut from other categories
+ }
+
+ // 1. export field titles if required
+ if ($this->exportOptions['IncludeFieldTitles'])
+ {
+ $data_array = Array();
+ foreach ($this->exportFields as $export_field)
+ {
+ $data_array = array_merge($data_array, $this->getFieldCaption($export_field));
+ }
+ $this->writeRecord($data_array);
+ }
+ $this->exportOptions['total_records'] = $this->Conn->GetOne( $this->getExportSQL(true) );
+ }
+
+ // 2. export data
+ $records = $this->Conn->Query( $this->getExportSQL() );
+ $records_exported = 0;
+ foreach ($records as $record_info) {
+ $this->curItem->Clear();
+ $this->curItem->SetDBFieldsFromHash($record_info);
+ $this->setCurrentID();
+ $this->curItem->raiseEvent('OnAfterItemLoad', $this->curItem->GetID() );
+
+ $data_array = Array();
+ foreach ($this->exportFields as $export_field)
+ {
+ $data_array = array_merge($data_array, $this->getFieldValue($export_field) );
+ }
+ $this->writeRecord($data_array);
+ $records_exported++;
+ }
+ $this->closeFile();
+
+ $this->exportOptions['start_from'] += $records_exported;
+ $this->saveOptions($event);
+
+ return $this->exportOptions;
+ }
+
+ function getItemFields()
+ {
+ // just in case dummy user selected automtic mode & moved columns too :(
+ return array_merge($this->curItem->Fields['AvailableColumns']['options'], $this->curItem->Fields['ExportColumns']['options']);
+ }
+
+ /**
+ * Checks if field really belongs to importable field list
+ *
+ * @param string $field_name
+ * @param kCatDBItem $object
+ * @return bool
+ */
+ function validateField($field_name, &$object)
+ {
+ // 1. convert custom field
+ $field_name = preg_replace('/^Custom_(.*)/', '__CUSTOM__\\1', $field_name);
+
+ // 2. convert category field (mixed version & serparated version)
+ $field_name = preg_replace('/^Category(Path|[0-9]+)/', '__CATEGORY__Category\\1', $field_name);
+
+ $valid_fields = $object->getPossibleExportColumns();
+ return isset($valid_fields[$field_name]) || isset($valid_fields['__VIRTUAL__'.$field_name]);
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param kEvent $event
+ */
+ function performImport(&$event)
+ {
+ if (!$this->exportOptions) {
+ // load import options in case if not previously loaded in verification function
+ $this->exportOptions = $this->loadOptions($event);
+ }
+
+ $backup_category_id = $this->Application->GetVar('m_cat_id');
+ $this->Application->SetVar('m_cat_id', (int)$this->Application->RecallVar('ImportCategory') );
+
+ $this->openFile($event);
+
+ $bytes_imported = 0;
+ if ($this->exportOptions['start_from'] == 0) // first export step
+ {
+ // 1st time run
+ if ($this->exportOptions['SkipFirstRow']) {
+ $this->readRecord();
+ $this->exportOptions['start_from'] = ftell($this->filePointer);
+ $bytes_imported = ftell($this->filePointer);
+ }
+
+ $current_category_id = $this->Application->GetVar('m_cat_id');
+ if ($current_category_id > 0) {
+ $sql = 'SELECT ParentPath FROM '.TABLE_PREFIX.'Category WHERE CategoryId = '.$current_category_id;
+ $this->exportOptions['ImportCategoryPath'] = $this->Conn->GetOne($sql);
+ }
+ else {
+ $this->exportOptions['ImportCategoryPath'] = '';
+ }
+ $this->exportOptions['total_records'] = filesize($this->getImportFilename());
+ }
+ else {
+ $this->loadCache();
+ }
+
+ $this->exportFields = $this->exportOptions['ExportColumns'];
+ $this->addToCache('category_parent_path', $this->Application->GetVar('m_cat_id'), $this->exportOptions['ImportCategoryPath']);
+
+ // 2. import data
+ $this->dummyCategory =& $this->Application->recallObject('c.-tmpitem', 'c', Array('skip_autoload' => true));
+ fseek($this->filePointer, $this->exportOptions['start_from']);
+
+ $items_processed = 0;
+ while (($bytes_imported < IMPORT_CHUNK && $items_processed < IMPORT_STEP) && !feof($this->filePointer)) {
+ $data = $this->readRecord();
+ if ($data) {
+ if ($this->exportOptions['ReplaceDuplicates']) {
+ // set fields used as keys for replace duplicates code
+ $this->resetImportObject($event, IMPORT_TEMP, $data);
+ }
+
+ $this->processCurrentItem($event, $data);
+ }
+ $bytes_imported = ftell($this->filePointer) - $this->exportOptions['start_from'];
+ $items_processed++;
+ }
+
+ $this->closeFile();
+ $this->Application->SetVar('m_cat_id', $backup_category_id);
+
+ $this->exportOptions['start_from'] += $bytes_imported;
+ $this->storeCache('new_ids');
+
+ $this->saveOptions($event);
+
+ if ($this->exportOptions['start_from'] == $this->exportOptions['total_records']) {
+ $this->Conn->Query('TRUNCATE TABLE '.$this->cacheTable);
+ }
+
+ return $this->exportOptions;
+ }
+
+ function setCurrentID()
+ {
+ $this->curItem->setID( $this->curItem->GetDBField($this->curItem->IDField) );
+ }
+
+ function setFieldValue($field_index, $value)
+ {
+ if (empty($value)) {
+ $value = null;
+ }
+
+ $field_name = getArrayValue($this->exportFields, $field_index);
+ if ($field_name == 'ResourceId') {
+ return false;
+ }
+
+ if (substr($field_name, 0, 7) == 'Custom_') {
+ $field_name = 'cust_'.substr($field_name, 7);
+ $this->curItem->SetField($field_name, $value);
+ }
+ elseif ($field_name == 'CategoryPath' || $field_name == '__CATEGORY__CategoryPath') {
+ $this->curItem->CategoryPath = $value ? explode($this->exportOptions['CategorySeparator'], $value) : Array();
+ }
+ elseif (substr($field_name, 0, 8) == 'Category') {
+ $this->curItem->CategoryPath[ (int)substr($field_name, 8) - 1 ] = $value;
+ }
+ elseif (substr($field_name, 0, 20) == '__CATEGORY__Category') {
+ $this->curItem->CategoryPath[ (int)substr($field_name, 20) ] = $value;
+ }
+ elseif (substr($field_name, 0, 11) == '__VIRTUAL__') {
+ $field_name = substr($field_name, 11);
+ $this->curItem->SetField($field_name, $value);
+ }
+ else {
+ $this->curItem->SetField($field_name, $value);
+ }
+
+ $pseudo_error = getArrayValue($this->curItem->FieldErrors, $field_name, 'pseudo');
+ if ($pseudo_error) {
+ $this->curItem->SetDBField($field_name, null);
+ unset($this->curItem->FieldErrors[$field_name]);
+ }
+ }
+
+ function resetImportObject(&$event, $object_type, $record_data = null)
+ {
+ switch ($object_type) {
+ case IMPORT_TEMP:
+ $this->curItem =& $event->getObject( Array('skip_autoload' => true) );
+ break;
+
+ case IMPORT_LIVE:
+ $this->curItem =& $this->Application->recallObject($event->Prefix.'.-tmpitem'.$event->Special, $event->Prefix, Array('skip_autoload' => true));
+ break;
+ }
+ $this->curItem->Clear();
+ $this->customFields = $this->Application->getUnitOption($event->Prefix, 'CustomFields');
+
+ if (isset($record_data)) {
+ $this->setImportData($record_data);
+ }
+ }
+
+ function setImportData($record_data)
+ {
+ foreach ($record_data as $field_index => $field_value) {
+ $this->setFieldValue($field_index, $field_value);
+ }
+ $this->setCurrentID();
+ }
+
+
+ function getItemCategory()
+ {
+ static $lang_prefix = null;
+ $backup_category_id = $this->Application->GetVar('m_cat_id');
+
+ $category_id = $this->getFromCache('category_names', implode(':', $this->curItem->CategoryPath));
+ if ($category_id) {
+ $this->Application->SetVar('m_cat_id', $category_id);
+ return $category_id;
+ }
+
+ if (is_null($lang_prefix)) {
+ $lang_prefix = 'l'.$this->Application->GetVar('m_lang').'_';
+ }
+
+ foreach ($this->curItem->CategoryPath as $category_index => $category_name) {
+ if (!$category_name) continue;
+ $category_key = crc32( implode(':', array_slice($this->curItem->CategoryPath, 0, $category_index + 1) ) );
+
+ $category_id = $this->getFromCache('category_names', $category_key);
+ if ($category_id === false) {
+ // get parent category path to search only in it
+ $current_category_id = $this->Application->GetVar('m_cat_id');
+// $parent_path = $this->getParentPath($current_category_id);
+
+ // get category id from database by name
+ $sql = 'SELECT CategoryId
+ FROM '.TABLE_PREFIX.'Category
+ WHERE ('.$lang_prefix.'Name = '.$this->Conn->qstr($category_name).') AND (ParentId = '.$current_category_id.')';
+ $category_id = $this->Conn->GetOne($sql);
+
+ if ($category_id === false) {
+ // category not in db -> create
+ $category_fields = Array( $lang_prefix.'Name' => $category_name, $lang_prefix.'Description' => $category_name,
+ 'Status' => STATUS_ACTIVE, 'ParentId' => $current_category_id, 'AutomaticFilename' => 1
+ );
+ $this->dummyCategory->SetDBFieldsFromHash($category_fields);
+ if ($this->dummyCategory->Create()) {
+ $category_id = $this->dummyCategory->GetID();
+ $this->addToCache('category_parent_path', $category_id, $this->dummyCategory->GetDBField('ParentPath'));
+ $this->addToCache('category_names', $category_key, $category_id);
+ }
+ }
+ else {
+ $this->addToCache('category_names', $category_key, $category_id);
+ }
+ }
+
+ if ($category_id) {
+ $this->Application->SetVar('m_cat_id', $category_id);
+ }
+ }
+ if (!$this->curItem->CategoryPath) {
+ $category_id = $backup_category_id;
+ }
+
+ return $category_id;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param kEvent $event
+ */
+ function processCurrentItem(&$event, $record_data)
+ {
+ $save_method = 'Create';
+ $load_keys = Array();
+
+ // create/update categories
+ $backup_category_id = $this->Application->GetVar('m_cat_id');
+
+ // perform replace duplicates code
+ if ($this->exportOptions['ReplaceDuplicates']) {
+ // get replace keys first, then reset current item to empty one
+ $category_id = $this->getItemCategory();
+ if ($this->exportOptions['CheckDuplicatesMethod'] == 1) {
+ if ($this->curItem->GetID()) {
+ $load_keys = Array($this->curItem->IDField => $this->curItem->GetID());
+ }
+ }
+ else {
+ $key_fields = $this->exportOptions['DuplicateCheckFields'];
+ foreach ($key_fields as $key_field) {
+ $load_keys[$key_field] = $this->curItem->GetDBField($key_field);
+ }
+ }
+
+ $this->resetImportObject($event, IMPORT_LIVE);
+
+ if (count($load_keys)) {
+ $where_clause = '';
+ foreach ($load_keys as $field_name => $field_value) {
+ if (preg_match('/^cust_(.*)/', $field_name, $regs)) {
+ $custom_id = array_search($regs[1], $this->customFields);
+ $field_name = 'l'.$this->Application->GetVar('m_lang').'_cust_'.$custom_id;
+ $where_clause .= '(custom_data.`'.$field_name.'` = '.$this->Conn->qstr($field_value).') AND ';
+ }
+ else {
+ $where_clause .= '(item_table.`'.$field_name.'` = '.$this->Conn->qstr($field_value).') AND ';
+ }
+
+ }
+ $where_clause = preg_replace('/(.*) AND $/', '\\1', $where_clause);
+
+ $item_id = $this->getFromCache('new_ids', crc32($where_clause));
+ if (!$item_id) {
+ if ($this->exportOptions['CheckDuplicatesMethod'] == 2) {
+ // by other fields
+ $parent_path = $this->getParentPath($category_id);
+ $where_clause = '(c.ParentPath LIKE "'.$parent_path.'%") AND '.$where_clause;
+ }
+
+ $cdata_table = $this->Application->getUnitOption($event->Prefix.'-cdata', 'TableName');
+ $sql = 'SELECT '.$this->curItem->IDField.'
+ FROM '.$this->curItem->TableName.' item_table
+ LEFT JOIN '.$cdata_table.' custom_data ON custom_data.ResourceId = item_table.ResourceId
+ LEFT JOIN '.TABLE_PREFIX.'CategoryItems ci ON ci.ItemResourceId = item_table.ResourceId
+ LEFT JOIN '.TABLE_PREFIX.'Category c ON c.CategoryId = ci.CategoryId
+ WHERE '.$where_clause;
+ $item_id = $this->Conn->GetOne($sql);
+ }
+ $save_method = $item_id && $this->curItem->Load($item_id) ? 'Update' : 'Create';
+ if ($save_method == 'Update') {
+ // replace id from csv file with found id
+ $record_data[ array_search($this->curItem->IDField, $this->exportFields) ] = $item_id;
+ }
+ }
+
+ $this->setImportData($record_data);
+ }
+ else {
+ $this->resetImportObject($event, IMPORT_LIVE, $record_data);
+ $category_id = $this->getItemCategory();
+ }
+
+ // create main record
+ if ($save_method == 'Create') {
+ $this->fillRequiredFields($this->false, $this->curItem, true);
+ }
+
+// $sql_start = getmicrotime();
+ if (!$this->curItem->$save_method()) {
+ $this->Application->SetVar('m_cat_id', $backup_category_id);
+ return false;
+ }
+// $sql_end = getmicrotime();
+// $this->saveLog('SQL ['.$save_method.'] Time: '.($sql_end - $sql_start).'s');
+
+ if ($load_keys && ($save_method == 'Create') && $this->exportOptions['ReplaceDuplicates']) {
+ // map new id to old id
+ $this->addToCache('new_ids', crc32($where_clause), $this->curItem->GetID() );
+ }
+
+ // assign item to categories
+ $this->curItem->assignToCategory($category_id, false);
+
+ $this->Application->SetVar('m_cat_id', $backup_category_id);
+ return true;
+ }
+
+ /*function saveLog($msg)
+ {
+ static $first_time = true;
+
+ $fp = fopen(FULL_PATH.'/sqls.log', $first_time ? 'w' : 'a');
+ fwrite($fp, $msg."\n");
+ fclose($fp);
+
+ $first_time = false;
+ }*/
+
+ /**
+ * Returns category parent path, if possible, then from cache
+ *
+ * @param int $category_id
+ * @return string
+ */
+ function getParentPath($category_id)
+ {
+ $parent_path = $this->getFromCache('category_parent_path', $category_id);
+ if ($parent_path === false) {
+ $sql = 'SELECT ParentPath
+ FROM '.TABLE_PREFIX.'Category
+ WHERE CategoryId = '.$category_id;
+ $parent_path = $this->Conn->GetOne($sql);
+ $this->addToCache('category_parent_path', $category_id, $parent_path);
+ }
+ return $parent_path;
+ }
+
+ function getFileExtension()
+ {
+ return $this->exportOptions['ExportFormat'] == 1 ? 'csv' : 'xml';
+ }
+
+ function getLineSeparator($option = 'LineEndings')
+ {
+ return $this->exportOptions[$option] == 1 ? "\r\n" : "\n";
+ }
+
+ /**
+ * Returns field caption for any exported field
+ *
+ * @param string $field
+ * @return string
+ */
+ function getFieldCaption($field)
+ {
+ if (substr($field, 0, 10) == '__CUSTOM__')
+ {
+ $ret = 'Custom_'.substr($field, 10, strlen($field) );
+ }
+ elseif (substr($field, 0, 12) == '__CATEGORY__')
+ {
+ return $this->getCategoryTitle();
+ }
+ elseif (substr($field, 0, 11) == '__VIRTUAL__') {
+ $ret = substr($field, 11);
+ }
+ else
+ {
+ $ret = $field;
+ }
+
+ return Array($ret);
+ }
+
+ /**
+ * Returns requested field value (including custom fields and category fields)
+ *
+ * @param string $field
+ * @return string
+ */
+ function getFieldValue($field)
+ {
+ if (substr($field, 0, 10) == '__CUSTOM__') {
+ $field = 'cust_'.substr($field, 10, strlen($field));
+ $ret = $this->curItem->GetField($field);
+ }
+ elseif (substr($field, 0, 12) == '__CATEGORY__') {
+ return $this->getCategoryPath();
+ }
+ elseif (substr($field, 0, 11) == '__VIRTUAL__') {
+ $field = substr($field, 11);
+ $ret = $this->curItem->GetField($field);
+ }
+ else
+ {
+ $ret = $this->curItem->GetField($field);
+ }
+
+ $ret = str_replace("\r\n", $this->getLineSeparator('LineEndingsInside'), $ret);
+ return Array($ret);
+ }
+
+ /**
+ * Returns category field(-s) caption based on export mode
+ *
+ * @return string
+ */
+ function getCategoryTitle()
+ {
+ // category path in separated fields
+ $category_count = $this->getMaxCategoryLevel();
+ if ($this->exportOptions['CategoryFormat'] == 1)
+ {
+ // category path in one field
+ return $category_count ? Array('CategoryPath') : Array();
+ }
+ else
+ {
+ $i = 0;
+ $ret = Array();
+ while ($i < $category_count) {
+ $ret[] = 'Category'.($i + 1);
+ $i++;
+ }
+ return $ret;
+ }
+ }
+
+ /**
+ * Returns category path in required format for current link
+ *
+ * @return string
+ */
+ function getCategoryPath()
+ {
+ $category_id = $this->curItem->GetDBField('CategoryId');
+ $category_path = $this->getFromCache('category_path', $category_id);
+ if (!$category_path)
+ {
+ $ml_formatter =& $this->Application->recallObject('kMultiLanguage');
+ $sql = 'SELECT '.$ml_formatter->LangFieldName('CachedNavbar').'
+ FROM '.TABLE_PREFIX.'Category
+ WHERE CategoryId = '.$category_id;
+ $category_path = $this->Conn->GetOne($sql);
+ $category_path = $category_path ? explode('&|&', $category_path) : Array();
+
+ if ($this->exportOptions['IsBaseCategory']) {
+ $i = $this->exportOptions['BaseLevel'];
+ while ($i > 0) {
+ array_shift($category_path);
+ $i--;
+ }
+ }
+
+ $category_count = $this->getMaxCategoryLevel();
+ if ($this->exportOptions['CategoryFormat'] == 1) {
+ // category path in single field
+ $category_path = $category_count ? Array( implode($this->exportOptions['CategorySeparator'], $category_path) ) : Array();
+ }
+ else {
+ // category path in separated fields
+ $levels_used = count($category_path);
+ if ($levels_used < $category_count)
+ {
+ $i = 0;
+ while ($i < $category_count - $levels_used) {
+ $category_path[] = '';
+ $i++;
+ }
+ }
+ }
+ $this->addToCache('category_path', $category_id, $category_path);
+ }
+
+ return $category_path;
+ }
+
+ /**
+ * Get maximal category deep level from links beeing exported
+ *
+ * @return int
+ */
+ function getMaxCategoryLevel()
+ {
+ static $max_level = -1;
+
+ if ($max_level != -1)
+ {
+ return $max_level;
+ }
+
+ $sql = 'SELECT IF(c.CategoryId IS NULL, 0, MAX( LENGTH(c.ParentPath) - LENGTH( REPLACE(c.ParentPath, "|", "") ) - 1 ))
+ FROM '.$this->curItem->TableName.' item_table
+ LEFT JOIN '.TABLE_PREFIX.'CategoryItems ci ON item_table.ResourceId = ci.ItemResourceId
+ LEFT JOIN '.TABLE_PREFIX.'Category c ON c.CategoryId = ci.CategoryId
+ WHERE (ci.PrimaryCat = 1) AND ';
+
+ $where_clause = '';
+ if ($this->exportOptions['export_ids'] === false) {
+ // get links from current category & all it's subcategories
+ if ($this->exportOptions['export_cats_ids'][0] == 0) {
+ $where_clause = 1;
+ }
+ else {
+ foreach ($this->exportOptions['export_cats_ids'] as $category_id) {
+ $where_clause .= '(c.ParentPath LIKE "%|'.$category_id.'|%") OR ';
+ }
+ $where_clause = preg_replace('/(.*) OR $/', '\\1', $where_clause);
+ }
+ }
+ else {
+ // get only selected links
+ $where_clause = $this->curItem->IDField.' IN ('.implode(',', $this->exportOptions['export_ids']).')';
+ }
+
+ $max_level = $this->Conn->GetOne($sql.'('.$where_clause.')');
+
+ if ($this->exportOptions['IsBaseCategory'] ) {
+ $max_level -= $this->exportOptions['BaseLevel'];
+ }
+
+ return $max_level;
+ }
+
+ /**
+ * Saves one record to export file
+ *
+ * @param Array $fields_hash
+ */
+ function writeRecord($fields_hash)
+ {
+ fputcsv2($this->filePointer, $fields_hash, $this->exportOptions['FieldsSeparatedBy'], $this->exportOptions['FieldsEnclosedBy'], $this->getLineSeparator() );
+ }
+
+ function readRecord()
+ {
+ return fgetcsv($this->filePointer, 10000, $this->exportOptions['FieldsSeparatedBy'], $this->exportOptions['FieldsEnclosedBy']);
+ }
+
+ function saveOptions(&$event, $options = null)
+ {
+ if (!isset($options)) {
+ $options = $this->exportOptions;
+ }
+ $this->Application->StoreVar($event->getPrefixSpecial().'_options', serialize($options) );
+ }
+
+ function loadOptions(&$event)
+ {
+ return unserialize($this->Application->RecallVar($event->getPrefixSpecial().'_options'));
+ }
+
+ /**
+ * Sets correct available & export fields
+ *
+ * @param kEvent $event
+ */
+ function prepareExportColumns(&$event)
+ {
+ $object =& $event->getObject( Array('skip_autoload' => true) );
+
+ $available_columns = Array();
+
+ if ($this->Application->getUnitOption($event->Prefix, 'CatalogItem')) {
+ // category field (mixed)
+ $available_columns['__CATEGORY__CategoryPath'] = 'CategoryPath';
+
+ if ($event->Special == 'import') {
+ // category field (separated fields)
+ $max_level = $this->Application->ConfigValue('MaxImportCategoryLevels');
+ $i = 0;
+ while ($i < $max_level) {
+ $available_columns['__CATEGORY__Category'.($i + 1)] = 'Category'.($i + 1);
+ $i++;
+ }
+ }
+ }
+
+ // db fields
+ foreach ($object->Fields as $field_name => $field_options)
+ {
+ if (!$object->SkipField($field_name))
+ {
+ $available_columns[$field_name] = $field_name.(getArrayValue($field_options, 'required') ? '*' : '');
+ }
+ }
+
+ $handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
+ $available_columns = array_merge_recursive2($available_columns, $handler->getCustomExportColumns($event));
+
+ // custom fields
+ foreach ($object->customFields as $custom_id => $custom_name)
+ {
+ $available_columns['__CUSTOM__'.$custom_name] = $custom_name;
+ }
+
+ // columns already in use
+ $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
+ if ($items_info)
+ {
+ list($item_id, $field_values) = each($items_info);
+ $export_keys = $field_values['ExportColumns'];
+ $export_keys = $export_keys ? explode('|', substr($export_keys, 1, -1) ) : Array();
+ }
+ else {
+ $export_keys = Array();
+ }
+
+ $export_columns = Array();
+ foreach ($export_keys as $field_key)
+ {
+ $field_name = $this->getExportField($field_key);
+ $export_columns[$field_key] = $field_name;
+ unset($available_columns[$field_key]);
+ }
+
+ $options = $object->GetFieldOptions('ExportColumns');
+ $options['options'] = $export_columns;
+ $object->SetFieldOptions('ExportColumns', $options);
+
+ $options = $object->GetFieldOptions('AvailableColumns');
+ $options['options'] = $available_columns;
+ $object->SetFieldOptions('AvailableColumns', $options);
+
+ $this->updateImportFiles($event);
+ $this->PrepareExportPresets($event);
+ }
+
+ function PrepareExportPresets(&$event)
+ {
+ $object =& $event->getObject( Array('skip_autoload' => true) );
+ $options = $object->GetFieldOptions('ExportPresets');
+
+ $user =& $this->Application->recallObject('u');
+ $export_settings = $user->getPersistantVar('export_settings');
+ if (!$export_settings) return ;
+ $export_settings = unserialize($export_settings);
+
+ if (!isset($export_settings[$event->Prefix])) return ;
+
+
+ $export_presets = array(''=>'');
+ foreach ($export_settings[$event->Prefix] as $key => $val) {
+ $export_presets[implode('|', $val['ExportColumns'])] = $key;
+ }
+
+ $options['options'] = $export_presets;
+ $object->SetFieldOptions('ExportPresets', $options);
+ }
+
+ function getExportField($field_key)
+ {
+ $prepends = Array('__CUSTOM__', '__CATEGORY__');
+ foreach ($prepends as $prepend)
+ {
+ if (substr($field_key, 0, strlen($prepend) ) == $prepend)
+ {
+ $field_key = substr($field_key, strlen($prepend), strlen($field_key) );
+ break;
+ }
+ }
+ return $field_key;
+ }
+
+ /**
+ * Updates uploaded files list
+ *
+ * @param kEvent $event
+ */
+ function updateImportFiles(&$event)
+ {
+ if ($event->Special != 'import') {
+ return false;
+ }
+
+ $object =& $event->getObject();
+
+ $import_filenames = Array();
+
+ if ($folder_handle = opendir(EXPORT_PATH)) {
+ while (false !== ($file = readdir($folder_handle))) {
+ if (is_dir(EXPORT_PATH.'/'.$file) || substr($file, 0, 1) == '.' || strtolower($file) == 'cvs' || strtolower($file) == 'dummy' || filesize(EXPORT_PATH.'/'.$file) == 0) continue;
+
+ $file_size = formatSize( filesize(EXPORT_PATH.'/'.$file) );
+ $import_filenames[$file] = $file.' ('.$file_size.')';
+ }
+ closedir($folder_handle);
+ }
+
+ $options = $object->GetFieldOptions('ImportLocalFilename');
+ $options['options'] = $import_filenames;
+ $object->SetFieldOptions('ImportLocalFilename', $options);
+ }
+
+ /**
+ * Returns module folder
+ *
+ * @param kEvent $event
+ * @return string
+ */
+ function getModuleFolder(&$event)
+ {
+ return $this->Application->getUnitOption($event->Prefix, 'ModuleFolder');
+ }
+
+ /**
+ * Export form validation & processing
+ *
+ * @param kEvent $event
+ */
+ function OnExportBegin(&$event)
+ {
+ $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
+ if (!$items_info)
+ {
+ $items_info = unserialize( $this->Application->RecallVar($event->getPrefixSpecial().'_ItemsInfo') );
+ $this->Application->SetVar($event->getPrefixSpecial(true), $items_info);
+ }
+
+ list($item_id, $field_values) = each($items_info);
+
+ $object =& $event->getObject( Array('skip_autoload' => true) );
+ $object->SetFieldsFromHash($field_values);
+ $field_values['ImportFilename'] = $object->GetDBField('ImportFilename'); //if upload formatter has renamed the file during moving !!!
+
+ $object->setID($item_id);
+ $this->setRequiredFields($event);
+
+ $export_object =& $this->Application->recallObject('CatItemExportHelper');
+
+ // save export/import options
+ if ($event->Special == 'export')
+ {
+ $export_ids = $this->Application->RecallVar($event->Prefix.'_export_ids');
+ $export_cats_ids = $this->Application->RecallVar($event->Prefix.'_export_cats_ids');
+
+ // used for multistep export
+ $field_values['export_ids'] = $export_ids ? explode(',', $export_ids) : false;
+ $field_values['export_cats_ids'] = $export_cats_ids ? explode(',', $export_cats_ids) : Array( $this->Application->GetVar('m_cat_id') );
+ }
+
+ $field_values['ExportColumns'] = $field_values['ExportColumns'] ? explode('|', substr($field_values['ExportColumns'], 1, -1) ) : Array();
+ $field_values['start_from'] = 0;
+
+ $this->Application->HandleEvent($nevent, $event->Prefix.':OnBeforeExportBegin', array('options'=>$field_values));
+ $field_values = $nevent->getEventParam('options');
+
+ $export_object->saveOptions($event, $field_values);
+
+ if( $export_object->verifyOptions($event) )
+ {
+ if ($object->GetDBField('ExportSavePreset')) {
+ $name = $object->GetDBField('ExportPresetName');
+ $user =& $this->Application->recallObject('u');
+ $export_settings = $user->getPersistantVar('export_settings');
+ $export_settings = $export_settings ? unserialize($export_settings) : array();
+ $export_settings[$event->Prefix][$name] = $field_values;
+ $user->setPersistantVar('export_settings', serialize($export_settings));
+ }
+
+ $progress_t = $this->Application->RecallVar('export_progress_t');
+ if ($progress_t) {
+ $this->Application->RemoveVar('export_progress_t');
+ }
+ else {
+ $progress_t = $export_object->getModuleFolder($event).'/'.$event->Special.'_progress';
+ }
+ $event->redirect = $progress_t;
+ }
+ else
+ {
+ // make uploaded file local & change source selection
+ $filename = getArrayValue($field_values, 'ImportFilename');
+ if ($filename) {
+ $export_object->updateImportFiles($event);
+ $object->SetDBField('ImportSource', 2);
+ $field_values['ImportSource'] = 2;
+ $object->SetDBField('ImportLocalFilename', $filename);
+ $field_values['ImportLocalFilename'] = $filename;
+ $export_object->saveOptions($event, $field_values);
+ }
+
+ $event->status = erFAIL;
+ $event->redirect = false;
+ }
+ }
+
+ /**
+ * set required fields based on import or export params
+ *
+ * @param kEvent $event
+ */
+ function setRequiredFields(&$event)
+ {
+ $required_fields['common'] = Array('FieldsSeparatedBy', 'LineEndings', 'CategoryFormat');
+
+ $required_fields['export'] = Array('ExportFormat', 'ExportFilename','ExportColumns');
+
+ $object =& $event->getObject();
+ if ($object->GetDBField('ExportSavePreset')) {
+ $required_fields['export'][] = 'ExportPresetName';
+ }
+
+ $required_fields['import'] = Array('FieldTitles', 'ImportSource', 'CheckDuplicatesMethod'); // ImportFilename, ImportLocalFilename
+
+ if ($event->Special == 'import')
+ {
+ $import_source = Array(1 => 'ImportFilename', 2 => 'ImportLocalFilename');
+ $used_field = $import_source[ $object->GetDBField('ImportSource') ];
+
+ $required_fields[$event->Special][] = $used_field;
+ $object->Fields[$used_field]['error_field'] = 'ImportSource';
+
+ if ($object->GetDBField('FieldTitles') == 2) $required_fields[$event->Special][] = 'ExportColumns'; // manual field titles
+ }
+
+ $required_fields = array_merge($required_fields['common'], $required_fields[$event->Special]);
+ foreach ($required_fields as $required_field) {
+ $object->setRequired($required_field, true);
+ }
+ }
+
+ }
+
+?>
Property changes on: branches/unlabeled/unlabeled-1.23.2/core/units/general/cat_dbitem_export.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.23
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property

Event Timeline