Mage_Core_Modules - Version 1.6.2.0

Version Notes

1.6.2.0

Download this release

Release Info

Developer Magento Core Team
Extension Mage_Core_Modules
Version 1.6.2.0
Comparing to
See all releases


Code changes from version 1.6.1.0 to 1.6.2.0

Files changed (86) hide show
  1. RELEASE_NOTES.txt +32 -0
  2. app/Mage.php +1 -1
  3. app/code/core/Mage/Admin/etc/config.xml +1 -1
  4. app/code/core/Mage/Bundle/Block/Catalog/Product/View/Type/Bundle.php +27 -27
  5. app/code/core/Mage/Bundle/Model/Product/Price.php +52 -40
  6. app/code/core/Mage/Bundle/Model/Resource/Indexer/Price.php +9 -1
  7. app/code/core/Mage/Bundle/Model/Resource/Indexer/Stock.php +0 -12
  8. app/code/core/Mage/Catalog/Model/Category/Indexer/Flat.php +22 -13
  9. app/code/core/Mage/Catalog/Model/Category/Indexer/Product.php +13 -9
  10. app/code/core/Mage/Catalog/Model/Indexer/Url.php +24 -12
  11. app/code/core/Mage/Catalog/Model/Observer.php +13 -0
  12. app/code/core/Mage/Catalog/Model/Product/Flat/Indexer.php +42 -2
  13. app/code/core/Mage/Catalog/Model/Product/Indexer/Flat.php +59 -16
  14. app/code/core/Mage/Catalog/Model/Product/Indexer/Price.php +24 -7
  15. app/code/core/Mage/Catalog/Model/Resource/Category/Flat.php +55 -2
  16. app/code/core/Mage/Catalog/Model/Resource/Category/Indexer/Product.php +159 -148
  17. app/code/core/Mage/Catalog/Model/Resource/Product/Flat/Indexer.php +38 -2
  18. app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php +19 -6
  19. app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Price.php +17 -16
  20. app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Price/Configurable.php +13 -12
  21. app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Price/Default.php +13 -15
  22. app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Price/Grouped.php +10 -2
  23. app/code/core/Mage/Catalog/Model/Resource/Url.php +2 -2
  24. app/code/core/Mage/Catalog/etc/config.xml +2 -2
  25. app/code/core/Mage/Catalog/sql/catalog_setup/upgrade-1.6.0.0.6-1.6.0.0.7.php +39 -0
  26. app/code/core/Mage/Catalog/sql/catalog_setup/upgrade-1.6.0.0.7-1.6.0.0.8.php +97 -0
  27. app/code/core/Mage/CatalogInventory/Model/Indexer/Stock.php +12 -9
  28. app/code/core/Mage/CatalogInventory/Model/Observer.php +11 -0
  29. app/code/core/Mage/CatalogInventory/Model/Resource/Indexer/Stock.php +13 -6
  30. app/code/core/Mage/CatalogInventory/Model/Resource/Indexer/Stock/Configurable.php +0 -12
  31. app/code/core/Mage/CatalogInventory/Model/Resource/Indexer/Stock/Default.php +8 -1
  32. app/code/core/Mage/CatalogInventory/Model/Resource/Indexer/Stock/Grouped.php +0 -12
  33. app/code/core/Mage/CatalogInventory/Model/Stock/Item.php +26 -3
  34. app/code/core/Mage/CatalogInventory/etc/config.xml +26 -0
  35. app/code/core/Mage/CatalogRule/Model/Rule.php +5 -1
  36. app/code/core/Mage/CatalogSearch/Model/Fulltext.php +4 -17
  37. app/code/core/Mage/CatalogSearch/Model/Indexer/Fulltext.php +67 -17
  38. app/code/core/Mage/CatalogSearch/Model/Resource/Fulltext.php +4 -6
  39. app/code/core/Mage/Core/Controller/Varien/Action.php +2 -0
  40. app/code/core/Mage/Core/etc/system.xml +1 -0
  41. app/code/core/Mage/Customer/controllers/AccountController.php +1 -1
  42. app/code/core/Mage/Customer/etc/config.xml +1 -1
  43. app/code/core/Mage/Customer/etc/system.xml +1 -0
  44. app/code/core/Mage/Downloadable/Model/Resource/Indexer/Price.php +12 -10
  45. app/code/core/Mage/ImportExport/Model/Import.php +2 -1
  46. app/code/core/Mage/Index/Block/Adminhtml/Notifications.php +5 -2
  47. app/code/core/Mage/Index/Block/Adminhtml/Process/Grid.php +62 -8
  48. app/code/core/Mage/Index/Block/Adminhtml/Process/Grid/Massaction.php +54 -0
  49. app/code/core/Mage/Index/Model/Event.php +68 -34
  50. app/code/core/Mage/Index/Model/Indexer.php +119 -52
  51. app/code/core/Mage/Index/Model/Indexer/Abstract.php +23 -7
  52. app/code/core/Mage/Index/Model/Observer.php +1 -1
  53. app/code/core/Mage/Index/Model/Process.php +171 -39
  54. app/code/core/Mage/Index/Model/Resource/Abstract.php +14 -12
  55. app/code/core/Mage/Index/Model/Resource/Event.php +52 -3
  56. app/code/core/Mage/Index/Model/Resource/Event/Collection.php +7 -2
  57. app/code/core/Mage/Index/Model/Resource/Process.php +41 -1
  58. app/code/core/Mage/Index/Model/Resource/Process/Collection.php +23 -0
  59. app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Payflowlink/Advanced.php +43 -0
  60. app/code/core/Mage/Paypal/Block/Iframe.php +2 -1
  61. app/code/core/Mage/Paypal/Block/Payflow/Advanced/Form.php +56 -0
  62. app/code/core/Mage/Paypal/Block/Payflow/Advanced/Iframe.php +67 -0
  63. app/code/core/Mage/Paypal/Block/Payflow/Advanced/Info.php +37 -0
  64. app/code/core/Mage/Paypal/Block/Payflow/Advanced/Review.php +38 -0
  65. app/code/core/Mage/Paypal/Block/Payflow/Link/Form.php +1 -1
  66. app/code/core/Mage/Paypal/Block/Payflow/Link/Iframe.php +13 -14
  67. app/code/core/Mage/Paypal/Block/Payflow/Link/Review.php +47 -0
  68. app/code/core/Mage/Paypal/Helper/Hss.php +3 -1
  69. app/code/core/Mage/Paypal/Model/Cart.php +7 -7
  70. app/code/core/Mage/Paypal/Model/Config.php +11 -10
  71. app/code/core/Mage/Paypal/Model/Observer.php +2 -25
  72. app/code/core/Mage/Paypal/Model/Payflowadvanced.php +57 -0
  73. app/code/core/Mage/Paypal/Model/Payflowlink.php +183 -310
  74. app/code/core/Mage/Paypal/Model/Report/Settlement.php +97 -45
  75. app/code/core/Mage/Paypal/Model/Resource/Payment/Transaction.php +1 -0
  76. app/code/core/Mage/Paypal/Model/Resource/Payment/Transaction/Collection.php +1 -0
  77. app/code/core/Mage/Paypal/Model/System/Config/Source/AuthorizationAmounts.php +6 -3
  78. app/code/core/Mage/Paypal/controllers/PayflowController.php +44 -57
  79. app/code/core/Mage/Paypal/controllers/PayflowadvancedController.php +170 -0
  80. app/code/core/Mage/Paypal/etc/config.xml +13 -10
  81. app/code/core/Mage/Paypal/etc/system.xml +179 -11
  82. app/code/core/Mage/Paypal/sql/paypal_setup/upgrade-1.6.0.1-1.6.0.2.php +35 -0
  83. app/code/core/Mage/Tag/Model/Resource/Indexer/Summary.php +3 -3
  84. app/code/core/Mage/Weee/Model/Observer.php +1 -1
  85. app/code/core/Mage/Wishlist/controllers/IndexController.php +6 -3
  86. package.xml +6 -6
RELEASE_NOTES.txt CHANGED
@@ -1,3 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ==== 1.6.1.0 ====
2
 
3
  === Major Highlights ===
1
+ ==== 1.6.2.0 ====
2
+
3
+ === Improvements ===
4
+ Refactored indexing process:
5
+ - Changed logic around reindexing to prevent conflicts between partial and full reindexing
6
+ - Prevented situations where concurrent indexing processes run at the same time and overwrite each other's data
7
+
8
+ === Changes ===
9
+ Implemented localized PayPal settings for Japan
10
+ Added PayPal Payments Advanced
11
+
12
+ === Fixes ===
13
+ Fixed Automatic reindexing based on matched events doesn't change "Status" and "Last Run" columns at process list grid
14
+ Fixed Bundle product totals are incorrect in Customization block
15
+ Fixed Product option title is absent in backend order page
16
+ Fixed SQL error on category view with enabled and configured FPT
17
+ Fixed Special price isn't considered for bundle dynamic products in "Your Customization" block
18
+ Fixed Cannot place order with downloadable product and discount code using Paypal Express payment method
19
+ Fixed Payflow Link Express Checkout ("Pay with PayPal" button) payment
20
+ Fixed Char set encoding is out-of-date in Settlement reports
21
+ Fixed Settlement reports can not be downloaded if in merchant's account "Settlement file" is set to 6.0 version
22
+ Fixed Updates for Payflow Link texts
23
+ Fixed Impossible to place Order using "Pay with PayPal" button from Payflow Link iframe, when Payment Action is Sale
24
+ Fixed Remove hint about $1 authorization amount from informational message text (Payflow Link configuration)
25
+ Fixed Missing column "position" at table catalog_category_anc_products_index_tmp
26
+ Fixed Translation with single quotes breaks JS
27
+ Fixed Two-step password reset
28
+ Fixed Unable to change root category for the store
29
+ Fixed Exception while products mass update attributes in backend
30
+
31
+
32
+
33
  ==== 1.6.1.0 ====
34
 
35
  === Major Highlights ===
app/Mage.php CHANGED
@@ -152,7 +152,7 @@ final class Mage
152
  return array(
153
  'major' => '1',
154
  'minor' => '6',
155
- 'revision' => '1',
156
  'patch' => '0',
157
  'stability' => '',
158
  'number' => '',
152
  return array(
153
  'major' => '1',
154
  'minor' => '6',
155
+ 'revision' => '2',
156
  'patch' => '0',
157
  'stability' => '',
158
  'number' => '',
app/code/core/Mage/Admin/etc/config.xml CHANGED
@@ -79,7 +79,7 @@
79
  <emails>
80
  <forgot_email_template>admin_emails_forgot_email_template</forgot_email_template>
81
  <forgot_email_identity>general</forgot_email_identity>
82
- <password_reset_link_expiration_period>3</password_reset_link_expiration_period>
83
  </emails>
84
  </admin>
85
  </default>
79
  <emails>
80
  <forgot_email_template>admin_emails_forgot_email_template</forgot_email_template>
81
  <forgot_email_identity>general</forgot_email_identity>
82
+ <password_reset_link_expiration_period>1</password_reset_link_expiration_period>
83
  </emails>
84
  </admin>
85
  </default>
app/code/core/Mage/Bundle/Block/Catalog/Product/View/Type/Bundle.php CHANGED
@@ -73,6 +73,11 @@ class Mage_Bundle_Block_Catalog_Product_View_Type_Bundle extends Mage_Catalog_Bl
73
  return true;
74
  }
75
 
 
 
 
 
 
76
  public function getJsonConfig()
77
  {
78
  Mage::app()->getLocale()->getJsPriceFormat();
@@ -80,15 +85,18 @@ class Mage_Bundle_Block_Catalog_Product_View_Type_Bundle extends Mage_Catalog_Bl
80
  $options = array();
81
  $selected = array();
82
  $currentProduct = $this->getProduct();
 
83
  $coreHelper = Mage::helper('core');
 
84
  $bundlePriceModel = Mage::getModel('bundle/product_price');
85
 
86
- if ($preconfiguredFlag = $currentProduct->hasPreconfiguredValues()) {
87
- $preconfiguredValues = $currentProduct->getPreconfiguredValues();
88
  $defaultValues = array();
89
  }
90
 
91
  foreach ($optionsArray as $_option) {
 
92
  if (!$_option->getSelections()) {
93
  continue;
94
  }
@@ -103,8 +111,9 @@ class Mage_Bundle_Block_Catalog_Product_View_Type_Bundle extends Mage_Catalog_Bl
103
  $selectionCount = count($_option->getSelections());
104
 
105
  foreach ($_option->getSelections() as $_selection) {
 
106
  $selectionId = $_selection->getSelectionId();
107
- $_qty = !($_selection->getSelectionQty()*1) ? '1' : $_selection->getSelectionQty()*1;
108
  // recalculate currency
109
  $tierPrices = $_selection->getTierPrice();
110
  foreach ($tierPrices as &$tierPriceInfo) {
@@ -112,17 +121,8 @@ class Mage_Bundle_Block_Catalog_Product_View_Type_Bundle extends Mage_Catalog_Bl
112
  }
113
  unset($tierPriceInfo); // break the reference with the last element
114
 
115
- $taxPercent = 0;
116
- $taxClassId = $_selection->getTaxClassId();
117
- if ($taxClassId) {
118
- $request = Mage::getSingleton('tax/calculation')->getRateRequest();
119
- $taxPercent = Mage::getSingleton('tax/calculation')->getRate(
120
- $request->setProductClassId($taxClassId)
121
- );
122
- }
123
-
124
  $itemPrice = $bundlePriceModel->getSelectionFinalTotalPrice($currentProduct, $_selection,
125
- $currentProduct->getQty(), $_selection->getQty());
126
 
127
  $canApplyMAP = false;
128
 
@@ -138,16 +138,16 @@ class Mage_Bundle_Block_Catalog_Product_View_Type_Bundle extends Mage_Catalog_Bl
138
  }
139
 
140
  $selection = array (
141
- 'qty' => $_qty,
142
- 'customQty' => $_selection->getSelectionCanChangeQty(),
143
- 'price' => $coreHelper->currency($_selection->getFinalPrice(), false, false),
144
- 'priceInclTax' => $coreHelper->currency($_priceInclTax, false, false),
145
- 'priceExclTax' => $coreHelper->currency($_priceExclTax, false, false),
146
- 'priceValue' => $coreHelper->currency($_selection->getSelectionPriceValue(), false, false),
147
- 'priceType' => $_selection->getSelectionPriceType(),
148
- 'tierPrice' => $tierPrices,
149
- 'name' => $_selection->getName(),
150
- 'plusDisposition' => 0,
151
  'minusDisposition' => 0,
152
  'canApplyMAP' => $canApplyMAP
153
  );
@@ -156,7 +156,7 @@ class Mage_Bundle_Block_Catalog_Product_View_Type_Bundle extends Mage_Catalog_Bl
156
  $args = array('response_object' => $responseObject, 'selection' => $_selection);
157
  Mage::dispatchEvent('bundle_product_view_config', $args);
158
  if (is_array($responseObject->getAdditionalOptions())) {
159
- foreach ($responseObject->getAdditionalOptions() as $o=>$v) {
160
  $selection[$o] = $v;
161
  }
162
  }
@@ -171,8 +171,8 @@ class Mage_Bundle_Block_Catalog_Product_View_Type_Bundle extends Mage_Catalog_Bl
171
  $options[$optionId] = $option;
172
 
173
  // Add attribute default value (if set)
174
- if ($preconfiguredFlag) {
175
- $configValue = $preconfiguredValues->getData('bundle_option/' . $optionId);
176
  if ($configValue) {
177
  $defaultValues[$optionId] = $configValue;
178
  }
@@ -192,7 +192,7 @@ class Mage_Bundle_Block_Catalog_Product_View_Type_Bundle extends Mage_Catalog_Bl
192
  'isMAPAppliedDirectly' => Mage::helper('catalog')->canApplyMsrp($this->getProduct(), null, false)
193
  );
194
 
195
- if ($preconfiguredFlag && !empty($defaultValues)) {
196
  $config['defaultValues'] = $defaultValues;
197
  }
198
 
73
  return true;
74
  }
75
 
76
+ /**
77
+ * Returns JSON encoded config to be used in JS scripts
78
+ *
79
+ * @return string
80
+ */
81
  public function getJsonConfig()
82
  {
83
  Mage::app()->getLocale()->getJsPriceFormat();
85
  $options = array();
86
  $selected = array();
87
  $currentProduct = $this->getProduct();
88
+ /* @var $coreHelper Mage_Core_Helper_Data */
89
  $coreHelper = Mage::helper('core');
90
+ /* @var $bundlePriceModel Mage_Bundle_Model_Product_Price */
91
  $bundlePriceModel = Mage::getModel('bundle/product_price');
92
 
93
+ if ($preConfiguredFlag = $currentProduct->hasPreconfiguredValues()) {
94
+ $preConfiguredValues = $currentProduct->getPreconfiguredValues();
95
  $defaultValues = array();
96
  }
97
 
98
  foreach ($optionsArray as $_option) {
99
+ /* @var $_option Mage_Bundle_Model_Option */
100
  if (!$_option->getSelections()) {
101
  continue;
102
  }
111
  $selectionCount = count($_option->getSelections());
112
 
113
  foreach ($_option->getSelections() as $_selection) {
114
+ /* @var $_selection Mage_Catalog_Model_Product */
115
  $selectionId = $_selection->getSelectionId();
116
+ $_qty = !($_selection->getSelectionQty() * 1) ? '1' : $_selection->getSelectionQty() * 1;
117
  // recalculate currency
118
  $tierPrices = $_selection->getTierPrice();
119
  foreach ($tierPrices as &$tierPriceInfo) {
121
  }
122
  unset($tierPriceInfo); // break the reference with the last element
123
 
 
 
 
 
 
 
 
 
 
124
  $itemPrice = $bundlePriceModel->getSelectionFinalTotalPrice($currentProduct, $_selection,
125
+ $currentProduct->getQty(), $_selection->getQty(), false);
126
 
127
  $canApplyMAP = false;
128
 
138
  }
139
 
140
  $selection = array (
141
+ 'qty' => $_qty,
142
+ 'customQty' => $_selection->getSelectionCanChangeQty(),
143
+ 'price' => $coreHelper->currency($_selection->getFinalPrice(), false, false),
144
+ 'priceInclTax' => $coreHelper->currency($_priceInclTax, false, false),
145
+ 'priceExclTax' => $coreHelper->currency($_priceExclTax, false, false),
146
+ 'priceValue' => $coreHelper->currency($_selection->getSelectionPriceValue(), false, false),
147
+ 'priceType' => $_selection->getSelectionPriceType(),
148
+ 'tierPrice' => $tierPrices,
149
+ 'name' => $_selection->getName(),
150
+ 'plusDisposition' => 0,
151
  'minusDisposition' => 0,
152
  'canApplyMAP' => $canApplyMAP
153
  );
156
  $args = array('response_object' => $responseObject, 'selection' => $_selection);
157
  Mage::dispatchEvent('bundle_product_view_config', $args);
158
  if (is_array($responseObject->getAdditionalOptions())) {
159
+ foreach ($responseObject->getAdditionalOptions() as $o => $v) {
160
  $selection[$o] = $v;
161
  }
162
  }
171
  $options[$optionId] = $option;
172
 
173
  // Add attribute default value (if set)
174
+ if ($preConfiguredFlag) {
175
+ $configValue = $preConfiguredValues->getData('bundle_option/' . $optionId);
176
  if ($configValue) {
177
  $defaultValues[$optionId] = $configValue;
178
  }
192
  'isMAPAppliedDirectly' => Mage::helper('catalog')->canApplyMsrp($this->getProduct(), null, false)
193
  );
194
 
195
+ if ($preConfiguredFlag && !empty($defaultValues)) {
196
  $config['defaultValues'] = $defaultValues;
197
  }
198
 
app/code/core/Mage/Bundle/Model/Product/Price.php CHANGED
@@ -27,9 +27,9 @@
27
  /**
28
  * Bundle Price Model
29
  *
30
- * @category Mage
31
- * @package Mage_Bundle
32
- * @author Magento Core Team <core@magentocommerce.com>
33
  */
34
  class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Price
35
  {
@@ -37,7 +37,7 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
37
  const PRICE_TYPE_DYNAMIC = 0;
38
 
39
  /**
40
- * Flag wich indicates - is min/max prices have been calculated by index
41
  *
42
  * @var bool
43
  */
@@ -56,6 +56,7 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
56
  /**
57
  * Return product base price
58
  *
 
59
  * @return string
60
  */
61
  public function getPrice($product)
@@ -70,11 +71,11 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
70
  /**
71
  * Get product final price
72
  *
73
- * @param double $qty
74
  * @param Mage_Catalog_Model_Product $product
75
  * @return double
76
  */
77
- public function getFinalPrice($qty=null, $product)
78
  {
79
  if (is_null($qty) && !is_null($product->getCalculatedFinalPrice())) {
80
  return $product->getCalculatedFinalPrice();
@@ -122,6 +123,15 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
122
  return max(0, $product->getData('final_price'));
123
  }
124
 
 
 
 
 
 
 
 
 
 
125
  public function getChildFinalPrice($product, $productQty, $childProduct, $childProductQty)
126
  {
127
  return $this->getSelectionFinalPrice($product, $childProduct, $productQty, $childProductQty, false);
@@ -134,7 +144,7 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
134
  * @see Mage_Bundle_Model_Product_Price::getTotalPrices()
135
  *
136
  * @param Mage_Catalog_Model_Product $product
137
- * @param string $which
138
  * @return decimal|array
139
  */
140
  public function getPrices($product, $which = null)
@@ -149,8 +159,8 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
149
  * @see Mage_Bundle_Model_Product_Price::getTotalPrices()
150
  *
151
  * @param Mage_Catalog_Model_Product $product
152
- * @param string $which
153
- * @param bool|null $includeTax
154
  * @return decimal|array
155
  */
156
  public function getPricesDependingOnTax($product, $which = null, $includeTax = null)
@@ -162,9 +172,9 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
162
  * Retrieve Price with take into account tier price
163
  *
164
  * @param Mage_Catalog_Model_Product $product
165
- * @param string|null $which
166
- * @param bool|null $includeTax
167
- * @param bool $takeTierPrice
168
  * @return decimal|array
169
  */
170
  public function getTotalPrices($product, $which = null, $includeTax = null, $takeTierPrice = true)
@@ -206,9 +216,6 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
206
  }
207
 
208
  $qty = $selection->getSelectionQty();
209
- if ($selection->getSelectionCanChangeQty() && !$option->isMultiSelection()) {
210
- $qty = min(1, $qty);
211
- }
212
 
213
  $item = $product->getPriceType() == self::PRICE_TYPE_FIXED ? $product : $selection;
214
 
@@ -353,8 +360,9 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
353
  *
354
  * @param Mage_Catalog_Model_Product $bundleProduct
355
  * @param Mage_Catalog_Model_Product $selectionProduct
356
- * @param decimal $selectionQty
357
- * @return decimal
 
358
  */
359
  public function getSelectionPrice($bundleProduct, $selectionProduct, $selectionQty = null, $multiplyQty = true)
360
  {
@@ -370,10 +378,14 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
370
  }
371
  } else {
372
  if ($selectionProduct->getSelectionPriceType()) { // percent
373
- return $bundleProduct->getPrice() * ($selectionProduct->getSelectionPriceValue() / 100) * $selectionQty;
374
  } else { // fixed
375
- return $selectionProduct->getSelectionPriceValue() * $selectionQty;
 
 
 
376
  }
 
377
  }
378
  }
379
 
@@ -382,7 +394,7 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
382
  *
383
  * @param Mage_Catalog_Model_Product $bundleProduct
384
  * @param Mage_Catalog_Model_Product $selectionProduct
385
- * @param decimal
386
  * @return decimal
387
  */
388
  public function getSelectionPreFinalPrice($bundleProduct, $selectionProduct, $qty = null)
@@ -401,9 +413,9 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
401
  *
402
  * @param Mage_Catalog_Model_Product $bundleProduct
403
  * @param Mage_Catalog_Model_Product $selectionProduct
404
- * @param decimal $bundleQty
405
- * @param decimal $selectionQty
406
- * @param bool $multiplyQty
407
  * @return decimal
408
  */
409
  public function getSelectionFinalPrice($bundleProduct, $selectionProduct, $bundleQty, $selectionQty = null,
@@ -419,10 +431,10 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
419
  *
420
  * @param Mage_Catalog_Model_Product $bundleProduct
421
  * @param Mage_Catalog_Model_Product $selectionProduct
422
- * @param decimal $bundleQty
423
- * @param decimal $selectionQty
424
- * @param bool $multiplyQty
425
- * @param bool $takeTierPrice
426
  * @return decimal
427
  */
428
  public function getSelectionFinalTotalPrice($bundleProduct, $selectionProduct, $bundleQty, $selectionQty,
@@ -446,8 +458,8 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
446
  * Apply tier price for bundle
447
  *
448
  * @param Mage_Catalog_Model_Product $product
449
- * @param decimal $qty
450
- * @param decimal $finalPrice
451
  * @return decimal
452
  */
453
  protected function _applyTierPrice($product, $qty, $finalPrice)
@@ -469,7 +481,7 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
469
  /**
470
  * Get product tier price by qty
471
  *
472
- * @param decimal $qty
473
  * @param Mage_Catalog_Model_Product $product
474
  * @return decimal
475
  */
@@ -554,14 +566,14 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
554
  /**
555
  * Calculate product price based on special price data and price rules
556
  *
557
- * @param float $basePrice
558
- * @param float $specialPrice
559
- * @param string $specialPriceFrom
560
- * @param string $specialPriceTo
561
  * @param float|null|false $rulePrice
562
- * @param mixed $wId
563
- * @param mixed $gId
564
- * @param null|int $productId
565
  * @return float
566
  */
567
  public static function calculatePrice($basePrice, $specialPrice, $specialPriceFrom, $specialPriceTo,
@@ -698,11 +710,11 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr
698
  /**
699
  * Calculate and apply special price
700
  *
701
- * @param float $finalPrice
702
- * @param float $specialPrice
703
  * @param string $specialPriceFrom
704
  * @param string $specialPriceTo
705
- * @param mixed $store
706
  * @return float
707
  */
708
  public static function calculateSpecialPrice($finalPrice, $specialPrice, $specialPriceFrom, $specialPriceTo,
27
  /**
28
  * Bundle Price Model
29
  *
30
+ * @category Mage
31
+ * @package Mage_Bundle
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
  */
34
  class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Price
35
  {
37
  const PRICE_TYPE_DYNAMIC = 0;
38
 
39
  /**
40
+ * Flag which indicates - is min/max prices have been calculated by index
41
  *
42
  * @var bool
43
  */
56
  /**
57
  * Return product base price
58
  *
59
+ * @param Mage_Catalog_Model_Product $product
60
  * @return string
61
  */
62
  public function getPrice($product)
71
  /**
72
  * Get product final price
73
  *
74
+ * @param double $qty
75
  * @param Mage_Catalog_Model_Product $product
76
  * @return double
77
  */
78
+ public function getFinalPrice($qty = null, $product)
79
  {
80
  if (is_null($qty) && !is_null($product->getCalculatedFinalPrice())) {
81
  return $product->getCalculatedFinalPrice();
123
  return max(0, $product->getData('final_price'));
124
  }
125
 
126
+ /**
127
+ * Returns final price of a child product
128
+ *
129
+ * @param Mage_Catalog_Model_Product $product
130
+ * @param float $productQty
131
+ * @param Mage_Catalog_Model_Product $childProduct
132
+ * @param float $childProductQty
133
+ * @return decimal
134
+ */
135
  public function getChildFinalPrice($product, $productQty, $childProduct, $childProductQty)
136
  {
137
  return $this->getSelectionFinalPrice($product, $childProduct, $productQty, $childProductQty, false);
144
  * @see Mage_Bundle_Model_Product_Price::getTotalPrices()
145
  *
146
  * @param Mage_Catalog_Model_Product $product
147
+ * @param string $which
148
  * @return decimal|array
149
  */
150
  public function getPrices($product, $which = null)
159
  * @see Mage_Bundle_Model_Product_Price::getTotalPrices()
160
  *
161
  * @param Mage_Catalog_Model_Product $product
162
+ * @param string $which
163
+ * @param bool|null $includeTax
164
  * @return decimal|array
165
  */
166
  public function getPricesDependingOnTax($product, $which = null, $includeTax = null)
172
  * Retrieve Price with take into account tier price
173
  *
174
  * @param Mage_Catalog_Model_Product $product
175
+ * @param string|null $which
176
+ * @param bool|null $includeTax
177
+ * @param bool $takeTierPrice
178
  * @return decimal|array
179
  */
180
  public function getTotalPrices($product, $which = null, $includeTax = null, $takeTierPrice = true)
216
  }
217
 
218
  $qty = $selection->getSelectionQty();
 
 
 
219
 
220
  $item = $product->getPriceType() == self::PRICE_TYPE_FIXED ? $product : $selection;
221
 
360
  *
361
  * @param Mage_Catalog_Model_Product $bundleProduct
362
  * @param Mage_Catalog_Model_Product $selectionProduct
363
+ * @param float|null $selectionQty
364
+ * @param null|bool $multiplyQty Whether to multiply selection's price by its quantity
365
+ * @return float
366
  */
367
  public function getSelectionPrice($bundleProduct, $selectionProduct, $selectionQty = null, $multiplyQty = true)
368
  {
378
  }
379
  } else {
380
  if ($selectionProduct->getSelectionPriceType()) { // percent
381
+ $price = $bundleProduct->getPrice() * ($selectionProduct->getSelectionPriceValue() / 100);
382
  } else { // fixed
383
+ $price = $selectionProduct->getSelectionPriceValue();
384
+ }
385
+ if ($multiplyQty) {
386
+ $price *= $selectionQty;
387
  }
388
+ return $price;
389
  }
390
  }
391
 
394
  *
395
  * @param Mage_Catalog_Model_Product $bundleProduct
396
  * @param Mage_Catalog_Model_Product $selectionProduct
397
+ * @param decimal $qty
398
  * @return decimal
399
  */
400
  public function getSelectionPreFinalPrice($bundleProduct, $selectionProduct, $qty = null)
413
  *
414
  * @param Mage_Catalog_Model_Product $bundleProduct
415
  * @param Mage_Catalog_Model_Product $selectionProduct
416
+ * @param decimal $bundleQty
417
+ * @param decimal $selectionQty
418
+ * @param bool $multiplyQty
419
  * @return decimal
420
  */
421
  public function getSelectionFinalPrice($bundleProduct, $selectionProduct, $bundleQty, $selectionQty = null,
431
  *
432
  * @param Mage_Catalog_Model_Product $bundleProduct
433
  * @param Mage_Catalog_Model_Product $selectionProduct
434
+ * @param decimal $bundleQty
435
+ * @param decimal $selectionQty
436
+ * @param bool $multiplyQty
437
+ * @param bool $takeTierPrice
438
  * @return decimal
439
  */
440
  public function getSelectionFinalTotalPrice($bundleProduct, $selectionProduct, $bundleQty, $selectionQty,
458
  * Apply tier price for bundle
459
  *
460
  * @param Mage_Catalog_Model_Product $product
461
+ * @param decimal $qty
462
+ * @param decimal $finalPrice
463
  * @return decimal
464
  */
465
  protected function _applyTierPrice($product, $qty, $finalPrice)
481
  /**
482
  * Get product tier price by qty
483
  *
484
+ * @param decimal $qty
485
  * @param Mage_Catalog_Model_Product $product
486
  * @return decimal
487
  */
566
  /**
567
  * Calculate product price based on special price data and price rules
568
  *
569
+ * @param float $basePrice
570
+ * @param float $specialPrice
571
+ * @param string $specialPriceFrom
572
+ * @param string $specialPriceTo
573
  * @param float|null|false $rulePrice
574
+ * @param mixed $wId
575
+ * @param mixed $gId
576
+ * @param null|int $productId
577
  * @return float
578
  */
579
  public static function calculatePrice($basePrice, $specialPrice, $specialPriceFrom, $specialPriceTo,
710
  /**
711
  * Calculate and apply special price
712
  *
713
+ * @param float $finalPrice
714
+ * @param float $specialPrice
715
  * @param string $specialPriceFrom
716
  * @param string $specialPriceTo
717
+ * @param mixed $store
718
  * @return float
719
  */
720
  public static function calculateSpecialPrice($finalPrice, $specialPrice, $specialPriceFrom, $specialPriceTo,
app/code/core/Mage/Bundle/Model/Resource/Indexer/Price.php CHANGED
@@ -42,7 +42,15 @@ class Mage_Bundle_Model_Resource_Indexer_Price extends Mage_Catalog_Model_Resour
42
  public function reindexAll()
43
  {
44
  $this->useIdxTable(true);
45
- $this->_prepareBundlePrice();
 
 
 
 
 
 
 
 
46
 
47
  return $this;
48
  }
42
  public function reindexAll()
43
  {
44
  $this->useIdxTable(true);
45
+
46
+ $this->beginTransaction();
47
+ try {
48
+ $this->_prepareBundlePrice();
49
+ $this->commit();
50
+ } catch (Exception $e) {
51
+ $this->rollBack();
52
+ throw $e;
53
+ }
54
 
55
  return $this;
56
  }
app/code/core/Mage/Bundle/Model/Resource/Indexer/Stock.php CHANGED
@@ -34,18 +34,6 @@
34
  */
35
  class Mage_Bundle_Model_Resource_Indexer_Stock extends Mage_CatalogInventory_Model_Resource_Indexer_Stock_Default
36
  {
37
- /**
38
- * Reindex temporary (price result data) for all products
39
- *
40
- * @return Mage_Bundle_Model_Resource_Indexer_Stock
41
- */
42
- public function reindexAll()
43
- {
44
- $this->useIdxTable(true);
45
- $this->_prepareIndexTable();
46
- return $this;
47
- }
48
-
49
  /**
50
  * Reindex temporary (price result data) for defined product(s)
51
  *
34
  */
35
  class Mage_Bundle_Model_Resource_Indexer_Stock extends Mage_CatalogInventory_Model_Resource_Indexer_Stock_Default
36
  {
 
 
 
 
 
 
 
 
 
 
 
 
37
  /**
38
  * Reindex temporary (price result data) for defined product(s)
39
  *
app/code/core/Mage/Catalog/Model/Category/Indexer/Flat.php CHANGED
@@ -34,6 +34,11 @@
34
  */
35
  class Mage_Catalog_Model_Category_Indexer_Flat extends Mage_Index_Model_Indexer_Abstract
36
  {
 
 
 
 
 
37
  /**
38
  * Matched entity events
39
  *
@@ -96,21 +101,22 @@ class Mage_Catalog_Model_Category_Indexer_Flat extends Mage_Index_Model_Indexer_
96
  return false;
97
  }
98
 
99
- $data = $event->getNewData();
100
- $resultKey = 'catalog_category_flat_match_result';
101
- if (isset($data[$resultKey])) {
102
- return $data[$resultKey];
103
  }
104
 
105
- $result = null;
106
  $entity = $event->getEntity();
107
  if ($entity == Mage_Core_Model_Store::ENTITY) {
108
  if ($event->getType() == Mage_Index_Model_Event::TYPE_DELETE) {
109
  $result = true;
110
- } else if ($event->getType() == Mage_Index_Model_Event::TYPE_SAVE) {
111
- /* @var $store Mage_Core_Model_Store */
112
  $store = $event->getDataObject();
113
- if ($store->isObjectNew() || $store->dataHasChangedFor('group_id') || $store->dataHasChangedFor('root_catefory_id')) {
 
 
 
114
  $result = true;
115
  } else {
116
  $result = false;
@@ -118,10 +124,12 @@ class Mage_Catalog_Model_Category_Indexer_Flat extends Mage_Index_Model_Indexer_
118
  } else {
119
  $result = false;
120
  }
121
- } else if ($entity == Mage_Core_Model_Store_Group::ENTITY) {
122
- /* @var $storeGroup Mage_Core_Model_Store_Group */
123
  $storeGroup = $event->getDataObject();
124
- if ($storeGroup->dataHasChangedFor('website_id')) {
 
 
125
  $result = true;
126
  } else {
127
  $result = false;
@@ -130,7 +138,7 @@ class Mage_Catalog_Model_Category_Indexer_Flat extends Mage_Index_Model_Indexer_
130
  $result = parent::matchEvent($event);
131
  }
132
 
133
- $event->addNewData($resultKey, $result);
134
 
135
  return $result;
136
  }
@@ -142,6 +150,7 @@ class Mage_Catalog_Model_Category_Indexer_Flat extends Mage_Index_Model_Indexer_
142
  */
143
  protected function _registerEvent(Mage_Index_Model_Event $event)
144
  {
 
145
  switch ($event->getEntity()) {
146
  case Mage_Catalog_Model_Category::ENTITY:
147
  $this->_registerCatalogCategoryEvent($event);
@@ -234,6 +243,6 @@ class Mage_Catalog_Model_Category_Indexer_Flat extends Mage_Index_Model_Indexer_
234
  */
235
  public function reindexAll()
236
  {
237
- $this->_getIndexer()->rebuild();
238
  }
239
  }
34
  */
35
  class Mage_Catalog_Model_Category_Indexer_Flat extends Mage_Index_Model_Indexer_Abstract
36
  {
37
+ /**
38
+ * Data key for matching result to be saved in
39
+ */
40
+ const EVENT_MATCH_RESULT_KEY = 'catalog_category_flat_match_result';
41
+
42
  /**
43
  * Matched entity events
44
  *
101
  return false;
102
  }
103
 
104
+ $data = $event->getNewData();
105
+ if (isset($data[self::EVENT_MATCH_RESULT_KEY])) {
106
+ return $data[self::EVENT_MATCH_RESULT_KEY];
 
107
  }
108
 
 
109
  $entity = $event->getEntity();
110
  if ($entity == Mage_Core_Model_Store::ENTITY) {
111
  if ($event->getType() == Mage_Index_Model_Event::TYPE_DELETE) {
112
  $result = true;
113
+ } elseif ($event->getType() == Mage_Index_Model_Event::TYPE_SAVE) {
114
+ /** @var $store Mage_Core_Model_Store */
115
  $store = $event->getDataObject();
116
+ if ($store && ($store->isObjectNew()
117
+ || $store->dataHasChangedFor('group_id')
118
+ || $store->dataHasChangedFor('root_category_id')
119
+ )) {
120
  $result = true;
121
  } else {
122
  $result = false;
124
  } else {
125
  $result = false;
126
  }
127
+ } elseif ($entity == Mage_Core_Model_Store_Group::ENTITY) {
128
+ /** @var $storeGroup Mage_Core_Model_Store_Group */
129
  $storeGroup = $event->getDataObject();
130
+ if ($storeGroup
131
+ && ($storeGroup->dataHasChangedFor('website_id') || $storeGroup->dataHasChangedFor('root_category_id'))
132
+ ) {
133
  $result = true;
134
  } else {
135
  $result = false;
138
  $result = parent::matchEvent($event);
139
  }
140
 
141
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, $result);
142
 
143
  return $result;
144
  }
150
  */
151
  protected function _registerEvent(Mage_Index_Model_Event $event)
152
  {
153
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
154
  switch ($event->getEntity()) {
155
  case Mage_Catalog_Model_Category::ENTITY:
156
  $this->_registerCatalogCategoryEvent($event);
243
  */
244
  public function reindexAll()
245
  {
246
+ $this->_getIndexer()->reindexAll();
247
  }
248
  }
app/code/core/Mage/Catalog/Model/Category/Indexer/Product.php CHANGED
@@ -53,6 +53,11 @@
53
  */
54
  class Mage_Catalog_Model_Category_Indexer_Product extends Mage_Index_Model_Indexer_Abstract
55
  {
 
 
 
 
 
56
  /**
57
  * @var array
58
  */
@@ -113,25 +118,23 @@ class Mage_Catalog_Model_Category_Indexer_Product extends Mage_Index_Model_Index
113
  public function matchEvent(Mage_Index_Model_Event $event)
114
  {
115
  $data = $event->getNewData();
116
- $resultKey = 'catalog_category_product_match_result';
117
- if (isset($data[$resultKey])) {
118
- return $data[$resultKey];
119
  }
120
 
121
- $result = null;
122
  $entity = $event->getEntity();
123
  if ($entity == Mage_Core_Model_Store::ENTITY) {
124
  $store = $event->getDataObject();
125
- if ($store->isObjectNew() || $store->dataHasChangedFor('group_id')) {
126
  $result = true;
127
  } else {
128
  $result = false;
129
  }
130
  } elseif ($entity == Mage_Core_Model_Store_Group::ENTITY) {
131
  $storeGroup = $event->getDataObject();
132
- $hasDataChanges = $storeGroup->dataHasChangedFor('root_category_id')
133
- || $storeGroup->dataHasChangedFor('website_id');
134
- if (!$storeGroup->isObjectNew() && $hasDataChanges) {
135
  $result = true;
136
  } else {
137
  $result = false;
@@ -140,7 +143,7 @@ class Mage_Catalog_Model_Category_Indexer_Product extends Mage_Index_Model_Index
140
  $result = parent::matchEvent($event);
141
  }
142
 
143
- $event->addNewData($resultKey, $result);
144
 
145
  return $result;
146
  }
@@ -154,6 +157,7 @@ class Mage_Catalog_Model_Category_Indexer_Product extends Mage_Index_Model_Index
154
  */
155
  protected function _registerEvent(Mage_Index_Model_Event $event)
156
  {
 
157
  $entity = $event->getEntity();
158
  switch ($entity) {
159
  case Mage_Catalog_Model_Product::ENTITY:
53
  */
54
  class Mage_Catalog_Model_Category_Indexer_Product extends Mage_Index_Model_Indexer_Abstract
55
  {
56
+ /**
57
+ * Data key for matching result to be saved in
58
+ */
59
+ const EVENT_MATCH_RESULT_KEY = 'catalog_category_product_match_result';
60
+
61
  /**
62
  * @var array
63
  */
118
  public function matchEvent(Mage_Index_Model_Event $event)
119
  {
120
  $data = $event->getNewData();
121
+ if (isset($data[self::EVENT_MATCH_RESULT_KEY])) {
122
+ return $data[self::EVENT_MATCH_RESULT_KEY];
 
123
  }
124
 
 
125
  $entity = $event->getEntity();
126
  if ($entity == Mage_Core_Model_Store::ENTITY) {
127
  $store = $event->getDataObject();
128
+ if ($store && ($store->isObjectNew() || $store->dataHasChangedFor('group_id'))) {
129
  $result = true;
130
  } else {
131
  $result = false;
132
  }
133
  } elseif ($entity == Mage_Core_Model_Store_Group::ENTITY) {
134
  $storeGroup = $event->getDataObject();
135
+ $hasDataChanges = $storeGroup && ($storeGroup->dataHasChangedFor('root_category_id')
136
+ || $storeGroup->dataHasChangedFor('website_id'));
137
+ if ($storeGroup && !$storeGroup->isObjectNew() && $hasDataChanges) {
138
  $result = true;
139
  } else {
140
  $result = false;
143
  $result = parent::matchEvent($event);
144
  }
145
 
146
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, $result);
147
 
148
  return $result;
149
  }
157
  */
158
  protected function _registerEvent(Mage_Index_Model_Event $event)
159
  {
160
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
161
  $entity = $event->getEntity();
162
  switch ($entity) {
163
  case Mage_Catalog_Model_Product::ENTITY:
app/code/core/Mage/Catalog/Model/Indexer/Url.php CHANGED
@@ -35,6 +35,11 @@
35
  */
36
  class Mage_Catalog_Model_Indexer_Url extends Mage_Index_Model_Indexer_Abstract
37
  {
 
 
 
 
 
38
  /**
39
  * Index math: product save, category save, store save
40
  * store group save, config save
@@ -98,33 +103,30 @@ class Mage_Catalog_Model_Indexer_Url extends Mage_Index_Model_Indexer_Abstract
98
  public function matchEvent(Mage_Index_Model_Event $event)
99
  {
100
  $data = $event->getNewData();
101
- $resultKey = 'catalog_url_match_result';
102
- if (isset($data[$resultKey])) {
103
- return $data[$resultKey];
104
  }
105
 
106
- $result = null;
107
  $entity = $event->getEntity();
108
  if ($entity == Mage_Core_Model_Store::ENTITY) {
109
  $store = $event->getDataObject();
110
- if ($store->isObjectNew() || $store->dataHasChangedFor('group_id')) {
111
  $result = true;
112
  } else {
113
  $result = false;
114
  }
115
  } else if ($entity == Mage_Core_Model_Store_Group::ENTITY) {
116
  $storeGroup = $event->getDataObject();
117
- $hasDataChanges = $storeGroup->dataHasChangedFor('root_category_id')
118
- || $storeGroup->dataHasChangedFor('website_id');
119
- if (!$storeGroup->isObjectNew() && $hasDataChanges) {
120
  $result = true;
121
  } else {
122
  $result = false;
123
  }
124
  } else if ($entity == Mage_Core_Model_Config_Data::ENTITY) {
125
  $configData = $event->getDataObject();
126
- $path = $configData->getPath();
127
- if (in_array($path, $this->_relatedConfigSettings)) {
128
  $result = $configData->isValueChanged();
129
  } else {
130
  $result = false;
@@ -133,7 +135,7 @@ class Mage_Catalog_Model_Indexer_Url extends Mage_Index_Model_Indexer_Abstract
133
  $result = parent::matchEvent($event);
134
  }
135
 
136
- $event->addNewData($resultKey, $result);
137
 
138
  return $result;
139
  }
@@ -145,6 +147,7 @@ class Mage_Catalog_Model_Indexer_Url extends Mage_Index_Model_Indexer_Abstract
145
  */
146
  protected function _registerEvent(Mage_Index_Model_Event $event)
147
  {
 
148
  $entity = $event->getEntity();
149
  switch ($entity) {
150
  case Mage_Catalog_Model_Product::ENTITY:
@@ -246,6 +249,15 @@ class Mage_Catalog_Model_Indexer_Url extends Mage_Index_Model_Indexer_Abstract
246
  */
247
  public function reindexAll()
248
  {
249
- Mage::getSingleton('catalog/url')->refreshRewrites();
 
 
 
 
 
 
 
 
 
250
  }
251
  }
35
  */
36
  class Mage_Catalog_Model_Indexer_Url extends Mage_Index_Model_Indexer_Abstract
37
  {
38
+ /**
39
+ * Data key for matching result to be saved in
40
+ */
41
+ const EVENT_MATCH_RESULT_KEY = 'catalog_url_match_result';
42
+
43
  /**
44
  * Index math: product save, category save, store save
45
  * store group save, config save
103
  public function matchEvent(Mage_Index_Model_Event $event)
104
  {
105
  $data = $event->getNewData();
106
+ if (isset($data[self::EVENT_MATCH_RESULT_KEY])) {
107
+ return $data[self::EVENT_MATCH_RESULT_KEY];
 
108
  }
109
 
 
110
  $entity = $event->getEntity();
111
  if ($entity == Mage_Core_Model_Store::ENTITY) {
112
  $store = $event->getDataObject();
113
+ if ($store && ($store->isObjectNew() || $store->dataHasChangedFor('group_id'))) {
114
  $result = true;
115
  } else {
116
  $result = false;
117
  }
118
  } else if ($entity == Mage_Core_Model_Store_Group::ENTITY) {
119
  $storeGroup = $event->getDataObject();
120
+ $hasDataChanges = $storeGroup && ($storeGroup->dataHasChangedFor('root_category_id')
121
+ || $storeGroup->dataHasChangedFor('website_id'));
122
+ if ($storeGroup && !$storeGroup->isObjectNew() && $hasDataChanges) {
123
  $result = true;
124
  } else {
125
  $result = false;
126
  }
127
  } else if ($entity == Mage_Core_Model_Config_Data::ENTITY) {
128
  $configData = $event->getDataObject();
129
+ if ($configData && in_array($configData->getPath(), $this->_relatedConfigSettings)) {
 
130
  $result = $configData->isValueChanged();
131
  } else {
132
  $result = false;
135
  $result = parent::matchEvent($event);
136
  }
137
 
138
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, $result);
139
 
140
  return $result;
141
  }
147
  */
148
  protected function _registerEvent(Mage_Index_Model_Event $event)
149
  {
150
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
151
  $entity = $event->getEntity();
152
  switch ($entity) {
153
  case Mage_Catalog_Model_Product::ENTITY:
249
  */
250
  public function reindexAll()
251
  {
252
+ /** @var $resourceModel Mage_Catalog_Model_Resource_Url */
253
+ $resourceModel = Mage::getResourceSingleton('catalog/url');
254
+ $resourceModel->beginTransaction();
255
+ try {
256
+ Mage::getSingleton('catalog/url')->refreshRewrites();
257
+ $resourceModel->commit();
258
+ } catch (Exception $e) {
259
+ $resourceModel->rollBack();
260
+ throw $e;
261
+ }
262
  }
263
  }
app/code/core/Mage/Catalog/Model/Observer.php CHANGED
@@ -231,4 +231,17 @@ class Mage_Catalog_Model_Observer
231
  $result = $observer->getEvent()->getData('result');
232
  $result->isAllowed = Mage::helper('catalog')->setStoreId($storeId)->isUsingStaticUrlsAllowed();
233
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  }
231
  $result = $observer->getEvent()->getData('result');
232
  $result->isAllowed = Mage::helper('catalog')->setStoreId($storeId)->isUsingStaticUrlsAllowed();
233
  }
234
+
235
+ /**
236
+ * Cron job method for product prices to reindex
237
+ *
238
+ * @param Mage_Cron_Model_Schedule $schedule
239
+ */
240
+ public function reindexProductPrices(Mage_Cron_Model_Schedule $schedule)
241
+ {
242
+ $indexProcess = Mage::getSingleton('index/indexer')->getProcessByCode('catalog_product_price');
243
+ if ($indexProcess) {
244
+ $indexProcess->reindexAll();
245
+ }
246
+ }
247
  }
app/code/core/Mage/Catalog/Model/Product/Flat/Indexer.php CHANGED
@@ -53,6 +53,16 @@
53
  */
54
  class Mage_Catalog_Model_Product_Flat_Indexer extends Mage_Core_Model_Abstract
55
  {
 
 
 
 
 
 
 
 
 
 
56
  /**
57
  * Standart model resource initialization
58
  *
@@ -70,7 +80,16 @@ class Mage_Catalog_Model_Product_Flat_Indexer extends Mage_Core_Model_Abstract
70
  */
71
  public function rebuild($store = null)
72
  {
73
- $this->_getResource()->rebuild($store);
 
 
 
 
 
 
 
 
 
74
  return $this;
75
  }
76
 
@@ -218,7 +237,7 @@ class Mage_Catalog_Model_Product_Flat_Indexer extends Mage_Core_Model_Abstract
218
  }
219
  return $this;
220
  }
221
-
222
  $resource = $this->_getResource();
223
  $resource->beginTransaction();
224
  try {
@@ -266,4 +285,25 @@ class Mage_Catalog_Model_Product_Flat_Indexer extends Mage_Core_Model_Abstract
266
  $this->_getResource()->deleteFlatTable($store);
267
  return $this;
268
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  }
53
  */
54
  class Mage_Catalog_Model_Product_Flat_Indexer extends Mage_Core_Model_Abstract
55
  {
56
+ /**
57
+ * Catalog product flat entity for indexers
58
+ */
59
+ const ENTITY = 'catalog_product_flat';
60
+
61
+ /**
62
+ * Indexers rebuild event type
63
+ */
64
+ const EVENT_TYPE_REBUILD = 'catalog_product_flat_rebuild';
65
+
66
  /**
67
  * Standart model resource initialization
68
  *
80
  */
81
  public function rebuild($store = null)
82
  {
83
+ if (is_null($store)) {
84
+ $this->_getResource()->prepareFlatTables();
85
+ } else {
86
+ $this->_getResource()->prepareFlatTable($store);
87
+ }
88
+ Mage::getSingleton('index/indexer')->processEntityAction(
89
+ new Varien_Object(array('id' => $store)),
90
+ self::ENTITY,
91
+ self::EVENT_TYPE_REBUILD
92
+ );
93
  return $this;
94
  }
95
 
237
  }
238
  return $this;
239
  }
240
+
241
  $resource = $this->_getResource();
242
  $resource->beginTransaction();
243
  try {
285
  $this->_getResource()->deleteFlatTable($store);
286
  return $this;
287
  }
288
+
289
+ /**
290
+ * Rebuild Catalog Product Flat Data for all stores
291
+ *
292
+ * @return Mage_Catalog_Model_Product_Flat_Indexer
293
+ */
294
+ public function reindexAll()
295
+ {
296
+ $this->_getResource()->reindexAll();
297
+ return $this;
298
+ }
299
+
300
+ /**
301
+ * Retrieve list of attribute codes for flat
302
+ *
303
+ * @return array
304
+ */
305
+ public function getAttributeCodes()
306
+ {
307
+ return $this->_getResource()->getAttributeCodes();
308
+ }
309
  }
app/code/core/Mage/Catalog/Model/Product/Indexer/Flat.php CHANGED
@@ -25,6 +25,11 @@
25
  */
26
  class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_Abstract
27
  {
 
 
 
 
 
28
  /**
29
  * Index math Entities array
30
  *
@@ -48,7 +53,10 @@ class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_A
48
  ),
49
  Mage_Catalog_Model_Convert_Adapter_Product::ENTITY => array(
50
  Mage_Index_Model_Event::TYPE_SAVE
51
- )
 
 
 
52
  );
53
 
54
  /**
@@ -95,34 +103,32 @@ class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_A
95
  return false;
96
  }
97
 
98
- $data = $event->getNewData();
99
- $resultKey = 'catalog_product_flat_match_result';
100
- if (isset($data[$resultKey])) {
101
- return $data[$resultKey];
102
  }
103
 
104
- $result = null;
105
  $entity = $event->getEntity();
106
  if ($entity == Mage_Catalog_Model_Resource_Eav_Attribute::ENTITY) {
107
  /* @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
108
  $attribute = $event->getDataObject();
109
  $addFilterable = Mage::helper('catalog/product_flat')->isAddFilterableAttributes();
110
 
111
- $enableBefore = ($attribute->getOrigData('backend_type') == 'static')
112
  || ($addFilterable && $attribute->getOrigData('is_filterable') > 0)
113
  || ($attribute->getOrigData('used_in_product_listing') == 1)
114
  || ($attribute->getOrigData('is_used_for_promo_rules') == 1)
115
- || ($attribute->getOrigData('used_for_sort_by') == 1);
116
 
117
- $enableAfter = ($attribute->getData('backend_type') == 'static')
118
  || ($addFilterable && $attribute->getData('is_filterable') > 0)
119
  || ($attribute->getData('used_in_product_listing') == 1)
120
  || ($attribute->getData('is_used_for_promo_rules') == 1)
121
- || ($attribute->getData('used_for_sort_by') == 1);
122
 
123
- if ($event->getType() == Mage_Index_Model_Event::TYPE_DELETE) {
124
  $result = $enableBefore;
125
- } else if ($event->getType() == Mage_Index_Model_Event::TYPE_SAVE) {
126
  if ($enableAfter || $enableBefore) {
127
  $result = true;
128
  } else {
@@ -137,7 +143,7 @@ class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_A
137
  } else {
138
  /* @var $store Mage_Core_Model_Store */
139
  $store = $event->getDataObject();
140
- if ($store->isObjectNew()) {
141
  $result = true;
142
  } else {
143
  $result = false;
@@ -146,7 +152,7 @@ class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_A
146
  } else if ($entity == Mage_Core_Model_Store_Group::ENTITY) {
147
  /* @var $storeGroup Mage_Core_Model_Store_Group */
148
  $storeGroup = $event->getDataObject();
149
- if ($storeGroup->dataHasChangedFor('website_id')) {
150
  $result = true;
151
  } else {
152
  $result = false;
@@ -155,7 +161,7 @@ class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_A
155
  $result = parent::matchEvent($event);
156
  }
157
 
158
- $event->addNewData($resultKey, $result);
159
 
160
  return $result;
161
  }
@@ -167,6 +173,7 @@ class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_A
167
  */
168
  protected function _registerEvent(Mage_Index_Model_Event $event)
169
  {
 
170
  switch ($event->getEntity()) {
171
  case Mage_Catalog_Model_Product::ENTITY:
172
  $this->_registerCatalogProductEvent($event);
@@ -185,6 +192,12 @@ class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_A
185
  $process = $event->getProcess();
186
  $process->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
187
  break;
 
 
 
 
 
 
188
  }
189
  }
190
 
@@ -224,6 +237,16 @@ class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_A
224
  $reindexData['catalog_product_flat_action_type'] = $actionObject->getActionType();
225
  }
226
 
 
 
 
 
 
 
 
 
 
 
227
  // register affected products
228
  if ($reindexFlat) {
229
  $reindexData['catalog_product_flat_product_ids'] = $actionObject->getProductIds();
@@ -261,6 +284,12 @@ class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_A
261
  protected function _processEvent(Mage_Index_Model_Event $event)
262
  {
263
  $data = $event->getNewData();
 
 
 
 
 
 
264
  if (!empty($data['catalog_product_flat_reindex_all'])) {
265
  $this->reindexAll();
266
  } else if (!empty($data['catalog_product_flat_product_id'])) {
@@ -289,6 +318,10 @@ class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_A
289
  $status = $data['catalog_product_flat_status'];
290
  $this->_getIndexer()->updateProductStatus($productIds, $status);
291
  }
 
 
 
 
292
  } else if (!empty($data['catalog_product_flat_delete_store_id'])) {
293
  $this->_getIndexer()->deleteStore($data['catalog_product_flat_delete_store_id']);
294
  }
@@ -300,6 +333,16 @@ class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_A
300
  */
301
  public function reindexAll()
302
  {
303
- $this->_getIndexer()->rebuild();
 
 
 
 
 
 
 
 
 
 
304
  }
305
  }
25
  */
26
  class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_Abstract
27
  {
28
+ /**
29
+ * Data key for matching result to be saved in
30
+ */
31
+ const EVENT_MATCH_RESULT_KEY = 'catalog_product_flat_match_result';
32
+
33
  /**
34
  * Index math Entities array
35
  *
53
  ),
54
  Mage_Catalog_Model_Convert_Adapter_Product::ENTITY => array(
55
  Mage_Index_Model_Event::TYPE_SAVE
56
+ ),
57
+ Mage_Catalog_Model_Product_Flat_Indexer::ENTITY => array(
58
+ Mage_Catalog_Model_Product_Flat_Indexer::EVENT_TYPE_REBUILD,
59
+ ),
60
  );
61
 
62
  /**
103
  return false;
104
  }
105
 
106
+ $data = $event->getNewData();
107
+ if (isset($data[self::EVENT_MATCH_RESULT_KEY])) {
108
+ return $data[self::EVENT_MATCH_RESULT_KEY];
 
109
  }
110
 
 
111
  $entity = $event->getEntity();
112
  if ($entity == Mage_Catalog_Model_Resource_Eav_Attribute::ENTITY) {
113
  /* @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
114
  $attribute = $event->getDataObject();
115
  $addFilterable = Mage::helper('catalog/product_flat')->isAddFilterableAttributes();
116
 
117
+ $enableBefore = $attribute && (($attribute->getOrigData('backend_type') == 'static')
118
  || ($addFilterable && $attribute->getOrigData('is_filterable') > 0)
119
  || ($attribute->getOrigData('used_in_product_listing') == 1)
120
  || ($attribute->getOrigData('is_used_for_promo_rules') == 1)
121
+ || ($attribute->getOrigData('used_for_sort_by') == 1));
122
 
123
+ $enableAfter = $attribute && (($attribute->getData('backend_type') == 'static')
124
  || ($addFilterable && $attribute->getData('is_filterable') > 0)
125
  || ($attribute->getData('used_in_product_listing') == 1)
126
  || ($attribute->getData('is_used_for_promo_rules') == 1)
127
+ || ($attribute->getData('used_for_sort_by') == 1));
128
 
129
+ if ($attribute && $event->getType() == Mage_Index_Model_Event::TYPE_DELETE) {
130
  $result = $enableBefore;
131
+ } elseif ($attribute && $event->getType() == Mage_Index_Model_Event::TYPE_SAVE) {
132
  if ($enableAfter || $enableBefore) {
133
  $result = true;
134
  } else {
143
  } else {
144
  /* @var $store Mage_Core_Model_Store */
145
  $store = $event->getDataObject();
146
+ if ($store && $store->isObjectNew()) {
147
  $result = true;
148
  } else {
149
  $result = false;
152
  } else if ($entity == Mage_Core_Model_Store_Group::ENTITY) {
153
  /* @var $storeGroup Mage_Core_Model_Store_Group */
154
  $storeGroup = $event->getDataObject();
155
+ if ($storeGroup && $storeGroup->dataHasChangedFor('website_id')) {
156
  $result = true;
157
  } else {
158
  $result = false;
161
  $result = parent::matchEvent($event);
162
  }
163
 
164
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, $result);
165
 
166
  return $result;
167
  }
173
  */
174
  protected function _registerEvent(Mage_Index_Model_Event $event)
175
  {
176
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
177
  switch ($event->getEntity()) {
178
  case Mage_Catalog_Model_Product::ENTITY:
179
  $this->_registerCatalogProductEvent($event);
192
  $process = $event->getProcess();
193
  $process->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
194
  break;
195
+ case Mage_Catalog_Model_Product_Flat_Indexer::ENTITY:
196
+ switch ($event->getType()) {
197
+ case Mage_Catalog_Model_Product_Flat_Indexer::EVENT_TYPE_REBUILD:
198
+ $event->addNewData('id', $event->getDataObject()->getId());
199
+ }
200
+ break;
201
  }
202
  }
203
 
237
  $reindexData['catalog_product_flat_action_type'] = $actionObject->getActionType();
238
  }
239
 
240
+ $flatAttributes = array();
241
+ if (is_array($attrData)) {
242
+ $flatAttributes = array_intersect($this->_getFlatAttributes(), array_keys($attrData));
243
+ }
244
+
245
+ if (count($flatAttributes) > 0) {
246
+ $reindexFlat = true;
247
+ $reindexData['catalog_product_flat_force_update'] = true;
248
+ }
249
+
250
  // register affected products
251
  if ($reindexFlat) {
252
  $reindexData['catalog_product_flat_product_ids'] = $actionObject->getProductIds();
284
  protected function _processEvent(Mage_Index_Model_Event $event)
285
  {
286
  $data = $event->getNewData();
287
+ if ($event->getType() == Mage_Catalog_Model_Product_Flat_Indexer::EVENT_TYPE_REBUILD) {
288
+ $this->_getIndexer()->getResource()->rebuild($data['id']);
289
+ return;
290
+ }
291
+
292
+
293
  if (!empty($data['catalog_product_flat_reindex_all'])) {
294
  $this->reindexAll();
295
  } else if (!empty($data['catalog_product_flat_product_id'])) {
318
  $status = $data['catalog_product_flat_status'];
319
  $this->_getIndexer()->updateProductStatus($productIds, $status);
320
  }
321
+
322
+ if (isset($data['catalog_product_flat_force_update'])) {
323
+ $this->_getIndexer()->updateProduct($productIds);
324
+ }
325
  } else if (!empty($data['catalog_product_flat_delete_store_id'])) {
326
  $this->_getIndexer()->deleteStore($data['catalog_product_flat_delete_store_id']);
327
  }
333
  */
334
  public function reindexAll()
335
  {
336
+ $this->_getIndexer()->reindexAll();
337
+ }
338
+
339
+ /**
340
+ * Retrieve list of attribute codes, that are used in flat
341
+ *
342
+ * @return array
343
+ */
344
+ protected function _getFlatAttributes()
345
+ {
346
+ return Mage::getModel('catalog/product_flat_indexer')->getAttributeCodes();
347
  }
348
  }
app/code/core/Mage/Catalog/Model/Product/Indexer/Price.php CHANGED
@@ -52,6 +52,16 @@
52
  */
53
  class Mage_Catalog_Model_Product_Indexer_Price extends Mage_Index_Model_Indexer_Abstract
54
  {
 
 
 
 
 
 
 
 
 
 
55
  /**
56
  * Matched Entities instruction array
57
  *
@@ -62,6 +72,7 @@ class Mage_Catalog_Model_Product_Indexer_Price extends Mage_Index_Model_Indexer_
62
  Mage_Index_Model_Event::TYPE_SAVE,
63
  Mage_Index_Model_Event::TYPE_DELETE,
64
  Mage_Index_Model_Event::TYPE_MASS_ACTION,
 
65
  ),
66
  Mage_Core_Model_Config_Data::ENTITY => array(
67
  Mage_Index_Model_Event::TYPE_SAVE
@@ -137,26 +148,24 @@ class Mage_Catalog_Model_Product_Indexer_Price extends Mage_Index_Model_Indexer_
137
  public function matchEvent(Mage_Index_Model_Event $event)
138
  {
139
  $data = $event->getNewData();
140
- $resultKey = 'catalog_product_price_match_result';
141
- if (isset($data[$resultKey])) {
142
- return $data[$resultKey];
143
  }
144
 
145
- $result = null;
146
  if ($event->getEntity() == Mage_Core_Model_Config_Data::ENTITY) {
147
  $data = $event->getDataObject();
148
- if (in_array($data->getPath(), $this->_relatedConfigSettings)) {
149
  $result = $data->isValueChanged();
150
  } else {
151
  $result = false;
152
  }
153
  } elseif ($event->getEntity() == Mage_Customer_Model_Group::ENTITY) {
154
- $result = $event->getDataObject()->isObjectNew();
155
  } else {
156
  $result = parent::matchEvent($event);
157
  }
158
 
159
- $event->addNewData($resultKey, $result);
160
 
161
  return $result;
162
  }
@@ -238,6 +247,7 @@ class Mage_Catalog_Model_Product_Indexer_Price extends Mage_Index_Model_Indexer_
238
  */
239
  protected function _registerEvent(Mage_Index_Model_Event $event)
240
  {
 
241
  $entity = $event->getEntity();
242
 
243
  if ($entity == Mage_Core_Model_Config_Data::ENTITY || $entity == Mage_Customer_Model_Group::ENTITY) {
@@ -258,6 +268,9 @@ class Mage_Catalog_Model_Product_Indexer_Price extends Mage_Index_Model_Indexer_
258
  case Mage_Index_Model_Event::TYPE_MASS_ACTION:
259
  $this->_registerCatalogProductMassActionEvent($event);
260
  break;
 
 
 
261
  }
262
 
263
  // call product type indexers registerEvent
@@ -276,6 +289,10 @@ class Mage_Catalog_Model_Product_Indexer_Price extends Mage_Index_Model_Indexer_
276
  protected function _processEvent(Mage_Index_Model_Event $event)
277
  {
278
  $data = $event->getNewData();
 
 
 
 
279
  if (!empty($data['catalog_product_price_reindex_all'])) {
280
  $this->reindexAll();
281
  }
52
  */
53
  class Mage_Catalog_Model_Product_Indexer_Price extends Mage_Index_Model_Indexer_Abstract
54
  {
55
+ /**
56
+ * Data key for matching result to be saved in
57
+ */
58
+ const EVENT_MATCH_RESULT_KEY = 'catalog_product_price_match_result';
59
+
60
+ /**
61
+ * Reindex price event type
62
+ */
63
+ const EVENT_TYPE_REINDEX_PRICE = 'catalog_reindex_price';
64
+
65
  /**
66
  * Matched Entities instruction array
67
  *
72
  Mage_Index_Model_Event::TYPE_SAVE,
73
  Mage_Index_Model_Event::TYPE_DELETE,
74
  Mage_Index_Model_Event::TYPE_MASS_ACTION,
75
+ self::EVENT_TYPE_REINDEX_PRICE,
76
  ),
77
  Mage_Core_Model_Config_Data::ENTITY => array(
78
  Mage_Index_Model_Event::TYPE_SAVE
148
  public function matchEvent(Mage_Index_Model_Event $event)
149
  {
150
  $data = $event->getNewData();
151
+ if (isset($data[self::EVENT_MATCH_RESULT_KEY])) {
152
+ return $data[self::EVENT_MATCH_RESULT_KEY];
 
153
  }
154
 
 
155
  if ($event->getEntity() == Mage_Core_Model_Config_Data::ENTITY) {
156
  $data = $event->getDataObject();
157
+ if ($data && in_array($data->getPath(), $this->_relatedConfigSettings)) {
158
  $result = $data->isValueChanged();
159
  } else {
160
  $result = false;
161
  }
162
  } elseif ($event->getEntity() == Mage_Customer_Model_Group::ENTITY) {
163
+ $result = $event->getDataObject() && $event->getDataObject()->isObjectNew();
164
  } else {
165
  $result = parent::matchEvent($event);
166
  }
167
 
168
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, $result);
169
 
170
  return $result;
171
  }
247
  */
248
  protected function _registerEvent(Mage_Index_Model_Event $event)
249
  {
250
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
251
  $entity = $event->getEntity();
252
 
253
  if ($entity == Mage_Core_Model_Config_Data::ENTITY || $entity == Mage_Customer_Model_Group::ENTITY) {
268
  case Mage_Index_Model_Event::TYPE_MASS_ACTION:
269
  $this->_registerCatalogProductMassActionEvent($event);
270
  break;
271
+ case self::EVENT_TYPE_REINDEX_PRICE:
272
+ $event->addNewData('id', $event->getDataObject()->getId());
273
+ break;
274
  }
275
 
276
  // call product type indexers registerEvent
289
  protected function _processEvent(Mage_Index_Model_Event $event)
290
  {
291
  $data = $event->getNewData();
292
+ if ($event->getType() == self::EVENT_TYPE_REINDEX_PRICE) {
293
+ $this->_getResource()->reindexProductIds($data['id']);
294
+ return;
295
+ }
296
  if (!empty($data['catalog_product_price_reindex_all'])) {
297
  $this->reindexAll();
298
  }
app/code/core/Mage/Catalog/Model/Resource/Category/Flat.php CHANGED
@@ -32,7 +32,7 @@
32
  * @package Mage_Catalog
33
  * @author Magento Core Team <core@magentocommerce.com>
34
  */
35
- class Mage_Catalog_Model_Resource_Category_Flat extends Mage_Core_Model_Resource_Db_Abstract
36
  {
37
  /**
38
  * Store id
@@ -97,6 +97,13 @@ class Mage_Catalog_Model_Resource_Category_Flat extends Mage_Core_Model_Resource
97
  */
98
  protected $_storesRootCategories;
99
 
 
 
 
 
 
 
 
100
  /**
101
  * Resource initializations
102
  *
@@ -462,7 +469,9 @@ class Mage_Catalog_Model_Resource_Category_Flat extends Mage_Core_Model_Resource
462
  $categoriesIds = array();
463
  /* @var $store Mage_Core_Model_Store */
464
  foreach ($stores as $store) {
465
- $this->_createTable($store->getId());
 
 
466
 
467
  if (!isset($categories[$store->getRootCategoryId()])) {
468
  $select = $this->_getWriteAdapter()->select()
@@ -1389,4 +1398,48 @@ class Mage_Catalog_Model_Resource_Category_Flat extends Mage_Core_Model_Resource
1389
 
1390
  return $this->_storesRootCategories;
1391
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1392
  }
32
  * @package Mage_Catalog
33
  * @author Magento Core Team <core@magentocommerce.com>
34
  */
35
+ class Mage_Catalog_Model_Resource_Category_Flat extends Mage_Index_Model_Resource_Abstract
36
  {
37
  /**
38
  * Store id
97
  */
98
  protected $_storesRootCategories;
99
 
100
+ /**
101
+ * Whether table changes are allowed
102
+ *
103
+ * @var bool
104
+ */
105
+ protected $_allowTableChanges = true;
106
+
107
  /**
108
  * Resource initializations
109
  *
469
  $categoriesIds = array();
470
  /* @var $store Mage_Core_Model_Store */
471
  foreach ($stores as $store) {
472
+ if ($this->_allowTableChanges) {
473
+ $this->_createTable($store->getId());
474
+ }
475
 
476
  if (!isset($categories[$store->getRootCategoryId()])) {
477
  $select = $this->_getWriteAdapter()->select()
1398
 
1399
  return $this->_storesRootCategories;
1400
  }
1401
+
1402
+ /**
1403
+ * Creating table and adding attributes as fields to table for all stores
1404
+ *
1405
+ * @return Mage_Catalog_Model_Resource_Category_Flat
1406
+ */
1407
+ protected function _createTables()
1408
+ {
1409
+ if ($this->_allowTableChanges) {
1410
+ foreach (Mage::app()->getStores() as $store) {
1411
+ $this->_createTable($store->getId());
1412
+ }
1413
+ }
1414
+ return $this;
1415
+ }
1416
+
1417
+ /**
1418
+ * Transactional rebuild flat data from eav
1419
+ *
1420
+ * @return Mage_Catalog_Model_Resource_Category_Flat
1421
+ */
1422
+ public function reindexAll()
1423
+ {
1424
+ $this->_createTables();
1425
+ $allowTableChanges = $this->_allowTableChanges;
1426
+ if ($allowTableChanges) {
1427
+ $this->_allowTableChanges = false;
1428
+ }
1429
+ $this->beginTransaction();
1430
+ try {
1431
+ $this->rebuild();
1432
+ $this->commit();
1433
+ if ($allowTableChanges) {
1434
+ $this->_allowTableChanges = true;
1435
+ }
1436
+ } catch (Exception $e) {
1437
+ $this->rollBack();
1438
+ if ($allowTableChanges) {
1439
+ $this->_allowTableChanges = true;
1440
+ }
1441
+ throw $e;
1442
+ }
1443
+ return $this;
1444
+ }
1445
  }
app/code/core/Mage/Catalog/Model/Resource/Category/Indexer/Product.php CHANGED
@@ -773,168 +773,179 @@ class Mage_Catalog_Model_Resource_Category_Indexer_Product extends Mage_Index_Mo
773
  public function reindexAll()
774
  {
775
  $this->useIdxTable(true);
776
- $this->clearTemporaryIndexTable();
777
- $idxTable = $this->getIdxTable();
778
- $idxAdapter = $this->_getIndexAdapter();
779
- $stores = $this->_getStoresInfo();
780
- /**
781
- * Build index for each store
782
- */
783
- foreach ($stores as $storeData) {
784
- $storeId = $storeData['store_id'];
785
- $websiteId = $storeData['website_id'];
786
- $rootPath = $storeData['root_path'];
787
- $rootId = $storeData['root_id'];
788
  /**
789
- * Prepare visibility for all enabled store products
790
  */
791
- $enabledTable = $this->_prepareEnabledProductsVisibility($websiteId, $storeId);
792
- /**
793
- * Select information about anchor categories
794
- */
795
- $anchorTable = $this->_prepareAnchorCategories($storeId, $rootPath);
796
- /**
797
- * Add relations between not anchor categories and products
798
- */
799
- $select = $idxAdapter->select();
800
- /** @var $select Varien_Db_Select */
801
- $select->from(
802
- array('cp' => $this->_categoryProductTable),
803
- array('category_id', 'product_id', 'position', 'is_parent' => new Zend_Db_Expr('1'),
804
- 'store_id' => new Zend_Db_Expr($storeId))
805
- )
806
- ->joinInner(array('pv' => $enabledTable), 'pv.product_id=cp.product_id', array('visibility'))
807
- ->joinLeft(array('ac' => $anchorTable), 'ac.category_id=cp.category_id', array())
808
- ->where('ac.category_id IS NULL');
809
-
810
- $query = $select->insertFromSelect(
811
- $idxTable,
812
- array('category_id', 'product_id', 'position', 'is_parent', 'store_id', 'visibility'),
813
- false
814
- );
815
- $idxAdapter->query($query);
 
 
 
 
 
 
 
 
816
 
817
- /**
818
- * Assign products not associated to any category to root category in index
819
- */
820
 
821
- $select = $idxAdapter->select();
822
- $select->from(
823
- array('pv' => $enabledTable),
824
- array(new Zend_Db_Expr($rootId), 'product_id', new Zend_Db_Expr('0'), new Zend_Db_Expr('1'),
825
- new Zend_Db_Expr($storeId), 'visibility')
826
- )
827
- ->joinLeft(array('cp' => $this->_categoryProductTable), 'pv.product_id=cp.product_id', array())
828
- ->where('cp.product_id IS NULL');
829
 
830
- $query = $select->insertFromSelect(
831
- $idxTable,
832
- array('category_id', 'product_id', 'position', 'is_parent', 'store_id', 'visibility'),
833
- false
834
- );
835
- $idxAdapter->query($query);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
836
 
837
- /**
838
- * Prepare anchor categories products
839
- */
840
- $anchorProductsTable = $this->_getAnchorCategoriesProductsTemporaryTable();
841
- $idxAdapter->delete($anchorProductsTable);
842
 
843
- $position = 'MIN('.
844
- $idxAdapter->getCheckSql(
845
- 'ca.category_id = ce.entity_id',
846
- $idxAdapter->quoteIdentifier('cp.position'),
847
- '('.$idxAdapter->quoteIdentifier('ce.position').' + 1) * '
848
- .'('.$idxAdapter->quoteIdentifier('ce.level').' + 1 * 10000)'
849
- .' + '.$idxAdapter->quoteIdentifier('cp.position')
 
 
850
  )
851
- .')';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
852
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
853
 
854
- $select = $idxAdapter->select()
855
- ->useStraightJoin(true)
856
- ->distinct(true)
857
- ->from(array('ca' => $anchorTable), array('category_id'))
858
- ->joinInner(
859
- array('ce' => $this->_categoryTable),
860
- $idxAdapter->quoteIdentifier('ce.path') . ' LIKE ' .
861
- $idxAdapter->quoteIdentifier('ca.path') . ' OR ce.entity_id = ca.category_id',
862
- array()
863
- )
864
- ->joinInner(
865
- array('cp' => $this->_categoryProductTable),
866
- 'cp.category_id = ce.entity_id',
867
- array('product_id')
868
- )
869
- ->joinInner(array('pv' => $enabledTable), 'pv.product_id = cp.product_id', array('position' => $position))
870
- ->group(array('ca.category_id', 'cp.product_id'));
871
- $query = $select->insertFromSelect($anchorProductsTable,
872
- array('category_id', 'product_id', 'position'), false);
873
- $idxAdapter->query($query);
874
 
875
  /**
876
- * Add anchor categories products to index
877
  */
878
- $select = $idxAdapter->select()
879
- ->from(
880
- array('ap' => $anchorProductsTable),
881
- array('category_id', 'product_id',
882
- 'position', // => new Zend_Db_Expr('MIN('. $idxAdapter->quoteIdentifier('ap.position').')'),
883
- 'is_parent' => $idxAdapter->getCheckSql('cp.product_id > 0', 1, 0),
884
- 'store_id' => new Zend_Db_Expr($storeId))
885
- )
886
- ->joinLeft(
887
- array('cp' => $this->_categoryProductTable),
888
- 'cp.category_id=ap.category_id AND cp.product_id=ap.product_id',
889
- array()
890
- )
891
- ->joinInner(array('pv' => $enabledTable), 'pv.product_id = ap.product_id', array('visibility'));
892
-
893
- $query = $select->insertFromSelect(
894
- $idxTable,
895
- array('category_id', 'product_id', 'position', 'is_parent', 'store_id', 'visibility'),
896
- false
897
- );
898
- $idxAdapter->query($query);
899
-
900
- $select = $idxAdapter->select()
901
- ->from(array('e' => $this->getTable('catalog/product')), null)
902
- ->join(
903
- array('ei' => $enabledTable),
904
- 'ei.product_id = e.entity_id',
905
- array())
906
- ->joinLeft(
907
- array('i' => $idxTable),
908
- 'i.product_id = e.entity_id AND i.category_id = :category_id AND i.store_id = :store_id',
909
- array())
910
- ->where('i.product_id IS NULL')
911
- ->columns(array(
912
- 'category_id' => new Zend_Db_Expr($rootId),
913
- 'product_id' => 'e.entity_id',
914
- 'position' => new Zend_Db_Expr('0'),
915
- 'is_parent' => new Zend_Db_Expr('1'),
916
- 'store_id' => new Zend_Db_Expr($storeId),
917
- 'visibility' => 'ei.visibility'
918
- ));
919
-
920
- $query = $select->insertFromSelect(
921
- $idxTable,
922
- array('category_id', 'product_id', 'position', 'is_parent', 'store_id', 'visibility'),
923
- false
924
- );
925
-
926
- $idxAdapter->query($query, array('store_id' => $storeId, 'category_id' => $rootId));
927
  }
928
-
929
- $this->syncData();
930
-
931
- /**
932
- * Clean up temporary tables
933
- */
934
- $this->clearTemporaryIndexTable();
935
- $idxAdapter->delete($enabledTable);
936
- $idxAdapter->delete($anchorTable);
937
- $idxAdapter->delete($anchorProductsTable);
938
  return $this;
939
  }
940
 
773
  public function reindexAll()
774
  {
775
  $this->useIdxTable(true);
776
+ $this->beginTransaction();
777
+ try {
778
+ $this->clearTemporaryIndexTable();
779
+ $idxTable = $this->getIdxTable();
780
+ $idxAdapter = $this->_getIndexAdapter();
781
+ $stores = $this->_getStoresInfo();
 
 
 
 
 
 
782
  /**
783
+ * Build index for each store
784
  */
785
+ foreach ($stores as $storeData) {
786
+ $storeId = $storeData['store_id'];
787
+ $websiteId = $storeData['website_id'];
788
+ $rootPath = $storeData['root_path'];
789
+ $rootId = $storeData['root_id'];
790
+ /**
791
+ * Prepare visibility for all enabled store products
792
+ */
793
+ $enabledTable = $this->_prepareEnabledProductsVisibility($websiteId, $storeId);
794
+ /**
795
+ * Select information about anchor categories
796
+ */
797
+ $anchorTable = $this->_prepareAnchorCategories($storeId, $rootPath);
798
+ /**
799
+ * Add relations between not anchor categories and products
800
+ */
801
+ $select = $idxAdapter->select();
802
+ /** @var $select Varien_Db_Select */
803
+ $select->from(
804
+ array('cp' => $this->_categoryProductTable),
805
+ array('category_id', 'product_id', 'position', 'is_parent' => new Zend_Db_Expr('1'),
806
+ 'store_id' => new Zend_Db_Expr($storeId))
807
+ )
808
+ ->joinInner(array('pv' => $enabledTable), 'pv.product_id=cp.product_id', array('visibility'))
809
+ ->joinLeft(array('ac' => $anchorTable), 'ac.category_id=cp.category_id', array())
810
+ ->where('ac.category_id IS NULL');
811
+
812
+ $query = $select->insertFromSelect(
813
+ $idxTable,
814
+ array('category_id', 'product_id', 'position', 'is_parent', 'store_id', 'visibility'),
815
+ false
816
+ );
817
+ $idxAdapter->query($query);
818
 
819
+ /**
820
+ * Assign products not associated to any category to root category in index
821
+ */
822
 
823
+ $select = $idxAdapter->select();
824
+ $select->from(
825
+ array('pv' => $enabledTable),
826
+ array(new Zend_Db_Expr($rootId), 'product_id', new Zend_Db_Expr('0'), new Zend_Db_Expr('1'),
827
+ new Zend_Db_Expr($storeId), 'visibility')
828
+ )
829
+ ->joinLeft(array('cp' => $this->_categoryProductTable), 'pv.product_id=cp.product_id', array())
830
+ ->where('cp.product_id IS NULL');
831
 
832
+ $query = $select->insertFromSelect(
833
+ $idxTable,
834
+ array('category_id', 'product_id', 'position', 'is_parent', 'store_id', 'visibility'),
835
+ false
836
+ );
837
+ $idxAdapter->query($query);
838
+
839
+ /**
840
+ * Prepare anchor categories products
841
+ */
842
+ $anchorProductsTable = $this->_getAnchorCategoriesProductsTemporaryTable();
843
+ $idxAdapter->delete($anchorProductsTable);
844
+
845
+ $position = 'MIN('.
846
+ $idxAdapter->getCheckSql(
847
+ 'ca.category_id = ce.entity_id',
848
+ $idxAdapter->quoteIdentifier('cp.position'),
849
+ '('.$idxAdapter->quoteIdentifier('ce.position').' + 1) * '
850
+ .'('.$idxAdapter->quoteIdentifier('ce.level').' + 1 * 10000)'
851
+ .' + '.$idxAdapter->quoteIdentifier('cp.position')
852
+ )
853
+ .')';
854
 
 
 
 
 
 
855
 
856
+ $select = $idxAdapter->select()
857
+ ->useStraightJoin(true)
858
+ ->distinct(true)
859
+ ->from(array('ca' => $anchorTable), array('category_id'))
860
+ ->joinInner(
861
+ array('ce' => $this->_categoryTable),
862
+ $idxAdapter->quoteIdentifier('ce.path') . ' LIKE ' .
863
+ $idxAdapter->quoteIdentifier('ca.path') . ' OR ce.entity_id = ca.category_id',
864
+ array()
865
  )
866
+ ->joinInner(
867
+ array('cp' => $this->_categoryProductTable),
868
+ 'cp.category_id = ce.entity_id',
869
+ array('product_id')
870
+ )
871
+ ->joinInner(
872
+ array('pv' => $enabledTable),
873
+ 'pv.product_id = cp.product_id',
874
+ array('position' => $position)
875
+ )
876
+ ->group(array('ca.category_id', 'cp.product_id'));
877
+ $query = $select->insertFromSelect($anchorProductsTable,
878
+ array('category_id', 'product_id', 'position'), false);
879
+ $idxAdapter->query($query);
880
+
881
+ /**
882
+ * Add anchor categories products to index
883
+ */
884
+ $select = $idxAdapter->select()
885
+ ->from(
886
+ array('ap' => $anchorProductsTable),
887
+ array('category_id', 'product_id',
888
+ 'position', // => new Zend_Db_Expr('MIN('. $idxAdapter->quoteIdentifier('ap.position').')'),
889
+ 'is_parent' => $idxAdapter->getCheckSql('cp.product_id > 0', 1, 0),
890
+ 'store_id' => new Zend_Db_Expr($storeId))
891
+ )
892
+ ->joinLeft(
893
+ array('cp' => $this->_categoryProductTable),
894
+ 'cp.category_id=ap.category_id AND cp.product_id=ap.product_id',
895
+ array()
896
+ )
897
+ ->joinInner(array('pv' => $enabledTable), 'pv.product_id = ap.product_id', array('visibility'));
898
 
899
+ $query = $select->insertFromSelect(
900
+ $idxTable,
901
+ array('category_id', 'product_id', 'position', 'is_parent', 'store_id', 'visibility'),
902
+ false
903
+ );
904
+ $idxAdapter->query($query);
905
+
906
+ $select = $idxAdapter->select()
907
+ ->from(array('e' => $this->getTable('catalog/product')), null)
908
+ ->join(
909
+ array('ei' => $enabledTable),
910
+ 'ei.product_id = e.entity_id',
911
+ array())
912
+ ->joinLeft(
913
+ array('i' => $idxTable),
914
+ 'i.product_id = e.entity_id AND i.category_id = :category_id AND i.store_id = :store_id',
915
+ array())
916
+ ->where('i.product_id IS NULL')
917
+ ->columns(array(
918
+ 'category_id' => new Zend_Db_Expr($rootId),
919
+ 'product_id' => 'e.entity_id',
920
+ 'position' => new Zend_Db_Expr('0'),
921
+ 'is_parent' => new Zend_Db_Expr('1'),
922
+ 'store_id' => new Zend_Db_Expr($storeId),
923
+ 'visibility' => 'ei.visibility'
924
+ ));
925
+
926
+ $query = $select->insertFromSelect(
927
+ $idxTable,
928
+ array('category_id', 'product_id', 'position', 'is_parent', 'store_id', 'visibility'),
929
+ false
930
+ );
931
 
932
+ $idxAdapter->query($query, array('store_id' => $storeId, 'category_id' => $rootId));
933
+ }
934
+
935
+ $this->syncData();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
936
 
937
  /**
938
+ * Clean up temporary tables
939
  */
940
+ $this->clearTemporaryIndexTable();
941
+ $idxAdapter->delete($enabledTable);
942
+ $idxAdapter->delete($anchorTable);
943
+ $idxAdapter->delete($anchorProductsTable);
944
+ $this->commit();
945
+ } catch (Exception $e) {
946
+ $this->rollBack();
947
+ throw $e;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
948
  }
 
 
 
 
 
 
 
 
 
 
949
  return $this;
950
  }
951
 
app/code/core/Mage/Catalog/Model/Resource/Product/Flat/Indexer.php CHANGED
@@ -32,7 +32,7 @@
32
  * @package Mage_Catalog
33
  * @author Magento Core Team <core@magentocommerce.com>
34
  */
35
- class Mage_Catalog_Model_Resource_Product_Flat_Indexer extends Mage_Core_Model_Resource_Db_Abstract
36
  {
37
  const XML_NODE_MAX_INDEX_COUNT = 'global/catalog/product/flat/max_index_count';
38
  const XML_NODE_ATTRIBUTE_NODES = 'global/catalog/product/flat/attribute_nodes';
@@ -93,6 +93,13 @@ class Mage_Catalog_Model_Resource_Product_Flat_Indexer extends Mage_Core_Model_R
93
  */
94
  protected $_existsFlatTables = array();
95
 
 
 
 
 
 
 
 
96
  /**
97
  * Initialize connection
98
  *
@@ -608,6 +615,9 @@ class Mage_Catalog_Model_Resource_Product_Flat_Indexer extends Mage_Core_Model_R
608
  */
609
  public function prepareFlatTable($storeId)
610
  {
 
 
 
611
  $adapter = $this->_getWriteAdapter();
612
  $tableName = $this->getFlatTableName($storeId);
613
 
@@ -743,7 +753,7 @@ class Mage_Catalog_Model_Resource_Product_Flat_Indexer extends Mage_Core_Model_R
743
  $adapter->dropForeignKey($tableName, $foreignChildKey);
744
  }
745
  if ($isAddChildData && !isset($describe['is_child'])) {
746
- $adapter->truncateTable($tableName);
747
  $dropIndexes['PRIMARY'] = $indexesNow['PRIMARY'];
748
  $addIndexes['PRIMARY'] = $indexesNeed['PRIMARY'];
749
 
@@ -807,6 +817,8 @@ class Mage_Catalog_Model_Resource_Product_Flat_Indexer extends Mage_Core_Model_R
807
  }
808
  }
809
 
 
 
810
  return $this;
811
  }
812
 
@@ -1366,4 +1378,28 @@ class Mage_Catalog_Model_Resource_Product_Flat_Indexer extends Mage_Core_Model_R
1366
  }
1367
  return false;
1368
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1369
  }
32
  * @package Mage_Catalog
33
  * @author Magento Core Team <core@magentocommerce.com>
34
  */
35
+ class Mage_Catalog_Model_Resource_Product_Flat_Indexer extends Mage_Index_Model_Resource_Abstract
36
  {
37
  const XML_NODE_MAX_INDEX_COUNT = 'global/catalog/product/flat/max_index_count';
38
  const XML_NODE_ATTRIBUTE_NODES = 'global/catalog/product/flat/attribute_nodes';
93
  */
94
  protected $_existsFlatTables = array();
95
 
96
+ /**
97
+ * Flat tables which were prepared
98
+ *
99
+ * @var array
100
+ */
101
+ protected $_preparedFlatTables = array();
102
+
103
  /**
104
  * Initialize connection
105
  *
615
  */
616
  public function prepareFlatTable($storeId)
617
  {
618
+ if (isset($this->_preparedFlatTables[$storeId])) {
619
+ return $this;
620
+ }
621
  $adapter = $this->_getWriteAdapter();
622
  $tableName = $this->getFlatTableName($storeId);
623
 
753
  $adapter->dropForeignKey($tableName, $foreignChildKey);
754
  }
755
  if ($isAddChildData && !isset($describe['is_child'])) {
756
+ $adapter->delete($tableName);
757
  $dropIndexes['PRIMARY'] = $indexesNow['PRIMARY'];
758
  $addIndexes['PRIMARY'] = $indexesNeed['PRIMARY'];
759
 
817
  }
818
  }
819
 
820
+ $this->_preparedFlatTables[$storeId] = true;
821
+
822
  return $this;
823
  }
824
 
1378
  }
1379
  return false;
1380
  }
1381
+
1382
+ /**
1383
+ * Transactional rebuild Catalog Product Flat Data
1384
+ *
1385
+ * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
1386
+ */
1387
+ public function reindexAll()
1388
+ {
1389
+ foreach (Mage::app()->getStores() as $storeId => $store) {
1390
+ $this->prepareFlatTable($storeId);
1391
+ $this->beginTransaction();
1392
+ try {
1393
+ $this->rebuild($store);
1394
+ $this->commit();
1395
+ } catch (Exception $e) {
1396
+ $this->rollBack();
1397
+ throw $e;
1398
+ }
1399
+ }
1400
+ $flag = $this->getFlatHelper()->getFlag();
1401
+ $flag->setIsBuild(true)->save();
1402
+
1403
+ return $this;
1404
+ }
1405
  }
app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Abstract.php CHANGED
@@ -44,12 +44,19 @@ abstract class Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract
44
  public function reindexAll()
45
  {
46
  $this->useIdxTable(true);
47
- $this->clearTemporaryIndexTable();
48
- $this->_prepareIndex();
49
- $this->_prepareRelationIndex();
50
- $this->_removeNotVisibleEntityFromIndex();
 
 
51
 
52
- $this->syncData();
 
 
 
 
 
53
 
54
  return $this;
55
  }
@@ -153,7 +160,13 @@ abstract class Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract
153
  ->from($idxTable, null);
154
 
155
  $condition = $write->quoteInto('=?',Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE);
156
- $this->_addAttributeToSelect($select, 'visibility', $idxTable . '.entity_id', $idxTable . '.store_id', $condition);
 
 
 
 
 
 
157
 
158
  $query = $select->deleteFromSelect($idxTable);
159
  $write->query($query);
44
  public function reindexAll()
45
  {
46
  $this->useIdxTable(true);
47
+ $this->beginTransaction();
48
+ try {
49
+ $this->clearTemporaryIndexTable();
50
+ $this->_prepareIndex();
51
+ $this->_prepareRelationIndex();
52
+ $this->_removeNotVisibleEntityFromIndex();
53
 
54
+ $this->syncData();
55
+ $this->commit();
56
+ } catch (Exception $e) {
57
+ $this->rollBack();
58
+ throw $e;
59
+ }
60
 
61
  return $this;
62
  }
160
  ->from($idxTable, null);
161
 
162
  $condition = $write->quoteInto('=?',Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE);
163
+ $this->_addAttributeToSelect(
164
+ $select,
165
+ 'visibility',
166
+ $idxTable . '.entity_id',
167
+ $idxTable . '.store_id',
168
+ $condition
169
+ );
170
 
171
  $query = $select->deleteFromSelect($idxTable);
172
  $write->query($query);
app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Price.php CHANGED
@@ -120,7 +120,7 @@ class Mage_Catalog_Model_Resource_Product_Indexer_Price extends Mage_Index_Model
120
  protected function _copyIndexDataToMainTable($processIds)
121
  {
122
  $write = $this->_getWriteAdapter();
123
- $write->beginTransaction();
124
  try {
125
  // remove old index
126
  $where = $write->quoteInto('entity_id IN(?)', $p