Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Wed, Jul 16, 3:01 AM

in-portal

Index: trunk/kernel/units/general/brackets.php
===================================================================
--- trunk/kernel/units/general/brackets.php (revision 3072)
+++ trunk/kernel/units/general/brackets.php (revision 3073)
@@ -1,336 +1,337 @@
<?php
class kBracketsHelper extends kHelper {
/**
* Field name holding minimal amount
*
* @var string
*/
var $min_field = '';
/**
* Field name holding maximal amount
*
* @var string
*/
var $max_field = '';
/**
* Default values to be set to automtically created price brackets
*
* @var Array
*/
var $default_values = Array();
function InitHelper($min_field, $max_field, $default_values)
{
$this->min_field = $min_field;
$this->max_field = $max_field;
$this->default_values = $default_values;
}
/**
* Adds 5 more empty brackets to brackets
*
* @param kEvent $event
*/
function OnMoreBrackets(&$event)
{
$field_values = $this->Application->GetVar( $event->getPrefixSpecial(true) );
$object =& $event->getObject();
foreach($field_values as $id => $record)
{
if($record[$this->max_field] == '&#8734;') $field_values[$id][$this->max_field] = -1;
}
$new_id = (int)$this->Conn->GetOne('SELECT MIN('.$object->IDField.') FROM '.$object->TableName);
if($new_id > 0) $new_id = 0;
do
{
$new_id--;
}while( $this->arraySearch($field_values, $object->IDField, $new_id) );
$last_max_qty = $this->Conn->GetOne('SELECT MAX('.$this->max_field.') FROM '.$object->TableName);
$min_qty = $this->Conn->GetOne('SELECT MIN('.$this->max_field.') FROM '.$object->TableName);
if($min_qty == -1) $last_max_qty = -1;
if(!$last_max_qty) $last_max_qty = 1;
for($i = $new_id; $i > $new_id - 5; $i--)
{
$field_values[$i][$object->IDField] = $i;
$field_values[$i][$this->min_field] = ($i == $new_id-4 && $last_max_qty != -1) ? $last_max_qty : '';
$field_values[$i][$this->max_field] = ($i == $new_id-4 && $last_max_qty != -1) ? -1 : '';
$field_values[$i] = array_merge_recursive2($field_values[$i], $this->default_values);
}
$event->CallSubEvent('OnPreSaveBrackets');
$this->Application->SetVar($event->getPrefixSpecial(true), $field_values);
}
/**
* Adds infinity bracket
*
* @param kEvent $event
*/
function OnInfinity(&$event)
{
$object =& $event->getObject();
$infinite_exists = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$object->TableName.' WHERE '.$this->max_field.' = -1');
if($infinite_exists == 0)
{
$field_values = $this->Application->GetVar( $event->getPrefixSpecial(true) );
reset($field_values);
$last_bracket = end($field_values);
$new_id = (int)$this->Conn->GetOne('SELECT MIN('.$object->IDField.') FROM '.$object->TableName);
$brackets_exist = (int)$this->Conn->GetOne('SELECT COUNT(*) FROM '.$object->TableName);
if($new_id > 0) $new_id = 0;
do
{
$new_id--;
}while( $this->arraySearch($field_values, $object->IDField, $new_id) );
$infinite_bracket[$object->IDField] = $new_id;
$infinite_bracket[$this->min_field] = ($brackets_exist > 0) ? $last_bracket[$this->max_field] : 1;
$infinite_bracket[$this->max_field] = '-1';
$infinite_bracket = array_merge_recursive2($infinite_bracket, $this->default_values);
$field_values[$new_id] = $infinite_bracket;
reset($field_values);
$this->Application->SetVar($event->getPrefixSpecial(true), $field_values);
}
}
/**
* Saves brackets to database
*
* @param kEvent $event
*/
function OnPreSaveBrackets(&$event)
{
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true));
if($items_info)
{
$object =& $event->getObject();
$linked_info = $object->getLinkedInfo();
- $stored_ids = $this->Conn->GetCol('SELECT '.$object->IDField.' FROM '.$object->TableName.' WHERE '.$linked_info['ParentTableKey'].' = '.$linked_info['ParentId']);
+ $stored_ids = $this->Conn->GetCol('SELECT '.$object->IDField.' FROM '.$object->TableName.' WHERE '.$linked_info['ForeignKey'].' = '.$linked_info['ParentId']);
uasort($items_info, Array(&$this, 'compareBrackets') );
foreach ($items_info as $item_id => $values)
{
if (in_array($item_id, $stored_ids)) { //if it's already exist
- $object->SetDefaultValues();
- $object->Load($item_id);
- $object->SetFieldsFromHash($values);
- if (!$object->Validate()) {
- unset($stored_ids[array_search($item_id, $stored_ids)]);
- $event->redirect = false;
- continue;
- }
- if( $object->Update($item_id) )
- {
- $event->status = erSUCCESS;
- }
- else
- {
- $event->status = erFAIL;
- $event->redirect = false;
- break;
- }
- unset( $stored_ids[ array_search($item_id, $stored_ids) ] );
+ $object->SetDefaultValues();
+ $object->Load($item_id);
+ $object->SetFieldsFromHash($values);
+ if (!$object->Validate()) {
+ unset($stored_ids[array_search($item_id, $stored_ids)]);
+ $event->redirect = false;
+ continue;
+ }
+ if( $object->Update($item_id) )
+ {
+ $event->status = erSUCCESS;
+ }
+ else
+ {
+ $event->status = erFAIL;
+ $event->redirect = false;
+ break;
+ }
+ unset( $stored_ids[ array_search($item_id, $stored_ids) ] );
}
else {
$object->SetDefaultValues();
$object->SetFieldsFromHash($values);
- $object->SetDBField($linked_info['ParentTableKey'], $linked_info['ParentId']);
+ $object->SetDBField($linked_info['ForeignKey'], $linked_info['ParentId']);
if( $object->Create() )
{
$object->setTempID();
$event->status = erSUCCESS;
}
}
}
// delete
- foreach ($stored_ids as $stored_id){
+ foreach ($stored_ids as $stored_id)
+ {
$this->Conn->Query('DELETE FROM '.$object->TableName.' WHERE '.$object->IDField.' = '.$stored_id);
}
}
}
function arrangeBrackets(&$event)
{
$object =& $event->getObject();
$temp = $this->Application->GetVar( $event->getPrefixSpecial(true) );
foreach($temp as $id => $record)
{
if( $record[$this->max_field] == '&#8734;' )
{
$temp[$id][$this->max_field] = -1;
}
}
$temp_orig = $temp;
reset($temp);
if( is_array($temp) )
{
// array to store max values (2nd column)
$end_values = Array();
// get minimal value of Min
$first_elem = current($temp);
$start = $first_elem[$this->min_field];
if(!$start) $start = 1;
foreach($temp as $id => $record)
{
if(
// MAX is less than start
($record[$this->max_field] <= $start && $record[$this->max_field] != -1) ||
// Max is empty
!$record[$this->max_field] ||
// Max already defined in $end_values
(array_search($record[$this->max_field], $end_values) !== false)
) { // then delete from brackets list
unset($temp[$id]);
}
else { // this is when ok - add to end_values list
$end_values[] = $record[$this->max_field];
}
}
// sort brackets by 2nd column (Max values)
uasort($temp, Array(&$this, 'compareBrackets') );
reset($temp);
$first_item = each($temp);
$first_item_key = $first_item['key'];
$linked_info = $object->getLinkedInfo();
$sql = 'SELECT %s FROM %s WHERE %s = %s';
- $ids = $this->Conn->GetCol( sprintf($sql, $object->IDField, $object->TableName, $linked_info['ParentTableKey'], $linked_info['ParentId']) );
+ $ids = $this->Conn->GetCol( sprintf($sql, $object->IDField, $object->TableName, $linked_info['ForeignKey'], $linked_info['ParentId']) );
if( is_array($ids) )
{
usort($ids, Array(&$this, 'sortBracketIDs') );
}
$min_id = min( min($ids) - 1, -1 );
foreach($temp as $key => $record)
{
$temp[$key][$this->min_field] = $start;
$start = $temp[$key][$this->max_field];
}
}
$this->Application->SetVar($event->getPrefixSpecial(true), $temp);
return $temp;
}
function compareBrackets($bracket1, $bracket2) // ap_bracket_comp
{
$bracket1_min = $bracket1[$this->min_field];
$bracket1_max = $bracket1[$this->max_field];
$bracket2_min = $bracket2[$this->min_field];
$bracket2_max = $bracket2[$this->max_field];
// limits
if( ($bracket1_min != '') && ($bracket1_max == '') && ($bracket2_min != '') && ($bracket2_max != '') ) return 1;
if( ($bracket1_min != '') && ($bracket1_max == '') && ($bracket2_min == '') && ($bracket2_max == '') ) return -1;
if( ($bracket1_max == '') && ($bracket2_max != '') ) return 1;
if( ($bracket1_max != '') && ($bracket2_max == '') ) return -1;
if( ( ($bracket1_max > $bracket2_max) && ($bracket2_max != -1) ) || ( ($bracket1_max == -1) && ($bracket2_max != -1) ) )
{
return 1;
}
elseif( ($bracket1_max < $bracket2_max) || ( ($bracket2_max == -1) && ($bracket1_max != -1) ) )
{
return -1;
}
else
{
return 0;
}
}
function sortBracketIDs($first_id, $second_id) // pr_bracket_id_sort
{
$first_abs = abs($first_id);
$second_abs = abs($second_id);
$first_sign = ($first_id == 0) ? 0 : $first_id / $first_abs;
$second_sign = ($second_id == 0) ? 0 : $second_id / $second_abs;
if($first_sign != $second_sign)
{
if($first_id > $second_id)
{
$bigger =& $first_abs;
$smaller =& $second_abs;
}
else
{
$bigger =& $second_abs;
$smaller =& $first_abs;
}
$smaller = $bigger + $smaller;
}
return ($first_abs > $second_abs) ? 1 : ($first_abs < $second_abs ? -1 : 0);
}
/**
* Searches through submitted grid data to find record with specific value in specific field
*
* @param Array $records // grid data from REQUEST
* @param string $field
* @param string $value
* @return bool
*/
function arraySearch($records, $field, $value) // check_array
{
foreach ($records as $record)
{
if ($record[$field] == $value)
{
return true;
}
}
return false;
}
/**
* Replate infinity mark with -1 before saving to db
*
* @param kEvent $event
*/
function replaceInfinity(&$event)
{
$object =& $event->getObject();
if($object->GetDBField($this->max_field) == '&#8734;') $bracket->SetDBField($this->max_field, -1);
}
}
?>
\ No newline at end of file
Property changes on: trunk/kernel/units/general/brackets.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1
\ No newline at end of property
+1.2
\ No newline at end of property
Index: trunk/core/kernel/utility/temp_handler.php
===================================================================
--- trunk/core/kernel/utility/temp_handler.php (revision 3072)
+++ trunk/core/kernel/utility/temp_handler.php (revision 3073)
@@ -1,614 +1,619 @@
<?php
class kTempTablesHandler extends kBase {
var $Tables = Array();
/**
* Master table name for temp handler
*
* @var string
* @access private
*/
var $MasterTable = '';
/**
* IDs from master table
*
* @var Array
* @access private
*/
var $MasterIDs = Array();
var $AlreadyProcessed = Array();
var $DroppedTables = Array();
var $FinalRefs = Array();
var $CopiedTables = Array();
/**
* Description
*
* @var kDBConnection
* @access public
*/
var $Conn;
function kTempTablesHandler()
{
parent::kBase();
$this->Conn =& $this->Application->GetADODBConnection();
}
function SetTables($tables)
{
// set tablename as key for tables array
$ret = Array();
$this->Tables = $tables;
$this->MasterTable = $tables['TableName'];
}
/**
* Get temp table name
*
* @param string $table
* @return string
*/
function GetTempName($table)
{
// function is sometimes called as static, so we CAN'T use $this->GetTempTablePrefix() here
return TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_edit_'.$table;
}
function GetTempTablePrefix()
{
return TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_edit_';
}
/**
* Return live table name based on temp table name
*
* @param string $temp_table
* @return string
*/
function GetLiveName($temp_table)
{
if( preg_match('/'.TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_edit_(.*)/',$temp_table,$rets) )
{
return $rets[1];
}
else
{
return $temp_table;
}
}
function IsTempTable($table)
{
return strpos($table, TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_edit_') !== false;
}
/**
* Return temporary table name for master table
*
* @return string
* @access public
*/
function GetMasterTempName()
{
return $this->GetTempName($this->MasterTable);
}
function CreateTempTable($table)
{
$query = sprintf("CREATE TABLE %s SELECT * FROM %s WHERE 0",
$this->GetTempName($table),
$table);
$this->Conn->Query($query);
}
function BuildTables($prefix, $ids)
{
$this->TableIdCounter = 0;
$tables = Array(
'TableName' => $this->Application->getUnitOption($prefix,'TableName'),
'IdField' => $this->Application->getUnitOption($prefix,'IDField'),
'IDs' => $ids,
'Prefix' => $prefix,
'TableId' => $this->TableIdCounter++,
);
$SubItems = $this->Application->getUnitOption($prefix,'SubItems');
if (is_array($SubItems)) {
foreach ($SubItems as $prefix) {
$this->AddTables($prefix, $tables);
}
}
$this->SetTables($tables);
}
function AddTables($prefix, &$tables)
{
$tmp = Array(
'TableName' => $this->Application->getUnitOption($prefix,'TableName'),
'IdField' => $this->Application->getUnitOption($prefix,'IDField'),
'ForeignKey' => $this->Application->getUnitOption($prefix,'ForeignKey'),
'ParentPrefix' => $this->Application->getUnitOption($prefix, 'ParentPrefix'),
'ParentTableKey' => $this->Application->getUnitOption($prefix,'ParentTableKey'),
'Prefix' => $prefix,
'AutoClone' => $this->Application->getUnitOption($prefix,'AutoClone'),
'AutoDelete' => $this->Application->getUnitOption($prefix,'AutoDelete'),
'TableId' => $this->TableIdCounter++,
);
- $this->FinalRefs[$tmp['TableName']] = $tmp['TableId'];
+ $this->FinalRefs[ $tmp['TableName'] ] = $tmp['TableId'];
+
$constrain = $this->Application->getUnitOption($prefix,'Constrain');
- if ($constrain) $tmp['Constrain'] = $constrain;
-
+ if ($constrain)
+ {
+ $tmp['Constrain'] = $constrain;
+ $this->FinalRefs[ $tmp['TableName'].$tmp['Constrain'] ] = $tmp['TableId'];
+ }
+
$SubItems = $this->Application->getUnitOption($prefix,'SubItems');
$same_sub_counter = 1;
if( is_array($SubItems) )
{
foreach($SubItems as $prefix)
{
$this->AddTables($prefix, $tmp);
}
}
if ( !is_array(getArrayValue($tables, 'SubTables')) ) {
$tables['SubTables'] = array();
}
$tables['SubTables'][] = $tmp;
}
function CloneItems($prefix, $special, $ids, $master=null, $foreign_key=null, $parent_prefix = null)
{
if (!isset($master)) $master = $this->Tables;
if( strpos($prefix,'.') !== false ) list($prefix,$special) = explode('.', $prefix, 2);
$prefix_special = rtrim($prefix.'.'.$special, '.');
//recalling by different name, because we may get kDBList, if we recall just by prefix
$recall_prefix = $prefix_special.($special ? '' : '.').'-item';
$this->Application->setUnitOption($prefix, 'AutoLoad', false);
$object =& $this->Application->recallObject($recall_prefix, $prefix);
foreach ($ids as $id)
{
$mode = 'create';
if ( $cloned_ids = getArrayValue($this->AlreadyProcessed, $master['TableName']) ) {
// if we have already cloned the id, replace it with cloned id and set mode to update
// update mode is needed to update second ForeignKey for items cloned by first ForeignKey
if ( getArrayValue($cloned_ids, $id) ) {
$id = $cloned_ids[$id];
$mode = 'update';
}
}
$object->Load($id);
$original_values = $object->FieldValues;
$object->NameCopy($master, $foreign_key);
if (isset($foreign_key)) {
$master_foreign_key_field = is_array($master['ForeignKey']) ? $master['ForeignKey'][$parent_prefix] : $master['ForeignKey'];
$object->SetDBField($master_foreign_key_field, $foreign_key);
}
if ($mode == 'create') {
$this->RaiseEvent('OnBeforeClone', $master['Prefix'], Array($object->GetId()), $foreign_key);
}
$res = $mode == 'update' ? $object->Update() : $object->Create();
if( $res )
{
if ( $mode == 'create' && is_array( getArrayValue($master, 'ForeignKey')) ) {
// remember original => clone mapping for dual ForeignKey updating
$this->AlreadyProcessed[$master['TableName']][$id] = $object->GetId();
}
if($object->mode == 't') $object->setTempID();
if ($mode == 'create') {
$this->RaiseEvent('OnAfterClone', $master['Prefix'], Array($object->GetId()), $foreign_key );
}
if ( is_array(getArrayValue($master, 'SubTables')) ) {
foreach($master['SubTables'] as $sub_table) {
if (!getArrayValue($sub_table, 'AutoClone')) continue;
$sub_TableName = ($object->mode == 't') ? $this->GetTempName($sub_table['TableName']) : $sub_table['TableName'];
$foreign_key_field = is_array($sub_table['ForeignKey']) ? $sub_table['ForeignKey'][$master['Prefix']] : $sub_table['ForeignKey'];
$parent_key_field = is_array($sub_table['ParentTableKey']) ? $sub_table['ParentTableKey'][$master['Prefix']] : $sub_table['ParentTableKey'];
$query = 'SELECT '.$sub_table['IdField'].' FROM '.$sub_TableName.'
WHERE '.$foreign_key_field.' = '.$original_values[$parent_key_field];
if (isset($sub_table['Constrain'])) $query .= ' AND '.$sub_table['Constrain'];
$sub_ids = $this->Conn->GetCol($query);
if ( is_array(getArrayValue($sub_table, 'ForeignKey')) ) {
// $sub_ids could containt newly cloned items, we need to remove it here
// to escape double cloning
$cloned_ids = getArrayValue($this->AlreadyProcessed, $sub_table['TableName']);
if ( !$cloned_ids ) $cloned_ids = Array();
$new_ids = array_values($cloned_ids);
$sub_ids = array_diff($sub_ids, $new_ids);
}
$parent_key = $object->GetDBField($parent_key_field);
$this->CloneItems($sub_table['Prefix'], '', $sub_ids, $sub_table, $parent_key, $master['Prefix']);
}
}
}
}
}
function DeleteItems($prefix, $special, $ids, $master=null, $foreign_key=null)
{
if (!isset($master)) $master = $this->Tables;
if( strpos($prefix,'.') !== false ) list($prefix,$special) = explode('.', $prefix, 2);
$prefix_special = rtrim($prefix.'.'.$special, '.');
//recalling by different name, because we may get kDBList, if we recall just by prefix
$recall_prefix = $prefix_special.($special ? '' : '.').'-item';
$this->Application->setUnitOption($prefix,'AutoLoad',false);
$object =& $this->Application->recallObject($recall_prefix, $prefix);
foreach ($ids as $id)
{
$object->Load($id);
$original_values = $object->FieldValues;
if( !$object->Delete($id) ) continue;
if ( is_array(getArrayValue($master, 'SubTables')) ) {
foreach($master['SubTables'] as $sub_table) {
if (!getArrayValue($sub_table, 'AutoDelete')) continue;
$sub_TableName = ($object->mode == 't') ? $this->GetTempName($sub_table['TableName']) : $sub_table['TableName'];
$foreign_key_field = is_array($sub_table['ForeignKey']) ? $sub_table['ForeignKey'][$master['Prefix']] : $sub_table['ForeignKey'];
$parent_key_field = is_array($sub_table['ParentTableKey']) ? $sub_table['ParentTableKey'][$master['Prefix']] : $sub_table['ParentTableKey'];
$query = 'SELECT '.$sub_table['IdField'].' FROM '.$sub_TableName.'
WHERE '.$foreign_key_field.' = '.$original_values[$parent_key_field];
$sub_ids = $this->Conn->GetCol($query);
$parent_key = $object->GetDBField($sub_table['ParentTableKey']);
$this->DeleteItems($sub_table['Prefix'], '', $sub_ids, $sub_table, $parent_key);
}
}
}
}
function DoCopyLiveToTemp($master, $ids, $parent_prefix=null)
{
// when two tables refers the same table as sub-sub-table, and ForeignKey and ParentTableKey are arrays
// the table will be first copied by first sub-table, then dropped and copied over by last ForeignKey in the array
// this should not do any problems :)
if ( !preg_match("/.*\.[0-9]+/", $master['Prefix']) ) {
if( $this->DropTempTable($master['TableName']) )
{
$this->CreateTempTable($master['TableName']);
}
}
if (is_array($ids)) {
$ids = join(',', $ids);
}
$table_sig = $master['TableName'].(isset($master['Constrain']) ? $master['Constrain'] : '');
if ($ids != '' && !in_array($table_sig, $this->CopiedTables)) {
if ( getArrayValue($master, 'ForeignKey') ) {
if ( is_array($master['ForeignKey']) ) {
$key_field = $master['ForeignKey'][$parent_prefix];
}
else {
$key_field = $master['ForeignKey'];
}
}
else {
$key_field = $master['IdField'];
}
$query = 'INSERT INTO '.$this->GetTempName($master['TableName']).'
SELECT * FROM '.$master['TableName'].'
WHERE '.$key_field.' IN ('.$ids.')';
if (isset($master['Constrain'])) $query .= ' AND '.$master['Constrain'];
$this->Conn->Query($query);
$this->CopiedTables[] = $table_sig;
$query = 'SELECT '.$master['IdField'].' FROM '.$master['TableName'].'
WHERE '.$key_field.' IN ('.$ids.')';
if (isset($master['Constrain'])) $query .= ' AND '.$master['Constrain'];
$this->RaiseEvent( 'OnAfterCopyToTemp', $master['Prefix'], $this->Conn->GetCol($query) );
}
if ( getArrayValue($master, 'SubTables') ) {
foreach ($master['SubTables'] as $sub_table) {
$parent_key = is_array($sub_table['ParentTableKey']) ? $sub_table['ParentTableKey'][$master['Prefix']] : $sub_table['ParentTableKey'];
if ( $ids != '' && $parent_key != $key_field ) {
$query = 'SELECT '.$parent_key.' FROM '.$master['TableName'].'
WHERE '.$key_field.' IN ('.$ids.')';
$sub_foreign_keys = join(',', $this->Conn->GetCol($query));
}
else {
$sub_foreign_keys = $ids;
}
$this->DoCopyLiveToTemp($sub_table, $sub_foreign_keys, $master['Prefix']);
}
}
}
function GetForeignKeys($master, $sub_table, $live_id, $temp_id=null)
{
$mode = 1; //multi
if (!is_array($live_id)) {
$live_id = Array($live_id);
$mode = 2; //single
}
if (isset($temp_id) && !is_array($temp_id)) $temp_id = Array($temp_id);
if ( isset($sub_table['ParentTableKey']) ) {
if ( is_array($sub_table['ParentTableKey']) ) {
$parent_key_field = $sub_table['ParentTableKey'][$master['Prefix']];
}
else {
$parent_key_field = $sub_table['ParentTableKey'];
}
}
else {
$parent_key_field = $master['IdField'];
}
if ( $cached = getArrayValue($this->FKeysCache, $master['TableName'].'.'.$parent_key_field) ) {
if ( array_key_exists(serialize($live_id), $cached) ) {
list($live_foreign_key, $temp_foreign_key) = $cached[serialize($live_id)];
if ($mode == 1) {
return $live_foreign_key;
}
else {
return Array($live_foreign_key[0], $temp_foreign_key[0]);
}
}
}
if ($parent_key_field != $master['IdField']) {
$query = 'SELECT '.$parent_key_field.' FROM '.$master['TableName'].'
WHERE '.$master['IdField'].' IN ('.join(',', $live_id).')';
$live_foreign_key = $this->Conn->GetCol($query);
if (isset($temp_id)) {
$query = 'SELECT '.$parent_key_field.' FROM '.$this->GetTempName($master['TableName']).'
WHERE '.$master['IdField'].' IN ('.join(',', $temp_id).')';
$temp_foreign_key = $this->Conn->GetCol($query);
}
else {
$temp_foreign_key = Array();
}
}
else {
$live_foreign_key = $live_id;
$temp_foreign_key = $temp_id;
}
$this->FKeysCache[$master['TableName'].'.'.$parent_key_field][serialize($live_id)] = Array($live_foreign_key, $temp_foreign_key);
if ($mode == 1) {
return $live_foreign_key;
}
else {
return Array($live_foreign_key[0], $temp_foreign_key[0]);
}
}
function DoCopyTempToOriginal($master, $parent_prefix=null)
{
$query = 'SELECT '.$master['IdField'].' FROM '.$this->GetTempName($master['TableName']);
if (isset($master['Constrain'])) $query .= ' WHERE '.$master['Constrain'];
$current_ids = $this->Conn->GetCol($query);
$table_sig = $master['TableName'].(isset($master['Constrain']) ? $master['Constrain'] : '');
if ($current_ids) {
// delete all ids from live table - for MasterTable ONLY!
// because items from Sub Tables get deteleted in CopySubTablesToLive !BY ForeignKey!
if ($master['TableName'] == $this->MasterTable) {
$this->RaiseEvent( 'OnBeforeDeleteFromLive', $master['Prefix'], $current_ids );
$query = 'DELETE FROM '.$master['TableName'].' WHERE '.$master['IdField'].' IN ('.join(',', $current_ids).')';
$this->Conn->Query($query);
}
if ( getArrayValue($master, 'SubTables') ) {
- if( in_array($table_sig, $this->CopiedTables) ) continue;
+ if( in_array($table_sig, $this->CopiedTables) || $this->FinalRefs[$table_sig] != $master['TableId'] ) return;
foreach($current_ids AS $id)
{
$this->RaiseEvent( 'OnBeforeCopyToLive', $master['Prefix'], Array($id) );
//reset negative ids to 0, so autoincrement in live table works fine
if($id < 0)
{
$query = 'UPDATE '.$this->GetTempName($master['TableName']).'
SET '.$master['IdField'].' = 0
WHERE '.$master['IdField'].' = '.$id;
if (isset($master['Constrain'])) $query .= ' AND '.$master['Constrain'];
$this->Conn->Query($query);
$id_to_copy = 0;
}
else
{
$id_to_copy = $id;
}
//copy current id_to_copy (0 for new or real id) to live table
$query = 'INSERT INTO '.$master['TableName'].'
SELECT * FROM '.$this->GetTempName($master['TableName']).'
WHERE '.$master['IdField'].' = '.$id_to_copy;
$this->Conn->Query($query);
$insert_id = $id_to_copy == 0 ? $this->Conn->getInsertID() : $id_to_copy;
$this->RaiseEvent( 'OnAfterCopyToLive', $master['Prefix'], Array($insert_id) );
$this->UpdateForeignKeys($master, $insert_id, $id);
//delete already copied record from master temp table
$query = 'DELETE FROM '.$this->GetTempName($master['TableName']).'
WHERE '.$master['IdField'].' = '.$id_to_copy;
if (isset($master['Constrain'])) $query .= ' AND '.$master['Constrain'];
$this->Conn->Query($query);
}
$this->CopiedTables[] = $table_sig;
// when all of ids in current master has been processed, copy all sub-tables data
$this->CopySubTablesToLive($master, $current_ids);
}
- elseif( !in_array($table_sig, $this->CopiedTables) ) { //If current master doesn't have sub-tables - we could use mass operations
+ elseif( !in_array($table_sig, $this->CopiedTables) && ($this->FinalRefs[$table_sig] == $master['TableId']) ) { //If current master doesn't have sub-tables - we could use mass operations
// We don't need to delete items from live here, as it get deleted in the beggining of the method for MasterTable
// or in parent table processing for sub-tables
$this->RaiseEvent('OnBeforeCopyToLive', $master['Prefix'], $current_ids);
// reset ALL negative IDs to 0 so it get inserted into live table with autoincrement
$query = 'UPDATE '.$this->GetTempName($master['TableName']).'
SET '.$master['IdField'].' = 0
WHERE '.$master['IdField'].' < 0';
if (isset($master['Constrain'])) $query .= ' AND '.$master['Constrain'];
$this->Conn->Query($query);
// copy ALL records to live table
$query = 'INSERT INTO '.$master['TableName'].'
SELECT * FROM '.$this->GetTempName($master['TableName']);
if (isset($master['Constrain'])) $query .= ' WHERE '.$master['Constrain'];
$this->Conn->Query($query);
$this->CopiedTables[] = $table_sig;
/*
!!! WE NEED TO FIND A WAY TO DETERMINE IF OnAfterCopyToLive is not an empty method, and do on-by-one insert
and pass Ids to OnAfterCopyToLive, otherwise it's not smart to do on-by-one insert for any object
OR WE COULD FIND A WAY TO GET ALL INSERTED IDS as an array and iterate them !!!
$this->RaiseEvent('OnAfterCopyToLive', IDS ??? );
*/
// no need to clear temp table - it will be dropped by next statement
}
}
- if ($this->FinalRefs[$master['TableName']] != $master['TableId']) return;
+ if ($this->FinalRefs[ $master['TableName'] ] != $master['TableId']) return;
/*if ( is_array(getArrayValue($master, 'ForeignKey')) ) { //if multiple ForeignKeys
if ( $master['ForeignKey'][$parent_prefix] != end($master['ForeignKey']) ) {
return; // Do not delete temp table if not all ForeignKeys have been processed (current is not the last)
}
}*/
$this->DropTempTable($master['TableName']);
}
function UpdateForeignKeys($master, $live_id, $temp_id) {
foreach ($master['SubTables'] as $sub_table) {
list ($live_foreign_key, $temp_foreign_key) = $this->GetForeignKeys($master, $sub_table, $live_id, $temp_id);
$foreign_key_field = is_array($sub_table['ForeignKey']) ? $sub_table['ForeignKey'][$master['Prefix']] : $sub_table['ForeignKey'];
//Update ForeignKey in sub TEMP table
if ($live_foreign_key != $temp_foreign_key) {
$query = 'UPDATE '.$this->GetTempName($sub_table['TableName']).'
SET '.$foreign_key_field.' = '.$live_foreign_key.'
WHERE '.$foreign_key_field.' = '.$temp_foreign_key;
if (isset($sub_table['Constrain'])) $query .= ' AND '.$sub_table['Constrain'];
$this->Conn->Query($query);
}
}
}
function CopySubTablesToLive($master, $current_ids) {
foreach ($master['SubTables'] as $sub_table) {
$table_sig = $sub_table['TableName'].(isset($sub_table['Constrain']) ? $sub_table['Constrain'] : '');
// delete records from live table by foreign key, so that records deleted from temp table
// get deleted from live
if (count($current_ids) > 0 && !in_array($table_sig, $this->CopiedTables) ) {
$foreign_keys = $this->GetForeignKeys($master, $sub_table, $current_ids);
$foreign_key_field = is_array($sub_table['ForeignKey']) ? $sub_table['ForeignKey'][$master['Prefix']] : $sub_table['ForeignKey'];
if (count($foreign_keys) > 0) {
$query = 'SELECT '.$sub_table['IdField'].' FROM '.$sub_table['TableName'].'
WHERE '.$foreign_key_field.' IN ('.join(',', $foreign_keys).')';
if (isset($sub_table['Constrain'])) $query .= ' AND '.$sub_table['Constrain'];
$this->RaiseEvent( 'OnBeforeDeleteFromLive', $sub_table['Prefix'], $this->Conn->GetCol($query) );
$query = 'DELETE FROM '.$sub_table['TableName'].'
WHERE '.$foreign_key_field.' IN ('.join(',', $foreign_keys).')';
if (isset($sub_table['Constrain'])) $query .= ' AND '.$sub_table['Constrain'];
$this->Conn->Query($query);
}
}
//sub_table passed here becomes master in the method, and recursively updated and copy its sub tables
$this->DoCopyTempToOriginal($sub_table, $master['Prefix']);
}
}
function RaiseEvent($name, $prefix, $ids, $foreign_key = null)
{
if ( !is_array($ids) ) return;
$event = new kEvent( Array('name'=>$name, 'prefix'=>$prefix, 'special'=>'') );
if( isset($foreign_key) ) $event->setEventParam('foreign_key', $foreign_key);
foreach($ids as $id)
{
$event->setEventParam('id', $id);
$this->Application->HandleEvent($event);
}
}
function DropTempTable($table)
{
if( in_array($table, $this->DroppedTables) ) return false;
$query = sprintf("DROP TABLE IF EXISTS %s",
$this->GetTempName($table)
);
array_push($this->DroppedTables, $table);
$this->DroppedTables = array_unique($this->DroppedTables);
$this->Conn->Query($query);
return true;
}
function PrepareEdit()
{
$this->DoCopyLiveToTemp($this->Tables, $this->Tables['IDs']);
}
function SaveEdit($skip_master=0)
{
$this->DoCopyTempToOriginal($this->Tables);
}
function CancelEdit($master=null)
{
if (!isset($master)) $master = $this->Tables;
$this->DropTempTable($master['TableName']);
if ( getArrayValue($master, 'SubTables') ) {
foreach ($master['SubTables'] as $sub_table) {
$this->CancelEdit($sub_table);
}
}
}
}
?>
\ No newline at end of file
Property changes on: trunk/core/kernel/utility/temp_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.14
\ No newline at end of property
+1.15
\ No newline at end of property
Index: trunk/core/units/general/brackets.php
===================================================================
--- trunk/core/units/general/brackets.php (revision 3072)
+++ trunk/core/units/general/brackets.php (revision 3073)
@@ -1,336 +1,337 @@
<?php
class kBracketsHelper extends kHelper {
/**
* Field name holding minimal amount
*
* @var string
*/
var $min_field = '';
/**
* Field name holding maximal amount
*
* @var string
*/
var $max_field = '';
/**
* Default values to be set to automtically created price brackets
*
* @var Array
*/
var $default_values = Array();
function InitHelper($min_field, $max_field, $default_values)
{
$this->min_field = $min_field;
$this->max_field = $max_field;
$this->default_values = $default_values;
}
/**
* Adds 5 more empty brackets to brackets
*
* @param kEvent $event
*/
function OnMoreBrackets(&$event)
{
$field_values = $this->Application->GetVar( $event->getPrefixSpecial(true) );
$object =& $event->getObject();
foreach($field_values as $id => $record)
{
if($record[$this->max_field] == '&#8734;') $field_values[$id][$this->max_field] = -1;
}
$new_id = (int)$this->Conn->GetOne('SELECT MIN('.$object->IDField.') FROM '.$object->TableName);
if($new_id > 0) $new_id = 0;
do
{
$new_id--;
}while( $this->arraySearch($field_values, $object->IDField, $new_id) );
$last_max_qty = $this->Conn->GetOne('SELECT MAX('.$this->max_field.') FROM '.$object->TableName);
$min_qty = $this->Conn->GetOne('SELECT MIN('.$this->max_field.') FROM '.$object->TableName);
if($min_qty == -1) $last_max_qty = -1;
if(!$last_max_qty) $last_max_qty = 1;
for($i = $new_id; $i > $new_id - 5; $i--)
{
$field_values[$i][$object->IDField] = $i;
$field_values[$i][$this->min_field] = ($i == $new_id-4 && $last_max_qty != -1) ? $last_max_qty : '';
$field_values[$i][$this->max_field] = ($i == $new_id-4 && $last_max_qty != -1) ? -1 : '';
$field_values[$i] = array_merge_recursive2($field_values[$i], $this->default_values);
}
$event->CallSubEvent('OnPreSaveBrackets');
$this->Application->SetVar($event->getPrefixSpecial(true), $field_values);
}
/**
* Adds infinity bracket
*
* @param kEvent $event
*/
function OnInfinity(&$event)
{
$object =& $event->getObject();
$infinite_exists = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$object->TableName.' WHERE '.$this->max_field.' = -1');
if($infinite_exists == 0)
{
$field_values = $this->Application->GetVar( $event->getPrefixSpecial(true) );
reset($field_values);
$last_bracket = end($field_values);
$new_id = (int)$this->Conn->GetOne('SELECT MIN('.$object->IDField.') FROM '.$object->TableName);
$brackets_exist = (int)$this->Conn->GetOne('SELECT COUNT(*) FROM '.$object->TableName);
if($new_id > 0) $new_id = 0;
do
{
$new_id--;
}while( $this->arraySearch($field_values, $object->IDField, $new_id) );
$infinite_bracket[$object->IDField] = $new_id;
$infinite_bracket[$this->min_field] = ($brackets_exist > 0) ? $last_bracket[$this->max_field] : 1;
$infinite_bracket[$this->max_field] = '-1';
$infinite_bracket = array_merge_recursive2($infinite_bracket, $this->default_values);
$field_values[$new_id] = $infinite_bracket;
reset($field_values);
$this->Application->SetVar($event->getPrefixSpecial(true), $field_values);
}
}
/**
* Saves brackets to database
*
* @param kEvent $event
*/
function OnPreSaveBrackets(&$event)
{
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true));
if($items_info)
{
$object =& $event->getObject();
$linked_info = $object->getLinkedInfo();
- $stored_ids = $this->Conn->GetCol('SELECT '.$object->IDField.' FROM '.$object->TableName.' WHERE '.$linked_info['ParentTableKey'].' = '.$linked_info['ParentId']);
+ $stored_ids = $this->Conn->GetCol('SELECT '.$object->IDField.' FROM '.$object->TableName.' WHERE '.$linked_info['ForeignKey'].' = '.$linked_info['ParentId']);
uasort($items_info, Array(&$this, 'compareBrackets') );
foreach ($items_info as $item_id => $values)
{
if (in_array($item_id, $stored_ids)) { //if it's already exist
- $object->SetDefaultValues();
- $object->Load($item_id);
- $object->SetFieldsFromHash($values);
- if (!$object->Validate()) {
- unset($stored_ids[array_search($item_id, $stored_ids)]);
- $event->redirect = false;
- continue;
- }
- if( $object->Update($item_id) )
- {
- $event->status = erSUCCESS;
- }
- else
- {
- $event->status = erFAIL;
- $event->redirect = false;
- break;
- }
- unset( $stored_ids[ array_search($item_id, $stored_ids) ] );
+ $object->SetDefaultValues();
+ $object->Load($item_id);
+ $object->SetFieldsFromHash($values);
+ if (!$object->Validate()) {
+ unset($stored_ids[array_search($item_id, $stored_ids)]);
+ $event->redirect = false;
+ continue;
+ }
+ if( $object->Update($item_id) )
+ {
+ $event->status = erSUCCESS;
+ }
+ else
+ {
+ $event->status = erFAIL;
+ $event->redirect = false;
+ break;
+ }
+ unset( $stored_ids[ array_search($item_id, $stored_ids) ] );
}
else {
$object->SetDefaultValues();
$object->SetFieldsFromHash($values);
- $object->SetDBField($linked_info['ParentTableKey'], $linked_info['ParentId']);
+ $object->SetDBField($linked_info['ForeignKey'], $linked_info['ParentId']);
if( $object->Create() )
{
$object->setTempID();
$event->status = erSUCCESS;
}
}
}
// delete
- foreach ($stored_ids as $stored_id){
+ foreach ($stored_ids as $stored_id)
+ {
$this->Conn->Query('DELETE FROM '.$object->TableName.' WHERE '.$object->IDField.' = '.$stored_id);
}
}
}
function arrangeBrackets(&$event)
{
$object =& $event->getObject();
$temp = $this->Application->GetVar( $event->getPrefixSpecial(true) );
foreach($temp as $id => $record)
{
if( $record[$this->max_field] == '&#8734;' )
{
$temp[$id][$this->max_field] = -1;
}
}
$temp_orig = $temp;
reset($temp);
if( is_array($temp) )
{
// array to store max values (2nd column)
$end_values = Array();
// get minimal value of Min
$first_elem = current($temp);
$start = $first_elem[$this->min_field];
if(!$start) $start = 1;
foreach($temp as $id => $record)
{
if(
// MAX is less than start
($record[$this->max_field] <= $start && $record[$this->max_field] != -1) ||
// Max is empty
!$record[$this->max_field] ||
// Max already defined in $end_values
(array_search($record[$this->max_field], $end_values) !== false)
) { // then delete from brackets list
unset($temp[$id]);
}
else { // this is when ok - add to end_values list
$end_values[] = $record[$this->max_field];
}
}
// sort brackets by 2nd column (Max values)
uasort($temp, Array(&$this, 'compareBrackets') );
reset($temp);
$first_item = each($temp);
$first_item_key = $first_item['key'];
$linked_info = $object->getLinkedInfo();
$sql = 'SELECT %s FROM %s WHERE %s = %s';
- $ids = $this->Conn->GetCol( sprintf($sql, $object->IDField, $object->TableName, $linked_info['ParentTableKey'], $linked_info['ParentId']) );
+ $ids = $this->Conn->GetCol( sprintf($sql, $object->IDField, $object->TableName, $linked_info['ForeignKey'], $linked_info['ParentId']) );
if( is_array($ids) )
{
usort($ids, Array(&$this, 'sortBracketIDs') );
}
$min_id = min( min($ids) - 1, -1 );
foreach($temp as $key => $record)
{
$temp[$key][$this->min_field] = $start;
$start = $temp[$key][$this->max_field];
}
}
$this->Application->SetVar($event->getPrefixSpecial(true), $temp);
return $temp;
}
function compareBrackets($bracket1, $bracket2) // ap_bracket_comp
{
$bracket1_min = $bracket1[$this->min_field];
$bracket1_max = $bracket1[$this->max_field];
$bracket2_min = $bracket2[$this->min_field];
$bracket2_max = $bracket2[$this->max_field];
// limits
if( ($bracket1_min != '') && ($bracket1_max == '') && ($bracket2_min != '') && ($bracket2_max != '') ) return 1;
if( ($bracket1_min != '') && ($bracket1_max == '') && ($bracket2_min == '') && ($bracket2_max == '') ) return -1;
if( ($bracket1_max == '') && ($bracket2_max != '') ) return 1;
if( ($bracket1_max != '') && ($bracket2_max == '') ) return -1;
if( ( ($bracket1_max > $bracket2_max) && ($bracket2_max != -1) ) || ( ($bracket1_max == -1) && ($bracket2_max != -1) ) )
{
return 1;
}
elseif( ($bracket1_max < $bracket2_max) || ( ($bracket2_max == -1) && ($bracket1_max != -1) ) )
{
return -1;
}
else
{
return 0;
}
}
function sortBracketIDs($first_id, $second_id) // pr_bracket_id_sort
{
$first_abs = abs($first_id);
$second_abs = abs($second_id);
$first_sign = ($first_id == 0) ? 0 : $first_id / $first_abs;
$second_sign = ($second_id == 0) ? 0 : $second_id / $second_abs;
if($first_sign != $second_sign)
{
if($first_id > $second_id)
{
$bigger =& $first_abs;
$smaller =& $second_abs;
}
else
{
$bigger =& $second_abs;
$smaller =& $first_abs;
}
$smaller = $bigger + $smaller;
}
return ($first_abs > $second_abs) ? 1 : ($first_abs < $second_abs ? -1 : 0);
}
/**
* Searches through submitted grid data to find record with specific value in specific field
*
* @param Array $records // grid data from REQUEST
* @param string $field
* @param string $value
* @return bool
*/
function arraySearch($records, $field, $value) // check_array
{
foreach ($records as $record)
{
if ($record[$field] == $value)
{
return true;
}
}
return false;
}
/**
* Replate infinity mark with -1 before saving to db
*
* @param kEvent $event
*/
function replaceInfinity(&$event)
{
$object =& $event->getObject();
if($object->GetDBField($this->max_field) == '&#8734;') $bracket->SetDBField($this->max_field, -1);
}
}
?>
\ No newline at end of file
Property changes on: trunk/core/units/general/brackets.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1
\ No newline at end of property
+1.2
\ No newline at end of property

Event Timeline