1: <?php
2: /**
3: * Magento
4: *
5: * NOTICE OF LICENSE
6: *
7: * This source file is subject to the Open Software License (OSL 3.0)
8: * that is bundled with this package in the file LICENSE.txt.
9: * It is also available through the world-wide-web at this URL:
10: * http://opensource.org/licenses/osl-3.0.php
11: * If you did not receive a copy of the license and are unable to
12: * obtain it through the world-wide-web, please send an email
13: * to license@magentocommerce.com so we can send you a copy immediately.
14: *
15: * DISCLAIMER
16: *
17: * Do not edit or add to this file if you wish to upgrade Magento to newer
18: * versions in the future. If you wish to customize Magento for your
19: * needs please refer to http://www.magentocommerce.com for more information.
20: *
21: * @category Mage
22: * @package Mage_Sales
23: * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
24: * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25: */
26:
27: /**
28: * Address Total Collector model
29: *
30: * @category Mage
31: * @package Mage_Core
32: * @author Magento Core Team <core@magentocommerce.com>
33: */
34: class Mage_Sales_Model_Quote_Address_Total_Collector extends Mage_Sales_Model_Config_Ordered
35: {
36: /**
37: * Path to sort order values of checkout totals
38: */
39: const XML_PATH_SALES_TOTALS_SORT = 'sales/totals_sort';
40:
41: /**
42: * Total models array ordered for right display sequence
43: *
44: * @var array
45: */
46: protected $_retrievers = array();
47:
48: /**
49: * Corresponding store object
50: *
51: * @var Mage_Core_Model_Store
52: */
53: protected $_store;
54:
55: /**
56: * Configuration path where to collect registered totals
57: *
58: * @var string
59: */
60: protected $_totalsConfigNode = 'global/sales/quote/totals';
61:
62: /**
63: * Cache key for collectors
64: *
65: * @var string
66: */
67: protected $_collectorsCacheKey = 'sorted_quote_collectors';
68:
69: /**
70: * Init corresponding total models
71: *
72: * @param array $options
73: */
74: public function __construct($options)
75: {
76: if (isset($options['store'])) {
77: $this->_store = $options['store'];
78: } else {
79: $this->_store = Mage::app()->getStore();
80: }
81: $this->_initModels()
82: ->_initCollectors()
83: ->_initRetrievers();
84: }
85:
86: /**
87: * Get total models array ordered for right calculation logic
88: *
89: * @return array
90: */
91: public function getCollectors()
92: {
93: return $this->_collectors;
94: }
95:
96: /**
97: * Get total models array ordered for right display sequence
98: *
99: * @return array
100: */
101: public function getRetrievers()
102: {
103: return $this->_retrievers;
104: }
105:
106: /**
107: * Init model class by configuration
108: *
109: * @param string $class
110: * @param string $totalCode
111: * @param array $totalConfig
112: * @return Mage_Sales_Model_Quote_Address_Total_Abstract
113: */
114: protected function _initModelInstance($class, $totalCode, $totalConfig)
115: {
116: $model = Mage::getModel($class);
117: if (!$model instanceof Mage_Sales_Model_Quote_Address_Total_Abstract) {
118: Mage::throwException(
119: Mage::helper('sales')->__('The address total model should be extended from Mage_Sales_Model_Quote_Address_Total_Abstract.')
120: );
121: }
122:
123: $model->setCode($totalCode);
124: $this->_modelsConfig[$totalCode]= $this->_prepareConfigArray($totalCode, $totalConfig);
125: $this->_modelsConfig[$totalCode]= $model->processConfigArray(
126: $this->_modelsConfig[$totalCode],
127: $this->_store
128: );
129:
130: return $model;
131: }
132:
133: /**
134: * Initialize total models configuration and objects
135: *
136: * @return Mage_Sales_Model_Quote_Address_Total_Collector
137: */
138: protected function _initModels()
139: {
140: $totalsConfig = Mage::getConfig()->getNode($this->_totalsConfigNode);
141:
142: foreach ($totalsConfig->children() as $totalCode => $totalConfig) {
143: $class = $totalConfig->getClassName();
144: if (!empty($class)) {
145: $this->_models[$totalCode] = $this->_initModelInstance($class, $totalCode, $totalConfig);
146: }
147: }
148: return $this;
149: }
150:
151: /**
152: * Initialize retrievers array
153: *
154: * @return Mage_Sales_Model_Quote_Address_Total_Collector
155: */
156: protected function _initRetrievers()
157: {
158: $sorts = Mage::getStoreConfig(self::XML_PATH_SALES_TOTALS_SORT, $this->_store);
159: foreach ($sorts as $code => $sortOrder) {
160: if (isset($this->_models[$code])) {
161: // Reserve enough space for collisions
162: $retrieverId = 100 * (int) $sortOrder;
163: // Check if there is a retriever with such id and find next available position if needed
164: while (isset($this->_retrievers[$retrieverId])) {
165: $retrieverId++;
166: }
167: $this->_retrievers[$retrieverId] = $this->_models[$code];
168: }
169: }
170: ksort($this->_retrievers);
171: $notSorted = array_diff(array_keys($this->_models), array_keys($sorts));
172: foreach ($notSorted as $code) {
173: $this->_retrievers[] = $this->_models[$code];
174: }
175: return $this;
176: }
177: }
178: