This repository has been archived by the owner on Jun 10, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Topological sorting implemented, XML fix for sorting removed.
- Loading branch information
Showing
3 changed files
with
258 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
<?php | ||
/** | ||
* Magento | ||
* | ||
* NOTICE OF LICENSE | ||
* | ||
* This source file is subject to the Open Software License (OSL 3.0) | ||
* that is bundled with this package in the file LICENSE.txt. | ||
* It is also available through the world-wide-web at this URL: | ||
* http://opensource.org/licenses/osl-3.0.php | ||
* If you did not receive a copy of the license and are unable to | ||
* obtain it through the world-wide-web, please send an email | ||
* to [email protected] so we can send you a copy immediately. | ||
* | ||
* DISCLAIMER | ||
* | ||
* Do not edit or add to this file if you wish to upgrade Magento to newer | ||
* versions in the future. If you wish to customize Magento for your | ||
* needs please refer to http://www.magento.com for more information. | ||
* | ||
* @category Mage | ||
* @package Mage_Sales | ||
* @copyright Copyright (c) 2006-2015 X.commerce, Inc. (http://www.magento.com) | ||
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) | ||
*/ | ||
|
||
/** | ||
* Configuration class for ordered items | ||
* | ||
* @category Mage | ||
* @package Mage_Sales | ||
* @author Magento Core Team <[email protected]> | ||
*/ | ||
abstract class Mage_Sales_Model_Config_Ordered extends Mage_Core_Model_Config_Base | ||
{ | ||
/** | ||
* Cache key for collectors | ||
* | ||
* @var string|null | ||
*/ | ||
protected $_collectorsCacheKey = null; | ||
|
||
/** | ||
* Configuration path where to collect registered totals | ||
* | ||
* @var string|null | ||
*/ | ||
protected $_totalsConfigNode = null; | ||
|
||
/** | ||
* Prepared models | ||
* | ||
* @var array | ||
*/ | ||
protected $_models = array(); | ||
|
||
/** | ||
* Models configuration | ||
* | ||
* @var array | ||
*/ | ||
protected $_modelsConfig = array(); | ||
|
||
/** | ||
* Sorted models | ||
* | ||
* @var array | ||
*/ | ||
protected $_collectors = array(); | ||
|
||
/** | ||
* Initialize total models configuration and objects | ||
* | ||
* @return Mage_Sales_Model_Config_Ordered | ||
*/ | ||
protected function _initModels() | ||
{ | ||
$totalsConfig = $this->getNode($this->_totalsConfigNode); | ||
|
||
foreach ($totalsConfig->children() as $totalCode => $totalConfig) { | ||
$class = $totalConfig->getClassName(); | ||
if (!empty($class)) { | ||
$this->_models[$totalCode] = $this->_initModelInstance($class, $totalCode, $totalConfig); | ||
} | ||
} | ||
return $this; | ||
} | ||
|
||
/** | ||
* Init model class by configuration | ||
* | ||
* @abstract | ||
* @param string $class | ||
* @param string $totalCode | ||
* @param array $totalConfig | ||
* @return mixed | ||
*/ | ||
abstract protected function _initModelInstance($class, $totalCode, $totalConfig); | ||
|
||
/** | ||
* Prepare configuration array for total model | ||
* | ||
* @param string $code | ||
* @param Mage_Core_Model_Config_Element $totalConfig | ||
* @return array | ||
*/ | ||
protected function _prepareConfigArray($code, $totalConfig) | ||
{ | ||
$totalConfig = (array)$totalConfig; | ||
if (isset($totalConfig['before'])) { | ||
$totalConfig['before'] = explode(',', $totalConfig['before']); | ||
} else { | ||
$totalConfig['before'] = array(); | ||
} | ||
if (isset($totalConfig['after'])) { | ||
$totalConfig['after'] = explode(',', $totalConfig['after']); | ||
} else { | ||
$totalConfig['after'] = array(); | ||
} | ||
$totalConfig['_code'] = $code; | ||
return $totalConfig; | ||
} | ||
|
||
/** | ||
* Aggregate before/after information from all items and sort totals based on this data | ||
* | ||
* @return array | ||
*/ | ||
protected function _getSortedCollectorCodes() | ||
{ | ||
if (Mage::app()->useCache('config')) { | ||
$cachedData = Mage::app()->loadCache($this->_collectorsCacheKey); | ||
if ($cachedData) { | ||
return unserialize($cachedData); | ||
} | ||
} | ||
$configArray = $this->_modelsConfig; | ||
// invoke simple sorting if the first element contains the "sort_order" key | ||
reset($configArray); | ||
$element = current($configArray); | ||
if (isset($element['sort_order'])) { | ||
uasort($configArray, array($this, '_compareSortOrder')); | ||
$sortedCollectors = array_keys($configArray); | ||
} else { | ||
$sortedCollectors = array_keys($configArray); | ||
// Move all totals with before specification in front of related total | ||
|
||
foreach ($configArray as $code => &$data) { | ||
foreach ($data['before'] as $positionCode) { | ||
if (!isset($configArray[$positionCode])) { | ||
continue; | ||
} | ||
if (!in_array($code, $configArray[$positionCode]['after'], true)) { | ||
// Also add additional after condition for related total, | ||
// to keep it always after total with before value specified | ||
$configArray[$positionCode]['after'][] = $code; | ||
} | ||
$currentPosition = array_search($code, $sortedCollectors, true); | ||
$desiredPosition = array_search($positionCode, $sortedCollectors, true); | ||
if ($currentPosition > $desiredPosition) { | ||
// Only if current position is not corresponding to before condition | ||
array_splice($sortedCollectors, $currentPosition, 1); // Removes existent | ||
array_splice($sortedCollectors, $desiredPosition, 0, $code); // Add at new position | ||
} | ||
} | ||
} | ||
// Sort out totals with after position specified | ||
foreach ($configArray as $code => &$data) { | ||
$maxAfter = null; | ||
$currentPosition = array_search($code, $sortedCollectors, true); | ||
|
||
foreach ($data['after'] as $positionCode) { | ||
$maxAfter = max($maxAfter, array_search($positionCode, $sortedCollectors, true)); | ||
} | ||
|
||
if ($maxAfter !== null && $maxAfter > $currentPosition) { | ||
// Moves only if it is in front of after total | ||
array_splice($sortedCollectors, $maxAfter + 1, 0, $code); // Add at new position | ||
array_splice($sortedCollectors, $currentPosition, 1); // Removes existent | ||
} | ||
} | ||
} | ||
if (Mage::app()->useCache('config')) { | ||
Mage::app()->saveCache(serialize($sortedCollectors), $this->_collectorsCacheKey, array( | ||
Mage_Core_Model_Config::CACHE_TAG | ||
) | ||
); | ||
} | ||
return $sortedCollectors; | ||
} | ||
|
||
/** | ||
* Initialize collectors array. | ||
* Collectors array is array of total models ordered based on configuration settings | ||
* | ||
* @return Mage_Sales_Model_Config_Ordered | ||
*/ | ||
protected function _initCollectors() | ||
{ | ||
$sortedCodes = $this->_getSortedCollectorCodes(); | ||
foreach ($sortedCodes as $code) { | ||
$this->_collectors[$code] = $this->_models[$code]; | ||
} | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Callback that uses after/before for comparison | ||
* | ||
* @param array $a | ||
* @param array $b | ||
* @return int | ||
*/ | ||
protected function _compareTotals($a, $b) | ||
{ | ||
$aCode = $a['_code']; | ||
$bCode = $b['_code']; | ||
if (in_array($aCode, $b['after']) || in_array($bCode, $a['before'])) { | ||
$res = -1; | ||
} elseif (in_array($bCode, $a['after']) || in_array($aCode, $b['before'])) { | ||
$res = 1; | ||
} else { | ||
$res = 0; | ||
} | ||
return $res; | ||
} | ||
|
||
/** | ||
* Callback that uses sort_order for comparison | ||
* | ||
* @param array $a | ||
* @param array $b | ||
* @return int | ||
*/ | ||
protected function _compareSortOrder($a, $b) | ||
{ | ||
if (!isset($a['sort_order']) || !isset($b['sort_order'])) { | ||
return 0; | ||
} | ||
if ($a['sort_order'] > $b['sort_order']) { | ||
$res = 1; | ||
} elseif ($a['sort_order'] < $b['sort_order']) { | ||
$res = -1; | ||
} else { | ||
$res = 0; | ||
} | ||
return $res; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters