Index: trunk/globals.php =================================================================== diff -u -r2015 -r2320 --- trunk/globals.php (.../globals.php) (revision 2015) +++ trunk/globals.php (.../globals.php) (revision 2320) @@ -1795,6 +1795,31 @@ } } +function ap_bracket_comp($elem1, $elem2) +{ + + if ($elem1['FromAmount']!="" && $elem1['ToAmount']=="" && $elem2['FromAmount']!="" && $elem2['ToAmount']!="") return 1; + if ($elem1['FromAmount']!="" && $elem1['ToAmount']=="" && $elem2['FromAmount']=="" && $elem2['ToAmount']=="") return -1; + + + if ($elem1['ToAmount']=="" && $elem2['ToAmount']!="") return 1; + if ($elem1['ToAmount']!="" && $elem2['ToAmount']=="") return -1; + + + if( ($elem1['ToAmount']>$elem2['ToAmount'] && $elem2['ToAmount']!=-1) || ($elem1['ToAmount'] == -1 && $elem2['ToAmount'] != -1 )) + { + return 1; + } + elseif ( ($elem1['ToAmount']<$elem2['ToAmount']) || ($elem2['ToAmount'] == -1 && $elem1['ToAmount'] != -1 )) + { + return -1; + } + else + { + return 0; + } +} + function pr_bracket_id_sort($first_id, $second_id) { $first_abs = abs($first_id); Index: trunk/core/units/general/brackets.php =================================================================== diff -u --- trunk/core/units/general/brackets.php (revision 0) +++ trunk/core/units/general/brackets.php (revision 2320) @@ -0,0 +1,336 @@ +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] == '∞') $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']); + + 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) ] ); + } + else { + $object->SetDefaultValues(); + $object->SetFieldsFromHash($values); + $object->SetDBField($linked_info['ParentTableKey'], $linked_info['ParentId']); + + if( $object->Create() ) + { + $object->setTempID(); + $event->status = erSUCCESS; + } + } + } + + // delete + 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] == '∞' ) + { + $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']) ); + 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) == '∞') $bracket->SetDBField($this->max_field, -1); + } + + } + +?> \ No newline at end of file Index: trunk/kernel/units/general/brackets.php =================================================================== diff -u --- trunk/kernel/units/general/brackets.php (revision 0) +++ trunk/kernel/units/general/brackets.php (revision 2320) @@ -0,0 +1,336 @@ +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] == '∞') $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']); + + 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) ] ); + } + else { + $object->SetDefaultValues(); + $object->SetFieldsFromHash($values); + $object->SetDBField($linked_info['ParentTableKey'], $linked_info['ParentId']); + + if( $object->Create() ) + { + $object->setTempID(); + $event->status = erSUCCESS; + } + } + } + + // delete + 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] == '∞' ) + { + $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']) ); + 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) == '∞') $bracket->SetDBField($this->max_field, -1); + } + + } + +?> \ No newline at end of file Index: trunk/core/units/general/my_application.php =================================================================== diff -u -r2310 -r2320 --- trunk/core/units/general/my_application.php (.../my_application.php) (revision 2310) +++ trunk/core/units/general/my_application.php (.../my_application.php) (revision 2320) @@ -21,6 +21,7 @@ $this->registerClass('InpCustomFieldsHelper',MODULES_PATH.'/kernel/units/general/custom_fields.php','InpCustomFieldsHelper'); $this->registerClass('kCountryStatesHelper',MODULES_PATH.'/kernel/units/general/country_states.php','CountryStatesHelper'); + $this->registerClass('kBracketsHelper',MODULES_PATH.'/kernel/units/general/brackets.php','BracketsHelper'); } /** Index: trunk/kernel/units/general/my_application.php =================================================================== diff -u -r2310 -r2320 --- trunk/kernel/units/general/my_application.php (.../my_application.php) (revision 2310) +++ trunk/kernel/units/general/my_application.php (.../my_application.php) (revision 2320) @@ -21,6 +21,7 @@ $this->registerClass('InpCustomFieldsHelper',MODULES_PATH.'/kernel/units/general/custom_fields.php','InpCustomFieldsHelper'); $this->registerClass('kCountryStatesHelper',MODULES_PATH.'/kernel/units/general/country_states.php','CountryStatesHelper'); + $this->registerClass('kBracketsHelper',MODULES_PATH.'/kernel/units/general/brackets.php','BracketsHelper'); } /** Index: trunk/core/kernel/kbase.php =================================================================== diff -u -r2285 -r2320 --- trunk/core/kernel/kbase.php (.../kbase.php) (revision 2285) +++ trunk/core/kernel/kbase.php (.../kbase.php) (revision 2320) @@ -73,12 +73,15 @@ * Returns joined prefix * and special if any * + * @param bool $from_submit if true, then joins prefix & special by "_", uses "." otherwise * @return string * @access protected */ - function getPrefixSpecial() + function getPrefixSpecial($from_submit = false) { - return rtrim($this->Prefix.'.'.$this->Special,'.'); + $separator = !$from_submit ? '.' : '_'; + $ret = $this->Prefix.$separator.$this->Special; + return rtrim($ret, $separator); } function &getProperty($property_name) @@ -108,6 +111,11 @@ $this->Conn =& $this->Application->GetADODBConnection(); } + function InitHelper() + { + + } + } class kDBBase extends kBase { @@ -479,7 +487,7 @@ 'ParentPrefix' => $parent_prefix ); - $main_object = $this->Application->recallObject($parent_prefix.'.'.$special); + $main_object =& $this->Application->recallObject($parent_prefix.'.'.$special); return array_merge($table_info, Array('ParentId'=> $main_object->GetDBField( $table_info['ParentTableKey'] ) ) ); } return false;