Version Notes
1.9.3.0
Download this release
Release Info
Developer | Magento Core Team |
Extension | Mage_Core_Modules |
Version | 1.9.3.0 |
Comparing to | |
See all releases |
Code changes from version 1.9.2.4 to 1.9.3.0
- .htaccess.sample +15 -0
- RELEASE_NOTES.txt +11 -1
- api.php +5 -2
- app/Mage.php +2 -2
- app/code/core/Mage/Admin/Model/User.php +3 -3
- app/code/core/Mage/Admin/etc/config.xml +1 -1
- app/code/core/Mage/Api/Model/Server/Handler/Abstract.php +47 -6
- app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php +1 -0
- app/code/core/Mage/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php +7 -2
- app/code/core/Mage/Catalog/Block/Product/Abstract.php +11 -6
- app/code/core/Mage/Catalog/Block/Product/List.php +2 -5
- app/code/core/Mage/Catalog/Block/Product/View.php +6 -61
- app/code/core/Mage/Catalog/Block/Product/View/Type/Configurable.php +33 -26
- app/code/core/Mage/Catalog/Helper/Image.php +8 -1
- app/code/core/Mage/Catalog/Helper/Product.php +40 -0
- app/code/core/Mage/Catalog/Helper/Product/Type/Composite.php +195 -0
- app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Groupprice/Abstract.php +6 -3
- app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Media.php +4 -1
- app/code/core/Mage/Catalog/Model/Product/Link/Api/V2.php +4 -4
- app/code/core/Mage/Catalog/Model/Resource/Eav/Attribute.php +1 -1
- app/code/core/Mage/Catalog/Model/Resource/Product/Attribute/Backend/Groupprice.php +13 -0
- app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Source.php +3 -3
- app/code/core/Mage/Catalog/Model/Resource/Product/Link/Product/Collection.php +48 -2
- app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php +11 -6
- app/code/core/Mage/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.19.1.3-1.6.0.0.19.1.4.php +77 -0
- app/code/core/Mage/Catalog/etc/config.xml +2 -1
- app/code/core/Mage/Catalog/etc/system.xml +9 -0
- app/code/core/Mage/Catalog/sql/catalog_setup/upgrade-1.6.0.0.19.1.2-1.6.0.0.19.1.3.php +44 -0
- app/code/core/Mage/Catalog/sql/catalog_setup/upgrade-1.6.0.0.19.1.4-1.6.0.0.19.1.5.php +37 -0
- app/code/core/Mage/CatalogInventory/Model/Observer.php +1 -0
- app/code/core/Mage/CatalogInventory/Model/Stock/Item.php +21 -0
- app/code/core/Mage/CatalogRule/Model/Action/Index/Refresh.php +26 -4
- app/code/core/Mage/CatalogSearch/Model/Resource/Advanced.php +1 -1
- app/code/core/Mage/CatalogSearch/Model/Resource/Fulltext.php +40 -42
- app/code/core/Mage/CatalogSearch/Model/Resource/Fulltext/Collection.php +173 -13
- app/code/core/Mage/CatalogSearch/Model/Resource/Helper/Mysql4.php +16 -1
- app/code/core/Mage/Checkout/Model/Cart.php +9 -6
- app/code/core/Mage/Checkout/Model/Type/Multishipping.php +3 -0
- app/code/core/Mage/Checkout/Model/Type/Onepage.php +16 -0
- app/code/core/Mage/Checkout/controllers/CartController.php +26 -1
- app/code/core/Mage/Checkout/controllers/OnepageController.php +22 -10
- app/code/core/Mage/Cms/Block/Page.php +24 -2
- app/code/core/Mage/Cms/Helper/Wysiwyg/Images.php +2 -1
- app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php +5 -4
- app/code/core/Mage/ConfigurableSwatches/Block/Catalog/Product/List/Price.php +95 -0
- app/code/core/Mage/ConfigurableSwatches/Helper/Data.php +27 -1
- app/code/core/Mage/ConfigurableSwatches/Helper/List/Price.php +118 -0
- app/code/core/Mage/ConfigurableSwatches/Helper/Mediafallback.php +52 -10
- app/code/core/Mage/ConfigurableSwatches/Model/Observer.php +14 -7
- app/code/core/Mage/ConfigurableSwatches/Model/Resource/Catalog/Product/Attribute/Super/Collection.php +52 -33
- app/code/core/Mage/ConfigurableSwatches/etc/system.xml +9 -0
- app/code/core/Mage/Core/Block/Abstract.php +11 -1
- app/code/core/Mage/Core/Block/Template.php +1 -1
- app/code/core/Mage/Core/Controller/Varien/Action.php +1 -0
- app/code/core/Mage/Core/Helper/String.php +41 -1
- app/code/core/Mage/Core/Helper/Url.php +1 -1
- app/code/core/Mage/Core/Model/Config.php +3 -0
- app/code/core/Mage/Core/Model/Email/Queue.php +0 -2
- app/code/core/Mage/Core/Model/Email/Template.php +1 -0
- app/code/core/Mage/Core/Model/Email/Template/Abstract.php +15 -31
- app/code/core/Mage/Core/Model/Encryption.php +2 -2
- app/code/core/Mage/Core/Model/File/Storage/Abstract.php +3 -3
- app/code/core/Mage/Core/Model/File/Validator/AvailablePath.php +6 -6
- app/code/core/Mage/Core/Model/Input/Filter/MaliciousCode.php +7 -1
- app/code/core/Mage/Core/Model/Layout.php +1 -1
- app/code/core/Mage/Core/Model/Resource/Url/Rewrite.php +3 -3
- app/code/core/Mage/Core/Model/Resource/Variable/Collection.php +1 -1
- app/code/core/Mage/Core/Model/Session/Abstract/Varien.php +21 -0
- app/code/core/Mage/Core/etc/config.xml +8 -0
- app/code/core/Mage/Core/etc/jstranslator.xml +2 -2
- app/code/core/Mage/Core/etc/system.xml +1 -1
- app/code/core/Mage/Core/functions.php +35 -0
- app/code/core/Mage/Cron/Model/Schedule.php +5 -1
- app/code/core/Mage/Customer/Block/Address/Book.php +2 -1
- app/code/core/Mage/Customer/Helper/Data.php +37 -0
- app/code/core/Mage/Customer/Model/Customer.php +66 -8
- app/code/core/Mage/Customer/Model/Flowpassword.php +121 -0
- app/code/core/Mage/Customer/Model/Observer.php +13 -1
- app/code/core/Mage/Customer/Model/Resource/Flowpassword.php +44 -0
- app/code/core/Mage/Customer/Model/Resource/Flowpassword/Collection.php +44 -0
- app/code/core/Mage/Customer/controllers/AccountController.php +55 -25
- app/code/core/Mage/Customer/controllers/AddressController.php +3 -0
- app/code/core/Mage/Customer/data/customer_setup/data-upgrade-1.6.2.0.4-1.6.2.0.5.php +78 -0
- app/code/core/Mage/Customer/etc/config.xml +33 -2
- app/code/core/Mage/Customer/etc/system.xml +64 -1
- app/code/core/Mage/Customer/sql/customer_setup/upgrade-1.6.2.0.4-1.6.2.0.5.php +58 -0
- app/code/core/Mage/Dataflow/Model/Profile.php +14 -4
- app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php +49 -21
- app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php +49 -24
- app/code/core/Mage/Downloadable/Helper/File.php +52 -612
- app/code/core/Mage/Eav/Block/Adminhtml/Attribute/Edit/Options/Abstract.php +2 -3
- app/code/core/Mage/Eav/Model/Entity/Abstract.php +10 -5
- app/code/core/Mage/Eav/Model/Entity/Attribute.php +2 -1
- app/code/core/Mage/Eav/Model/Entity/Attribute/Abstract.php +11 -2
- app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Table.php +2 -2
- app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php +2 -0
- app/code/core/Mage/ImportExport/Helper/Data.php +13 -2
- app/code/core/Mage/ImportExport/Model/Export.php +47 -1
- app/code/core/Mage/ImportExport/Model/Export/Adapter/Abstract.php +17 -0
- app/code/core/Mage/ImportExport/Model/Export/Adapter/Csv.php +2 -0
- app/code/core/Mage/ImportExport/Model/Export/Entity/Abstract.php +58 -2
- app/code/core/Mage/ImportExport/Model/Export/Entity/Customer.php +312 -73
- app/code/core/Mage/ImportExport/Model/Export/Entity/Product.php +161 -88
- app/code/core/Mage/ImportExport/Model/Export/Entity/Product/Type/Abstract.php +1 -1
- app/code/core/Mage/ImportExport/Model/Import/Entity/Customer.php +62 -8
- app/code/core/Mage/ImportExport/Model/Import/Entity/Customer/Address.php +76 -36
- app/code/core/Mage/ImportExport/Model/Import/Entity/Product.php +118 -46
- app/code/core/Mage/ImportExport/Model/Import/Entity/Product/Type/Configurable.php +27 -11
- app/code/core/Mage/ImportExport/Model/Import/Uploader.php +1 -1
- app/code/core/Mage/ImportExport/controllers/Adminhtml/ExportController.php +4 -1
- app/code/core/Mage/ImportExport/etc/config.xml +3 -0
- app/code/core/Mage/ImportExport/etc/system.xml +19 -0
- app/code/core/Mage/Oauth/Model/Server.php +3 -3
- app/code/core/Mage/Paygate/Model/Authorizenet.php +9 -3
- app/code/core/Mage/Payment/Block/Info/Checkmo.php +8 -2
- app/code/core/Mage/Payment/Model/Method/Cc.php +1 -1
- app/code/core/Mage/Paypal/Model/Api/Nvp.php +2 -1
- app/code/core/Mage/Paypal/Model/Express/Checkout.php +23 -1
- app/code/core/Mage/Paypal/Model/Resource/Payment/Transaction.php +20 -0
- app/code/core/Mage/Persistent/Model/Persistent/Config.php +3 -1
- app/code/core/Mage/Reports/Model/Product/Index/Abstract.php +20 -2
- app/code/core/Mage/Reports/Model/Resource/Helper/Mysql4.php +29 -7
- app/code/core/Mage/Rss/Controller/Abstract.php +77 -0
- app/code/core/Mage/Rss/controllers/CatalogController.php +26 -38
- app/code/core/Mage/Rss/controllers/IndexController.php +2 -15
- app/code/core/Mage/Rss/controllers/OrderController.php +22 -18
- app/code/core/Mage/Rss/data/rss_setup/data-install-1.6.0.0.php +34 -0
- app/code/core/Mage/Rss/etc/config.xml +7 -3
- app/code/core/Mage/Rss/etc/system.xml +84 -5
- app/code/core/Mage/Sales/Helper/Guest.php +1 -1
- app/code/core/Mage/Sales/Model/Email/Template.php +1 -1
- app/code/core/Mage/Sales/Model/Order.php +17 -3
- app/code/core/Mage/Sales/Model/Order/Invoice/Total/Subtotal.php +4 -36
- app/code/core/Mage/Sales/Model/Quote/Address/Total/Subtotal.php +1 -1
- app/code/core/Mage/Sales/Model/Quote/Item.php +1 -1
- app/code/core/Mage/Sales/Model/Quote/Item/Abstract.php +4 -1
- app/code/core/Mage/Sales/Model/Resource/Order/Payment.php +24 -0
- app/code/core/Mage/Sales/Model/Resource/Order/Payment/Transaction.php +24 -0
- app/code/core/Mage/Sales/Model/Resource/Quote.php +2 -2
- app/code/core/Mage/Sales/Model/Resource/Quote/Payment.php +20 -0
- app/code/core/Mage/Sales/Model/Resource/Recurring/Profile.php +27 -0
- app/code/core/Mage/Sales/Model/Resource/Report/Bestsellers.php +3 -8
- app/code/core/Mage/Sales/Model/Resource/Report/Bestsellers/Collection.php +19 -6
- app/code/core/Mage/Sales/etc/config.xml +2 -1
- app/code/core/Mage/Sales/sql/sales_setup/upgrade-1.6.0.9-1.6.0.10.php +51 -0
- app/code/core/Mage/SalesRule/Model/Rule/Condition/Product.php +1 -1
- app/code/core/Mage/SalesRule/Model/Rule/Condition/Product/Combine.php +16 -1
- app/code/core/Mage/SalesRule/Model/Validator.php +182 -188
- app/code/core/Mage/SalesRule/etc/config.xml +2 -2
- app/code/core/Mage/Sitemap/Model/Sitemap.php +4 -2
- app/code/core/Mage/Tax/etc/config.xml +2 -2
- app/code/core/Mage/Uploader/Block/Abstract.php +247 -0
- app/code/core/Mage/Uploader/Block/Multiple.php +71 -0
- app/code/core/Mage/Uploader/Block/Single.php +52 -0
- app/code/core/Mage/Uploader/Helper/Data.php +35 -0
- app/code/core/Mage/Uploader/Helper/File.php +758 -0
- app/code/core/Mage/Uploader/Model/Config/Abstract.php +76 -0
- app/code/core/Mage/Uploader/Model/Config/Browsebutton.php +73 -0
- app/code/core/Mage/Uploader/Model/Config/Misc.php +54 -0
- app/code/core/Mage/Uploader/Model/Config/Uploader.php +128 -0
- app/code/core/Mage/Uploader/etc/config.xml +73 -0
- app/code/core/Mage/Uploader/etc/jstranslator.xml +45 -0
- app/code/core/Mage/Usa/Model/Shipping/Carrier/Dhl.php +4 -4
- app/code/core/Mage/Usa/Model/Shipping/Carrier/Dhl/International.php +18 -3
- app/code/core/Mage/Usa/Model/Shipping/Carrier/Fedex.php +3 -2
- app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups.php +3 -3
- app/code/core/Mage/Usa/Model/Shipping/Carrier/Usps.php +6 -0
- app/code/core/Mage/Usa/etc/config.xml +5 -1
- app/code/core/Mage/Usa/etc/system.xml +27 -0
- app/code/core/Mage/Weee/Model/Observer.php +4 -1
- app/code/core/Mage/Wishlist/Block/Customer/Wishlist/Item/Options.php +6 -3
- app/code/core/Mage/Wishlist/Helper/Data.php +4 -1
- app/code/core/Mage/Wishlist/controllers/IndexController.php +3 -0
- app/code/core/Zend/Validate/Hostname.php +1684 -0
- app/etc/modules/Mage_All.xml +8 -1
- cron.php +1 -1
- errors/processor.php +21 -9
- package.xml +5 -5
.htaccess.sample
CHANGED
@@ -127,6 +127,21 @@
|
|
127 |
|
128 |
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
############################################
|
131 |
## always send 404 on missing files in these folders
|
132 |
|
127 |
|
128 |
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
129 |
|
130 |
+
<IfModule mod_setenvif.c>
|
131 |
+
<IfModule mod_headers.c>
|
132 |
+
|
133 |
+
############################################
|
134 |
+
# X-Content-Type-Options: nosniff disable content-type sniffing on some browsers.
|
135 |
+
Header set X-Content-Type-Options: nosniff
|
136 |
+
|
137 |
+
############################################
|
138 |
+
# This header forces to enables the Cross-site scripting (XSS) filter in browsers (if disabled)
|
139 |
+
BrowserMatch \bMSIE\s8 ie8
|
140 |
+
Header set X-XSS-Protection: "1; mode=block" env=!ie8
|
141 |
+
|
142 |
+
</IfModule>
|
143 |
+
</IfModule>
|
144 |
+
|
145 |
############################################
|
146 |
## always send 404 on missing files in these folders
|
147 |
|
RELEASE_NOTES.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
==== 1.9.2.4 ====
|
2 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
3 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
@@ -53,7 +63,7 @@
|
|
53 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
54 |
] NOTE: Current Release Notes are maintained at: [
|
55 |
] [
|
56 |
-
] http://
|
57 |
] [
|
58 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
59 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1 |
+
==== 1.9.3.0 ====
|
2 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
3 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
4 |
+
] NOTE: Current Release Notes are maintained at: [
|
5 |
+
] [
|
6 |
+
] http://merch.docs.magento.com/ce/user_guide/magento/release-notes-ce-1.9.3.0.html [
|
7 |
+
] [
|
8 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
9 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
10 |
+
|
11 |
==== 1.9.2.4 ====
|
12 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
13 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
63 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
64 |
] NOTE: Current Release Notes are maintained at: [
|
65 |
] [
|
66 |
+
] http://devdocs.magento.com/guides/m1x/ce18-ee113/ce1.9_release-notes.html [
|
67 |
] [
|
68 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
69 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
api.php
CHANGED
@@ -74,8 +74,11 @@ if (in_array($apiAlias, Mage_Api2_Model_Server::getApiTypes())) {
|
|
74 |
} else {
|
75 |
/* @var $server Mage_Api_Model_Server */
|
76 |
$server = Mage::getSingleton('api/server');
|
77 |
-
|
78 |
-
|
|
|
|
|
|
|
79 |
// if no adapters found in aliases - find it by default, by code
|
80 |
if (null === $adapterCode) {
|
81 |
$adapterCode = $apiAlias;
|
74 |
} else {
|
75 |
/* @var $server Mage_Api_Model_Server */
|
76 |
$server = Mage::getSingleton('api/server');
|
77 |
+
if (!$apiAlias) {
|
78 |
+
$adapterCode = 'default';
|
79 |
+
} else {
|
80 |
+
$adapterCode = $server->getAdapterCodeByAlias($apiAlias);
|
81 |
+
}
|
82 |
// if no adapters found in aliases - find it by default, by code
|
83 |
if (null === $adapterCode) {
|
84 |
$adapterCode = $apiAlias;
|
app/Mage.php
CHANGED
@@ -170,8 +170,8 @@ final class Mage
|
|
170 |
return array(
|
171 |
'major' => '1',
|
172 |
'minor' => '9',
|
173 |
-
'revision' => '
|
174 |
-
'patch' => '
|
175 |
'stability' => '',
|
176 |
'number' => '',
|
177 |
);
|
170 |
return array(
|
171 |
'major' => '1',
|
172 |
'minor' => '9',
|
173 |
+
'revision' => '3',
|
174 |
+
'patch' => '0',
|
175 |
'stability' => '',
|
176 |
'number' => '',
|
177 |
);
|
app/code/core/Mage/Admin/Model/User.php
CHANGED
@@ -640,8 +640,8 @@ class Mage_Admin_Model_User extends Mage_Core_Model_Abstract
|
|
640 |
return true;
|
641 |
}
|
642 |
|
643 |
-
$
|
644 |
-
if ($
|
645 |
return true;
|
646 |
}
|
647 |
|
@@ -665,7 +665,7 @@ class Mage_Admin_Model_User extends Mage_Core_Model_Abstract
|
|
665 |
/**
|
666 |
* Simple sql format date
|
667 |
*
|
668 |
-
* @param string $
|
669 |
* @return string
|
670 |
*/
|
671 |
protected function _getDateNow($dayOnly = false)
|
640 |
return true;
|
641 |
}
|
642 |
|
643 |
+
$hoursDifference = floor(($currentTimestamp - $tokenTimestamp) / (60 * 60));
|
644 |
+
if ($hoursDifference >= $tokenExpirationPeriod) {
|
645 |
return true;
|
646 |
}
|
647 |
|
665 |
/**
|
666 |
* Simple sql format date
|
667 |
*
|
668 |
+
* @param string | boolean $dayOnly
|
669 |
* @return string
|
670 |
*/
|
671 |
protected function _getDateNow($dayOnly = false)
|
app/code/core/Mage/Admin/etc/config.xml
CHANGED
@@ -85,7 +85,7 @@
|
|
85 |
<emails>
|
86 |
<forgot_email_template>admin_emails_forgot_email_template</forgot_email_template>
|
87 |
<forgot_email_identity>general</forgot_email_identity>
|
88 |
-
<password_reset_link_expiration_period>
|
89 |
</emails>
|
90 |
</admin>
|
91 |
</default>
|
85 |
<emails>
|
86 |
<forgot_email_template>admin_emails_forgot_email_template</forgot_email_template>
|
87 |
<forgot_email_identity>general</forgot_email_identity>
|
88 |
+
<password_reset_link_expiration_period>2</password_reset_link_expiration_period>
|
89 |
</emails>
|
90 |
</admin>
|
91 |
</default>
|
app/code/core/Mage/Api/Model/Server/Handler/Abstract.php
CHANGED
@@ -288,13 +288,15 @@ abstract class Mage_Api_Model_Server_Handler_Abstract
|
|
288 |
}
|
289 |
|
290 |
if (method_exists($model, $method)) {
|
|
|
291 |
if (isset($methodInfo->arguments) && ((string)$methodInfo->arguments) == 'array') {
|
292 |
-
|
293 |
} elseif (!is_array($args)) {
|
294 |
-
|
295 |
} else {
|
296 |
-
|
297 |
}
|
|
|
298 |
} else {
|
299 |
throw new Mage_Api_Exception('resource_path_not_callable');
|
300 |
}
|
@@ -401,13 +403,15 @@ abstract class Mage_Api_Model_Server_Handler_Abstract
|
|
401 |
}
|
402 |
|
403 |
if (method_exists($model, $method)) {
|
|
|
404 |
if (isset($methodInfo->arguments) && ((string)$methodInfo->arguments) == 'array') {
|
405 |
-
$
|
406 |
} elseif (!is_array($args)) {
|
407 |
-
$
|
408 |
} else {
|
409 |
-
$
|
410 |
}
|
|
|
411 |
} else {
|
412 |
throw new Mage_Api_Exception('resource_path_not_callable');
|
413 |
}
|
@@ -543,4 +547,41 @@ abstract class Mage_Api_Model_Server_Handler_Abstract
|
|
543 |
$this->_startSession($sessionId);
|
544 |
return array_values($this->_getConfig()->getFaults());
|
545 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
546 |
} // Class Mage_Api_Model_Server_Handler_Abstract End
|
288 |
}
|
289 |
|
290 |
if (method_exists($model, $method)) {
|
291 |
+
$result = array();
|
292 |
if (isset($methodInfo->arguments) && ((string)$methodInfo->arguments) == 'array') {
|
293 |
+
$result = $model->$method((is_array($args) ? $args : array($args)));
|
294 |
} elseif (!is_array($args)) {
|
295 |
+
$result = $model->$method($args);
|
296 |
} else {
|
297 |
+
$result = call_user_func_array(array(&$model, $method), $args);
|
298 |
}
|
299 |
+
return $this->processingMethodResult($result);
|
300 |
} else {
|
301 |
throw new Mage_Api_Exception('resource_path_not_callable');
|
302 |
}
|
403 |
}
|
404 |
|
405 |
if (method_exists($model, $method)) {
|
406 |
+
$callResult = array();
|
407 |
if (isset($methodInfo->arguments) && ((string)$methodInfo->arguments) == 'array') {
|
408 |
+
$callResult = $model->$method((is_array($args) ? $args : array($args)));
|
409 |
} elseif (!is_array($args)) {
|
410 |
+
$callResult = $model->$method($args);
|
411 |
} else {
|
412 |
+
$callResult = call_user_func_array(array(&$model, $method), $args);
|
413 |
}
|
414 |
+
$result[] = $this->processingMethodResult($callResult);
|
415 |
} else {
|
416 |
throw new Mage_Api_Exception('resource_path_not_callable');
|
417 |
}
|
547 |
$this->_startSession($sessionId);
|
548 |
return array_values($this->_getConfig()->getFaults());
|
549 |
}
|
550 |
+
|
551 |
+
/**
|
552 |
+
* Prepare Api data for XML exporting
|
553 |
+
* See allowed characters in XML:
|
554 |
+
* @link http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char
|
555 |
+
*
|
556 |
+
* @param array $result
|
557 |
+
* @return mixed
|
558 |
+
*/
|
559 |
+
public function processingMethodResult(array $result)
|
560 |
+
{
|
561 |
+
foreach ($result as &$row) {
|
562 |
+
if (!is_null($row) && !is_bool($row) && !is_numeric($row)) {
|
563 |
+
$row = $this->processingRow($row);
|
564 |
+
}
|
565 |
+
}
|
566 |
+
return $result;
|
567 |
+
}
|
568 |
+
|
569 |
+
/**
|
570 |
+
* Prepare Api row data for XML exporting
|
571 |
+
* Convert not allowed symbol to numeric character reference
|
572 |
+
*
|
573 |
+
* @param $row
|
574 |
+
* @return mixed
|
575 |
+
*/
|
576 |
+
public function processingRow($row)
|
577 |
+
{
|
578 |
+
$row = preg_replace_callback(
|
579 |
+
'/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]/u',
|
580 |
+
function ($matches) {
|
581 |
+
return '&#' . Mage::helper('core/string')->uniOrd($matches[0]) . ';';
|
582 |
+
},
|
583 |
+
$row
|
584 |
+
);
|
585 |
+
return $row;
|
586 |
+
}
|
587 |
} // Class Mage_Api_Model_Server_Handler_Abstract End
|
app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php
CHANGED
@@ -121,6 +121,7 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Attributes
|
|
121 |
$groupPrice->setRenderer(
|
122 |
$this->getLayout()->createBlock('adminhtml/catalog_product_edit_tab_price_group')
|
123 |
->setPriceColumnHeader(Mage::helper('bundle')->__('Percent Discount'))
|
|
|
124 |
->setPriceValidation('validate-greater-than-zero validate-percents')
|
125 |
);
|
126 |
}
|
121 |
$groupPrice->setRenderer(
|
122 |
$this->getLayout()->createBlock('adminhtml/catalog_product_edit_tab_price_group')
|
123 |
->setPriceColumnHeader(Mage::helper('bundle')->__('Percent Discount'))
|
124 |
+
->setIsPercent(true)
|
125 |
->setPriceValidation('validate-greater-than-zero validate-percents')
|
126 |
);
|
127 |
}
|
app/code/core/Mage/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php
CHANGED
@@ -85,8 +85,13 @@ class Mage_Bundle_Block_Catalog_Product_View_Type_Bundle_Option extends Mage_Bun
|
|
85 |
$_canChangeQty = $_default->getSelectionCanChangeQty();
|
86 |
} elseif (!$inPreConfigured && $selectedOptions && is_numeric($selectedOptions)) {
|
87 |
$selectedSelection = $_option->getSelectionById($selectedOptions);
|
88 |
-
|
89 |
-
|
|
|
|
|
|
|
|
|
|
|
90 |
} elseif (!$this->_showSingle() || $inPreConfigured) {
|
91 |
$_defaultQty = $this->_getSelectedQty();
|
92 |
$_canChangeQty = (bool)$_defaultQty;
|
85 |
$_canChangeQty = $_default->getSelectionCanChangeQty();
|
86 |
} elseif (!$inPreConfigured && $selectedOptions && is_numeric($selectedOptions)) {
|
87 |
$selectedSelection = $_option->getSelectionById($selectedOptions);
|
88 |
+
if ($selectedSelection) {
|
89 |
+
$_defaultQty = $selectedSelection->getSelectionQty() * 1;
|
90 |
+
$_canChangeQty = $selectedSelection->getSelectionCanChangeQty();
|
91 |
+
} else {
|
92 |
+
$_defaultQty = $_selections[0]->getSelectionQty() * 1;
|
93 |
+
$_canChangeQty = $_selections[0]->getSelectionCanChangeQty();
|
94 |
+
}
|
95 |
} elseif (!$this->_showSingle() || $inPreConfigured) {
|
96 |
$_defaultQty = $this->_getSelectedQty();
|
97 |
$_canChangeQty = (bool)$_defaultQty;
|
app/code/core/Mage/Catalog/Block/Product/Abstract.php
CHANGED
@@ -104,6 +104,16 @@ abstract class Mage_Catalog_Block_Product_Abstract extends Mage_Core_Block_Templ
|
|
104 |
*/
|
105 |
protected $_mapRenderer = 'msrp';
|
106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
/**
|
108 |
* Retrieve url for add product to cart
|
109 |
* Will return product view page URL if product has required options
|
@@ -195,12 +205,7 @@ abstract class Mage_Catalog_Block_Product_Abstract extends Mage_Core_Block_Templ
|
|
195 |
*/
|
196 |
public function getMinimalQty($product)
|
197 |
{
|
198 |
-
|
199 |
-
if ($stockItem) {
|
200 |
-
return ($stockItem->getMinSaleQty()
|
201 |
-
&& $stockItem->getMinSaleQty() > 0 ? $stockItem->getMinSaleQty() * 1 : null);
|
202 |
-
}
|
203 |
-
return null;
|
204 |
}
|
205 |
|
206 |
/**
|
104 |
*/
|
105 |
protected $_mapRenderer = 'msrp';
|
106 |
|
107 |
+
/**
|
108 |
+
* Get catalog product helper
|
109 |
+
*
|
110 |
+
* @return Mage_Catalog_Helper_Product
|
111 |
+
*/
|
112 |
+
public function getProductHelper()
|
113 |
+
{
|
114 |
+
return Mage::helper('catalog/product');
|
115 |
+
}
|
116 |
+
|
117 |
/**
|
118 |
* Retrieve url for add product to cart
|
119 |
* Will return product view page URL if product has required options
|
205 |
*/
|
206 |
public function getMinimalQty($product)
|
207 |
{
|
208 |
+
return $this->getProductHelper()->getMinimalQty($product);
|
|
|
|
|
|
|
|
|
|
|
209 |
}
|
210 |
|
211 |
/**
|
app/code/core/Mage/Catalog/Block/Product/List.php
CHANGED
@@ -62,16 +62,13 @@ class Mage_Catalog_Block_Product_List extends Mage_Catalog_Block_Product_Abstrac
|
|
62 |
$this->setCategoryId(Mage::app()->getStore()->getRootCategoryId());
|
63 |
}
|
64 |
|
65 |
-
// if this is a product view page
|
66 |
if (Mage::registry('product')) {
|
67 |
-
|
68 |
$categories = Mage::registry('product')->getCategoryCollection()
|
69 |
->setPage(1, 1)
|
70 |
->load();
|
71 |
-
// if the product is associated with any category
|
72 |
if ($categories->count()) {
|
73 |
-
|
74 |
-
$this->setCategoryId(current($categories->getIterator()));
|
75 |
}
|
76 |
}
|
77 |
|
62 |
$this->setCategoryId(Mage::app()->getStore()->getRootCategoryId());
|
63 |
}
|
64 |
|
|
|
65 |
if (Mage::registry('product')) {
|
66 |
+
/** @var Mage_Catalog_Model_Resource_Category_Collection $categories */
|
67 |
$categories = Mage::registry('product')->getCategoryCollection()
|
68 |
->setPage(1, 1)
|
69 |
->load();
|
|
|
70 |
if ($categories->count()) {
|
71 |
+
$this->setCategoryId($categories->getFirstItem()->getId());
|
|
|
72 |
}
|
73 |
}
|
74 |
|
app/code/core/Mage/Catalog/Block/Product/View.php
CHANGED
@@ -141,62 +141,14 @@ class Mage_Catalog_Block_Product_View extends Mage_Catalog_Block_Product_Abstrac
|
|
141 |
return Mage::helper('core')->jsonEncode($config);
|
142 |
}
|
143 |
|
144 |
-
$_request = Mage::getSingleton('tax/calculation')->getDefaultRateRequest();
|
145 |
/* @var $product Mage_Catalog_Model_Product */
|
146 |
$product = $this->getProduct();
|
147 |
-
$_request->setProductClassId($product->getTaxClassId());
|
148 |
-
$defaultTax = Mage::getSingleton('tax/calculation')->getRate($_request);
|
149 |
|
150 |
-
$
|
151 |
-
$
|
152 |
-
$
|
153 |
-
|
154 |
-
|
155 |
-
$_finalPrice = $product->getFinalPrice();
|
156 |
-
if ($product->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
|
157 |
-
$_priceInclTax = Mage::helper('tax')->getPrice($product, $_finalPrice, true,
|
158 |
-
null, null, null, null, null, false);
|
159 |
-
$_priceExclTax = Mage::helper('tax')->getPrice($product, $_finalPrice, false,
|
160 |
-
null, null, null, null, null, false);
|
161 |
-
} else {
|
162 |
-
$_priceInclTax = Mage::helper('tax')->getPrice($product, $_finalPrice, true);
|
163 |
-
$_priceExclTax = Mage::helper('tax')->getPrice($product, $_finalPrice);
|
164 |
-
}
|
165 |
-
$_tierPrices = array();
|
166 |
-
$_tierPricesInclTax = array();
|
167 |
-
foreach ($product->getTierPrice() as $tierPrice) {
|
168 |
-
$_tierPrices[] = Mage::helper('core')->currency(
|
169 |
-
Mage::helper('tax')->getPrice($product, (float)$tierPrice['website_price'], false) - $_priceExclTax
|
170 |
-
, false, false);
|
171 |
-
$_tierPricesInclTax[] = Mage::helper('core')->currency(
|
172 |
-
Mage::helper('tax')->getPrice($product, (float)$tierPrice['website_price'], true) - $_priceInclTax
|
173 |
-
, false, false);
|
174 |
-
}
|
175 |
-
$config = array(
|
176 |
-
'productId' => $product->getId(),
|
177 |
-
'priceFormat' => Mage::app()->getLocale()->getJsPriceFormat(),
|
178 |
-
'includeTax' => Mage::helper('tax')->priceIncludesTax() ? 'true' : 'false',
|
179 |
-
'showIncludeTax' => Mage::helper('tax')->displayPriceIncludingTax(),
|
180 |
-
'showBothPrices' => Mage::helper('tax')->displayBothPrices(),
|
181 |
-
'productPrice' => Mage::helper('core')->currency($_finalPrice, false, false),
|
182 |
-
'productOldPrice' => Mage::helper('core')->currency($_regularPrice, false, false),
|
183 |
-
'priceInclTax' => Mage::helper('core')->currency($_priceInclTax, false, false),
|
184 |
-
'priceExclTax' => Mage::helper('core')->currency($_priceExclTax, false, false),
|
185 |
-
/**
|
186 |
-
* @var skipCalculate
|
187 |
-
* @deprecated after 1.5.1.0
|
188 |
-
*/
|
189 |
-
'skipCalculate' => ($_priceExclTax != $_priceInclTax ? 0 : 1),
|
190 |
-
'defaultTax' => $defaultTax,
|
191 |
-
'currentTax' => $currentTax,
|
192 |
-
'idSuffix' => '_clone',
|
193 |
-
'oldPlusDisposition' => 0,
|
194 |
-
'plusDisposition' => 0,
|
195 |
-
'plusDispositionTax' => 0,
|
196 |
-
'oldMinusDisposition' => 0,
|
197 |
-
'minusDisposition' => 0,
|
198 |
-
'tierPrices' => $_tierPrices,
|
199 |
-
'tierPricesInclTax' => $_tierPricesInclTax,
|
200 |
);
|
201 |
|
202 |
$responseObject = new Varien_Object();
|
@@ -259,14 +211,7 @@ class Mage_Catalog_Block_Product_View extends Mage_Catalog_Block_Product_Abstrac
|
|
259 |
$product = $this->getProduct();
|
260 |
}
|
261 |
|
262 |
-
|
263 |
-
$config = $product->getPreconfiguredValues();
|
264 |
-
$configQty = $config->getQty();
|
265 |
-
if ($configQty > $qty) {
|
266 |
-
$qty = $configQty;
|
267 |
-
}
|
268 |
-
|
269 |
-
return $qty;
|
270 |
}
|
271 |
|
272 |
/**
|
141 |
return Mage::helper('core')->jsonEncode($config);
|
142 |
}
|
143 |
|
|
|
144 |
/* @var $product Mage_Catalog_Model_Product */
|
145 |
$product = $this->getProduct();
|
|
|
|
|
146 |
|
147 |
+
/** @var Mage_Catalog_Helper_Product_Type_Composite $compositeProductHelper */
|
148 |
+
$compositeProductHelper = $this->helper('catalog/product_type_composite');
|
149 |
+
$config = array_merge(
|
150 |
+
$compositeProductHelper->prepareJsonGeneralConfig(),
|
151 |
+
$compositeProductHelper->prepareJsonProductConfig($product)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
);
|
153 |
|
154 |
$responseObject = new Varien_Object();
|
211 |
$product = $this->getProduct();
|
212 |
}
|
213 |
|
214 |
+
return $this->getProductHelper()->getDefaultQty($product);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
215 |
}
|
216 |
|
217 |
/**
|
app/code/core/Mage/Catalog/Block/Product/View/Type/Configurable.php
CHANGED
@@ -48,6 +48,16 @@ class Mage_Catalog_Block_Product_View_Type_Configurable extends Mage_Catalog_Blo
|
|
48 |
*/
|
49 |
protected $_resPrices = array();
|
50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
/**
|
52 |
* Get allowed attributes
|
53 |
*
|
@@ -91,7 +101,10 @@ class Mage_Catalog_Block_Product_View_Type_Configurable extends Mage_Catalog_Blo
|
|
91 |
$allProducts = $this->getProduct()->getTypeInstance(true)
|
92 |
->getUsedProducts(null, $this->getProduct());
|
93 |
foreach ($allProducts as $product) {
|
94 |
-
if ($product->isSaleable()
|
|
|
|
|
|
|
95 |
$products[] = $product;
|
96 |
}
|
97 |
}
|
@@ -103,11 +116,12 @@ class Mage_Catalog_Block_Product_View_Type_Configurable extends Mage_Catalog_Blo
|
|
103 |
/**
|
104 |
* retrieve current store
|
105 |
*
|
|
|
106 |
* @return Mage_Core_Model_Store
|
107 |
*/
|
108 |
public function getCurrentStore()
|
109 |
{
|
110 |
-
return
|
111 |
}
|
112 |
|
113 |
/**
|
@@ -138,10 +152,10 @@ class Mage_Catalog_Block_Product_View_Type_Configurable extends Mage_Catalog_Blo
|
|
138 |
$preconfiguredValues = $currentProduct->getPreconfiguredValues();
|
139 |
$defaultValues = array();
|
140 |
}
|
141 |
-
|
142 |
foreach ($this->getAllowProducts() as $product) {
|
143 |
$productId = $product->getId();
|
144 |
-
|
145 |
foreach ($this->getAllowAttributes() as $attribute) {
|
146 |
$productAttribute = $attribute->getProductAttribute();
|
147 |
$productAttributeId = $productAttribute->getId();
|
@@ -189,7 +203,13 @@ class Mage_Catalog_Block_Product_View_Type_Configurable extends Mage_Catalog_Blo
|
|
189 |
$configurablePrice = $currentProduct->getConfigurablePrice();
|
190 |
|
191 |
if (isset($options[$attributeId][$value['value_index']])) {
|
192 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
} else {
|
194 |
$productsIndex = array();
|
195 |
}
|
@@ -300,64 +320,51 @@ class Mage_Catalog_Block_Product_View_Type_Configurable extends Mage_Catalog_Blo
|
|
300 |
/**
|
301 |
* Calculation real price
|
302 |
*
|
|
|
303 |
* @param float $price
|
304 |
* @param bool $isPercent
|
305 |
* @return mixed
|
306 |
*/
|
307 |
protected function _preparePrice($price, $isPercent = false)
|
308 |
{
|
309 |
-
|
310 |
-
$price = $this->getProduct()->getFinalPrice() * $price / 100;
|
311 |
-
}
|
312 |
-
|
313 |
-
return $this->_registerJsPrice($this->_convertPrice($price, true));
|
314 |
}
|
315 |
|
316 |
/**
|
317 |
* Calculation price before special price
|
318 |
*
|
|
|
319 |
* @param float $price
|
320 |
* @param bool $isPercent
|
321 |
* @return mixed
|
322 |
*/
|
323 |
protected function _prepareOldPrice($price, $isPercent = false)
|
324 |
{
|
325 |
-
|
326 |
-
$price = $this->getProduct()->getPrice() * $price / 100;
|
327 |
-
}
|
328 |
-
|
329 |
-
return $this->_registerJsPrice($this->_convertPrice($price, true));
|
330 |
}
|
331 |
|
332 |
/**
|
333 |
* Replace ',' on '.' for js
|
334 |
*
|
|
|
335 |
* @param float $price
|
336 |
* @return string
|
337 |
*/
|
338 |
protected function _registerJsPrice($price)
|
339 |
{
|
340 |
-
return
|
341 |
}
|
342 |
|
343 |
/**
|
344 |
* Convert price from default currency to current currency
|
345 |
*
|
|
|
346 |
* @param float $price
|
347 |
* @param boolean $round
|
348 |
* @return float
|
349 |
*/
|
350 |
protected function _convertPrice($price, $round = false)
|
351 |
{
|
352 |
-
|
353 |
-
return 0;
|
354 |
-
}
|
355 |
-
|
356 |
-
$price = $this->getCurrentStore()->convertPrice($price);
|
357 |
-
if ($round) {
|
358 |
-
$price = $this->getCurrentStore()->roundPrice($price);
|
359 |
-
}
|
360 |
-
|
361 |
-
return $price;
|
362 |
}
|
363 |
}
|
48 |
*/
|
49 |
protected $_resPrices = array();
|
50 |
|
51 |
+
/**
|
52 |
+
* Get helper for calculation purposes
|
53 |
+
*
|
54 |
+
* @return Mage_Catalog_Helper_Product_Type_Composite
|
55 |
+
*/
|
56 |
+
protected function _getHelper()
|
57 |
+
{
|
58 |
+
return $this->helper('catalog/product_type_composite');
|
59 |
+
}
|
60 |
+
|
61 |
/**
|
62 |
* Get allowed attributes
|
63 |
*
|
101 |
$allProducts = $this->getProduct()->getTypeInstance(true)
|
102 |
->getUsedProducts(null, $this->getProduct());
|
103 |
foreach ($allProducts as $product) {
|
104 |
+
if ($product->isSaleable()
|
105 |
+
|| $skipSaleableCheck
|
106 |
+
|| (!$product->getStockItem()->getIsInStock()
|
107 |
+
&& Mage::helper('cataloginventory')->isShowOutOfStock())) {
|
108 |
$products[] = $product;
|
109 |
}
|
110 |
}
|
116 |
/**
|
117 |
* retrieve current store
|
118 |
*
|
119 |
+
* @deprecated
|
120 |
* @return Mage_Core_Model_Store
|
121 |
*/
|
122 |
public function getCurrentStore()
|
123 |
{
|
124 |
+
return $this->_getHelper()->getCurrentStore();
|
125 |
}
|
126 |
|
127 |
/**
|
152 |
$preconfiguredValues = $currentProduct->getPreconfiguredValues();
|
153 |
$defaultValues = array();
|
154 |
}
|
155 |
+
$productStock = array();
|
156 |
foreach ($this->getAllowProducts() as $product) {
|
157 |
$productId = $product->getId();
|
158 |
+
$productStock[$productId] = $product->getStockItem()->getIsInStock();
|
159 |
foreach ($this->getAllowAttributes() as $attribute) {
|
160 |
$productAttribute = $attribute->getProductAttribute();
|
161 |
$productAttributeId = $productAttribute->getId();
|
203 |
$configurablePrice = $currentProduct->getConfigurablePrice();
|
204 |
|
205 |
if (isset($options[$attributeId][$value['value_index']])) {
|
206 |
+
$productsIndexOptions = $options[$attributeId][$value['value_index']];
|
207 |
+
$productsIndex = array();
|
208 |
+
foreach ($productsIndexOptions as $productIndex) {
|
209 |
+
if ($productStock[$productIndex]) {
|
210 |
+
$productsIndex[] = $productIndex;
|
211 |
+
}
|
212 |
+
}
|
213 |
} else {
|
214 |
$productsIndex = array();
|
215 |
}
|
320 |
/**
|
321 |
* Calculation real price
|
322 |
*
|
323 |
+
* @deprecated
|
324 |
* @param float $price
|
325 |
* @param bool $isPercent
|
326 |
* @return mixed
|
327 |
*/
|
328 |
protected function _preparePrice($price, $isPercent = false)
|
329 |
{
|
330 |
+
return $this->_getHelper()->preparePrice($this->getProduct(), $price, $isPercent);
|
|
|
|
|
|
|
|
|
331 |
}
|
332 |
|
333 |
/**
|
334 |
* Calculation price before special price
|
335 |
*
|
336 |
+
* @deprecated
|
337 |
* @param float $price
|
338 |
* @param bool $isPercent
|
339 |
* @return mixed
|
340 |
*/
|
341 |
protected function _prepareOldPrice($price, $isPercent = false)
|
342 |
{
|
343 |
+
return $this->_getHelper()->prepareOldPrice($this->getProduct(), $price, $isPercent);
|
|
|
|
|
|
|
|
|
344 |
}
|
345 |
|
346 |
/**
|
347 |
* Replace ',' on '.' for js
|
348 |
*
|
349 |
+
* @deprecated
|
350 |
* @param float $price
|
351 |
* @return string
|
352 |
*/
|
353 |
protected function _registerJsPrice($price)
|
354 |
{
|
355 |
+
return $this->_getHelper()->registerJsPrice($price);
|
356 |
}
|
357 |
|
358 |
/**
|
359 |
* Convert price from default currency to current currency
|
360 |
*
|
361 |
+
* @deprecated
|
362 |
* @param float $price
|
363 |
* @param boolean $round
|
364 |
* @return float
|
365 |
*/
|
366 |
protected function _convertPrice($price, $round = false)
|
367 |
{
|
368 |
+
return $this->_getHelper()->convertPrice($price, $round);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
369 |
}
|
370 |
}
|
app/code/core/Mage/Catalog/Helper/Image.php
CHANGED
@@ -33,6 +33,7 @@ class Mage_Catalog_Helper_Image extends Mage_Core_Helper_Abstract
|
|
33 |
{
|
34 |
const XML_NODE_PRODUCT_BASE_IMAGE_WIDTH = 'catalog/product_image/base_width';
|
35 |
const XML_NODE_PRODUCT_SMALL_IMAGE_WIDTH = 'catalog/product_image/small_width';
|
|
|
36 |
|
37 |
/**
|
38 |
* Current model
|
@@ -634,10 +635,16 @@ class Mage_Catalog_Helper_Image extends Mage_Core_Helper_Abstract
|
|
634 |
* @throws Mage_Core_Exception
|
635 |
*/
|
636 |
public function validateUploadFile($filePath) {
|
637 |
-
|
|
|
|
|
638 |
Mage::throwException($this->__('Disallowed file type.'));
|
639 |
}
|
640 |
|
|
|
|
|
|
|
|
|
641 |
$_processor = new Varien_Image($filePath);
|
642 |
return $_processor->getMimeType() !== null;
|
643 |
}
|
33 |
{
|
34 |
const XML_NODE_PRODUCT_BASE_IMAGE_WIDTH = 'catalog/product_image/base_width';
|
35 |
const XML_NODE_PRODUCT_SMALL_IMAGE_WIDTH = 'catalog/product_image/small_width';
|
36 |
+
const XML_NODE_PRODUCT_MAX_DIMENSION = 'catalog/product_image/max_dimension';
|
37 |
|
38 |
/**
|
39 |
* Current model
|
635 |
* @throws Mage_Core_Exception
|
636 |
*/
|
637 |
public function validateUploadFile($filePath) {
|
638 |
+
$maxDimension = Mage::getStoreConfig(self::XML_NODE_PRODUCT_MAX_DIMENSION);
|
639 |
+
$imageInfo = getimagesize($filePath);
|
640 |
+
if (!$imageInfo) {
|
641 |
Mage::throwException($this->__('Disallowed file type.'));
|
642 |
}
|
643 |
|
644 |
+
if ($imageInfo[0] > $maxDimension || $imageInfo[1] > $maxDimension) {
|
645 |
+
Mage::throwException($this->__('Disalollowed file format.'));
|
646 |
+
}
|
647 |
+
|
648 |
$_processor = new Varien_Image($filePath);
|
649 |
return $_processor->getMimeType() !== null;
|
650 |
}
|
app/code/core/Mage/Catalog/Helper/Product.php
CHANGED
@@ -35,6 +35,8 @@ class Mage_Catalog_Helper_Product extends Mage_Core_Helper_Url
|
|
35 |
const XML_PATH_PRODUCT_URL_USE_CATEGORY = 'catalog/seo/product_use_categories';
|
36 |
const XML_PATH_USE_PRODUCT_CANONICAL_TAG = 'catalog/seo/product_canonical_tag';
|
37 |
|
|
|
|
|
38 |
/**
|
39 |
* Flag that shows if Magento has to check product to be saleable (enabled and/or inStock)
|
40 |
*
|
@@ -485,4 +487,42 @@ class Mage_Catalog_Helper_Product extends Mage_Core_Helper_Url
|
|
485 |
{
|
486 |
return $this->_skipSaleableCheck;
|
487 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
488 |
}
|
35 |
const XML_PATH_PRODUCT_URL_USE_CATEGORY = 'catalog/seo/product_use_categories';
|
36 |
const XML_PATH_USE_PRODUCT_CANONICAL_TAG = 'catalog/seo/product_canonical_tag';
|
37 |
|
38 |
+
const DEFAULT_QTY = 1;
|
39 |
+
|
40 |
/**
|
41 |
* Flag that shows if Magento has to check product to be saleable (enabled and/or inStock)
|
42 |
*
|
487 |
{
|
488 |
return $this->_skipSaleableCheck;
|
489 |
}
|
490 |
+
|
491 |
+
/**
|
492 |
+
* Gets minimal sales quantity
|
493 |
+
*
|
494 |
+
* @param Mage_Catalog_Model_Product $product
|
495 |
+
* @return int|null
|
496 |
+
*/
|
497 |
+
public function getMinimalQty($product)
|
498 |
+
{
|
499 |
+
$stockItem = $product->getStockItem();
|
500 |
+
if ($stockItem && $stockItem->getMinSaleQty()) {
|
501 |
+
return $stockItem->getMinSaleQty() * 1;
|
502 |
+
}
|
503 |
+
return null;
|
504 |
+
}
|
505 |
+
|
506 |
+
/**
|
507 |
+
* Get default qty - either as preconfigured, or as 1.
|
508 |
+
* Also restricts it by minimal qty.
|
509 |
+
*
|
510 |
+
* @param Mage_Catalog_Model_Product $product
|
511 |
+
* @return int|float
|
512 |
+
*/
|
513 |
+
public function getDefaultQty($product)
|
514 |
+
{
|
515 |
+
$qty = $this->getMinimalQty($product);
|
516 |
+
$configQty = $product->getPreconfiguredValues()->getQty();
|
517 |
+
|
518 |
+
if ($product->isConfigurable() || $configQty > $qty) {
|
519 |
+
$qty = $configQty;
|
520 |
+
}
|
521 |
+
|
522 |
+
if (is_null($qty)) {
|
523 |
+
$qty = self::DEFAULT_QTY;
|
524 |
+
}
|
525 |
+
|
526 |
+
return $qty;
|
527 |
+
}
|
528 |
}
|
app/code/core/Mage/Catalog/Helper/Product/Type/Composite.php
ADDED
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Catalog
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Helper for preparing properties for configurable product
|
29 |
+
*
|
30 |
+
* @category Mage
|
31 |
+
* @package Mage_Catalog
|
32 |
+
* @author Magento Core Team <core@magentocommerce.com>
|
33 |
+
*/
|
34 |
+
class Mage_Catalog_Helper_Product_Type_Composite extends Mage_Core_Helper_Abstract
|
35 |
+
{
|
36 |
+
/**
|
37 |
+
* Calculation real price
|
38 |
+
*
|
39 |
+
* @param Mage_Catalog_Model_Product $product
|
40 |
+
* @param float $price
|
41 |
+
* @param bool $isPercent
|
42 |
+
* @param null|int $storeId
|
43 |
+
* @return mixed
|
44 |
+
*/
|
45 |
+
public function preparePrice($product, $price, $isPercent = false, $storeId = null)
|
46 |
+
{
|
47 |
+
if ($isPercent && !empty($price)) {
|
48 |
+
$price = $product->getFinalPrice() * $price / 100;
|
49 |
+
}
|
50 |
+
|
51 |
+
return $this->registerJsPrice($this->convertPrice($price, true, $storeId));
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Calculation price before special price
|
56 |
+
*
|
57 |
+
* @param Mage_Catalog_Model_Product $product
|
58 |
+
* @param float $price
|
59 |
+
* @param bool $isPercent
|
60 |
+
* @param null|int $storeId
|
61 |
+
* @return mixed
|
62 |
+
*/
|
63 |
+
public function prepareOldPrice($product, $price, $isPercent = false, $storeId = null)
|
64 |
+
{
|
65 |
+
if ($isPercent && !empty($price)) {
|
66 |
+
$price = $product->getPrice() * $price / 100;
|
67 |
+
}
|
68 |
+
|
69 |
+
return $this->registerJsPrice($this->convertPrice($price, true, $storeId));
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Replace ',' on '.' for js
|
74 |
+
*
|
75 |
+
* @param float $price
|
76 |
+
* @return string
|
77 |
+
*/
|
78 |
+
public function registerJsPrice($price)
|
79 |
+
{
|
80 |
+
return str_replace(',', '.', $price);
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Convert price from default currency to current currency
|
85 |
+
*
|
86 |
+
* @param float $price
|
87 |
+
* @param boolean $round
|
88 |
+
* @param null|int $storeId
|
89 |
+
* @return float
|
90 |
+
*/
|
91 |
+
public function convertPrice($price, $round = false, $storeId = null)
|
92 |
+
{
|
93 |
+
if (empty($price)) {
|
94 |
+
return 0;
|
95 |
+
}
|
96 |
+
|
97 |
+
$price = $this->getCurrentStore($storeId)->convertPrice($price);
|
98 |
+
if ($round) {
|
99 |
+
$price = $this->getCurrentStore($storeId)->roundPrice($price);
|
100 |
+
}
|
101 |
+
|
102 |
+
return $price;
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Retrieve current store
|
107 |
+
*
|
108 |
+
* @param null $storeId
|
109 |
+
* @return Mage_Core_Model_Store
|
110 |
+
*/
|
111 |
+
public function getCurrentStore($storeId = null)
|
112 |
+
{
|
113 |
+
return Mage::app()->getStore($storeId);
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Prepare general params for product to be used in getJsonConfig()
|
118 |
+
* @see Mage_Catalog_Block_Product_View::getJsonConfig()
|
119 |
+
* @see Mage_ConfigurableSwatches_Block_Catalog_Product_List_Price::getJsonConfig()
|
120 |
+
*
|
121 |
+
* @return array
|
122 |
+
*/
|
123 |
+
public function prepareJsonGeneralConfig()
|
124 |
+
{
|
125 |
+
return array(
|
126 |
+
'priceFormat' => Mage::app()->getLocale()->getJsPriceFormat(),
|
127 |
+
'includeTax' => Mage::helper('tax')->priceIncludesTax() ? 'true' : 'false',
|
128 |
+
'showIncludeTax' => Mage::helper('tax')->displayPriceIncludingTax(),
|
129 |
+
'showBothPrices' => Mage::helper('tax')->displayBothPrices(),
|
130 |
+
'idSuffix' => '',
|
131 |
+
'oldPlusDisposition' => 0,
|
132 |
+
'plusDisposition' => 0,
|
133 |
+
'plusDispositionTax' => 0,
|
134 |
+
'oldMinusDisposition' => 0,
|
135 |
+
'minusDisposition' => 0,
|
136 |
+
);
|
137 |
+
}
|
138 |
+
|
139 |
+
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Prepare product specific params to be used in getJsonConfig()
|
143 |
+
* @see Mage_Catalog_Block_Product_View::getJsonConfig()
|
144 |
+
* @see Mage_ConfigurableSwatches_Block_Catalog_Product_List_Price::getJsonConfig()
|
145 |
+
*
|
146 |
+
* @param Mage_Catalog_Model_Product $product
|
147 |
+
* @return array
|
148 |
+
*/
|
149 |
+
public function prepareJsonProductConfig($product)
|
150 |
+
{
|
151 |
+
$_request = Mage::getSingleton('tax/calculation')->getDefaultRateRequest();
|
152 |
+
$_request->setProductClassId($product->getTaxClassId());
|
153 |
+
$defaultTax = Mage::getSingleton('tax/calculation')->getRate($_request);
|
154 |
+
|
155 |
+
$_request = Mage::getSingleton('tax/calculation')->getRateRequest();
|
156 |
+
$_request->setProductClassId($product->getTaxClassId());
|
157 |
+
$currentTax = Mage::getSingleton('tax/calculation')->getRate($_request);
|
158 |
+
|
159 |
+
$_regularPrice = $product->getPrice();
|
160 |
+
$_finalPrice = $product->getFinalPrice();
|
161 |
+
if ($product->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
|
162 |
+
$_priceInclTax = Mage::helper('tax')->getPrice($product, $_finalPrice, true,
|
163 |
+
null, null, null, null, null, false);
|
164 |
+
$_priceExclTax = Mage::helper('tax')->getPrice($product, $_finalPrice, false,
|
165 |
+
null, null, null, null, null, false);
|
166 |
+
} else {
|
167 |
+
$_priceInclTax = Mage::helper('tax')->getPrice($product, $_finalPrice, true);
|
168 |
+
$_priceExclTax = Mage::helper('tax')->getPrice($product, $_finalPrice);
|
169 |
+
}
|
170 |
+
$_tierPrices = array();
|
171 |
+
$_tierPricesInclTax = array();
|
172 |
+
foreach ($product->getTierPrice() as $tierPrice) {
|
173 |
+
$_tierPrices[] = Mage::helper('core')->currency(
|
174 |
+
Mage::helper('tax')->getPrice($product, (float)$tierPrice['website_price'], false) - $_priceExclTax
|
175 |
+
, false, false);
|
176 |
+
$_tierPricesInclTax[] = Mage::helper('core')->currency(
|
177 |
+
Mage::helper('tax')->getPrice($product, (float)$tierPrice['website_price'], true) - $_priceInclTax
|
178 |
+
, false, false);
|
179 |
+
}
|
180 |
+
|
181 |
+
return array(
|
182 |
+
'productId' => $product->getId(),
|
183 |
+
'productPrice' => Mage::helper('core')->currency($_finalPrice, false, false),
|
184 |
+
'productOldPrice' => Mage::helper('core')->currency($_regularPrice, false, false),
|
185 |
+
'priceInclTax' => Mage::helper('core')->currency($_priceInclTax, false, false),
|
186 |
+
'priceExclTax' => Mage::helper('core')->currency($_priceExclTax, false, false),
|
187 |
+
'skipCalculate' => ($_priceExclTax != $_priceInclTax ? 0 : 1),
|
188 |
+
'defaultTax' => $defaultTax,
|
189 |
+
'currentTax' => $currentTax,
|
190 |
+
'tierPrices' => $_tierPrices,
|
191 |
+
'tierPricesInclTax' => $_tierPricesInclTax,
|
192 |
+
'swatchPrices' => $product->getSwatchPrices(),
|
193 |
+
);
|
194 |
+
}
|
195 |
+
}
|
app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Groupprice/Abstract.php
CHANGED
@@ -227,6 +227,7 @@ abstract class Mage_Catalog_Model_Product_Attribute_Backend_Groupprice_Abstract
|
|
227 |
$data = $this->_getResource()->loadPriceData($object->getId(), $websiteId);
|
228 |
foreach ($data as $k => $v) {
|
229 |
$data[$k]['website_price'] = $v['price'];
|
|
|
230 |
if ($v['all_groups']) {
|
231 |
$data[$k]['cust_group'] = Mage_Customer_Model_Group::CUST_GROUP_ALL;
|
232 |
}
|
@@ -318,6 +319,7 @@ abstract class Mage_Catalog_Model_Product_Attribute_Backend_Groupprice_Abstract
|
|
318 |
'all_groups' => $useForAllGroups ? 1 : 0,
|
319 |
'customer_group_id' => $customerGroupId,
|
320 |
'value' => $data['price'],
|
|
|
321 |
), $this->_getAdditionalUniqueFields($data));
|
322 |
}
|
323 |
|
@@ -347,10 +349,11 @@ abstract class Mage_Catalog_Model_Product_Attribute_Backend_Groupprice_Abstract
|
|
347 |
|
348 |
if (!empty($update)) {
|
349 |
foreach ($update as $k => $v) {
|
350 |
-
if ($old[$k]['price'] != $v['value']) {
|
351 |
$price = new Varien_Object(array(
|
352 |
-
'value_id'
|
353 |
-
'value'
|
|
|
354 |
));
|
355 |
$this->_getResource()->savePriceData($price);
|
356 |
|
227 |
$data = $this->_getResource()->loadPriceData($object->getId(), $websiteId);
|
228 |
foreach ($data as $k => $v) {
|
229 |
$data[$k]['website_price'] = $v['price'];
|
230 |
+
$data[$k]['is_percent'] = isset($v['is_percent']) ? isset($v['is_percent']) : 0;
|
231 |
if ($v['all_groups']) {
|
232 |
$data[$k]['cust_group'] = Mage_Customer_Model_Group::CUST_GROUP_ALL;
|
233 |
}
|
319 |
'all_groups' => $useForAllGroups ? 1 : 0,
|
320 |
'customer_group_id' => $customerGroupId,
|
321 |
'value' => $data['price'],
|
322 |
+
'is_percent' => isset($data['is_percent']) ? $data['is_percent'] : 0,
|
323 |
), $this->_getAdditionalUniqueFields($data));
|
324 |
}
|
325 |
|
349 |
|
350 |
if (!empty($update)) {
|
351 |
foreach ($update as $k => $v) {
|
352 |
+
if ($old[$k]['price'] != $v['value'] || $old[$k]['is_percent'] != $v['is_percent']) {
|
353 |
$price = new Varien_Object(array(
|
354 |
+
'value_id' => $old[$k]['price_id'],
|
355 |
+
'value' => $v['value'],
|
356 |
+
'is_percent' => $v['is_percent']
|
357 |
));
|
358 |
$this->_getResource()->savePriceData($price);
|
359 |
|
app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Media.php
CHANGED
@@ -643,8 +643,11 @@ class Mage_Catalog_Model_Product_Attribute_Backend_Media extends Mage_Eav_Model_
|
|
643 |
|
644 |
} catch (Exception $e) {
|
645 |
$file = $this->_getConfig()->getMediaPath($file);
|
|
|
646 |
Mage::throwException(
|
647 |
-
Mage::helper('catalog')->__(
|
|
|
|
|
648 |
);
|
649 |
}
|
650 |
|
643 |
|
644 |
} catch (Exception $e) {
|
645 |
$file = $this->_getConfig()->getMediaPath($file);
|
646 |
+
$io = new Varien_Io_File();
|
647 |
Mage::throwException(
|
648 |
+
Mage::helper('catalog')->__(
|
649 |
+
'Failed to copy file %s. Please, delete media with non-existing images and try again.',
|
650 |
+
$io->getFilteredPath($file))
|
651 |
);
|
652 |
}
|
653 |
|
app/code/core/Mage/Catalog/Model/Product/Link/Api/V2.php
CHANGED
@@ -61,8 +61,8 @@ class Mage_Catalog_Model_Product_Link_Api_V2 extends Mage_Catalog_Model_Product_
|
|
61 |
|
62 |
$links[(int)$linkedProductId] = array();
|
63 |
foreach ($collection->getLinkModel()->getAttributes() as $attribute) {
|
64 |
-
if (isset($data
|
65 |
-
$links[(int)$linkedProductId][$attribute['code']] = $data
|
66 |
}
|
67 |
}
|
68 |
|
@@ -118,8 +118,8 @@ class Mage_Catalog_Model_Product_Link_Api_V2 extends Mage_Catalog_Model_Product_
|
|
118 |
}
|
119 |
|
120 |
foreach ($collection->getLinkModel()->getAttributes() as $attribute) {
|
121 |
-
if (isset($data
|
122 |
-
$links[(int)$linkedProductId][$attribute['code']] = $data
|
123 |
}
|
124 |
}
|
125 |
|
61 |
|
62 |
$links[(int)$linkedProductId] = array();
|
63 |
foreach ($collection->getLinkModel()->getAttributes() as $attribute) {
|
64 |
+
if (isset($data->{$attribute['code']})) {
|
65 |
+
$links[(int)$linkedProductId][$attribute['code']] = $data->{$attribute['code']};
|
66 |
}
|
67 |
}
|
68 |
|
118 |
}
|
119 |
|
120 |
foreach ($collection->getLinkModel()->getAttributes() as $attribute) {
|
121 |
+
if (isset($data->{$attribute['code']})) {
|
122 |
+
$links[(int)$linkedProductId][$attribute['code']] = $data->{$attribute['code']};
|
123 |
}
|
124 |
}
|
125 |
|
app/code/core/Mage/Catalog/Model/Resource/Eav/Attribute.php
CHANGED
@@ -359,7 +359,7 @@ class Mage_Catalog_Model_Resource_Eav_Attribute extends Mage_Eav_Model_Entity_At
|
|
359 |
|
360 |
if ($backendType == 'int' && $frontendInput == 'select') {
|
361 |
return true;
|
362 |
-
} else if ($backendType == 'varchar' && $frontendInput == 'multiselect') {
|
363 |
return true;
|
364 |
} else if ($backendType == 'decimal') {
|
365 |
return true;
|
359 |
|
360 |
if ($backendType == 'int' && $frontendInput == 'select') {
|
361 |
return true;
|
362 |
+
} else if (($backendType == 'varchar' || $backendType == 'text') && $frontendInput == 'multiselect') {
|
363 |
return true;
|
364 |
} else if ($backendType == 'decimal') {
|
365 |
return true;
|
app/code/core/Mage/Catalog/Model/Resource/Product/Attribute/Backend/Groupprice.php
CHANGED
@@ -43,4 +43,17 @@ class Mage_Catalog_Model_Resource_Product_Attribute_Backend_Groupprice
|
|
43 |
{
|
44 |
$this->_init('catalog/product_attribute_group_price', 'value_id');
|
45 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
}
|
43 |
{
|
44 |
$this->_init('catalog/product_attribute_group_price', 'value_id');
|
45 |
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Add is_percent column
|
49 |
+
*
|
50 |
+
* @param array $columns
|
51 |
+
* @return array
|
52 |
+
*/
|
53 |
+
protected function _loadPriceDataColumns($columns)
|
54 |
+
{
|
55 |
+
$columns = parent::_loadPriceDataColumns($columns);
|
56 |
+
$columns['is_percent'] = 'is_percent';
|
57 |
+
return $columns;
|
58 |
+
}
|
59 |
}
|
app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Eav/Source.php
CHANGED
@@ -61,7 +61,7 @@ class Mage_Catalog_Model_Resource_Product_Indexer_Eav_Source
|
|
61 |
->where($this->_getIndexableAttributesCondition());
|
62 |
|
63 |
if ($multiSelect == true) {
|
64 |
-
$select->where('ea.backend_type = ?', '
|
65 |
->where('ea.frontend_input = ?', 'multiselect');
|
66 |
} else {
|
67 |
$select->where('ea.backend_type = ?', 'int')
|
@@ -203,14 +203,14 @@ class Mage_Catalog_Model_Resource_Product_Indexer_Eav_Source
|
|
203 |
$productValueExpression = $adapter->getCheckSql('pvs.value_id > 0', 'pvs.value', 'pvd.value');
|
204 |
$select = $adapter->select()
|
205 |
->from(
|
206 |
-
array('pvd' => $this->getValueTable('catalog/product', '
|
207 |
array('entity_id', 'attribute_id'))
|
208 |
->join(
|
209 |
array('cs' => $this->getTable('core/store')),
|
210 |
'',
|
211 |
array('store_id'))
|
212 |
->joinLeft(
|
213 |
-
array('pvs' => $this->getValueTable('catalog/product', '
|
214 |
'pvs.entity_id = pvd.entity_id AND pvs.attribute_id = pvd.attribute_id'
|
215 |
. ' AND pvs.store_id=cs.store_id',
|
216 |
array('value' => $productValueExpression))
|
61 |
->where($this->_getIndexableAttributesCondition());
|
62 |
|
63 |
if ($multiSelect == true) {
|
64 |
+
$select->where('ea.backend_type = ?', 'text')
|
65 |
->where('ea.frontend_input = ?', 'multiselect');
|
66 |
} else {
|
67 |
$select->where('ea.backend_type = ?', 'int')
|
203 |
$productValueExpression = $adapter->getCheckSql('pvs.value_id > 0', 'pvs.value', 'pvd.value');
|
204 |
$select = $adapter->select()
|
205 |
->from(
|
206 |
+
array('pvd' => $this->getValueTable('catalog/product', 'text')),
|
207 |
array('entity_id', 'attribute_id'))
|
208 |
->join(
|
209 |
array('cs' => $this->getTable('core/store')),
|
210 |
'',
|
211 |
array('store_id'))
|
212 |
->joinLeft(
|
213 |
+
array('pvs' => $this->getValueTable('catalog/product', 'text')),
|
214 |
'pvs.entity_id = pvd.entity_id AND pvs.attribute_id = pvd.attribute_id'
|
215 |
. ' AND pvs.store_id=cs.store_id',
|
216 |
array('value' => $productValueExpression))
|
app/code/core/Mage/Catalog/Model/Resource/Product/Link/Product/Collection.php
CHANGED
@@ -282,6 +282,19 @@ class Mage_Catalog_Model_Resource_Product_Link_Product_Collection extends Mage_C
|
|
282 |
return $this;
|
283 |
}
|
284 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
285 |
/**
|
286 |
* Join attributes
|
287 |
*
|
@@ -294,10 +307,9 @@ class Mage_Catalog_Model_Resource_Product_Link_Product_Collection extends Mage_C
|
|
294 |
}
|
295 |
$attributes = $this->getLinkModel()->getAttributes();
|
296 |
|
297 |
-
$attributesByType = array();
|
298 |
foreach ($attributes as $attribute) {
|
299 |
$table = $this->getLinkModel()->getAttributeTypeTable($attribute['type']);
|
300 |
-
$alias =
|
301 |
|
302 |
$joinCondiotion = array(
|
303 |
"{$alias}.link_id = links.link_id",
|
@@ -331,4 +343,38 @@ class Mage_Catalog_Model_Resource_Product_Link_Product_Collection extends Mage_C
|
|
331 |
}
|
332 |
return parent::setOrder($attribute, $dir);
|
333 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
334 |
}
|
282 |
return $this;
|
283 |
}
|
284 |
|
285 |
+
/**
|
286 |
+
* Get table alias for link model attribute
|
287 |
+
*
|
288 |
+
* @param string $attributeCode
|
289 |
+
* @param string $attributeType
|
290 |
+
*
|
291 |
+
* @return string
|
292 |
+
*/
|
293 |
+
protected function _getLinkAttributeTableAlias($attributeCode, $attributeType)
|
294 |
+
{
|
295 |
+
return sprintf('link_attribute_%s_%s', $attributeCode, $attributeType);
|
296 |
+
}
|
297 |
+
|
298 |
/**
|
299 |
* Join attributes
|
300 |
*
|
307 |
}
|
308 |
$attributes = $this->getLinkModel()->getAttributes();
|
309 |
|
|
|
310 |
foreach ($attributes as $attribute) {
|
311 |
$table = $this->getLinkModel()->getAttributeTypeTable($attribute['type']);
|
312 |
+
$alias = $this->_getLinkAttributeTableAlias($attribute['code'], $attribute['type']);
|
313 |
|
314 |
$joinCondiotion = array(
|
315 |
"{$alias}.link_id = links.link_id",
|
343 |
}
|
344 |
return parent::setOrder($attribute, $dir);
|
345 |
}
|
346 |
+
|
347 |
+
/**
|
348 |
+
* Add specific link model attribute to collection filter
|
349 |
+
*
|
350 |
+
* @param string $attributeCode
|
351 |
+
* @param array|null $condition
|
352 |
+
*
|
353 |
+
* @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
|
354 |
+
*/
|
355 |
+
public function addLinkModelFieldToFilter($attributeCode, $condition = null)
|
356 |
+
{
|
357 |
+
if (!$this->getProduct() || !$this->getProduct()->getId()) {
|
358 |
+
return $this;
|
359 |
+
}
|
360 |
+
|
361 |
+
$attribute = null;
|
362 |
+
foreach ($this->getLinkModel()->getAttributes() as $attributeData) {
|
363 |
+
if ($attributeData['code'] == $attributeCode) {
|
364 |
+
$attribute = $attributeData;
|
365 |
+
break;
|
366 |
+
}
|
367 |
+
}
|
368 |
+
|
369 |
+
if (!$attribute) {
|
370 |
+
return $this;
|
371 |
+
}
|
372 |
+
|
373 |
+
$this->_hasLinkFilter = true;
|
374 |
+
|
375 |
+
$field = $this->_getLinkAttributeTableAlias($attribute['code'], $attribute['type']) . '.value';
|
376 |
+
$this->getSelect()->where($this->_getConditionSql($field, $condition));
|
377 |
+
|
378 |
+
return $this;
|
379 |
+
}
|
380 |
}
|
app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
CHANGED
@@ -241,7 +241,7 @@ class Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
|
|
241 |
}
|
242 |
|
243 |
$values = array();
|
244 |
-
|
245 |
foreach ($this->_items as $item) {
|
246 |
$productAttribute = $item->getProductAttribute();
|
247 |
if (!($productAttribute instanceof Mage_Eav_Model_Entity_Attribute_Abstract)) {
|
@@ -251,7 +251,7 @@ class Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
|
|
251 |
|
252 |
$optionsByValue = array();
|
253 |
foreach ($options as $option) {
|
254 |
-
$optionsByValue[$option['value']] = $option['label'];
|
255 |
}
|
256 |
|
257 |
foreach ($this->getProduct()->getTypeInstance(true)
|
@@ -267,18 +267,23 @@ class Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
|
|
267 |
$values[$item->getId() . ':' . $optionValue] = array(
|
268 |
'product_super_attribute_id' => $item->getId(),
|
269 |
'value_index' => $optionValue,
|
270 |
-
'label' => $optionsByValue[$optionValue],
|
271 |
-
'default_label' => $optionsByValue[$optionValue],
|
272 |
-
'store_label' => $optionsByValue[$optionValue],
|
273 |
'is_percent' => 0,
|
274 |
'pricing_value' => null,
|
275 |
-
'use_default_value' => true
|
|
|
276 |
);
|
277 |
}
|
278 |
}
|
279 |
}
|
280 |
}
|
281 |
|
|
|
|
|
|
|
|
|
282 |
foreach ($pricings[0] as $pricing) {
|
283 |
// Addding pricing to options
|
284 |
$valueKey = $pricing['product_super_attribute_id'] . ':' . $pricing['value_index'];
|
241 |
}
|
242 |
|
243 |
$values = array();
|
244 |
+
$sortOrder = 1;
|
245 |
foreach ($this->_items as $item) {
|
246 |
$productAttribute = $item->getProductAttribute();
|
247 |
if (!($productAttribute instanceof Mage_Eav_Model_Entity_Attribute_Abstract)) {
|
251 |
|
252 |
$optionsByValue = array();
|
253 |
foreach ($options as $option) {
|
254 |
+
$optionsByValue[$option['value']] = array('label' => $option['label'], 'order' => $sortOrder++);
|
255 |
}
|
256 |
|
257 |
foreach ($this->getProduct()->getTypeInstance(true)
|
267 |
$values[$item->getId() . ':' . $optionValue] = array(
|
268 |
'product_super_attribute_id' => $item->getId(),
|
269 |
'value_index' => $optionValue,
|
270 |
+
'label' => $optionsByValue[$optionValue]['label'],
|
271 |
+
'default_label' => $optionsByValue[$optionValue]['label'],
|
272 |
+
'store_label' => $optionsByValue[$optionValue]['label'],
|
273 |
'is_percent' => 0,
|
274 |
'pricing_value' => null,
|
275 |
+
'use_default_value' => true,
|
276 |
+
'order' => $optionsByValue[$optionValue]['order']
|
277 |
);
|
278 |
}
|
279 |
}
|
280 |
}
|
281 |
}
|
282 |
|
283 |
+
uasort($values, function($a, $b) {
|
284 |
+
return $a['order'] - $b['order'];
|
285 |
+
});
|
286 |
+
|
287 |
foreach ($pricings[0] as $pricing) {
|
288 |
// Addding pricing to options
|
289 |
$valueKey = $pricing['product_super_attribute_id'] . ':' . $pricing['value_index'];
|
app/code/core/Mage/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.19.1.3-1.6.0.0.19.1.4.php
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Catalog
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
/** @var $installer Mage_Catalog_Model_Resource_Setup */
|
27 |
+
|
28 |
+
$installer = $this;
|
29 |
+
$installer->startSetup();
|
30 |
+
$connection = $installer->getConnection();
|
31 |
+
|
32 |
+
$catalogProductEntityTypeId = Mage::getSingleton('eav/config')->getEntityType('catalog_product')->getEntityTypeId();
|
33 |
+
|
34 |
+
$attributes = Mage::getResourceModel('eav/entity_attribute_collection')
|
35 |
+
->addFieldToFilter('frontend_input', 'multiselect')
|
36 |
+
->addFieldToFilter('entity_type_id', $catalogProductEntityTypeId)
|
37 |
+
->getItems();
|
38 |
+
|
39 |
+
foreach ($attributes as $attribute) {
|
40 |
+
$entityTypeId = $attribute->getEntityTypeId();
|
41 |
+
$attributeId = $attribute->getId();
|
42 |
+
$attributeTableOld = $installer->getAttributeTable($entityTypeId, $attributeId);
|
43 |
+
|
44 |
+
$installer->updateAttribute($entityTypeId, $attributeId, 'backend_type', 'text');
|
45 |
+
|
46 |
+
$attributeTableNew = $installer->getAttributeTable($entityTypeId, $attributeId);
|
47 |
+
|
48 |
+
if ($attributeTableOld != $attributeTableNew) {
|
49 |
+
$connection->disableTableKeys($attributeTableOld)
|
50 |
+
->disableTableKeys($attributeTableNew);
|
51 |
+
|
52 |
+
$select = $connection->select()
|
53 |
+
->from($attributeTableOld, array('entity_type_id', 'attribute_id', 'store_id', 'entity_id', 'value'))
|
54 |
+
->where('entity_type_id = ?', $entityTypeId)
|
55 |
+
->where('attribute_id = ?', $attributeId);
|
56 |
+
|
57 |
+
$query = $select->insertFromSelect($attributeTableNew,
|
58 |
+
array('entity_type_id', 'attribute_id', 'store_id', 'entity_id', 'value')
|
59 |
+
);
|
60 |
+
|
61 |
+
$connection->query($query);
|
62 |
+
|
63 |
+
$connection->delete($attributeTableOld,
|
64 |
+
$connection->quoteInto('entity_type_id = ?', $entityTypeId)
|
65 |
+
. $connection->quoteInto(' AND attribute_id = ?', $attributeId)
|
66 |
+
);
|
67 |
+
|
68 |
+
$connection->enableTableKeys($attributeTableOld)
|
69 |
+
->enableTableKeys($attributeTableNew);
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
Mage::getModel('index/indexer')
|
74 |
+
->getProcessByCode(Mage_Catalog_Helper_Product_Flat::CATALOG_FLAT_PROCESS_CODE)
|
75 |
+
->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
|
76 |
+
|
77 |
+
$installer->endSetup();
|
app/code/core/Mage/Catalog/etc/config.xml
CHANGED
@@ -28,7 +28,7 @@
|
|
28 |
<config>
|
29 |
<modules>
|
30 |
<Mage_Catalog>
|
31 |
-
<version>1.6.0.0.19.1.
|
32 |
</Mage_Catalog>
|
33 |
</modules>
|
34 |
<admin>
|
@@ -807,6 +807,7 @@
|
|
807 |
<product_image>
|
808 |
<base_width>1800</base_width>
|
809 |
<small_width>210</small_width>
|
|
|
810 |
</product_image>
|
811 |
<seo>
|
812 |
<product_url_suffix>.html</product_url_suffix>
|
28 |
<config>
|
29 |
<modules>
|
30 |
<Mage_Catalog>
|
31 |
+
<version>1.6.0.0.19.1.5</version>
|
32 |
</Mage_Catalog>
|
33 |
</modules>
|
34 |
<admin>
|
807 |
<product_image>
|
808 |
<base_width>1800</base_width>
|
809 |
<small_width>210</small_width>
|
810 |
+
<max_dimension>5000</max_dimension>
|
811 |
</product_image>
|
812 |
<seo>
|
813 |
<product_url_suffix>.html</product_url_suffix>
|
app/code/core/Mage/Catalog/etc/system.xml
CHANGED
@@ -211,6 +211,15 @@
|
|
211 |
<show_in_website>1</show_in_website>
|
212 |
<show_in_store>1</show_in_store>
|
213 |
</small_width>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
214 |
</fields>
|
215 |
</product_image>
|
216 |
<placeholder translate="label">
|
211 |
<show_in_website>1</show_in_website>
|
212 |
<show_in_store>1</show_in_store>
|
213 |
</small_width>
|
214 |
+
<max_dimension translate="label comment">
|
215 |
+
<label>Maximum resolution for upload image</label>
|
216 |
+
<comment>Maximum width and height resolutions for upload image</comment>
|
217 |
+
<frontend_type>text</frontend_type>
|
218 |
+
<sort_order>30</sort_order>
|
219 |
+
<show_in_default>1</show_in_default>
|
220 |
+
<show_in_website>1</show_in_website>
|
221 |
+
<show_in_store>1</show_in_store>
|
222 |
+
</max_dimension>
|
223 |
</fields>
|
224 |
</product_image>
|
225 |
<placeholder translate="label">
|
app/code/core/Mage/Catalog/sql/catalog_setup/upgrade-1.6.0.0.19.1.2-1.6.0.0.19.1.3.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Catalog
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
$installer = $this;
|
28 |
+
/** @var $installer Mage_Catalog_Model_Resource_Setup */
|
29 |
+
|
30 |
+
$attribute = 'special_price';
|
31 |
+
$installer
|
32 |
+
->updateAttribute(
|
33 |
+
Mage_Catalog_Model_Product::ENTITY,
|
34 |
+
'special_price',
|
35 |
+
'note',
|
36 |
+
NULL
|
37 |
+
)
|
38 |
+
->updateAttribute(
|
39 |
+
Mage_Catalog_Model_Product::ENTITY,
|
40 |
+
'special_price',
|
41 |
+
'frontend_class',
|
42 |
+
'validate-special-price'
|
43 |
+
)
|
44 |
+
;
|
app/code/core/Mage/Catalog/sql/catalog_setup/upgrade-1.6.0.0.19.1.4-1.6.0.0.19.1.5.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Catalog
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
/** @var $installer Mage_Catalog_Model_Resource_Setup */
|
28 |
+
$installer = $this;
|
29 |
+
$connection = $installer->getConnection();
|
30 |
+
|
31 |
+
$connection->addColumn($installer->getTable('catalog/product_attribute_group_price'), 'is_percent', array(
|
32 |
+
'type' => Varien_Db_Ddl_Table::TYPE_SMALLINT,
|
33 |
+
'unsigned' => true,
|
34 |
+
'nullable' => false,
|
35 |
+
'default' => '0',
|
36 |
+
'comment' => 'Is Percent',
|
37 |
+
));
|
app/code/core/Mage/CatalogInventory/Model/Observer.php
CHANGED
@@ -384,6 +384,7 @@ class Mage_CatalogInventory_Model_Observer
|
|
384 |
$stockItem = $option->getProduct()->getStockItem();
|
385 |
|
386 |
if ($quoteItem->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
|
|
|
387 |
$stockItem->setProductName($quoteItem->getName());
|
388 |
}
|
389 |
|
384 |
$stockItem = $option->getProduct()->getStockItem();
|
385 |
|
386 |
if ($quoteItem->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
|
387 |
+
$stockItem->setParentItem($quoteItem);
|
388 |
$stockItem->setProductName($quoteItem->getName());
|
389 |
}
|
390 |
|
app/code/core/Mage/CatalogInventory/Model/Stock/Item.php
CHANGED
@@ -525,6 +525,27 @@ class Mage_CatalogInventory_Model_Stock_Item extends Mage_Core_Model_Abstract
|
|
525 |
$qty = Mage::app()->getLocale()->getNumber($qty);
|
526 |
}
|
527 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
528 |
/**
|
529 |
* Check quantity type
|
530 |
*/
|
525 |
$qty = Mage::app()->getLocale()->getNumber($qty);
|
526 |
}
|
527 |
|
528 |
+
/**
|
529 |
+
* Check if child product assigned to parent
|
530 |
+
*/
|
531 |
+
$parentItem = $this->getParentItem();
|
532 |
+
if ($this->getIsChildItem() && !empty($parentItem)) {
|
533 |
+
$typeInstance = $parentItem->getProduct()->getTypeInstance(true);
|
534 |
+
$requiredChildrenIds = $typeInstance->getChildrenIds($parentItem->getProductId(), true);
|
535 |
+
$childrenIds = array();
|
536 |
+
foreach ($requiredChildrenIds as $groupedChildrenIds) {
|
537 |
+
$childrenIds = array_merge($childrenIds, $groupedChildrenIds);
|
538 |
+
}
|
539 |
+
if (!in_array($this->getProductId(), $childrenIds)) {
|
540 |
+
$result->setHasError(true)
|
541 |
+
->setMessage(Mage::helper('cataloginventory')
|
542 |
+
->__('This product with current option is not available'))
|
543 |
+
->setQuoteMessage(Mage::helper('cataloginventory')->__('Some of the products are not available'))
|
544 |
+
->setQuoteMessageIndex('stock');
|
545 |
+
return $result;
|
546 |
+
}
|
547 |
+
}
|
548 |
+
|
549 |
/**
|
550 |
* Check quantity type
|
551 |
*/
|
app/code/core/Mage/CatalogRule/Model/Action/Index/Refresh.php
CHANGED
@@ -319,8 +319,16 @@ class Mage_CatalogRule_Model_Action_Index_Refresh
|
|
319 |
);
|
320 |
$priceColumn = $this->_connection->getIfNullSql(
|
321 |
$this->_connection->getIfNullSql(
|
322 |
-
|
323 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
),
|
325 |
'p.price'
|
326 |
);
|
@@ -343,8 +351,22 @@ class Mage_CatalogRule_Model_Action_Index_Refresh
|
|
343 |
);
|
344 |
$priceColumn = $this->_connection->getIfNullSql(
|
345 |
$this->_connection->getIfNullSql(
|
346 |
-
|
347 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
348 |
),
|
349 |
$this->_connection->getIfNullSql(
|
350 |
'p.value',
|
319 |
);
|
320 |
$priceColumn = $this->_connection->getIfNullSql(
|
321 |
$this->_connection->getIfNullSql(
|
322 |
+
$this->_connection->getCheckSql(
|
323 |
+
'pg.is_percent = 1',
|
324 |
+
'p.price * (100 - pg.value)/100',
|
325 |
+
'pg.value'
|
326 |
+
),
|
327 |
+
$this->_connection->getCheckSql(
|
328 |
+
'pgd.is_percent = 1',
|
329 |
+
'p.price * (100 - pgd.value)/100',
|
330 |
+
'pgd.value'
|
331 |
+
)
|
332 |
),
|
333 |
'p.price'
|
334 |
);
|
351 |
);
|
352 |
$priceColumn = $this->_connection->getIfNullSql(
|
353 |
$this->_connection->getIfNullSql(
|
354 |
+
$this->_connection->getCheckSql(
|
355 |
+
'pg.is_percent = 1',
|
356 |
+
$this->_connection->getIfNullSql(
|
357 |
+
'p.value',
|
358 |
+
'pd.value'
|
359 |
+
) . ' * (100 - pg.value)/100',
|
360 |
+
'pg.value'
|
361 |
+
),
|
362 |
+
$this->_connection->getCheckSql(
|
363 |
+
'pgd.is_percent = 1',
|
364 |
+
$this->_connection->getIfNullSql(
|
365 |
+
'p.value',
|
366 |
+
'pd.value'
|
367 |
+
) . ' * (100 - pgd.value)/100',
|
368 |
+
'pgd.value'
|
369 |
+
)
|
370 |
),
|
371 |
$this->_connection->getIfNullSql(
|
372 |
'p.value',
|
app/code/core/Mage/CatalogSearch/Model/Resource/Advanced.php
CHANGED
@@ -84,7 +84,7 @@ class Mage_CatalogSearch_Model_Resource_Advanced extends Mage_Core_Model_Resourc
|
|
84 |
if (is_array($value)) {
|
85 |
if (!empty($value['from']) || !empty($value['to'])) { // range
|
86 |
$condition = $value;
|
87 |
-
} else if ($attribute->getBackendType()
|
88 |
$condition = array('in_set' => $value);
|
89 |
} else if (!isset($value['from']) && !isset($value['to'])) { // select
|
90 |
$condition = array('in' => $value);
|
84 |
if (is_array($value)) {
|
85 |
if (!empty($value['from']) || !empty($value['to'])) { // range
|
86 |
$condition = $value;
|
87 |
+
} else if (in_array($attribute->getBackendType(), array('varchar', 'text'))) { // multiselect
|
88 |
$condition = array('in_set' => $value);
|
89 |
} else if (!isset($value['from']) && !isset($value['to'])) { // select
|
90 |
$condition = array('in' => $value);
|
app/code/core/Mage/CatalogSearch/Model/Resource/Fulltext.php
CHANGED
@@ -77,9 +77,10 @@ class Mage_CatalogSearch_Model_Resource_Fulltext extends Mage_Core_Model_Resourc
|
|
77 |
*/
|
78 |
protected $_allowTableChanges = true;
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
83 |
|
84 |
/**
|
85 |
* Init resource model
|
@@ -298,12 +299,7 @@ class Mage_CatalogSearch_Model_Resource_Fulltext extends Mage_Core_Model_Resourc
|
|
298 |
*/
|
299 |
public function resetSearchResults()
|
300 |
{
|
301 |
-
$adapter = $this->_getWriteAdapter();
|
302 |
-
$adapter->update($this->getTable('catalogsearch/search_query'), array('is_processed' => 0));
|
303 |
-
$adapter->delete($this->getTable('catalogsearch/result'));
|
304 |
-
|
305 |
Mage::dispatchEvent('catalogsearch_reset_search_result');
|
306 |
-
|
307 |
return $this;
|
308 |
}
|
309 |
|
@@ -334,39 +330,38 @@ class Mage_CatalogSearch_Model_Resource_Fulltext extends Mage_Core_Model_Resourc
|
|
334 |
public function prepareResult($object, $queryText, $query)
|
335 |
{
|
336 |
$adapter = $this->_getWriteAdapter();
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
$
|
341 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
342 |
|
343 |
-
|
344 |
-
|
345 |
-
$likeCond = '';
|
346 |
-
if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_LIKE
|
347 |
-
|| $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE
|
348 |
-
) {
|
349 |
-
$helper = Mage::getResourceHelper('core');
|
350 |
-
$words = Mage::helper('core/string')->splitWords($queryText, true, $query->getMaxQueryWords());
|
351 |
-
foreach ($words as $word) {
|
352 |
-
$like[] = $helper->getCILike('s.data_index', $word, array('position' => 'any'));
|
353 |
-
}
|
354 |
-
if ($like) {
|
355 |
-
$likeCond = '(' . join(' OR ', $like) . ')';
|
356 |
-
}
|
357 |
}
|
|
|
358 |
$mainTableAlias = 's';
|
359 |
-
$fields = array(
|
360 |
-
|
361 |
-
'product_id',
|
362 |
-
);
|
363 |
$select = $adapter->select()
|
364 |
->from(array($mainTableAlias => $this->getMainTable()), $fields)
|
365 |
->joinInner(array('e' => $this->getTable('catalog/product')),
|
366 |
'e.entity_id = s.product_id',
|
367 |
array())
|
368 |
-
->where($mainTableAlias.'.store_id = ?', (int)$query->getStoreId());
|
369 |
|
|
|
370 |
if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_FULLTEXT
|
371 |
|| $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE
|
372 |
) {
|
@@ -374,11 +369,10 @@ class Mage_CatalogSearch_Model_Resource_Fulltext extends Mage_Core_Model_Resourc
|
|
374 |
$where = Mage::getResourceHelper('catalogsearch')
|
375 |
->chooseFulltext($this->getMainTable(), $mainTableAlias, $select);
|
376 |
}
|
377 |
-
|
378 |
if ($likeCond != '' && $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE) {
|
379 |
-
|
380 |
} elseif ($likeCond != '' && $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_LIKE) {
|
381 |
-
$select->columns(array('relevance'
|
382 |
$where = $likeCond;
|
383 |
}
|
384 |
|
@@ -386,18 +380,22 @@ class Mage_CatalogSearch_Model_Resource_Fulltext extends Mage_Core_Model_Resourc
|
|
386 |
$select->where($where);
|
387 |
}
|
388 |
|
389 |
-
$
|
390 |
-
$this->getTable('catalogsearch/result'),
|
391 |
-
array(),
|
392 |
-
Varien_Db_Adapter_Interface::INSERT_ON_DUPLICATE);
|
393 |
-
$adapter->query($sql, $bind);
|
394 |
-
|
395 |
-
$query->setIsProcessed(1);
|
396 |
}
|
397 |
|
398 |
return $this;
|
399 |
}
|
400 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
401 |
/**
|
402 |
* Retrieve EAV Config Singleton
|
403 |
*
|
77 |
*/
|
78 |
protected $_allowTableChanges = true;
|
79 |
|
80 |
+
/**
|
81 |
+
* @var array
|
82 |
+
*/
|
83 |
+
protected $_foundData = array();
|
84 |
|
85 |
/**
|
86 |
* Init resource model
|
299 |
*/
|
300 |
public function resetSearchResults()
|
301 |
{
|
|
|
|
|
|
|
|
|
302 |
Mage::dispatchEvent('catalogsearch_reset_search_result');
|
|
|
303 |
return $this;
|
304 |
}
|
305 |
|
330 |
public function prepareResult($object, $queryText, $query)
|
331 |
{
|
332 |
$adapter = $this->_getWriteAdapter();
|
333 |
+
$searchType = $object->getSearchType($query->getStoreId());
|
334 |
+
|
335 |
+
$preparedTerms = Mage::getResourceHelper('catalogsearch')
|
336 |
+
->prepareTerms($queryText, $query->getMaxQueryWords());
|
337 |
+
|
338 |
+
$bind = array();
|
339 |
+
$like = array();
|
340 |
+
$likeCond = '';
|
341 |
+
if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_LIKE
|
342 |
+
|| $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE
|
343 |
+
) {
|
344 |
+
$helper = Mage::getResourceHelper('core');
|
345 |
+
$words = Mage::helper('core/string')->splitWords($queryText, true, $query->getMaxQueryWords());
|
346 |
+
foreach ($words as $word) {
|
347 |
+
$like[] = $helper->getCILike('s.data_index', $word, array('position' => 'any'));
|
348 |
+
}
|
349 |
|
350 |
+
if ($like) {
|
351 |
+
$likeCond = '(' . join(' OR ', $like) . ')';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
}
|
353 |
+
|
354 |
$mainTableAlias = 's';
|
355 |
+
$fields = array('product_id');
|
356 |
+
|
|
|
|
|
357 |
$select = $adapter->select()
|
358 |
->from(array($mainTableAlias => $this->getMainTable()), $fields)
|
359 |
->joinInner(array('e' => $this->getTable('catalog/product')),
|
360 |
'e.entity_id = s.product_id',
|
361 |
array())
|
362 |
+
->where($mainTableAlias . '.store_id = ?', (int)$query->getStoreId());
|
363 |
|
364 |
+
$where = "";
|
365 |
if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_FULLTEXT
|
366 |
|| $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE
|
367 |
) {
|
369 |
$where = Mage::getResourceHelper('catalogsearch')
|
370 |
->chooseFulltext($this->getMainTable(), $mainTableAlias, $select);
|
371 |
}
|
|
|
372 |
if ($likeCond != '' && $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE) {
|
373 |
+
$where .= ($where ? ' OR ' : '') . $likeCond;
|
374 |
} elseif ($likeCond != '' && $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_LIKE) {
|
375 |
+
$select->columns(array('relevance' => new Zend_Db_Expr(0)));
|
376 |
$where = $likeCond;
|
377 |
}
|
378 |
|
380 |
$select->where($where);
|
381 |
}
|
382 |
|
383 |
+
$this->_foundData = $adapter->fetchPairs($select, $bind);
|
|
|
|
|
|
|
|
|
|
|
|
|
384 |
}
|
385 |
|
386 |
return $this;
|
387 |
}
|
388 |
|
389 |
+
/**
|
390 |
+
* Retrieve found data
|
391 |
+
*
|
392 |
+
* @return array
|
393 |
+
*/
|
394 |
+
public function getFoundData()
|
395 |
+
{
|
396 |
+
return $this->_foundData;
|
397 |
+
}
|
398 |
+
|
399 |
/**
|
400 |
* Retrieve EAV Config Singleton
|
401 |
*
|
app/code/core/Mage/CatalogSearch/Model/Resource/Fulltext/Collection.php
CHANGED
@@ -34,6 +34,39 @@
|
|
34 |
*/
|
35 |
class Mage_CatalogSearch_Model_Resource_Fulltext_Collection extends Mage_Catalog_Model_Resource_Product_Collection
|
36 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
/**
|
38 |
* Retrieve query model object
|
39 |
*
|
@@ -47,22 +80,101 @@ class Mage_CatalogSearch_Model_Resource_Fulltext_Collection extends Mage_Catalog
|
|
47 |
/**
|
48 |
* Add search query filter
|
49 |
*
|
50 |
-
* @param
|
51 |
* @return Mage_CatalogSearch_Model_Resource_Fulltext_Collection
|
52 |
*/
|
53 |
public function addSearchFilter($query)
|
54 |
{
|
55 |
-
|
56 |
-
|
57 |
-
$this->getSelect()->joinInner(
|
58 |
-
array('search_result' => $this->getTable('catalogsearch/result')),
|
59 |
-
$this->getConnection()->quoteInto(
|
60 |
-
'search_result.product_id=e.entity_id AND search_result.query_id=?',
|
61 |
-
$this->_getQuery()->getId()
|
62 |
-
),
|
63 |
-
array('relevance' => 'relevance')
|
64 |
-
);
|
65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
return $this;
|
67 |
}
|
68 |
|
@@ -76,7 +188,8 @@ class Mage_CatalogSearch_Model_Resource_Fulltext_Collection extends Mage_Catalog
|
|
76 |
public function setOrder($attribute, $dir = 'desc')
|
77 |
{
|
78 |
if ($attribute == 'relevance') {
|
79 |
-
$this->
|
|
|
80 |
} else {
|
81 |
parent::setOrder($attribute, $dir);
|
82 |
}
|
@@ -84,7 +197,34 @@ class Mage_CatalogSearch_Model_Resource_Fulltext_Collection extends Mage_Catalog
|
|
84 |
}
|
85 |
|
86 |
/**
|
87 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
*
|
89 |
* @return Mage_CatalogSearch_Model_Resource_Fulltext_Collection
|
90 |
*/
|
@@ -92,4 +232,24 @@ class Mage_CatalogSearch_Model_Resource_Fulltext_Collection extends Mage_Catalog
|
|
92 |
{
|
93 |
return $this;
|
94 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
}
|
34 |
*/
|
35 |
class Mage_CatalogSearch_Model_Resource_Fulltext_Collection extends Mage_Catalog_Model_Resource_Product_Collection
|
36 |
{
|
37 |
+
/**
|
38 |
+
* Name for relevance order
|
39 |
+
*/
|
40 |
+
const RELEVANCE_ORDER_NAME = 'relevance';
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Found data
|
44 |
+
*
|
45 |
+
* @var array
|
46 |
+
*/
|
47 |
+
protected $_foundData = null;
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Sort order by relevance
|
51 |
+
*
|
52 |
+
* @var null
|
53 |
+
*/
|
54 |
+
protected $_relevanceSortOrder = SORT_DESC;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Sort by relevance flag
|
58 |
+
*
|
59 |
+
* @var bool
|
60 |
+
*/
|
61 |
+
protected $_sortByRelevance = false;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Is search filter applied flag
|
65 |
+
*
|
66 |
+
* @var bool
|
67 |
+
*/
|
68 |
+
protected $_isSearchFiltersApplied = false;
|
69 |
+
|
70 |
/**
|
71 |
* Retrieve query model object
|
72 |
*
|
80 |
/**
|
81 |
* Add search query filter
|
82 |
*
|
83 |
+
* @param $query
|
84 |
* @return Mage_CatalogSearch_Model_Resource_Fulltext_Collection
|
85 |
*/
|
86 |
public function addSearchFilter($query)
|
87 |
{
|
88 |
+
return $this;
|
89 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
|
91 |
+
/**
|
92 |
+
* Before load handler
|
93 |
+
*
|
94 |
+
* @return Mage_Catalog_Model_Resource_Product_Collection
|
95 |
+
*/
|
96 |
+
protected function _beforeLoad()
|
97 |
+
{
|
98 |
+
if (!$this->_isSearchFiltersApplied) {
|
99 |
+
$this->_applySearchFilters();
|
100 |
+
}
|
101 |
+
|
102 |
+
return parent::_beforeLoad();
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Get collection size
|
107 |
+
*
|
108 |
+
* @return int
|
109 |
+
*/
|
110 |
+
public function getSize()
|
111 |
+
{
|
112 |
+
if (!$this->_isSearchFiltersApplied) {
|
113 |
+
$this->_applySearchFilters();
|
114 |
+
}
|
115 |
+
|
116 |
+
return parent::getSize();
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Apply collection search filter
|
121 |
+
*
|
122 |
+
* @return Mage_CatalogSearch_Model_Resource_Fulltext_Collection
|
123 |
+
*/
|
124 |
+
protected function _applySearchFilters()
|
125 |
+
{
|
126 |
+
$foundIds = $this->getFoundIds();
|
127 |
+
if (!empty($foundIds)) {
|
128 |
+
$this->addIdFilter($foundIds);
|
129 |
+
} else {
|
130 |
+
$this->getSelect()->orWhere('FALSE');
|
131 |
+
}
|
132 |
+
$this->_isSearchFiltersApplied = true;
|
133 |
+
|
134 |
+
return $this;
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Get found products ids
|
139 |
+
*
|
140 |
+
* @return array
|
141 |
+
*/
|
142 |
+
public function getFoundIds()
|
143 |
+
{
|
144 |
+
if (is_null($this->_foundData)) {
|
145 |
+
/** @var Mage_CatalogSearch_Model_Fulltext $preparedResult */
|
146 |
+
$preparedResult = Mage::getSingleton('catalogsearch/fulltext');
|
147 |
+
$preparedResult->prepareResult();
|
148 |
+
$this->_foundData = $preparedResult->getResource()->getFoundData();
|
149 |
+
}
|
150 |
+
if (isset($this->_orders[self::RELEVANCE_ORDER_NAME])) {
|
151 |
+
$this->_resortFoundDataByRelevance();
|
152 |
+
}
|
153 |
+
return array_keys($this->_foundData);
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Resort found data by relevance
|
158 |
+
*
|
159 |
+
* @return Mage_CatalogSearch_Model_Resource_Fulltext_Collection
|
160 |
+
*/
|
161 |
+
protected function _resortFoundDataByRelevance()
|
162 |
+
{
|
163 |
+
if (is_array($this->_foundData)) {
|
164 |
+
$data = array();
|
165 |
+
foreach ($this->_foundData as $id => $relevance) {
|
166 |
+
$this->_foundData[$id] = $relevance . '_' . $id;
|
167 |
+
}
|
168 |
+
natsort($this->_foundData);
|
169 |
+
if ($this->_relevanceSortOrder == SORT_DESC) {
|
170 |
+
$this->_foundData = array_reverse($this->_foundData);
|
171 |
+
}
|
172 |
+
foreach ($this->_foundData as $dataString) {
|
173 |
+
list ($relevance, $id) = explode('_', $dataString);
|
174 |
+
$data[$id] = $relevance;
|
175 |
+
}
|
176 |
+
$this->_foundData = $data;
|
177 |
+
}
|
178 |
return $this;
|
179 |
}
|
180 |
|
188 |
public function setOrder($attribute, $dir = 'desc')
|
189 |
{
|
190 |
if ($attribute == 'relevance') {
|
191 |
+
$this->_relevanceSortOrder = ($dir == 'asc') ? SORT_ASC : SORT_DESC;
|
192 |
+
$this->addOrder(self::RELEVANCE_ORDER_NAME);
|
193 |
} else {
|
194 |
parent::setOrder($attribute, $dir);
|
195 |
}
|
197 |
}
|
198 |
|
199 |
/**
|
200 |
+
* Add sorting by relevance to select
|
201 |
+
*
|
202 |
+
* @return Mage_CatalogSearch_Model_Resource_Fulltext_Collection
|
203 |
+
*/
|
204 |
+
protected function _addRelevanceSorting()
|
205 |
+
{
|
206 |
+
$foundIds = $this->getFoundIds();
|
207 |
+
if (!$foundIds) {
|
208 |
+
return $this;
|
209 |
+
}
|
210 |
+
|
211 |
+
/** @var Mage_CatalogSearch_Model_Resource_Helper_Mysql4 $resourceHelper */
|
212 |
+
$resourceHelper = Mage::getResourceHelper('catalogsearch');
|
213 |
+
$this->_select->order(
|
214 |
+
new Zend_Db_Expr(
|
215 |
+
$resourceHelper->getFieldOrderExpression(
|
216 |
+
'e.' . $this->getResource()->getIdFieldName(),
|
217 |
+
$foundIds
|
218 |
+
)
|
219 |
+
. ' ' . Zend_Db_Select::SQL_ASC
|
220 |
+
)
|
221 |
+
);
|
222 |
+
|
223 |
+
return $this;
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Stub method for compatibility with other search engines
|
228 |
*
|
229 |
* @return Mage_CatalogSearch_Model_Resource_Fulltext_Collection
|
230 |
*/
|
232 |
{
|
233 |
return $this;
|
234 |
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Render sql select orders
|
238 |
+
*
|
239 |
+
* @return Varien_Data_Collection_Db
|
240 |
+
*/
|
241 |
+
protected function _renderOrders()
|
242 |
+
{
|
243 |
+
if (!$this->_isOrdersRendered) {
|
244 |
+
foreach ($this->_orders as $attribute => $direction) {
|
245 |
+
if ($attribute == self::RELEVANCE_ORDER_NAME) {
|
246 |
+
$this->_addRelevanceSorting();
|
247 |
+
} else {
|
248 |
+
$this->addAttributeToSort($attribute, $direction);
|
249 |
+
}
|
250 |
+
}
|
251 |
+
$this->_isOrdersRendered = true;
|
252 |
+
}
|
253 |
+
return $this;
|
254 |
+
}
|
255 |
}
|
app/code/core/Mage/CatalogSearch/Model/Resource/Helper/Mysql4.php
CHANGED
@@ -52,6 +52,7 @@ class Mage_CatalogSearch_Model_Resource_Helper_Mysql4 extends Mage_Eav_Model_Res
|
|
52 |
* Prepare Terms
|
53 |
*
|
54 |
* @param string $str The source string
|
|
|
55 |
* @return array(0=>words, 1=>terms)
|
56 |
*/
|
57 |
function prepareTerms($str, $maxWordLength = 0)
|
@@ -112,10 +113,24 @@ class Mage_CatalogSearch_Model_Resource_Helper_Mysql4 extends Mage_Eav_Model_Res
|
|
112 |
*
|
113 |
* @param mixed $table The table to insert data into.
|
114 |
* @param array $data Column-value pairs or array of column-value pairs.
|
115 |
-
* @param
|
116 |
* @return int The number of affected rows.
|
117 |
*/
|
118 |
public function insertOnDuplicate($table, array $data, array $fields = array()) {
|
119 |
return $this->_getWriteAdapter()->insertOnDuplicate($table, $data, $fields);
|
120 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
}
|
52 |
* Prepare Terms
|
53 |
*
|
54 |
* @param string $str The source string
|
55 |
+
* @param int $maxWordLength
|
56 |
* @return array(0=>words, 1=>terms)
|
57 |
*/
|
58 |
function prepareTerms($str, $maxWordLength = 0)
|
113 |
*
|
114 |
* @param mixed $table The table to insert data into.
|
115 |
* @param array $data Column-value pairs or array of column-value pairs.
|
116 |
+
* @param array $fields update fields pairs or values
|
117 |
* @return int The number of affected rows.
|
118 |
*/
|
119 |
public function insertOnDuplicate($table, array $data, array $fields = array()) {
|
120 |
return $this->_getWriteAdapter()->insertOnDuplicate($table, $data, $fields);
|
121 |
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Get field expression for order by
|
125 |
+
*
|
126 |
+
* @param string $fieldName
|
127 |
+
* @param array $orderedIds
|
128 |
+
*
|
129 |
+
* @return string
|
130 |
+
*/
|
131 |
+
public function getFieldOrderExpression($fieldName, array $orderedIds)
|
132 |
+
{
|
133 |
+
$fieldName = $this->_getWriteAdapter()->quoteIdentifier($fieldName);
|
134 |
+
return "FIELD({$fieldName}, {$this->_getReadAdapter()->quote($orderedIds)})";
|
135 |
+
}
|
136 |
}
|
app/code/core/Mage/Checkout/Model/Cart.php
CHANGED
@@ -229,10 +229,6 @@ class Mage_Checkout_Model_Cart extends Varien_Object implements Mage_Checkout_Mo
|
|
229 |
$request = new Varien_Object($requestInfo);
|
230 |
}
|
231 |
|
232 |
-
if (!$request->hasQty()) {
|
233 |
-
$request->setQty(1);
|
234 |
-
}
|
235 |
-
|
236 |
return $request;
|
237 |
}
|
238 |
|
@@ -248,14 +244,21 @@ class Mage_Checkout_Model_Cart extends Varien_Object implements Mage_Checkout_Mo
|
|
248 |
$product = $this->_getProduct($productInfo);
|
249 |
$request = $this->_getProductRequest($requestInfo);
|
250 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
$productId = $product->getId();
|
252 |
|
253 |
-
if ($product->getStockItem()) {
|
254 |
$minimumQty = $product->getStockItem()->getMinSaleQty();
|
255 |
//If product was not found in cart and there is set minimal qty for it
|
256 |
if ($minimumQty && $minimumQty > 0 && $request->getQty() < $minimumQty
|
257 |
&& !$this->getQuote()->hasProductId($productId)
|
258 |
-
){
|
259 |
$request->setQty($minimumQty);
|
260 |
}
|
261 |
}
|
229 |
$request = new Varien_Object($requestInfo);
|
230 |
}
|
231 |
|
|
|
|
|
|
|
|
|
232 |
return $request;
|
233 |
}
|
234 |
|
244 |
$product = $this->_getProduct($productInfo);
|
245 |
$request = $this->_getProductRequest($requestInfo);
|
246 |
|
247 |
+
/** @var Mage_Catalog_Helper_Product $helper */
|
248 |
+
$helper = Mage::helper('catalog/product');
|
249 |
+
|
250 |
+
if (!$request->hasQty()) {
|
251 |
+
$request->setQty($helper->getDefaultQty($product));
|
252 |
+
}
|
253 |
+
|
254 |
$productId = $product->getId();
|
255 |
|
256 |
+
if (!$product->isConfigurable() && $product->getStockItem()) {
|
257 |
$minimumQty = $product->getStockItem()->getMinSaleQty();
|
258 |
//If product was not found in cart and there is set minimal qty for it
|
259 |
if ($minimumQty && $minimumQty > 0 && $request->getQty() < $minimumQty
|
260 |
&& !$this->getQuote()->hasProductId($productId)
|
261 |
+
) {
|
262 |
$request->setQty($minimumQty);
|
263 |
}
|
264 |
}
|
app/code/core/Mage/Checkout/Model/Type/Multishipping.php
CHANGED
@@ -308,6 +308,9 @@ class Mage_Checkout_Model_Type_Multishipping extends Mage_Checkout_Model_Type_Ab
|
|
308 |
if (!$quoteAddress = $this->getQuote()->getShippingAddressByCustomerAddressId($address->getId())) {
|
309 |
$quoteAddress = Mage::getModel('sales/quote_address')->importCustomerAddress($address);
|
310 |
$this->getQuote()->addShippingAddress($quoteAddress);
|
|
|
|
|
|
|
311 |
}
|
312 |
|
313 |
$quoteAddress = $this->getQuote()->getShippingAddressByCustomerAddressId($address->getId());
|
308 |
if (!$quoteAddress = $this->getQuote()->getShippingAddressByCustomerAddressId($address->getId())) {
|
309 |
$quoteAddress = Mage::getModel('sales/quote_address')->importCustomerAddress($address);
|
310 |
$this->getQuote()->addShippingAddress($quoteAddress);
|
311 |
+
if ($couponCode = $this->getCheckoutSession()->getCartCouponCode()) {
|
312 |
+
$this->getQuote()->setCouponCode($couponCode);
|
313 |
+
}
|
314 |
}
|
315 |
|
316 |
$quoteAddress = $this->getQuote()->getShippingAddressByCustomerAddressId($address->getId());
|
app/code/core/Mage/Checkout/Model/Type/Onepage.php
CHANGED
@@ -362,6 +362,7 @@ class Mage_Checkout_Model_Type_Onepage
|
|
362 |
->setShippingMethod($shippingMethod)
|
363 |
->setCollectShippingRates(true);
|
364 |
$this->getCheckout()->setStepData('shipping', 'complete', true);
|
|
|
365 |
break;
|
366 |
}
|
367 |
}
|
@@ -592,6 +593,8 @@ class Mage_Checkout_Model_Type_Onepage
|
|
592 |
return array('error' => 1, 'message' => $validateRes);
|
593 |
}
|
594 |
|
|
|
|
|
595 |
$this->getQuote()->collectTotals()->save();
|
596 |
|
597 |
$this->getCheckout()
|
@@ -946,4 +949,17 @@ class Mage_Checkout_Model_Type_Onepage
|
|
946 |
}
|
947 |
return $orderId;
|
948 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
949 |
}
|
362 |
->setShippingMethod($shippingMethod)
|
363 |
->setCollectShippingRates(true);
|
364 |
$this->getCheckout()->setStepData('shipping', 'complete', true);
|
365 |
+
$this->_setCartCouponCode();
|
366 |
break;
|
367 |
}
|
368 |
}
|
593 |
return array('error' => 1, 'message' => $validateRes);
|
594 |
}
|
595 |
|
596 |
+
$this->_setCartCouponCode();
|
597 |
+
|
598 |
$this->getQuote()->collectTotals()->save();
|
599 |
|
600 |
$this->getCheckout()
|
949 |
}
|
950 |
return $orderId;
|
951 |
}
|
952 |
+
|
953 |
+
/**
|
954 |
+
* Sets cart coupon code from checkout to quote
|
955 |
+
*
|
956 |
+
* @return $this
|
957 |
+
*/
|
958 |
+
protected function _setCartCouponCode()
|
959 |
+
{
|
960 |
+
if ($couponCode = $this->getCheckout()->getCartCouponCode()) {
|
961 |
+
$this->getQuote()->setCouponCode($couponCode);
|
962 |
+
}
|
963 |
+
return $this;
|
964 |
+
}
|
965 |
}
|
app/code/core/Mage/Checkout/controllers/CartController.php
CHANGED
@@ -89,7 +89,10 @@ class Mage_Checkout_CartController extends Mage_Core_Controller_Front_Action
|
|
89 |
) {
|
90 |
$this->getResponse()->setRedirect($backUrl);
|
91 |
} else {
|
92 |
-
if (
|
|
|
|
|
|
|
93 |
$this->_getSession()->setContinueShoppingUrl($this->_getRefererUrl());
|
94 |
}
|
95 |
$this->_redirect('checkout/cart');
|
@@ -141,6 +144,20 @@ class Mage_Checkout_CartController extends Mage_Core_Controller_Front_Action
|
|
141 |
$cart = $this->_getCart();
|
142 |
if ($cart->getQuote()->getItemsCount()) {
|
143 |
$cart->init();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
$cart->save();
|
145 |
|
146 |
if (!$this->_getQuote()->validateMinimumAmount()) {
|
@@ -526,6 +543,13 @@ class Mage_Checkout_CartController extends Mage_Core_Controller_Front_Action
|
|
526 |
->setRegion($region)
|
527 |
->setCollectShippingRates(true);
|
528 |
$this->_getQuote()->save();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
529 |
$this->_goBack();
|
530 |
}
|
531 |
|
@@ -581,6 +605,7 @@ class Mage_Checkout_CartController extends Mage_Core_Controller_Front_Action
|
|
581 |
$this->_getSession()->addSuccess(
|
582 |
$this->__('Coupon code "%s" was applied.', Mage::helper('core')->escapeHtml($couponCode))
|
583 |
);
|
|
|
584 |
} else {
|
585 |
$this->_getSession()->addError(
|
586 |
$this->__('Coupon code "%s" is not valid.', Mage::helper('core')->escapeHtml($couponCode))
|
89 |
) {
|
90 |
$this->getResponse()->setRedirect($backUrl);
|
91 |
} else {
|
92 |
+
if (
|
93 |
+
(strtolower($this->getRequest()->getActionName()) == 'add')
|
94 |
+
&& !$this->getRequest()->getParam('in_cart')
|
95 |
+
) {
|
96 |
$this->_getSession()->setContinueShoppingUrl($this->_getRefererUrl());
|
97 |
}
|
98 |
$this->_redirect('checkout/cart');
|
144 |
$cart = $this->_getCart();
|
145 |
if ($cart->getQuote()->getItemsCount()) {
|
146 |
$cart->init();
|
147 |
+
if (
|
148 |
+
$cart->getQuote()->getShippingAddress()
|
149 |
+
&& $this->_getSession()->getEstimatedShippingAddressData()
|
150 |
+
&& $couponCode = $this->_getSession()->getCartCouponCode()
|
151 |
+
) {
|
152 |
+
$estimatedSessionAddressData = $this->_getSession()->getEstimatedShippingAddressData();
|
153 |
+
$cart->getQuote()->getShippingAddress()
|
154 |
+
->setCountryId($estimatedSessionAddressData['country_id'])
|
155 |
+
->setCity($estimatedSessionAddressData['city'])
|
156 |
+
->setPostcode($estimatedSessionAddressData['postcode'])
|
157 |
+
->setRegionId($estimatedSessionAddressData['region_id'])
|
158 |
+
->setRegion($estimatedSessionAddressData['region']);
|
159 |
+
$cart->getQuote()->setCouponCode($couponCode);
|
160 |
+
}
|
161 |
$cart->save();
|
162 |
|
163 |
if (!$this->_getQuote()->validateMinimumAmount()) {
|
543 |
->setRegion($region)
|
544 |
->setCollectShippingRates(true);
|
545 |
$this->_getQuote()->save();
|
546 |
+
$this->_getSession()->setEstimatedShippingAddressData(array(
|
547 |
+
'country_id' => $country,
|
548 |
+
'postcode' => $postcode,
|
549 |
+
'city' => $city,
|
550 |
+
'region_id' => $regionId,
|
551 |
+
'region' => $region
|
552 |
+
));
|
553 |
$this->_goBack();
|
554 |
}
|
555 |
|
605 |
$this->_getSession()->addSuccess(
|
606 |
$this->__('Coupon code "%s" was applied.', Mage::helper('core')->escapeHtml($couponCode))
|
607 |
);
|
608 |
+
$this->_getSession()->setCartCouponCode($couponCode);
|
609 |
} else {
|
610 |
$this->_getSession()->addError(
|
611 |
$this->__('Coupon code "%s" is not valid.', Mage::helper('core')->escapeHtml($couponCode))
|
app/code/core/Mage/Checkout/controllers/OnepageController.php
CHANGED
@@ -334,8 +334,7 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
|
|
334 |
$address = $this->getOnepage()->getAddress($addressId);
|
335 |
|
336 |
if (Mage::getSingleton('customer/session')->getCustomer()->getId() == $address->getCustomerId()) {
|
337 |
-
$this->
|
338 |
-
$this->getResponse()->setBody($address->toJson());
|
339 |
} else {
|
340 |
$this->getResponse()->setHeader('HTTP/1.1','403 Forbidden');
|
341 |
}
|
@@ -353,7 +352,7 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
|
|
353 |
if ($this->getRequest()->isPost()) {
|
354 |
$method = $this->getRequest()->getPost('method');
|
355 |
$result = $this->getOnepage()->saveCheckoutMethod($method);
|
356 |
-
$this->
|
357 |
}
|
358 |
}
|
359 |
|
@@ -395,7 +394,7 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
|
|
395 |
}
|
396 |
}
|
397 |
|
398 |
-
$this->
|
399 |
}
|
400 |
}
|
401 |
|
@@ -419,7 +418,7 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
|
|
419 |
'html' => $this->_getShippingMethodsHtml()
|
420 |
);
|
421 |
}
|
422 |
-
$this->
|
423 |
}
|
424 |
}
|
425 |
|
@@ -442,7 +441,7 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
|
|
442 |
'request' => $this->getRequest(),
|
443 |
'quote' => $this->getOnepage()->getQuote()));
|
444 |
$this->getOnepage()->getQuote()->collectTotals();
|
445 |
-
$this->
|
446 |
|
447 |
$result['goto_section'] = 'payment';
|
448 |
$result['update_section'] = array(
|
@@ -451,7 +450,7 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
|
|
451 |
);
|
452 |
}
|
453 |
$this->getOnepage()->getQuote()->collectTotals()->save();
|
454 |
-
$this->
|
455 |
}
|
456 |
}
|
457 |
|
@@ -498,7 +497,7 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
|
|
498 |
Mage::logException($e);
|
499 |
$result['error'] = $this->__('Unable to set Payment Method.');
|
500 |
}
|
501 |
-
$this->
|
502 |
}
|
503 |
|
504 |
/**
|
@@ -561,7 +560,7 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
|
|
561 |
$result['success'] = false;
|
562 |
$result['error'] = true;
|
563 |
$result['error_messages'] = $this->__('Please agree to all the terms and conditions before placing the order.');
|
564 |
-
$this->
|
565 |
return;
|
566 |
}
|
567 |
}
|
@@ -630,7 +629,7 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
|
|
630 |
$result['redirect'] = $redirectUrl;
|
631 |
}
|
632 |
|
633 |
-
$this->
|
634 |
}
|
635 |
|
636 |
/**
|
@@ -657,4 +656,17 @@ class Mage_Checkout_OnepageController extends Mage_Checkout_Controller_Action
|
|
657 |
|| Mage::helper('checkout')->isAllowedGuestCheckout($this->getOnepage()->getQuote())
|
658 |
|| !Mage::helper('checkout')->isCustomerMustBeLogged();
|
659 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
660 |
}
|
334 |
$address = $this->getOnepage()->getAddress($addressId);
|
335 |
|
336 |
if (Mage::getSingleton('customer/session')->getCustomer()->getId() == $address->getCustomerId()) {
|
337 |
+
$this->_prepareDataJSON($address->toArray());
|
|
|
338 |
} else {
|
339 |
$this->getResponse()->setHeader('HTTP/1.1','403 Forbidden');
|
340 |
}
|
352 |
if ($this->getRequest()->isPost()) {
|
353 |
$method = $this->getRequest()->getPost('method');
|
354 |
$result = $this->getOnepage()->saveCheckoutMethod($method);
|
355 |
+
$this->_prepareDataJSON($result);
|
356 |
}
|
357 |
}
|
358 |
|
394 |
}
|
395 |
}
|
396 |
|
397 |
+
$this->_prepareDataJSON($result);
|
398 |
}
|
399 |
}
|
400 |
|
418 |
'html' => $this->_getShippingMethodsHtml()
|
419 |
);
|
420 |
}
|
421 |
+
$this->_prepareDataJSON($result);
|
422 |
}
|
423 |
}
|
424 |
|
441 |
'request' => $this->getRequest(),
|
442 |
'quote' => $this->getOnepage()->getQuote()));
|
443 |
$this->getOnepage()->getQuote()->collectTotals();
|
444 |
+
$this->_prepareDataJSON($result);
|
445 |
|
446 |
$result['goto_section'] = 'payment';
|
447 |
$result['update_section'] = array(
|
450 |
);
|
451 |
}
|
452 |
$this->getOnepage()->getQuote()->collectTotals()->save();
|
453 |
+
$this->_prepareDataJSON($result);
|
454 |
}
|
455 |
}
|
456 |
|
497 |
Mage::logException($e);
|
498 |
$result['error'] = $this->__('Unable to set Payment Method.');
|
499 |
}
|
500 |
+
$this->_prepareDataJSON($result);
|
501 |
}
|
502 |
|
503 |
/**
|
560 |
$result['success'] = false;
|
561 |
$result['error'] = true;
|
562 |
$result['error_messages'] = $this->__('Please agree to all the terms and conditions before placing the order.');
|
563 |
+
$this->_prepareDataJSON($result);
|
564 |
return;
|
565 |
}
|
566 |
}
|
629 |
$result['redirect'] = $redirectUrl;
|
630 |
}
|
631 |
|
632 |
+
$this->_prepareDataJSON($result);
|
633 |
}
|
634 |
|
635 |
/**
|
656 |
|| Mage::helper('checkout')->isAllowedGuestCheckout($this->getOnepage()->getQuote())
|
657 |
|| !Mage::helper('checkout')->isCustomerMustBeLogged();
|
658 |
}
|
659 |
+
|
660 |
+
/**
|
661 |
+
* Prepare JSON formatted data for response to client
|
662 |
+
*
|
663 |
+
* @param $response
|
664 |
+
* @return Zend_Controller_Response_Abstract
|
665 |
+
*/
|
666 |
+
protected function _prepareDataJSON($response)
|
667 |
+
{
|
668 |
+
$this->getResponse()->setHeader('Content-type', 'application/json', true);
|
669 |
+
return $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($response));
|
670 |
+
}
|
671 |
+
|
672 |
}
|
app/code/core/Mage/Cms/Block/Page.php
CHANGED
@@ -63,14 +63,28 @@ class Mage_Cms_Block_Page extends Mage_Core_Block_Abstract
|
|
63 |
protected function _prepareLayout()
|
64 |
{
|
65 |
$page = $this->getPage();
|
|
|
66 |
|
67 |
// show breadcrumbs
|
68 |
if (Mage::getStoreConfig('web/default/show_cms_breadcrumbs')
|
69 |
&& ($breadcrumbs = $this->getLayout()->getBlock('breadcrumbs'))
|
70 |
&& ($page->getIdentifier()!==Mage::getStoreConfig('web/default/cms_home_page'))
|
71 |
&& ($page->getIdentifier()!==Mage::getStoreConfig('web/default/cms_no_route'))) {
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
}
|
75 |
|
76 |
$root = $this->getLayout()->getBlock('root');
|
@@ -85,6 +99,14 @@ class Mage_Cms_Block_Page extends Mage_Core_Block_Abstract
|
|
85 |
$head->setDescription($page->getMetaDescription());
|
86 |
}
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
return parent::_prepareLayout();
|
89 |
}
|
90 |
|
63 |
protected function _prepareLayout()
|
64 |
{
|
65 |
$page = $this->getPage();
|
66 |
+
$breadcrumbsArray = array();
|
67 |
|
68 |
// show breadcrumbs
|
69 |
if (Mage::getStoreConfig('web/default/show_cms_breadcrumbs')
|
70 |
&& ($breadcrumbs = $this->getLayout()->getBlock('breadcrumbs'))
|
71 |
&& ($page->getIdentifier()!==Mage::getStoreConfig('web/default/cms_home_page'))
|
72 |
&& ($page->getIdentifier()!==Mage::getStoreConfig('web/default/cms_no_route'))) {
|
73 |
+
$breadcrumbsArray[] = array(
|
74 |
+
'crumbName' => 'home',
|
75 |
+
'crumbInfo' => array(
|
76 |
+
'label' => Mage::helper('cms')->__('Home'),
|
77 |
+
'title' => Mage::helper('cms')->__('Go to Home Page'),
|
78 |
+
'link' => Mage::getBaseUrl()
|
79 |
+
)
|
80 |
+
);
|
81 |
+
$breadcrumbsArray[] = array(
|
82 |
+
'crumbName' => 'cms_page',
|
83 |
+
'crumbInfo' => array(
|
84 |
+
'label' => $page->getTitle(),
|
85 |
+
'title' => $page->getTitle()
|
86 |
+
)
|
87 |
+
);
|
88 |
}
|
89 |
|
90 |
$root = $this->getLayout()->getBlock('root');
|
99 |
$head->setDescription($page->getMetaDescription());
|
100 |
}
|
101 |
|
102 |
+
$breadcrumbsObject = new Varien_Object();
|
103 |
+
$breadcrumbsObject->setCrumbs($breadcrumbsArray);
|
104 |
+
|
105 |
+
Mage::dispatchEvent('cms_generate_breadcrumbs', array('breadcrumbs' => $breadcrumbsObject));
|
106 |
+
|
107 |
+
foreach ($breadcrumbsObject->getCrumbs() as $breadcrumbsItem) {
|
108 |
+
$breadcrumbs->addCrumb($breadcrumbsItem['crumbName'], $breadcrumbsItem['crumbInfo']);
|
109 |
+
}
|
110 |
return parent::_prepareLayout();
|
111 |
}
|
112 |
|
app/code/core/Mage/Cms/Helper/Wysiwyg/Images.php
CHANGED
@@ -222,7 +222,8 @@ class Mage_Cms_Helper_Wysiwyg_Images extends Mage_Core_Helper_Abstract
|
|
222 |
}
|
223 |
$io = new Varien_Io_File();
|
224 |
if (!$io->isWriteable($currentPath) && !$io->mkdir($currentPath)) {
|
225 |
-
$message = Mage::helper('cms')->__('The directory %s is not writable by server.'
|
|
|
226 |
Mage::throwException($message);
|
227 |
}
|
228 |
$this->_currentPath = $currentPath;
|
222 |
}
|
223 |
$io = new Varien_Io_File();
|
224 |
if (!$io->isWriteable($currentPath) && !$io->mkdir($currentPath)) {
|
225 |
+
$message = Mage::helper('cms')->__('The directory %s is not writable by server.',
|
226 |
+
$io->getFilteredPath($currentPath));
|
227 |
Mage::throwException($message);
|
228 |
}
|
229 |
$this->_currentPath = $currentPath;
|
app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php
CHANGED
@@ -227,17 +227,18 @@ class Mage_Cms_Model_Wysiwyg_Images_Storage extends Varien_Object
|
|
227 |
$rootCmp = rtrim($this->getHelper()->getStorageRoot(), DS);
|
228 |
$pathCmp = rtrim($path, DS);
|
229 |
|
|
|
|
|
230 |
if ($rootCmp == $pathCmp) {
|
231 |
-
Mage::throwException(Mage::helper('cms')->__('Cannot delete root directory %s.',
|
|
|
232 |
}
|
233 |
|
234 |
-
$io = new Varien_Io_File();
|
235 |
-
|
236 |
if (Mage::helper('core/file_storage_database')->checkDbUsage()) {
|
237 |
Mage::getModel('core/file_storage_directory_database')->deleteDirectory($path);
|
238 |
}
|
239 |
if (!$io->rmdir($path, true)) {
|
240 |
-
Mage::throwException(Mage::helper('cms')->__('Cannot delete directory %s.', $path));
|
241 |
}
|
242 |
|
243 |
if (strpos($pathCmp, $rootCmp) === 0) {
|
227 |
$rootCmp = rtrim($this->getHelper()->getStorageRoot(), DS);
|
228 |
$pathCmp = rtrim($path, DS);
|
229 |
|
230 |
+
$io = new Varien_Io_File();
|
231 |
+
|
232 |
if ($rootCmp == $pathCmp) {
|
233 |
+
Mage::throwException(Mage::helper('cms')->__('Cannot delete root directory %s.',
|
234 |
+
$io->getFilteredPath($path)));
|
235 |
}
|
236 |
|
|
|
|
|
237 |
if (Mage::helper('core/file_storage_database')->checkDbUsage()) {
|
238 |
Mage::getModel('core/file_storage_directory_database')->deleteDirectory($path);
|
239 |
}
|
240 |
if (!$io->rmdir($path, true)) {
|
241 |
+
Mage::throwException(Mage::helper('cms')->__('Cannot delete directory %s.', $io->getFilteredPath($path)));
|
242 |
}
|
243 |
|
244 |
if (strpos($pathCmp, $rootCmp) === 0) {
|
app/code/core/Mage/ConfigurableSwatches/Block/Catalog/Product/List/Price.php
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_ConfigurableSwatches
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
class Mage_ConfigurableSwatches_Block_Catalog_Product_List_Price extends Mage_Core_Block_Template
|
28 |
+
{
|
29 |
+
/**
|
30 |
+
* @var string
|
31 |
+
*/
|
32 |
+
protected $_template = 'configurableswatches/catalog/product/list/price/js.phtml';
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Get target product IDs from product collection
|
36 |
+
* which was set on block
|
37 |
+
*
|
38 |
+
* @return Mage_Eav_Model_Entity_Collection_Abstract
|
39 |
+
*/
|
40 |
+
protected function getProducts()
|
41 |
+
{
|
42 |
+
return $this->getProductCollection();
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Get configuration for configurable swatches price change
|
47 |
+
*
|
48 |
+
* @return string
|
49 |
+
*/
|
50 |
+
public function getJsonConfig()
|
51 |
+
{
|
52 |
+
/** @var Mage_Catalog_Helper_Product_Type_Composite $compositeProductHelper */
|
53 |
+
$compositeProductHelper = $this->helper('catalog/product_type_composite');
|
54 |
+
|
55 |
+
$config = array(
|
56 |
+
'generalConfig' => $compositeProductHelper->prepareJsonGeneralConfig()
|
57 |
+
);
|
58 |
+
foreach ($this->getProducts() as $product) {
|
59 |
+
/** @var $product Mage_Catalog_Model_Product */
|
60 |
+
if (!$product->getSwatchPrices()) {
|
61 |
+
continue;
|
62 |
+
}
|
63 |
+
|
64 |
+
$config['products'][$product->getId()] = $compositeProductHelper->prepareJsonProductConfig($product);
|
65 |
+
$config['products'][$product->getId()]['swatchPrices'] = $product->getSwatchPrices();
|
66 |
+
|
67 |
+
$responseObject = new Varien_Object();
|
68 |
+
Mage::dispatchEvent('catalog_product_view_config', array(
|
69 |
+
'response_object' => $responseObject,
|
70 |
+
'product' => $product,
|
71 |
+
));
|
72 |
+
if (is_array($responseObject->getAdditionalOptions())) {
|
73 |
+
foreach ($responseObject->getAdditionalOptions() as $option => $value) {
|
74 |
+
$config['products'][$product->getId()][$option] = $value;
|
75 |
+
}
|
76 |
+
}
|
77 |
+
}
|
78 |
+
return $this->helper('core')->jsonEncode($config);
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Disable output if all preconditions doesn't meet
|
83 |
+
*
|
84 |
+
* @return string
|
85 |
+
*/
|
86 |
+
protected function _toHtml()
|
87 |
+
{
|
88 |
+
if (!$this->helper('configurableswatches/list_price')->isEnabled()) {
|
89 |
+
return '';
|
90 |
+
}
|
91 |
+
|
92 |
+
return parent::_toHtml();
|
93 |
+
}
|
94 |
+
|
95 |
+
}
|
app/code/core/Mage/ConfigurableSwatches/Helper/Data.php
CHANGED
@@ -92,7 +92,10 @@ class Mage_ConfigurableSwatches_Helper_Data extends Mage_Core_Helper_Abstract
|
|
92 |
public function getSwatchAttributeIds()
|
93 |
{
|
94 |
if (is_null($this->_configAttributeIds)) {
|
95 |
-
$this->_configAttributeIds =
|
|
|
|
|
|
|
96 |
}
|
97 |
return $this->_configAttributeIds;
|
98 |
}
|
@@ -111,4 +114,27 @@ class Mage_ConfigurableSwatches_Helper_Data extends Mage_Core_Helper_Abstract
|
|
111 |
$configAttrs = $this->getSwatchAttributeIds();
|
112 |
return in_array($attr, $configAttrs);
|
113 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
}
|
92 |
public function getSwatchAttributeIds()
|
93 |
{
|
94 |
if (is_null($this->_configAttributeIds)) {
|
95 |
+
$this->_configAttributeIds = array();
|
96 |
+
if (Mage::getStoreConfig(self::CONFIG_PATH_SWATCH_ATTRIBUTES)) {
|
97 |
+
$this->_configAttributeIds = explode(',', Mage::getStoreConfig(self::CONFIG_PATH_SWATCH_ATTRIBUTES));
|
98 |
+
}
|
99 |
}
|
100 |
return $this->_configAttributeIds;
|
101 |
}
|
114 |
$configAttrs = $this->getSwatchAttributeIds();
|
115 |
return in_array($attr, $configAttrs);
|
116 |
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Get swatches product javascript
|
120 |
+
*
|
121 |
+
* @return string
|
122 |
+
*/
|
123 |
+
public function getSwatchesProductJs()
|
124 |
+
{
|
125 |
+
/**
|
126 |
+
* @var $product Mage_Catalog_Model_Product
|
127 |
+
*/
|
128 |
+
$product = Mage::registry('current_product');
|
129 |
+
if ($this->isEnabled() && $product) {
|
130 |
+
$configAttrs = $this->getSwatchAttributeIds();
|
131 |
+
$configurableAttributes = $product->getTypeInstance(true)->getConfigurableAttributesAsArray($product);
|
132 |
+
foreach ($configurableAttributes as $configurableAttribute) {
|
133 |
+
if (in_array($configurableAttribute['attribute_id'], $configAttrs)) {
|
134 |
+
return 'js/configurableswatches/swatches-product.js';
|
135 |
+
}
|
136 |
+
}
|
137 |
+
}
|
138 |
+
return '';
|
139 |
+
}
|
140 |
}
|
app/code/core/Mage/ConfigurableSwatches/Helper/List/Price.php
ADDED
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_ConfigurableSwatches
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Class implementing price change for swatches in product listing pages
|
29 |
+
*/
|
30 |
+
class Mage_ConfigurableSwatches_Helper_List_Price extends Mage_Core_Helper_Abstract
|
31 |
+
{
|
32 |
+
/**
|
33 |
+
* Path to to check is it required to change prices
|
34 |
+
*/
|
35 |
+
const XML_PATH_SWATCH_PRICE = 'configswatches/general/product_list_price_change';
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Set swatch_price on products where swatch option_id is set
|
39 |
+
* Depends on following product data:
|
40 |
+
* - product must have children products attached and be configurable by type
|
41 |
+
*
|
42 |
+
* @param array $products
|
43 |
+
* @param int $storeId
|
44 |
+
* @return void
|
45 |
+
*/
|
46 |
+
public function attachConfigurableProductChildrenPricesMapping(array $products, $storeId = null)
|
47 |
+
{
|
48 |
+
$listSwatchAttrId = Mage::helper('configurableswatches/productlist')->getSwatchAttributeId();
|
49 |
+
$result = array();
|
50 |
+
|
51 |
+
foreach ($products as $product) {
|
52 |
+
/** @var $product Mage_Catalog_Model_Product */
|
53 |
+
if ($product->getTypeId() !== Mage_Catalog_Model_Product_Type_Configurable::TYPE_CODE
|
54 |
+
&& !is_array($product->getChildrenProducts())
|
55 |
+
) {
|
56 |
+
continue;
|
57 |
+
}
|
58 |
+
|
59 |
+
/** @var Mage_Catalog_Model_Product_Type_Configurable $typeInstance */
|
60 |
+
$typeInstance = $product->getTypeInstance();
|
61 |
+
$allowedAttributes = $typeInstance->getConfigurableAttributeCollection($product);
|
62 |
+
foreach ($allowedAttributes as $attribute) {
|
63 |
+
/** @var $attribute Mage_Catalog_Model_Product_Type_Configurable_Attribute */
|
64 |
+
if ($attribute->getAttributeId() !== $listSwatchAttrId) {
|
65 |
+
continue;
|
66 |
+
}
|
67 |
+
|
68 |
+
foreach ($attribute->getPrices() as $attributePrice) {
|
69 |
+
$product->setConfigurablePrice(
|
70 |
+
$this->_getHelper()->preparePrice(
|
71 |
+
$product,
|
72 |
+
$attributePrice['pricing_value'],
|
73 |
+
$attributePrice['is_percent'],
|
74 |
+
$storeId
|
75 |
+
)
|
76 |
+
);
|
77 |
+
Mage::dispatchEvent(
|
78 |
+
'catalog_product_type_configurable_price',
|
79 |
+
array('product' => $product)
|
80 |
+
);
|
81 |
+
$configurablePrice = $product->getConfigurablePrice();
|
82 |
+
$cofigurableSwatchesHelper = Mage::helper('configurableswatches');
|
83 |
+
$result[$cofigurableSwatchesHelper::normalizeKey($attributePrice['store_label'])] = array(
|
84 |
+
'price' => $configurablePrice,
|
85 |
+
'oldPrice' => $this->_getHelper()->prepareOldPrice(
|
86 |
+
$product,
|
87 |
+
$attributePrice['pricing_value'],
|
88 |
+
$attributePrice['is_percent'],
|
89 |
+
$storeId
|
90 |
+
),
|
91 |
+
);
|
92 |
+
}
|
93 |
+
}
|
94 |
+
$product->setSwatchPrices($result);
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Get helper for calculation purposes
|
100 |
+
*
|
101 |
+
* @return Mage_Catalog_Helper_Product_Type_Composite
|
102 |
+
*/
|
103 |
+
protected function _getHelper()
|
104 |
+
{
|
105 |
+
return Mage::helper('catalog/product_type_composite');
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Check if option for swatches price change is enabled
|
110 |
+
*
|
111 |
+
* @return bool
|
112 |
+
*/
|
113 |
+
public function isEnabled()
|
114 |
+
{
|
115 |
+
return Mage::getStoreConfigFlag(self::XML_PATH_SWATCH_PRICE);
|
116 |
+
}
|
117 |
+
|
118 |
+
}
|
app/code/core/Mage/ConfigurableSwatches/Helper/Mediafallback.php
CHANGED
@@ -37,12 +37,39 @@ class Mage_ConfigurableSwatches_Helper_Mediafallback extends Mage_Core_Helper_Ab
|
|
37 |
* - product must have children products attached
|
38 |
*
|
39 |
* @param array $parentProducts
|
|
|
40 |
* @param $storeId
|
41 |
* @return void
|
42 |
*/
|
43 |
public function attachConfigurableProductChildrenAttributeMapping(array $parentProducts, $storeId)
|
44 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
$listSwatchAttr = Mage::helper('configurableswatches/productlist')->getSwatchAttribute();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
|
47 |
$parentProductIds = array();
|
48 |
/* @var $parentProduct Mage_Catalog_Model_Product */
|
@@ -53,6 +80,7 @@ class Mage_ConfigurableSwatches_Helper_Mediafallback extends Mage_Core_Helper_Ab
|
|
53 |
$configAttributes = Mage::getResourceModel('configurableswatches/catalog_product_attribute_super_collection')
|
54 |
->addParentProductsFilter($parentProductIds)
|
55 |
->attachEavAttributes()
|
|
|
56 |
->setStoreId($storeId)
|
57 |
;
|
58 |
|
@@ -61,9 +89,15 @@ class Mage_ConfigurableSwatches_Helper_Mediafallback extends Mage_Core_Helper_Ab
|
|
61 |
$optionLabels += $attribute->getOptionLabels();
|
62 |
}
|
63 |
|
|
|
|
|
|
|
|
|
|
|
64 |
foreach ($parentProducts as $parentProduct) {
|
65 |
$mapping = array();
|
66 |
$listSwatchValues = array();
|
|
|
67 |
|
68 |
/* @var $attribute Mage_Catalog_Model_Product_Type_Configurable_Attribute */
|
69 |
foreach ($configAttributes as $attribute) {
|
@@ -74,8 +108,10 @@ class Mage_ConfigurableSwatches_Helper_Mediafallback extends Mage_Core_Helper_Ab
|
|
74 |
|
75 |
foreach ($parentProduct->getChildrenProducts() as $childProduct) {
|
76 |
|
77 |
-
// product has no value for attribute, we can't process it
|
78 |
-
|
|
|
|
|
79 |
continue;
|
80 |
}
|
81 |
$optionId = $childProduct->getData($attribute->getAttributeCode());
|
@@ -85,11 +121,6 @@ class Mage_ConfigurableSwatches_Helper_Mediafallback extends Mage_Core_Helper_Ab
|
|
85 |
continue;
|
86 |
}
|
87 |
|
88 |
-
// normalize to all lower case before we start using them
|
89 |
-
$optionLabels = array_map(function ($value) {
|
90 |
-
return array_map('Mage_ConfigurableSwatches_Helper_Data::normalizeKey', $value);
|
91 |
-
}, $optionLabels);
|
92 |
-
|
93 |
// using default value as key unless store-specific label is present
|
94 |
$optionLabel = $optionLabels[$optionId][0];
|
95 |
if (isset($optionLabels[$optionId][$storeId])) {
|
@@ -110,7 +141,8 @@ class Mage_ConfigurableSwatches_Helper_Mediafallback extends Mage_Core_Helper_Ab
|
|
110 |
if ($attribute->getAttributeId() == $listSwatchAttr->getAttributeId()
|
111 |
&& !in_array($mapping[$optionLabel]['label'], $listSwatchValues)
|
112 |
) {
|
113 |
-
$listSwatchValues[$optionId]
|
|
|
114 |
}
|
115 |
} // end looping child products
|
116 |
} // end looping attributes
|
@@ -120,8 +152,13 @@ class Mage_ConfigurableSwatches_Helper_Mediafallback extends Mage_Core_Helper_Ab
|
|
120 |
$mapping[$key]['product_ids'] = array_unique($mapping[$key]['product_ids']);
|
121 |
}
|
122 |
|
|
|
|
|
|
|
|
|
123 |
$parentProduct->setChildAttributeLabelMapping($mapping)
|
124 |
-
->setListSwatchAttrValues($listSwatchValues)
|
|
|
125 |
} // end looping parent products
|
126 |
}
|
127 |
|
@@ -201,7 +238,12 @@ class Mage_ConfigurableSwatches_Helper_Mediafallback extends Mage_Core_Helper_Ab
|
|
201 |
/* @var $childProduct Mage_Catalog_Model_Product */
|
202 |
if ($product->hasChildrenProducts()) {
|
203 |
foreach ($product->getChildrenProducts() as $childProduct) {
|
204 |
-
|
|
|
|
|
|
|
|
|
|
|
205 |
$imagesByType[$imageType][$childProduct->getId()] = $image;
|
206 |
}
|
207 |
}
|
37 |
* - product must have children products attached
|
38 |
*
|
39 |
* @param array $parentProducts
|
40 |
+
* @deprecated use $this->attachProductChildrenAttributeMapping() instead
|
41 |
* @param $storeId
|
42 |
* @return void
|
43 |
*/
|
44 |
public function attachConfigurableProductChildrenAttributeMapping(array $parentProducts, $storeId)
|
45 |
{
|
46 |
+
return $this->attachProductChildrenAttributeMapping($parentProducts, $storeId);
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Set child_attribute_label_mapping on products with attribute label -> product mapping
|
51 |
+
* Depends on following product data:
|
52 |
+
* - product must have children products attached
|
53 |
+
*
|
54 |
+
* @param array $parentProducts
|
55 |
+
* @param $storeId
|
56 |
+
* @param bool $onlyListAttributes
|
57 |
+
* @return void
|
58 |
+
*/
|
59 |
+
public function attachProductChildrenAttributeMapping(array $parentProducts, $storeId, $onlyListAttributes = false)
|
60 |
+
{
|
61 |
+
/** @var $listSwatchAttr Mage_Eav_Model_Attribute */
|
62 |
$listSwatchAttr = Mage::helper('configurableswatches/productlist')->getSwatchAttribute();
|
63 |
+
$swatchAttributeIds = array();
|
64 |
+
if (!$onlyListAttributes) {
|
65 |
+
$swatchAttributeIds = Mage::helper('configurableswatches')->getSwatchAttributeIds();
|
66 |
+
}
|
67 |
+
if ($listSwatchAttr->getId()) {
|
68 |
+
$swatchAttributeIds[] = $listSwatchAttr->getId();
|
69 |
+
}
|
70 |
+
if (empty($swatchAttributeIds)) {
|
71 |
+
return;
|
72 |
+
}
|
73 |
|
74 |
$parentProductIds = array();
|
75 |
/* @var $parentProduct Mage_Catalog_Model_Product */
|
80 |
$configAttributes = Mage::getResourceModel('configurableswatches/catalog_product_attribute_super_collection')
|
81 |
->addParentProductsFilter($parentProductIds)
|
82 |
->attachEavAttributes()
|
83 |
+
->addFieldToFilter('eav_attributes.attribute_id', array('in' => $swatchAttributeIds))
|
84 |
->setStoreId($storeId)
|
85 |
;
|
86 |
|
89 |
$optionLabels += $attribute->getOptionLabels();
|
90 |
}
|
91 |
|
92 |
+
// normalize to all lower case before we start using them
|
93 |
+
$optionLabels = array_map(function ($value) {
|
94 |
+
return array_map('Mage_ConfigurableSwatches_Helper_Data::normalizeKey', $value);
|
95 |
+
}, $optionLabels);
|
96 |
+
|
97 |
foreach ($parentProducts as $parentProduct) {
|
98 |
$mapping = array();
|
99 |
$listSwatchValues = array();
|
100 |
+
$listSwatchStockValues = array();
|
101 |
|
102 |
/* @var $attribute Mage_Catalog_Model_Product_Type_Configurable_Attribute */
|
103 |
foreach ($configAttributes as $attribute) {
|
108 |
|
109 |
foreach ($parentProduct->getChildrenProducts() as $childProduct) {
|
110 |
|
111 |
+
// product has no value for attribute or not available, we can't process it
|
112 |
+
$isInStock = $childProduct->getStockItem()->getIsInStock();
|
113 |
+
if (!$childProduct->hasData($attribute->getAttributeCode())
|
114 |
+
|| (!$isInStock && !Mage::helper('cataloginventory')->isShowOutOfStock())) {
|
115 |
continue;
|
116 |
}
|
117 |
$optionId = $childProduct->getData($attribute->getAttributeCode());
|
121 |
continue;
|
122 |
}
|
123 |
|
|
|
|
|
|
|
|
|
|
|
124 |
// using default value as key unless store-specific label is present
|
125 |
$optionLabel = $optionLabels[$optionId][0];
|
126 |
if (isset($optionLabels[$optionId][$storeId])) {
|
141 |
if ($attribute->getAttributeId() == $listSwatchAttr->getAttributeId()
|
142 |
&& !in_array($mapping[$optionLabel]['label'], $listSwatchValues)
|
143 |
) {
|
144 |
+
$listSwatchValues[$optionId] = $mapping[$optionLabel]['label'];
|
145 |
+
$listSwatchStockValues[$optionId] = $isInStock;
|
146 |
}
|
147 |
} // end looping child products
|
148 |
} // end looping attributes
|
152 |
$mapping[$key]['product_ids'] = array_unique($mapping[$key]['product_ids']);
|
153 |
}
|
154 |
|
155 |
+
if (count($listSwatchValues)) {
|
156 |
+
$listSwatchValues = array_replace(array_intersect_key($optionLabels, $listSwatchValues),
|
157 |
+
$listSwatchValues);
|
158 |
+
}
|
159 |
$parentProduct->setChildAttributeLabelMapping($mapping)
|
160 |
+
->setListSwatchAttrValues($listSwatchValues)
|
161 |
+
->setListSwatchAttrStockValues($listSwatchStockValues);
|
162 |
} // end looping parent products
|
163 |
}
|
164 |
|
238 |
/* @var $childProduct Mage_Catalog_Model_Product */
|
239 |
if ($product->hasChildrenProducts()) {
|
240 |
foreach ($product->getChildrenProducts() as $childProduct) {
|
241 |
+
$image = $this->_resizeProductImage($childProduct, $imageType, $keepFrame);
|
242 |
+
if (!$image) {
|
243 |
+
$image = $this->_resizeProductImage($childProduct, 'image', $keepFrame);
|
244 |
+
}
|
245 |
+
|
246 |
+
if ($image) {
|
247 |
$imagesByType[$imageType][$childProduct->getId()] = $image;
|
248 |
}
|
249 |
}
|
app/code/core/Mage/ConfigurableSwatches/Model/Observer.php
CHANGED
@@ -37,8 +37,11 @@ class Mage_ConfigurableSwatches_Model_Observer extends Mage_Core_Model_Abstract
|
|
37 |
return; // exit without loading swatch functionality
|
38 |
}
|
39 |
|
40 |
-
/* @var $
|
41 |
-
$
|
|
|
|
|
|
|
42 |
|
43 |
/* @var $collection Mage_Catalog_Model_Resource_Product_Collection */
|
44 |
$collection = $observer->getCollection();
|
@@ -51,15 +54,19 @@ class Mage_ConfigurableSwatches_Model_Observer extends Mage_Core_Model_Abstract
|
|
51 |
|
52 |
$products = $collection->getItems();
|
53 |
|
54 |
-
$
|
55 |
|
56 |
-
$
|
|
|
|
|
|
|
|
|
57 |
|
58 |
-
$
|
59 |
|
60 |
/* @var $product Mage_Catalog_Model_Product */
|
61 |
foreach ($products as $product) {
|
62 |
-
$
|
63 |
Mage::helper('configurableswatches/productimg')
|
64 |
->indexProductImages($product, $product->getListSwatchAttrValues());
|
65 |
}
|
@@ -90,7 +97,7 @@ class Mage_ConfigurableSwatches_Model_Observer extends Mage_Core_Model_Abstract
|
|
90 |
|
91 |
$helper->groupMediaGalleryImages($product);
|
92 |
|
93 |
-
$helper->
|
94 |
}
|
95 |
|
96 |
/**
|
37 |
return; // exit without loading swatch functionality
|
38 |
}
|
39 |
|
40 |
+
/* @var $mediaHelper Mage_ConfigurableSwatches_Helper_Mediafallback */
|
41 |
+
$mediaHelper = Mage::helper('configurableswatches/mediafallback');
|
42 |
+
|
43 |
+
/** @var $priceHelper Mage_ConfigurableSwatches_Helper_List_Price */
|
44 |
+
$priceHelper = Mage::helper('configurableswatches/list_price');
|
45 |
|
46 |
/* @var $collection Mage_Catalog_Model_Resource_Product_Collection */
|
47 |
$collection = $observer->getCollection();
|
54 |
|
55 |
$products = $collection->getItems();
|
56 |
|
57 |
+
$mediaHelper->attachChildrenProducts($products, $collection->getStoreId());
|
58 |
|
59 |
+
$mediaHelper->attachProductChildrenAttributeMapping($products, $collection->getStoreId());
|
60 |
+
|
61 |
+
if ($priceHelper->isEnabled()) {
|
62 |
+
$priceHelper->attachConfigurableProductChildrenPricesMapping($products, $collection->getStoreId());
|
63 |
+
}
|
64 |
|
65 |
+
$mediaHelper->attachGallerySetToCollection($products, $collection->getStoreId());
|
66 |
|
67 |
/* @var $product Mage_Catalog_Model_Product */
|
68 |
foreach ($products as $product) {
|
69 |
+
$mediaHelper->groupMediaGalleryImages($product);
|
70 |
Mage::helper('configurableswatches/productimg')
|
71 |
->indexProductImages($product, $product->getListSwatchAttrValues());
|
72 |
}
|
97 |
|
98 |
$helper->groupMediaGalleryImages($product);
|
99 |
|
100 |
+
$helper->attachProductChildrenAttributeMapping(array($product), $product->getStoreId(), false);
|
101 |
}
|
102 |
|
103 |
/**
|
app/code/core/Mage/ConfigurableSwatches/Model/Resource/Catalog/Product/Attribute/Super/Collection.php
CHANGED
@@ -99,40 +99,59 @@ class Mage_ConfigurableSwatches_Model_Resource_Catalog_Product_Attribute_Super_C
|
|
99 |
*/
|
100 |
protected function _loadOptionLabels()
|
101 |
{
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
array('attr' => $this->getTable('catalog/product_super_attribute')),
|
106 |
-
array(
|
107 |
-
'product_super_attribute_id' => 'attr.product_super_attribute_id',
|
108 |
-
))
|
109 |
-
->join(
|
110 |
-
array('opt' => $this->getTable('eav/attribute_option')),
|
111 |
-
'opt.attribute_id = attr.attribute_id',
|
112 |
-
array(
|
113 |
-
'attribute_id' => 'opt.attribute_id',
|
114 |
-
'option_id' => 'opt.option_id',
|
115 |
-
))
|
116 |
-
->join(
|
117 |
-
array('lab' => $this->getTable('eav/attribute_option_value')),
|
118 |
-
'lab.option_id = opt.option_id',
|
119 |
-
array(
|
120 |
-
'label' => 'lab.value',
|
121 |
-
'store_id' => 'lab.store_id',
|
122 |
-
))
|
123 |
-
->where('attr.product_super_attribute_id IN (?)', array_keys($this->_items))
|
124 |
-
;
|
125 |
-
|
126 |
-
$result = $this->getConnection()->fetchAll($select);
|
127 |
-
foreach ($result as $data) {
|
128 |
-
$item = $this->getItemById($data['product_super_attribute_id']);
|
129 |
-
if (!is_array($labels = $item->getOptionLabels())) {
|
130 |
-
$labels = array();
|
131 |
-
}
|
132 |
-
$labels[$data['option_id']][$data['store_id']] = $data['label'];
|
133 |
-
$item->setOptionLabels($labels);
|
134 |
-
}
|
135 |
}
|
136 |
return $this;
|
137 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
}
|
99 |
*/
|
100 |
protected function _loadOptionLabels()
|
101 |
{
|
102 |
+
$labels = $this->_getOptionLabels();
|
103 |
+
foreach ($this->getItems() as $item) {
|
104 |
+
$item->setOptionLabels($labels);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
}
|
106 |
return $this;
|
107 |
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Get Option Labels
|
111 |
+
*
|
112 |
+
* @return array
|
113 |
+
*/
|
114 |
+
protected function _getOptionLabels()
|
115 |
+
{
|
116 |
+
$attributeIds = $this->_getAttributeIds();
|
117 |
+
|
118 |
+
$select = $this->getConnection()->select();
|
119 |
+
$select->from(array('options' => $this->getTable('eav/attribute_option')))
|
120 |
+
->join(
|
121 |
+
array('labels' => $this->getTable('eav/attribute_option_value')),
|
122 |
+
'labels.option_id = options.option_id',
|
123 |
+
array(
|
124 |
+
'label' => 'labels.value',
|
125 |
+
'store_id' => 'labels.store_id',
|
126 |
+
)
|
127 |
+
)
|
128 |
+
->where('options.attribute_id IN (?)', $attributeIds)
|
129 |
+
->where(
|
130 |
+
'labels.store_id IN (?)',
|
131 |
+
array(Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID, $this->getStoreId())
|
132 |
+
);
|
133 |
+
|
134 |
+
$resultSet = $this->getConnection()->query($select);
|
135 |
+
$labels = array();
|
136 |
+
while ($option = $resultSet->fetch()) {
|
137 |
+
$labels[$option['option_id']][$option['store_id']] = $option['label'];
|
138 |
+
}
|
139 |
+
return $labels;
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Get Attribute IDs
|
144 |
+
*
|
145 |
+
* @return array
|
146 |
+
*/
|
147 |
+
protected function _getAttributeIds()
|
148 |
+
{
|
149 |
+
$attributeIds = array();
|
150 |
+
foreach ($this->getItems() as $item) {
|
151 |
+
$attributeIds[] = $item->getAttributeId();
|
152 |
+
}
|
153 |
+
$attributeIds = array_unique($attributeIds);
|
154 |
+
|
155 |
+
return $attributeIds;
|
156 |
+
}
|
157 |
}
|
app/code/core/Mage/ConfigurableSwatches/etc/system.xml
CHANGED
@@ -71,6 +71,15 @@
|
|
71 |
<show_in_website>1</show_in_website>
|
72 |
<show_in_store>1</show_in_store>
|
73 |
</product_list_attribute>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
</fields>
|
75 |
</general>
|
76 |
<product_detail_dimensions translate="label comment" module="configurableswatches">
|
71 |
<show_in_website>1</show_in_website>
|
72 |
<show_in_store>1</show_in_store>
|
73 |
</product_list_attribute>
|
74 |
+
<product_list_price_change translate="label" module="configurableswatches">
|
75 |
+
<label>Dynamic Price Change for Swatches in Product Listing</label>
|
76 |
+
<frontend_type>select</frontend_type>
|
77 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
78 |
+
<sort_order>40</sort_order>
|
79 |
+
<show_in_default>1</show_in_default>
|
80 |
+
<show_in_website>1</show_in_website>
|
81 |
+
<show_in_store>1</show_in_store>
|
82 |
+
</product_list_price_change>
|
83 |
</fields>
|
84 |
</general>
|
85 |
<product_detail_dimensions translate="label comment" module="configurableswatches">
|
app/code/core/Mage/Core/Block/Abstract.php
CHANGED
@@ -36,6 +36,10 @@
|
|
36 |
*/
|
37 |
abstract class Mage_Core_Block_Abstract extends Varien_Object
|
38 |
{
|
|
|
|
|
|
|
|
|
39 |
/**
|
40 |
* Cache group Tag
|
41 |
*/
|
@@ -1289,7 +1293,13 @@ abstract class Mage_Core_Block_Abstract extends Varien_Object
|
|
1289 |
public function getCacheKey()
|
1290 |
{
|
1291 |
if ($this->hasData('cache_key')) {
|
1292 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1293 |
}
|
1294 |
/**
|
1295 |
* don't prevent recalculation by saving generated cache key
|
36 |
*/
|
37 |
abstract class Mage_Core_Block_Abstract extends Varien_Object
|
38 |
{
|
39 |
+
/**
|
40 |
+
* Prefix for cache key
|
41 |
+
*/
|
42 |
+
const CACHE_KEY_PREFIX = 'BLOCK_';
|
43 |
/**
|
44 |
* Cache group Tag
|
45 |
*/
|
1293 |
public function getCacheKey()
|
1294 |
{
|
1295 |
if ($this->hasData('cache_key')) {
|
1296 |
+
$cacheKey = $this->getData('cache_key');
|
1297 |
+
if (strpos($cacheKey, self::CACHE_KEY_PREFIX) !== 0) {
|
1298 |
+
$cacheKey = self::CACHE_KEY_PREFIX . $cacheKey;
|
1299 |
+
$this->setData('cache_key', $cacheKey);
|
1300 |
+
}
|
1301 |
+
|
1302 |
+
return $cacheKey;
|
1303 |
}
|
1304 |
/**
|
1305 |
* don't prevent recalculation by saving generated cache key
|
app/code/core/Mage/Core/Block/Template.php
CHANGED
@@ -212,7 +212,7 @@ class Mage_Core_Block_Template extends Mage_Core_Block_Abstract
|
|
212 |
|
213 |
// EXTR_SKIP protects from overriding
|
214 |
// already defined variables
|
215 |
-
extract
|
216 |
$do = $this->getDirectOutput();
|
217 |
|
218 |
if (!$do) {
|
212 |
|
213 |
// EXTR_SKIP protects from overriding
|
214 |
// already defined variables
|
215 |
+
extract($this->_viewVars, EXTR_SKIP);
|
216 |
$do = $this->getDirectOutput();
|
217 |
|
218 |
if (!$do) {
|
app/code/core/Mage/Core/Controller/Varien/Action.php
CHANGED
@@ -1054,6 +1054,7 @@ abstract class Mage_Core_Controller_Varien_Action
|
|
1054 |
return $this;
|
1055 |
}
|
1056 |
if ($content['type'] == 'filename') {
|
|
|
1057 |
$isFile = true;
|
1058 |
$file = $content['value'];
|
1059 |
$contentLength = filesize($file);
|
1054 |
return $this;
|
1055 |
}
|
1056 |
if ($content['type'] == 'filename') {
|
1057 |
+
clearstatcache();
|
1058 |
$isFile = true;
|
1059 |
$file = $content['value'];
|
1060 |
$contentLength = filesize($file);
|
app/code/core/Mage/Core/Helper/String.php
CHANGED
@@ -172,6 +172,13 @@ class Mage_Core_Helper_String extends Mage_Core_Helper_Abstract
|
|
172 |
// trim
|
173 |
if ($trim) {
|
174 |
$str = trim(preg_replace('/\s{2,}/siu', ' ', $str));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
}
|
176 |
// do a usual str_split, but safe for our encoding
|
177 |
if ((!$keepWords) || ($length < 2)) {
|
@@ -194,7 +201,14 @@ class Mage_Core_Helper_String extends Mage_Core_Helper_Abstract
|
|
194 |
$space = ' ';
|
195 |
$spaceLen = 1;
|
196 |
}
|
197 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
$currentLength = 0;
|
199 |
$result[$i] = '';
|
200 |
$space = '';
|
@@ -476,4 +490,30 @@ class Mage_Core_Helper_String extends Mage_Core_Helper_Abstract
|
|
476 |
return $this->_arrayHelper;
|
477 |
}
|
478 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
479 |
}
|
172 |
// trim
|
173 |
if ($trim) {
|
174 |
$str = trim(preg_replace('/\s{2,}/siu', ' ', $str));
|
175 |
+
/**
|
176 |
+
* In cases like:
|
177 |
+
* Mage::helper('core/string')->str_split('0 1 2 ', 2, false, true);
|
178 |
+
* the result array have elements with boolean "false" value.
|
179 |
+
* So it fixed by
|
180 |
+
*/
|
181 |
+
$strlen = $this->strlen($str);
|
182 |
}
|
183 |
// do a usual str_split, but safe for our encoding
|
184 |
if ((!$keepWords) || ($length < 2)) {
|
201 |
$space = ' ';
|
202 |
$spaceLen = 1;
|
203 |
}
|
204 |
+
/**
|
205 |
+
* The empty($result[$i]) is not appropriate, because in case with empty("0") expression returns "true",
|
206 |
+
* so in cases when string have "0" symbol, the "0" will lost.
|
207 |
+
* Try Mage::helper('core/string')->str_split("0 aa", 2, true);
|
208 |
+
* Therefore the empty($result[$i]) expression
|
209 |
+
* replaced by !isset($result[$i]) || isset($result[$i]) && $result[$i] === ''
|
210 |
+
*/
|
211 |
+
if (!isset($result[$i]) || isset($result[$i]) && $result[$i] === '') {
|
212 |
$currentLength = 0;
|
213 |
$result[$i] = '';
|
214 |
$space = '';
|
490 |
return $this->_arrayHelper;
|
491 |
}
|
492 |
|
493 |
+
/**
|
494 |
+
* Unicode compatible ord() method
|
495 |
+
*
|
496 |
+
* @param string $c char to get value from
|
497 |
+
* @return integer
|
498 |
+
*/
|
499 |
+
public function uniOrd($c)
|
500 |
+
{
|
501 |
+
$ord = 0;
|
502 |
+
$h = ord($c[0]);
|
503 |
+
|
504 |
+
if ($h <= 0x7F) {
|
505 |
+
$ord = $h;
|
506 |
+
} else if ($h < 0xC2) {
|
507 |
+
$ord = 0;
|
508 |
+
} else if ($h <= 0xDF) {
|
509 |
+
$ord = (($h & 0x1F) << 6 | (ord($c[1]) & 0x3F));
|
510 |
+
} else if ($h <= 0xEF) {
|
511 |
+
$ord = (($h & 0x0F) << 12 | (ord($c[1]) & 0x3F) << 6 | (ord($c[2]) & 0x3F));
|
512 |
+
} else if ($h <= 0xF4) {
|
513 |
+
$ord = (($h & 0x0F) << 18 | (ord($c[1]) & 0x3F) << 12 |
|
514 |
+
(ord($c[2]) & 0x3F) << 6 | (ord($c[3]) & 0x3F));
|
515 |
+
}
|
516 |
+
|
517 |
+
return $ord;
|
518 |
+
}
|
519 |
}
|
app/code/core/Mage/Core/Helper/Url.php
CHANGED
@@ -51,7 +51,7 @@ class Mage_Core_Helper_Url extends Mage_Core_Helper_Abstract
|
|
51 |
$port = (in_array($port, $defaultPorts)) ? '' : ':' . $port;
|
52 |
}
|
53 |
$url = $request->getScheme() . '://' . $request->getHttpHost() . $port . $request->getServer('REQUEST_URI');
|
54 |
-
return $url;
|
55 |
// return $this->_getUrl('*/*/*', array('_current' => true, '_use_rewrite' => true));
|
56 |
}
|
57 |
|
51 |
$port = (in_array($port, $defaultPorts)) ? '' : ':' . $port;
|
52 |
}
|
53 |
$url = $request->getScheme() . '://' . $request->getHttpHost() . $port . $request->getServer('REQUEST_URI');
|
54 |
+
return $this->escapeUrl($url);
|
55 |
// return $this->_getUrl('*/*/*', array('_current' => true, '_use_rewrite' => true));
|
56 |
}
|
57 |
|
app/code/core/Mage/Core/Model/Config.php
CHANGED
@@ -256,6 +256,9 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
|
|
256 |
if ($cacheLoad) {
|
257 |
return $this;
|
258 |
}
|
|
|
|
|
|
|
259 |
$this->loadModules();
|
260 |
$this->loadDb();
|
261 |
$this->saveCache();
|
256 |
if ($cacheLoad) {
|
257 |
return $this;
|
258 |
}
|
259 |
+
|
260 |
+
$this->_useCache = false;
|
261 |
+
|
262 |
$this->loadModules();
|
263 |
$this->loadDb();
|
264 |
$this->saveCache();
|
app/code/core/Mage/Core/Model/Email/Queue.php
CHANGED
@@ -44,8 +44,6 @@
|
|
44 |
*
|
45 |
* @category Mage
|
46 |
* @package Mage_Core
|
47 |
-
* @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
|
48 |
-
* @license http://www.magentocommerce.com/license/enterprise-edition
|
49 |
*/
|
50 |
class Mage_Core_Model_Email_Queue extends Mage_Core_Model_Abstract
|
51 |
{
|
44 |
*
|
45 |
* @category Mage
|
46 |
* @package Mage_Core
|
|
|
|
|
47 |
*/
|
48 |
class Mage_Core_Model_Email_Queue extends Mage_Core_Model_Abstract
|
49 |
{
|
app/code/core/Mage/Core/Model/Email/Template.php
CHANGED
@@ -407,6 +407,7 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Email_Template_Abst
|
|
407 |
if ($this->hasQueue() && $this->getQueue() instanceof Mage_Core_Model_Email_Queue) {
|
408 |
/** @var $emailQueue Mage_Core_Model_Email_Queue */
|
409 |
$emailQueue = $this->getQueue();
|
|
|
410 |
$emailQueue->setMessageBody($text);
|
411 |
$emailQueue->setMessageParameters(array(
|
412 |
'subject' => $subject,
|
407 |
if ($this->hasQueue() && $this->getQueue() instanceof Mage_Core_Model_Email_Queue) {
|
408 |
/** @var $emailQueue Mage_Core_Model_Email_Queue */
|
409 |
$emailQueue = $this->getQueue();
|
410 |
+
$emailQueue->clearRecipients();
|
411 |
$emailQueue->setMessageBody($text);
|
412 |
$emailQueue->setMessageParameters(array(
|
413 |
'subject' => $subject,
|
app/code/core/Mage/Core/Model/Email/Template/Abstract.php
CHANGED
@@ -149,8 +149,7 @@ abstract class Mage_Core_Model_Email_Template_Abstract extends Mage_Core_Model_T
|
|
149 |
protected function _addEmailVariables($variables, $storeId)
|
150 |
{
|
151 |
if (!isset($variables['store'])) {
|
152 |
-
$store = Mage::app()->getStore($storeId);
|
153 |
-
$variables['store'] = $store;
|
154 |
}
|
155 |
if (!isset($variables['logo_url'])) {
|
156 |
$variables['logo_url'] = $this->_getLogoUrl($storeId);
|
@@ -158,35 +157,20 @@ abstract class Mage_Core_Model_Email_Template_Abstract extends Mage_Core_Model_T
|
|
158 |
if (!isset($variables['logo_alt'])) {
|
159 |
$variables['logo_alt'] = $this->_getLogoAlt($storeId);
|
160 |
}
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
Mage_Core_Model_Store::XML_PATH_STORE_STORE_PHONE,
|
176 |
-
$storeId
|
177 |
-
);
|
178 |
-
}
|
179 |
-
if (!isset($variables['store_hours'])) {
|
180 |
-
$variables['store_hours'] = Mage::getStoreConfig(
|
181 |
-
Mage_Core_Model_Store::XML_PATH_STORE_STORE_HOURS,
|
182 |
-
$storeId
|
183 |
-
);
|
184 |
-
}
|
185 |
-
if (!isset($variables['store_email'])) {
|
186 |
-
$variables['store_email'] = Mage::getStoreConfig(
|
187 |
-
Mage_Customer_Helper_Data::XML_PATH_SUPPORT_EMAIL,
|
188 |
-
$storeId
|
189 |
-
);
|
190 |
}
|
191 |
// If template is text mode, don't include styles
|
192 |
if (!$this->isPlain()) {
|
149 |
protected function _addEmailVariables($variables, $storeId)
|
150 |
{
|
151 |
if (!isset($variables['store'])) {
|
152 |
+
$variables['store'] = Mage::app()->getStore($storeId);
|
|
|
153 |
}
|
154 |
if (!isset($variables['logo_url'])) {
|
155 |
$variables['logo_url'] = $this->_getLogoUrl($storeId);
|
157 |
if (!isset($variables['logo_alt'])) {
|
158 |
$variables['logo_alt'] = $this->_getLogoAlt($storeId);
|
159 |
}
|
160 |
+
|
161 |
+
$defaultValuesMap = array(
|
162 |
+
"logo_width" => self::XML_PATH_DESIGN_EMAIL_LOGO_WIDTH,
|
163 |
+
"logo_height" => self::XML_PATH_DESIGN_EMAIL_LOGO_HEIGHT,
|
164 |
+
"phone" => Mage_Core_Model_Store::XML_PATH_STORE_STORE_PHONE,
|
165 |
+
"store_phone" => Mage_Core_Model_Store::XML_PATH_STORE_STORE_PHONE,
|
166 |
+
"store_hours" => Mage_Core_Model_Store::XML_PATH_STORE_STORE_HOURS,
|
167 |
+
"store_email" => Mage_Customer_Helper_Data::XML_PATH_SUPPORT_EMAIL,
|
168 |
+
);
|
169 |
+
|
170 |
+
foreach ($defaultValuesMap as $variableName => $configValue) {
|
171 |
+
if (!isset($variables[$variableName])) {
|
172 |
+
$variables[$variableName] = Mage::getStoreConfig($configValue, $storeId);
|
173 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
}
|
175 |
// If template is text mode, don't include styles
|
176 |
if (!$this->isPlain()) {
|
app/code/core/Mage/Core/Model/Encryption.php
CHANGED
@@ -98,9 +98,9 @@ class Mage_Core_Model_Encryption
|
|
98 |
$hashArr = explode(':', $hash);
|
99 |
switch (count($hashArr)) {
|
100 |
case 1:
|
101 |
-
return $this->hash($password)
|
102 |
case 2:
|
103 |
-
return $this->hash($hashArr[1] . $password)
|
104 |
}
|
105 |
Mage::throwException('Invalid hash.');
|
106 |
}
|
98 |
$hashArr = explode(':', $hash);
|
99 |
switch (count($hashArr)) {
|
100 |
case 1:
|
101 |
+
return hash_equals($this->hash($password), $hash);
|
102 |
case 2:
|
103 |
+
return hash_equals($this->hash($hashArr[1] . $password), $hashArr[0]);
|
104 |
}
|
105 |
Mage::throwException('Invalid hash.');
|
106 |
}
|
app/code/core/Mage/Core/Model/File/Storage/Abstract.php
CHANGED
@@ -74,12 +74,12 @@ abstract class Mage_Core_Model_File_Storage_Abstract extends Mage_Core_Model_Abs
|
|
74 |
{
|
75 |
$path = ltrim($path, '\\/');
|
76 |
$fullPath = $this->getMediaBaseDirectory() . DS . $path;
|
77 |
-
|
78 |
if (!file_exists($fullPath) || !is_file($fullPath)) {
|
79 |
-
Mage::throwException(Mage::helper('core')->__('File %s does not exist', $fullPath));
|
80 |
}
|
81 |
if (!is_readable($fullPath)) {
|
82 |
-
Mage::throwException(Mage::helper('core')->__('File %s is not readable', $fullPath));
|
83 |
}
|
84 |
|
85 |
$path = str_replace(array('/', '\\'), '/', $path);
|
74 |
{
|
75 |
$path = ltrim($path, '\\/');
|
76 |
$fullPath = $this->getMediaBaseDirectory() . DS . $path;
|
77 |
+
$io = new Varien_Io_File();
|
78 |
if (!file_exists($fullPath) || !is_file($fullPath)) {
|
79 |
+
Mage::throwException(Mage::helper('core')->__('File %s does not exist', $io->getFilteredPath($fullPath)));
|
80 |
}
|
81 |
if (!is_readable($fullPath)) {
|
82 |
+
Mage::throwException(Mage::helper('core')->__('File %s is not readable', $io->getFilteredPath($fullPath)));
|
83 |
}
|
84 |
|
85 |
$path = str_replace(array('/', '\\'), '/', $path);
|
app/code/core/Mage/Core/Model/File/Validator/AvailablePath.php
CHANGED
@@ -92,7 +92,7 @@ class Mage_Core_Model_File_Validator_AvailablePath extends Zend_Validate_Abstrac
|
|
92 |
/**
|
93 |
* Initialize message templates with translating
|
94 |
*
|
95 |
-
* @return
|
96 |
*/
|
97 |
protected function _initMessageTemplates()
|
98 |
{
|
@@ -114,7 +114,7 @@ class Mage_Core_Model_File_Validator_AvailablePath extends Zend_Validate_Abstrac
|
|
114 |
*
|
115 |
* @param array $paths All paths masks types.
|
116 |
* E.g.: array('available' => array(...), 'protected' => array(...))
|
117 |
-
* @return
|
118 |
*/
|
119 |
public function setPaths(array $paths)
|
120 |
{
|
@@ -131,7 +131,7 @@ class Mage_Core_Model_File_Validator_AvailablePath extends Zend_Validate_Abstrac
|
|
131 |
* Set protected paths masks
|
132 |
*
|
133 |
* @param array $paths
|
134 |
-
* @return
|
135 |
*/
|
136 |
public function setProtectedPaths(array $paths)
|
137 |
{
|
@@ -143,7 +143,7 @@ class Mage_Core_Model_File_Validator_AvailablePath extends Zend_Validate_Abstrac
|
|
143 |
* Add protected paths masks
|
144 |
*
|
145 |
* @param string|array $path
|
146 |
-
* @return
|
147 |
*/
|
148 |
public function addProtectedPath($path)
|
149 |
{
|
@@ -169,7 +169,7 @@ class Mage_Core_Model_File_Validator_AvailablePath extends Zend_Validate_Abstrac
|
|
169 |
* Set available paths masks
|
170 |
*
|
171 |
* @param array $paths
|
172 |
-
* @return
|
173 |
*/
|
174 |
public function setAvailablePaths(array $paths)
|
175 |
{
|
@@ -181,7 +181,7 @@ class Mage_Core_Model_File_Validator_AvailablePath extends Zend_Validate_Abstrac
|
|
181 |
* Add available paths mask
|
182 |
*
|
183 |
* @param string|array $path
|
184 |
-
* @return
|
185 |
*/
|
186 |
public function addAvailablePath($path)
|
187 |
{
|
92 |
/**
|
93 |
* Initialize message templates with translating
|
94 |
*
|
95 |
+
* @return Mage_Core_Model_File_Validator_AvailablePath
|
96 |
*/
|
97 |
protected function _initMessageTemplates()
|
98 |
{
|
114 |
*
|
115 |
* @param array $paths All paths masks types.
|
116 |
* E.g.: array('available' => array(...), 'protected' => array(...))
|
117 |
+
* @return Mage_Core_Model_File_Validator_AvailablePath
|
118 |
*/
|
119 |
public function setPaths(array $paths)
|
120 |
{
|
131 |
* Set protected paths masks
|
132 |
*
|
133 |
* @param array $paths
|
134 |
+
* @return Mage_Core_Model_File_Validator_AvailablePath
|
135 |
*/
|
136 |
public function setProtectedPaths(array $paths)
|
137 |
{
|
143 |
* Add protected paths masks
|
144 |
*
|
145 |
* @param string|array $path
|
146 |
+
* @return Mage_Core_Model_File_Validator_AvailablePath
|
147 |
*/
|
148 |
public function addProtectedPath($path)
|
149 |
{
|
169 |
* Set available paths masks
|
170 |
*
|
171 |
* @param array $paths
|
172 |
+
* @return Mage_Core_Model_File_Validator_AvailablePath
|
173 |
*/
|
174 |
public function setAvailablePaths(array $paths)
|
175 |
{
|
181 |
* Add available paths mask
|
182 |
*
|
183 |
* @param string|array $path
|
184 |
+
* @return Mage_Core_Model_File_Validator_AvailablePath
|
185 |
*/
|
186 |
public function addAvailablePath($path)
|
187 |
{
|
app/code/core/Mage/Core/Model/Input/Filter/MaliciousCode.php
CHANGED
@@ -65,7 +65,13 @@ class Mage_Core_Model_Input_Filter_MaliciousCode implements Zend_Filter_Interfac
|
|
65 |
*/
|
66 |
public function filter($value)
|
67 |
{
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
}
|
70 |
|
71 |
/**
|
65 |
*/
|
66 |
public function filter($value)
|
67 |
{
|
68 |
+
$result = false;
|
69 |
+
do {
|
70 |
+
$subject = $result ? $result : $value;
|
71 |
+
$result = preg_replace($this->_expressions, '', $subject, -1, $count);
|
72 |
+
} while ($count !== 0);
|
73 |
+
|
74 |
+
return $result;
|
75 |
}
|
76 |
|
77 |
/**
|
app/code/core/Mage/Core/Model/Layout.php
CHANGED
@@ -552,7 +552,7 @@ class Mage_Core_Model_Layout extends Varien_Simplexml_Config
|
|
552 |
$out = '';
|
553 |
if (!empty($this->_output)) {
|
554 |
foreach ($this->_output as $callback) {
|
555 |
-
$out .= $this->getBlock($callback[0])
|
556 |
}
|
557 |
}
|
558 |
|
552 |
$out = '';
|
553 |
if (!empty($this->_output)) {
|
554 |
foreach ($this->_output as $callback) {
|
555 |
+
$out .= $this->getBlock($callback[0])->{$callback[1]}();
|
556 |
}
|
557 |
}
|
558 |
|
app/code/core/Mage/Core/Model/Resource/Url/Rewrite.php
CHANGED
@@ -134,12 +134,12 @@ class Mage_Core_Model_Resource_Url_Rewrite extends Mage_Core_Model_Resource_Db_A
|
|
134 |
public function loadByRequestPath(Mage_Core_Model_Url_Rewrite $object, $path)
|
135 |
{
|
136 |
if (!is_array($path)) {
|
137 |
-
$path = array($path);
|
138 |
}
|
139 |
|
140 |
$pathBind = array();
|
141 |
foreach ($path as $key => $url) {
|
142 |
-
$pathBind['path' . $key] = $url;
|
143 |
}
|
144 |
// Form select
|
145 |
$adapter = $this->_getReadAdapter();
|
@@ -151,7 +151,7 @@ class Mage_Core_Model_Resource_Url_Rewrite extends Mage_Core_Model_Resource_Db_A
|
|
151 |
$items = $adapter->fetchAll($select, $pathBind);
|
152 |
|
153 |
// Go through all found records and choose one with lowest penalty - earlier path in array, concrete store
|
154 |
-
$mapPenalty = array_flip(array_values($path)); // we got mapping array(path => index), lower index - better
|
155 |
$currentPenalty = null;
|
156 |
$foundItem = null;
|
157 |
foreach ($items as $item) {
|
134 |
public function loadByRequestPath(Mage_Core_Model_Url_Rewrite $object, $path)
|
135 |
{
|
136 |
if (!is_array($path)) {
|
137 |
+
$path = array(strtolower($path));
|
138 |
}
|
139 |
|
140 |
$pathBind = array();
|
141 |
foreach ($path as $key => $url) {
|
142 |
+
$pathBind['path' . $key] = strtolower($url);
|
143 |
}
|
144 |
// Form select
|
145 |
$adapter = $this->_getReadAdapter();
|
151 |
$items = $adapter->fetchAll($select, $pathBind);
|
152 |
|
153 |
// Go through all found records and choose one with lowest penalty - earlier path in array, concrete store
|
154 |
+
$mapPenalty = array_change_key_case(array_flip(array_values($path))); // we got mapping array(path => index), lower index - better
|
155 |
$currentPenalty = null;
|
156 |
$foundItem = null;
|
157 |
foreach ($items as $item) {
|
app/code/core/Mage/Core/Model/Resource/Variable/Collection.php
CHANGED
@@ -84,7 +84,7 @@ class Mage_Core_Model_Resource_Variable_Collection extends Mage_Core_Model_Resou
|
|
84 |
->join(
|
85 |
array('value_table' => $this->getTable('core/variable_value')),
|
86 |
'value_table.variable_id = main_table.variable_id',
|
87 |
-
array('value_table.
|
88 |
$this->addFieldToFilter('value_table.store_id', array('eq' => $this->getStoreId()));
|
89 |
return $this;
|
90 |
}
|
84 |
->join(
|
85 |
array('value_table' => $this->getTable('core/variable_value')),
|
86 |
'value_table.variable_id = main_table.variable_id',
|
87 |
+
array('value_table.plain_value', 'value_table.html_value'));
|
88 |
$this->addFieldToFilter('value_table.store_id', array('eq' => $this->getStoreId()));
|
89 |
return $this;
|
90 |
}
|
app/code/core/Mage/Core/Model/Session/Abstract/Varien.php
CHANGED
@@ -32,6 +32,7 @@ class Mage_Core_Model_Session_Abstract_Varien extends Varien_Object
|
|
32 |
const VALIDATOR_HTTP_X_FORVARDED_FOR_KEY = 'http_x_forwarded_for';
|
33 |
const VALIDATOR_HTTP_VIA_KEY = 'http_via';
|
34 |
const VALIDATOR_REMOTE_ADDR_KEY = 'remote_addr';
|
|
|
35 |
const SECURE_COOKIE_CHECK_KEY = '_secure_cookie_check';
|
36 |
|
37 |
/**
|
@@ -377,6 +378,16 @@ class Mage_Core_Model_Session_Abstract_Varien extends Varien_Object
|
|
377 |
return true;
|
378 |
}
|
379 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
380 |
/**
|
381 |
* Retrieve skip User Agent validation strings (Flash etc)
|
382 |
*
|
@@ -446,6 +457,14 @@ class Mage_Core_Model_Session_Abstract_Varien extends Varien_Object
|
|
446 |
return false;
|
447 |
}
|
448 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
449 |
return true;
|
450 |
}
|
451 |
|
@@ -479,6 +498,8 @@ class Mage_Core_Model_Session_Abstract_Varien extends Varien_Object
|
|
479 |
$parts[self::VALIDATOR_HTTP_USER_AGENT_KEY] = (string)$_SERVER['HTTP_USER_AGENT'];
|
480 |
}
|
481 |
|
|
|
|
|
482 |
return $parts;
|
483 |
}
|
484 |
|
32 |
const VALIDATOR_HTTP_X_FORVARDED_FOR_KEY = 'http_x_forwarded_for';
|
33 |
const VALIDATOR_HTTP_VIA_KEY = 'http_via';
|
34 |
const VALIDATOR_REMOTE_ADDR_KEY = 'remote_addr';
|
35 |
+
const VALIDATOR_SESSION_EXPIRE_TIMESTAMP = 'session_expire_timestamp';
|
36 |
const SECURE_COOKIE_CHECK_KEY = '_secure_cookie_check';
|
37 |
|
38 |
/**
|
378 |
return true;
|
379 |
}
|
380 |
|
381 |
+
/**
|
382 |
+
* Use session expire timestamp in validator key
|
383 |
+
*
|
384 |
+
* @return bool
|
385 |
+
*/
|
386 |
+
public function useValidateSessionExpire()
|
387 |
+
{
|
388 |
+
return true;
|
389 |
+
}
|
390 |
+
|
391 |
/**
|
392 |
* Retrieve skip User Agent validation strings (Flash etc)
|
393 |
*
|
457 |
return false;
|
458 |
}
|
459 |
|
460 |
+
if ($this->useValidateSessionExpire()
|
461 |
+
&& $sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP] < time() ) {
|
462 |
+
return false;
|
463 |
+
} else {
|
464 |
+
$this->_data[self::VALIDATOR_KEY][self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP]
|
465 |
+
= $validatorData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP];
|
466 |
+
}
|
467 |
+
|
468 |
return true;
|
469 |
}
|
470 |
|
498 |
$parts[self::VALIDATOR_HTTP_USER_AGENT_KEY] = (string)$_SERVER['HTTP_USER_AGENT'];
|
499 |
}
|
500 |
|
501 |
+
$parts[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP] = time() + $this->getCookie()->getLifetime();
|
502 |
+
|
503 |
return $parts;
|
504 |
}
|
505 |
|
app/code/core/Mage/Core/etc/config.xml
CHANGED
@@ -456,6 +456,14 @@
|
|
456 |
<public_files_valid_paths>
|
457 |
<protected>
|
458 |
<app>/app/*/*</app>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
459 |
</protected>
|
460 |
</public_files_valid_paths>
|
461 |
</file>
|
456 |
<public_files_valid_paths>
|
457 |
<protected>
|
458 |
<app>/app/*/*</app>
|
459 |
+
<dev>/dev/*/*</dev>
|
460 |
+
<downloader>/downloader/*/*</downloader>
|
461 |
+
<errors>/errors/*/*</errors>
|
462 |
+
<includes>/includes/*/*</includes>
|
463 |
+
<js>/js/*/*</js>
|
464 |
+
<lib>/lib/*/*</lib>
|
465 |
+
<shell>/shell/*/*</shell>
|
466 |
+
<skin>/skin/*/*</skin>
|
467 |
</protected>
|
468 |
</public_files_valid_paths>
|
469 |
</file>
|
app/code/core/Mage/Core/etc/jstranslator.xml
CHANGED
@@ -82,7 +82,7 @@
|
|
82 |
<message>Please use only visible characters and spaces.</message>
|
83 |
</validate-email-sender>
|
84 |
<validate-password translate="message" module="core">
|
85 |
-
<message>Please enter 6 or more characters
|
86 |
</validate-password>
|
87 |
<validate-admin-password translate="message" module="core">
|
88 |
<message>Please enter 7 or more characters. Password should contain both numeric and alphabetic characters.</message>
|
@@ -130,7 +130,7 @@
|
|
130 |
<message>Please select State/Province.</message>
|
131 |
</validate-state>
|
132 |
<validate-new-password translate="message" module="core">
|
133 |
-
<message>Please enter 6 or more characters
|
134 |
</validate-new-password>
|
135 |
<validate-greater-than-zero translate="message" module="core">
|
136 |
<message>Please enter a number greater than 0 in this field.</message>
|
82 |
<message>Please use only visible characters and spaces.</message>
|
83 |
</validate-email-sender>
|
84 |
<validate-password translate="message" module="core">
|
85 |
+
<message>Please enter 6 or more characters without leading or trailing spaces.</message>
|
86 |
</validate-password>
|
87 |
<validate-admin-password translate="message" module="core">
|
88 |
<message>Please enter 7 or more characters. Password should contain both numeric and alphabetic characters.</message>
|
130 |
<message>Please select State/Province.</message>
|
131 |
</validate-state>
|
132 |
<validate-new-password translate="message" module="core">
|
133 |
+
<message>Please enter 6 or more characters without leading or trailing spaces.</message>
|
134 |
</validate-new-password>
|
135 |
<validate-greater-than-zero translate="message" module="core">
|
136 |
<message>Please enter a number greater than 0 in this field.</message>
|
app/code/core/Mage/Core/etc/system.xml
CHANGED
@@ -1068,7 +1068,7 @@
|
|
1068 |
<show_in_store>0</show_in_store>
|
1069 |
</forgot_email_identity>
|
1070 |
<password_reset_link_expiration_period translate="label comment">
|
1071 |
-
<label>Recovery Link Expiration Period (
|
1072 |
<comment>Please enter a number 1 or greater in this field.</comment>
|
1073 |
<frontend_type>text</frontend_type>
|
1074 |
<validate>required-entry validate-digits validate-digits-range digits-range-1-</validate>
|
1068 |
<show_in_store>0</show_in_store>
|
1069 |
</forgot_email_identity>
|
1070 |
<password_reset_link_expiration_period translate="label comment">
|
1071 |
+
<label>Recovery Link Expiration Period (hours)</label>
|
1072 |
<comment>Please enter a number 1 or greater in this field.</comment>
|
1073 |
<frontend_type>text</frontend_type>
|
1074 |
<validate>required-entry validate-digits validate-digits-range digits-range-1-</validate>
|
app/code/core/Mage/Core/functions.php
CHANGED
@@ -375,3 +375,38 @@ if ( !function_exists('sys_get_temp_dir') ) {
|
|
375 |
}
|
376 |
}
|
377 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
375 |
}
|
376 |
}
|
377 |
}
|
378 |
+
|
379 |
+
if (!function_exists('hash_equals')) {
|
380 |
+
/**
|
381 |
+
* Compares two strings using the same time whether they're equal or not.
|
382 |
+
* A difference in length will leak
|
383 |
+
*
|
384 |
+
* @param string $known_string
|
385 |
+
* @param string $user_string
|
386 |
+
* @return boolean Returns true when the two strings are equal, false otherwise.
|
387 |
+
*/
|
388 |
+
function hash_equals($known_string, $user_string)
|
389 |
+
{
|
390 |
+
$result = 0;
|
391 |
+
|
392 |
+
if (!is_string($known_string)) {
|
393 |
+
trigger_error("hash_equals(): Expected known_string to be a string", E_USER_WARNING);
|
394 |
+
return false;
|
395 |
+
}
|
396 |
+
|
397 |
+
if (!is_string($user_string)) {
|
398 |
+
trigger_error("hash_equals(): Expected user_string to be a string", E_USER_WARNING);
|
399 |
+
return false;
|
400 |
+
}
|
401 |
+
|
402 |
+
if (strlen($known_string) != strlen($user_string)) {
|
403 |
+
return false;
|
404 |
+
}
|
405 |
+
|
406 |
+
for ($i = 0; $i < strlen($known_string); $i++) {
|
407 |
+
$result |= (ord($known_string[$i]) ^ ord($user_string[$i]));
|
408 |
+
}
|
409 |
+
|
410 |
+
return 0 === $result;
|
411 |
+
}
|
412 |
+
}
|
app/code/core/Mage/Cron/Model/Schedule.php
CHANGED
@@ -215,6 +215,10 @@ class Mage_Cron_Model_Schedule extends Mage_Core_Model_Abstract
|
|
215 |
*/
|
216 |
public function tryLockJob($oldStatus = self::STATUS_PENDING)
|
217 |
{
|
218 |
-
|
|
|
|
|
|
|
|
|
219 |
}
|
220 |
}
|
215 |
*/
|
216 |
public function tryLockJob($oldStatus = self::STATUS_PENDING)
|
217 |
{
|
218 |
+
$result = $this->_getResource()->trySetJobStatusAtomic($this->getId(), self::STATUS_RUNNING, $oldStatus);
|
219 |
+
if ($result) {
|
220 |
+
$this->setStatus(self::STATUS_RUNNING);
|
221 |
+
}
|
222 |
+
return $result;
|
223 |
}
|
224 |
}
|
app/code/core/Mage/Customer/Block/Address/Book.php
CHANGED
@@ -56,7 +56,8 @@ class Mage_Customer_Block_Address_Book extends Mage_Core_Block_Template
|
|
56 |
|
57 |
public function getDeleteUrl()
|
58 |
{
|
59 |
-
return $this->getUrl('customer/address/delete'
|
|
|
60 |
}
|
61 |
|
62 |
public function getAddressEditUrl($address)
|
56 |
|
57 |
public function getDeleteUrl()
|
58 |
{
|
59 |
+
return $this->getUrl('customer/address/delete',
|
60 |
+
array(Mage_Core_Model_Url::FORM_KEY => Mage::getSingleton('core/session')->getFormKey()));
|
61 |
}
|
62 |
|
63 |
public function getAddressEditUrl($address)
|
app/code/core/Mage/Customer/Helper/Data.php
CHANGED
@@ -85,6 +85,13 @@ class Mage_Customer_Helper_Data extends Mage_Core_Helper_Abstract
|
|
85 |
const XML_PATH_CUSTOMER_REQUIRE_ADMIN_USER_TO_CHANGE_USER_PASSWORD
|
86 |
= 'customer/password/require_admin_user_to_change_user_password';
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
/**
|
89 |
* VAT class constants
|
90 |
*/
|
@@ -483,6 +490,36 @@ class Mage_Customer_Helper_Data extends Mage_Core_Helper_Abstract
|
|
483 |
return (int)Mage::getStoreConfig(Mage_Customer_Model_Group::XML_PATH_DEFAULT_ID, $store);
|
484 |
}
|
485 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
486 |
/**
|
487 |
* Retrieve customer group ID based on his VAT number
|
488 |
*
|
85 |
const XML_PATH_CUSTOMER_REQUIRE_ADMIN_USER_TO_CHANGE_USER_PASSWORD
|
86 |
= 'customer/password/require_admin_user_to_change_user_password';
|
87 |
|
88 |
+
/**
|
89 |
+
* Configuration path to password forgotten flow change
|
90 |
+
*/
|
91 |
+
const XML_PATH_CUSTOMER_FORGOT_PASSWORD_FLOW_SECURE = 'admin/security/forgot_password_flow_secure';
|
92 |
+
const XML_PATH_CUSTOMER_FORGOT_PASSWORD_EMAIL_TIMES = 'admin/security/forgot_password_email_times';
|
93 |
+
const XML_PATH_CUSTOMER_FORGOT_PASSWORD_IP_TIMES = 'admin/security/forgot_password_ip_times';
|
94 |
+
|
95 |
/**
|
96 |
* VAT class constants
|
97 |
*/
|
490 |
return (int)Mage::getStoreConfig(Mage_Customer_Model_Group::XML_PATH_DEFAULT_ID, $store);
|
491 |
}
|
492 |
|
493 |
+
/**
|
494 |
+
* Retrieve forgot password flow secure type
|
495 |
+
*
|
496 |
+
* @return int
|
497 |
+
*/
|
498 |
+
public function getCustomerForgotPasswordFlowSecure()
|
499 |
+
{
|
500 |
+
return (int)Mage::getStoreConfig(self::XML_PATH_CUSTOMER_FORGOT_PASSWORD_FLOW_SECURE);
|
501 |
+
}
|
502 |
+
|
503 |
+
/**
|
504 |
+
* Retrieve forgot password requests to times per 24 hours from 1 e-mail
|
505 |
+
*
|
506 |
+
* @return int
|
507 |
+
*/
|
508 |
+
public function getCustomerForgotPasswordEmailTimes()
|
509 |
+
{
|
510 |
+
return (int)Mage::getStoreConfig(self::XML_PATH_CUSTOMER_FORGOT_PASSWORD_EMAIL_TIMES);
|
511 |
+
}
|
512 |
+
|
513 |
+
/**
|
514 |
+
* Retrieve forgot password requests to times per hour from 1 IP
|
515 |
+
*
|
516 |
+
* @return int
|
517 |
+
*/
|
518 |
+
public function getCustomerForgotPasswordIpTimes()
|
519 |
+
{
|
520 |
+
return (int)Mage::getStoreConfig(self::XML_PATH_CUSTOMER_FORGOT_PASSWORD_IP_TIMES);
|
521 |
+
}
|
522 |
+
|
523 |
/**
|
524 |
* Retrieve customer group ID based on his VAT number
|
525 |
*
|
app/code/core/Mage/Customer/Model/Customer.php
CHANGED
@@ -46,6 +46,8 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract
|
|
46 |
const XML_PATH_CONFIRM_EMAIL_TEMPLATE = 'customer/create_account/email_confirmation_template';
|
47 |
const XML_PATH_CONFIRMED_EMAIL_TEMPLATE = 'customer/create_account/email_confirmed_template';
|
48 |
const XML_PATH_GENERATE_HUMAN_FRIENDLY_ID = 'customer/create_account/generate_human_friendly_id';
|
|
|
|
|
49 |
/**#@-*/
|
50 |
|
51 |
/**#@+
|
@@ -66,6 +68,11 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract
|
|
66 |
|
67 |
const CACHE_TAG = 'customer';
|
68 |
|
|
|
|
|
|
|
|
|
|
|
69 |
/**
|
70 |
* Model event prefix
|
71 |
*
|
@@ -385,7 +392,7 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract
|
|
385 |
public function hashPassword($password, $salt = null)
|
386 |
{
|
387 |
return $this->_getHelper('core')
|
388 |
-
->getHash($password, !is_null($salt) ? $salt : Mage_Admin_Model_User::HASH_SALT_LENGTH);
|
389 |
}
|
390 |
|
391 |
/**
|
@@ -585,10 +592,11 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract
|
|
585 |
* @param string $type
|
586 |
* @param string $backUrl
|
587 |
* @param string $storeId
|
|
|
588 |
* @throws Mage_Core_Exception
|
589 |
* @return Mage_Customer_Model_Customer
|
590 |
*/
|
591 |
-
public function sendNewAccountEmail($type = 'registered', $backUrl = '', $storeId = '0')
|
592 |
{
|
593 |
$types = array(
|
594 |
'registered' => self::XML_PATH_REGISTER_EMAIL_TEMPLATE, // welcome email, when confirmation is disabled
|
@@ -603,8 +611,10 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract
|
|
603 |
$storeId = $this->_getWebsiteStoreId($this->getSendemailStoreId());
|
604 |
}
|
605 |
|
|
|
606 |
$this->_sendEmailTemplate($types[$type], self::XML_PATH_REGISTER_EMAIL_IDENTITY,
|
607 |
array('customer' => $this, 'back_url' => $backUrl), $storeId);
|
|
|
608 |
|
609 |
return $this;
|
610 |
}
|
@@ -655,6 +665,25 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract
|
|
655 |
return $this;
|
656 |
}
|
657 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
658 |
/**
|
659 |
* Send corresponding email template
|
660 |
*
|
@@ -662,14 +691,16 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract
|
|
662 |
* @param string $emailSender configuration path of email identity
|
663 |
* @param array $templateParams
|
664 |
* @param int|null $storeId
|
|
|
665 |
* @return Mage_Customer_Model_Customer
|
666 |
*/
|
667 |
-
protected function _sendEmailTemplate($template, $sender, $templateParams = array(), $storeId = null)
|
668 |
{
|
|
|
669 |
/** @var $mailer Mage_Core_Model_Email_Template_Mailer */
|
670 |
$mailer = Mage::getModel('core/email_template_mailer');
|
671 |
$emailInfo = Mage::getModel('core/email_info');
|
672 |
-
$emailInfo->addTo($
|
673 |
$mailer->addEmailInfo($emailInfo);
|
674 |
|
675 |
// Set all required params and send emails
|
@@ -838,8 +869,9 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract
|
|
838 |
if (!$this->getId() && !Zend_Validate::is($password , 'NotEmpty')) {
|
839 |
$errors[] = Mage::helper('customer')->__('The password cannot be empty.');
|
840 |
}
|
841 |
-
if (strlen($password) && !Zend_Validate::is($password, 'StringLength', array(
|
842 |
-
$errors[] = Mage::helper('customer')
|
|
|
843 |
}
|
844 |
$confirmation = $this->getPasswordConfirmation();
|
845 |
if ($password != $confirmation) {
|
@@ -866,6 +898,32 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract
|
|
866 |
return $errors;
|
867 |
}
|
868 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
869 |
/**
|
870 |
* Import customer data from text array
|
871 |
*
|
@@ -1339,8 +1397,8 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract
|
|
1339 |
return true;
|
1340 |
}
|
1341 |
|
1342 |
-
$
|
1343 |
-
if ($
|
1344 |
return true;
|
1345 |
}
|
1346 |
|
46 |
const XML_PATH_CONFIRM_EMAIL_TEMPLATE = 'customer/create_account/email_confirmation_template';
|
47 |
const XML_PATH_CONFIRMED_EMAIL_TEMPLATE = 'customer/create_account/email_confirmed_template';
|
48 |
const XML_PATH_GENERATE_HUMAN_FRIENDLY_ID = 'customer/create_account/generate_human_friendly_id';
|
49 |
+
const XML_PATH_CHANGED_PASSWORD_OR_EMAIL_TEMPLATE = 'customer/changed_account/password_or_email_template';
|
50 |
+
const XML_PATH_CHANGED_PASSWORD_OR_EMAIL_IDENTITY = 'customer/changed_account/password_or_email_identity';
|
51 |
/**#@-*/
|
52 |
|
53 |
/**#@+
|
68 |
|
69 |
const CACHE_TAG = 'customer';
|
70 |
|
71 |
+
/**
|
72 |
+
* Minimum Password Length
|
73 |
+
*/
|
74 |
+
const MINIMUM_PASSWORD_LENGTH = 6;
|
75 |
+
|
76 |
/**
|
77 |
* Model event prefix
|
78 |
*
|
392 |
public function hashPassword($password, $salt = null)
|
393 |
{
|
394 |
return $this->_getHelper('core')
|
395 |
+
->getHash(trim($password), !is_null($salt) ? $salt : Mage_Admin_Model_User::HASH_SALT_LENGTH);
|
396 |
}
|
397 |
|
398 |
/**
|
592 |
* @param string $type
|
593 |
* @param string $backUrl
|
594 |
* @param string $storeId
|
595 |
+
* @param string $password
|
596 |
* @throws Mage_Core_Exception
|
597 |
* @return Mage_Customer_Model_Customer
|
598 |
*/
|
599 |
+
public function sendNewAccountEmail($type = 'registered', $backUrl = '', $storeId = '0', $password = '')
|
600 |
{
|
601 |
$types = array(
|
602 |
'registered' => self::XML_PATH_REGISTER_EMAIL_TEMPLATE, // welcome email, when confirmation is disabled
|
611 |
$storeId = $this->_getWebsiteStoreId($this->getSendemailStoreId());
|
612 |
}
|
613 |
|
614 |
+
$this->setPassword($password);
|
615 |
$this->_sendEmailTemplate($types[$type], self::XML_PATH_REGISTER_EMAIL_IDENTITY,
|
616 |
array('customer' => $this, 'back_url' => $backUrl), $storeId);
|
617 |
+
$this->cleanPasswordsValidationData();
|
618 |
|
619 |
return $this;
|
620 |
}
|
665 |
return $this;
|
666 |
}
|
667 |
|
668 |
+
/**
|
669 |
+
* Send info email about changed password or email
|
670 |
+
*
|
671 |
+
* @return Mage_Customer_Model_Customer
|
672 |
+
*/
|
673 |
+
public function sendChangedPasswordOrEmail()
|
674 |
+
{
|
675 |
+
$storeId = $this->getStoreId();
|
676 |
+
if (!$storeId) {
|
677 |
+
$storeId = $this->_getWebsiteStoreId();
|
678 |
+
}
|
679 |
+
|
680 |
+
$this->_sendEmailTemplate(self::XML_PATH_CHANGED_PASSWORD_OR_EMAIL_TEMPLATE,
|
681 |
+
self::XML_PATH_CHANGED_PASSWORD_OR_EMAIL_IDENTITY,
|
682 |
+
array('customer' => $this), $storeId, $this->getOldEmail());
|
683 |
+
|
684 |
+
return $this;
|
685 |
+
}
|
686 |
+
|
687 |
/**
|
688 |
* Send corresponding email template
|
689 |
*
|
691 |
* @param string $emailSender configuration path of email identity
|
692 |
* @param array $templateParams
|
693 |
* @param int|null $storeId
|
694 |
+
* @param string|null $customerEmail
|
695 |
* @return Mage_Customer_Model_Customer
|
696 |
*/
|
697 |
+
protected function _sendEmailTemplate($template, $sender, $templateParams = array(), $storeId = null, $customerEmail = null)
|
698 |
{
|
699 |
+
$customerEmail = ($customerEmail) ? $customerEmail : $this->getEmail();
|
700 |
/** @var $mailer Mage_Core_Model_Email_Template_Mailer */
|
701 |
$mailer = Mage::getModel('core/email_template_mailer');
|
702 |
$emailInfo = Mage::getModel('core/email_info');
|
703 |
+
$emailInfo->addTo($customerEmail, $this->getName());
|
704 |
$mailer->addEmailInfo($emailInfo);
|
705 |
|
706 |
// Set all required params and send emails
|
869 |
if (!$this->getId() && !Zend_Validate::is($password , 'NotEmpty')) {
|
870 |
$errors[] = Mage::helper('customer')->__('The password cannot be empty.');
|
871 |
}
|
872 |
+
if (strlen($password) && !Zend_Validate::is($password, 'StringLength', array(self::MINIMUM_PASSWORD_LENGTH))) {
|
873 |
+
$errors[] = Mage::helper('customer')
|
874 |
+
->__('The minimum password length is %s', self::MINIMUM_PASSWORD_LENGTH);
|
875 |
}
|
876 |
$confirmation = $this->getPasswordConfirmation();
|
877 |
if ($password != $confirmation) {
|
898 |
return $errors;
|
899 |
}
|
900 |
|
901 |
+
/**
|
902 |
+
* Validate customer attribute values on password reset
|
903 |
+
* @return bool
|
904 |
+
*/
|
905 |
+
public function validateResetPassword()
|
906 |
+
{
|
907 |
+
$errors = array();
|
908 |
+
$password = $this->getPassword();
|
909 |
+
if (!Zend_Validate::is($password, 'NotEmpty')) {
|
910 |
+
$errors[] = Mage::helper('customer')->__('The password cannot be empty.');
|
911 |
+
}
|
912 |
+
if (!Zend_Validate::is($password, 'StringLength', array(self::MINIMUM_PASSWORD_LENGTH))) {
|
913 |
+
$errors[] = Mage::helper('customer')
|
914 |
+
->__('The minimum password length is %s', self::MINIMUM_PASSWORD_LENGTH);
|
915 |
+
}
|
916 |
+
$confirmation = $this->getPasswordConfirmation();
|
917 |
+
if ($password != $confirmation) {
|
918 |
+
$errors[] = Mage::helper('customer')->__('Please make sure your passwords match.');
|
919 |
+
}
|
920 |
+
|
921 |
+
if (empty($errors)) {
|
922 |
+
return true;
|
923 |
+
}
|
924 |
+
return $errors;
|
925 |
+
}
|
926 |
+
|
927 |
/**
|
928 |
* Import customer data from text array
|
929 |
*
|
1397 |
return true;
|
1398 |
}
|
1399 |
|
1400 |
+
$hoursDifference = floor(($currentTimestamp - $tokenTimestamp) / (60 * 60));
|
1401 |
+
if ($hoursDifference >= $tokenExpirationPeriod) {
|
1402 |
return true;
|
1403 |
}
|
1404 |
|
app/code/core/Mage/Customer/Model/Flowpassword.php
ADDED
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Customer
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Customer flow password info Model
|
30 |
+
*
|
31 |
+
* @category Mage
|
32 |
+
* @package Mage_Customer
|
33 |
+
* @author Magento Core Team <core@magentocommerce.com>
|
34 |
+
*/
|
35 |
+
class Mage_Customer_Model_Flowpassword extends Mage_Core_Model_Abstract
|
36 |
+
{
|
37 |
+
protected function _construct()
|
38 |
+
{
|
39 |
+
$this->_init('customer/flowpassword');
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Prepare data before save
|
44 |
+
*
|
45 |
+
* @return Mage_Core_Model_Abstract
|
46 |
+
*/
|
47 |
+
protected function _beforeSave()
|
48 |
+
{
|
49 |
+
$this->_prepareData();
|
50 |
+
return parent::_beforeSave();
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Prepare customer flow password data
|
55 |
+
*
|
56 |
+
* @return Mage_Customer_Model_Flowpassword
|
57 |
+
*/
|
58 |
+
protected function _prepareData()
|
59 |
+
{
|
60 |
+
$validatorData = Mage::getSingleton('customer/session')->getValidatorData();
|
61 |
+
$this->setIp($validatorData[Mage_Customer_Model_Session::VALIDATOR_REMOTE_ADDR_KEY])
|
62 |
+
->setRequestedDate(Mage::getModel('core/date')->date());
|
63 |
+
return $this;
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Check forgot password requests to times per 24 hours from 1 e-mail
|
68 |
+
*
|
69 |
+
* @param string $email
|
70 |
+
* @return bool
|
71 |
+
*/
|
72 |
+
public function checkCustomerForgotPasswordFlowEmail($email)
|
73 |
+
{
|
74 |
+
$helper = Mage::helper('customer');
|
75 |
+
$checkForgotPasswordFlowTypes = array(
|
76 |
+
Mage_Adminhtml_Model_System_Config_Source_Customer_Forgotpassword::FORGOTPASS_FLOW_IP_EMAIL,
|
77 |
+
Mage_Adminhtml_Model_System_Config_Source_Customer_Forgotpassword::FORGOTPASS_FLOW_EMAIL
|
78 |
+
);
|
79 |
+
|
80 |
+
if (in_array($helper->getCustomerForgotPasswordFlowSecure(), $checkForgotPasswordFlowTypes)) {
|
81 |
+
$forgotPassword = $this->getCollection()
|
82 |
+
->addFieldToFilter('email', array('eq' => $email))
|
83 |
+
->addFieldToFilter('requested_date',
|
84 |
+
array('gt' => Mage::getModel('core/date')->date(null, '-1 day')));
|
85 |
+
|
86 |
+
if ($forgotPassword->getSize() > $helper->getCustomerForgotPasswordEmailTimes()) {
|
87 |
+
return false;
|
88 |
+
}
|
89 |
+
}
|
90 |
+
return true;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Check forgot password requests to times per hour from 1 IP
|
95 |
+
*
|
96 |
+
* @return bool
|
97 |
+
*/
|
98 |
+
public function checkCustomerForgotPasswordFlowIp()
|
99 |
+
{
|
100 |
+
$helper = Mage::helper('customer');
|
101 |
+
$validatorData = Mage::getSingleton('customer/session')->getValidatorData();
|
102 |
+
$remoteAddr = $validatorData[Mage_Customer_Model_Session::VALIDATOR_REMOTE_ADDR_KEY];
|
103 |
+
$checkForgotPasswordFlowTypes = array(
|
104 |
+
Mage_Adminhtml_Model_System_Config_Source_Customer_Forgotpassword::FORGOTPASS_FLOW_IP_EMAIL,
|
105 |
+
Mage_Adminhtml_Model_System_Config_Source_Customer_Forgotpassword::FORGOTPASS_FLOW_IP
|
106 |
+
);
|
107 |
+
|
108 |
+
if (in_array($helper->getCustomerForgotPasswordFlowSecure(), $checkForgotPasswordFlowTypes) && $remoteAddr) {
|
109 |
+
$forgotPassword = $this->getCollection()
|
110 |
+
->addFieldToFilter('ip', array('eq' => $remoteAddr))
|
111 |
+
->addFieldToFilter('requested_date',
|
112 |
+
array('gt' => Mage::getModel('core/date')->date(null, '-1 hour')));
|
113 |
+
|
114 |
+
if ($forgotPassword->getSize() > $helper->getCustomerForgotPasswordIpTimes()) {
|
115 |
+
return false;
|
116 |
+
}
|
117 |
+
}
|
118 |
+
return true;
|
119 |
+
}
|
120 |
+
}
|
121 |
+
|
app/code/core/Mage/Customer/Model/Observer.php
CHANGED
@@ -141,7 +141,8 @@ class Mage_Customer_Model_Observer
|
|
141 |
$customerAddress = $observer->getCustomerAddress();
|
142 |
$customer = $customerAddress->getCustomer();
|
143 |
|
144 |
-
|
|
|
145 |
|| Mage::registry(self::VIV_PROCESSED_FLAG)
|
146 |
|| !$this->_canProcessAddress($customerAddress)
|
147 |
) {
|
@@ -218,4 +219,15 @@ class Mage_Customer_Model_Observer
|
|
218 |
);
|
219 |
$customer->save();
|
220 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
}
|
141 |
$customerAddress = $observer->getCustomerAddress();
|
142 |
$customer = $customerAddress->getCustomer();
|
143 |
|
144 |
+
$store = Mage::app()->getStore()->isAdmin() ? $customer->getStore() : null;
|
145 |
+
if (!Mage::helper('customer/address')->isVatValidationEnabled($store)
|
146 |
|| Mage::registry(self::VIV_PROCESSED_FLAG)
|
147 |
|| !$this->_canProcessAddress($customerAddress)
|
148 |
) {
|
219 |
);
|
220 |
$customer->save();
|
221 |
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Clear customer flow password table
|
225 |
+
*
|
226 |
+
*/
|
227 |
+
public function deleteCustomerFlowPassword()
|
228 |
+
{
|
229 |
+
$connection = Mage::getSingleton('core/resource')->getConnection('write');
|
230 |
+
$condition = array('requested_date < ?' => Mage::getModel('core/date')->date(null, '-1 day'));
|
231 |
+
$connection->delete($connection->getTableName('customer_flowpassword'), $condition);
|
232 |
+
}
|
233 |
}
|
app/code/core/Mage/Customer/Model/Resource/Flowpassword.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Customer
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Customer flow password info resource model
|
30 |
+
*
|
31 |
+
* @category Mage
|
32 |
+
* @package Mage_Customer
|
33 |
+
* @author Magento Core Team <core@magentocommerce.com>
|
34 |
+
*/
|
35 |
+
class Mage_Customer_Model_Resource_Flowpassword extends Mage_Core_Model_Resource_Db_Abstract
|
36 |
+
{
|
37 |
+
/**
|
38 |
+
* Resource initialization
|
39 |
+
*/
|
40 |
+
protected function _construct()
|
41 |
+
{
|
42 |
+
$this->_init('customer/flowpassword', 'flowpassword_id');
|
43 |
+
}
|
44 |
+
}
|
app/code/core/Mage/Customer/Model/Resource/Flowpassword/Collection.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Customer
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Customer flow password info collection
|
30 |
+
*
|
31 |
+
* @category Mage
|
32 |
+
* @package Mage_Customer
|
33 |
+
* @author Magento Core Team <core@magentocommerce.com>
|
34 |
+
*/
|
35 |
+
class Mage_Customer_Model_Resource_Flowpassword_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
|
36 |
+
{
|
37 |
+
/**
|
38 |
+
* Resource initialization
|
39 |
+
*/
|
40 |
+
protected function _construct()
|
41 |
+
{
|
42 |
+
$this->_init('customer/flowpassword');
|
43 |
+
}
|
44 |
+
}
|
app/code/core/Mage/Customer/controllers/AccountController.php
CHANGED
@@ -339,7 +339,8 @@ class Mage_Customer_AccountController extends Mage_Core_Controller_Front_Action
|
|
339 |
$customer->sendNewAccountEmail(
|
340 |
'confirmation',
|
341 |
$session->getBeforeAuthUrl(),
|
342 |
-
$store->getId()
|
|
|
343 |
);
|
344 |
$customerHelper = $this->_getHelper('customer');
|
345 |
$session->addSuccess($this->__('Account confirmation is required. Please, check your email for the confirmation link. To resend the confirmation email please <a href="%s">click here</a>.',
|
@@ -571,7 +572,8 @@ class Mage_Customer_AccountController extends Mage_Core_Controller_Front_Action
|
|
571 |
$customer->sendNewAccountEmail(
|
572 |
$isJustConfirmed ? 'confirmed' : 'registered',
|
573 |
'',
|
574 |
-
Mage::app()->getStore()->getId()
|
|
|
575 |
);
|
576 |
|
577 |
$successUrl = $this->_getUrl('*/*/index', array('_secure' => true));
|
@@ -722,6 +724,25 @@ class Mage_Customer_AccountController extends Mage_Core_Controller_Front_Action
|
|
722 |
{
|
723 |
$email = (string) $this->getRequest()->getPost('email');
|
724 |
if ($email) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
725 |
if (!Zend_Validate::is($email, 'EmailAddress')) {
|
726 |
$this->_getSession()->setForgottenEmail($email);
|
727 |
$this->_getSession()->addError($this->__('Invalid email address.'));
|
@@ -825,7 +846,7 @@ class Mage_Customer_AccountController extends Mage_Core_Controller_Front_Action
|
|
825 |
|
826 |
$customer->setPassword($password);
|
827 |
$customer->setPasswordConfirmation($passwordConfirmation);
|
828 |
-
$validationErrorMessages = $customer->
|
829 |
if (is_array($validationErrorMessages)) {
|
830 |
$errorMessages = array_merge($errorMessages, $validationErrorMessages);
|
831 |
}
|
@@ -927,7 +948,7 @@ class Mage_Customer_AccountController extends Mage_Core_Controller_Front_Action
|
|
927 |
if ($this->getRequest()->isPost()) {
|
928 |
/** @var $customer Mage_Customer_Model_Customer */
|
929 |
$customer = $this->_getSession()->getCustomer();
|
930 |
-
|
931 |
/** @var $customerForm Mage_Customer_Model_Form */
|
932 |
$customerForm = $this->_getModel('customer/form');
|
933 |
$customerForm->setFormCode('customer_account_edit')
|
@@ -943,32 +964,30 @@ class Mage_Customer_AccountController extends Mage_Core_Controller_Front_Action
|
|
943 |
$customerForm->compactData($customerData);
|
944 |
$errors = array();
|
945 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
946 |
// If password change was requested then add it to common validation scheme
|
947 |
-
|
948 |
-
|
|
|
949 |
$newPass = $this->getRequest()->getPost('password');
|
950 |
$confPass = $this->getRequest()->getPost('confirmation');
|
951 |
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
if ($customer->hashPassword($currPass, $salt) == $oldPass) {
|
960 |
-
if (strlen($newPass)) {
|
961 |
-
/**
|
962 |
-
* Set entered password and its confirmation - they
|
963 |
-
* will be validated later to match each other and be of right length
|
964 |
-
*/
|
965 |
-
$customer->setPassword($newPass);
|
966 |
-
$customer->setPasswordConfirmation($confPass);
|
967 |
-
} else {
|
968 |
-
$errors[] = $this->__('New password field cannot be empty.');
|
969 |
-
}
|
970 |
} else {
|
971 |
-
$errors[] = $this->__('
|
972 |
}
|
973 |
}
|
974 |
|
@@ -990,10 +1009,21 @@ class Mage_Customer_AccountController extends Mage_Core_Controller_Front_Action
|
|
990 |
|
991 |
try {
|
992 |
$customer->cleanPasswordsValidationData();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
993 |
$customer->save();
|
994 |
$this->_getSession()->setCustomer($customer)
|
995 |
->addSuccess($this->__('The account information has been saved.'));
|
996 |
|
|
|
|
|
|
|
|
|
997 |
$this->_redirect('customer/account');
|
998 |
return;
|
999 |
} catch (Mage_Core_Exception $e) {
|
339 |
$customer->sendNewAccountEmail(
|
340 |
'confirmation',
|
341 |
$session->getBeforeAuthUrl(),
|
342 |
+
$store->getId(),
|
343 |
+
$this->getRequest()->getPost('password')
|
344 |
);
|
345 |
$customerHelper = $this->_getHelper('customer');
|
346 |
$session->addSuccess($this->__('Account confirmation is required. Please, check your email for the confirmation link. To resend the confirmation email please <a href="%s">click here</a>.',
|
572 |
$customer->sendNewAccountEmail(
|
573 |
$isJustConfirmed ? 'confirmed' : 'registered',
|
574 |
'',
|
575 |
+
Mage::app()->getStore()->getId(),
|
576 |
+
$this->getRequest()->getPost('password')
|
577 |
);
|
578 |
|
579 |
$successUrl = $this->_getUrl('*/*/index', array('_secure' => true));
|
724 |
{
|
725 |
$email = (string) $this->getRequest()->getPost('email');
|
726 |
if ($email) {
|
727 |
+
/**
|
728 |
+
* @var $flowPassword Mage_Customer_Model_Flowpassword
|
729 |
+
*/
|
730 |
+
$flowPassword = $this->_getModel('customer/flowpassword');
|
731 |
+
$flowPassword->setEmail($email)->save();
|
732 |
+
|
733 |
+
if (!$flowPassword->checkCustomerForgotPasswordFlowEmail($email)) {
|
734 |
+
$this->_getSession()
|
735 |
+
->addError($this->__('You have exceeded requests to times per 24 hours from 1 e-mail.'));
|
736 |
+
$this->_redirect('*/*/forgotpassword');
|
737 |
+
return;
|
738 |
+
}
|
739 |
+
|
740 |
+
if (!$flowPassword->checkCustomerForgotPasswordFlowIp()) {
|
741 |
+
$this->_getSession()->addError($this->__('You have exceeded requests to times per hour from 1 IP.'));
|
742 |
+
$this->_redirect('*/*/forgotpassword');
|
743 |
+
return;
|
744 |
+
}
|
745 |
+
|
746 |
if (!Zend_Validate::is($email, 'EmailAddress')) {
|
747 |
$this->_getSession()->setForgottenEmail($email);
|
748 |
$this->_getSession()->addError($this->__('Invalid email address.'));
|
846 |
|
847 |
$customer->setPassword($password);
|
848 |
$customer->setPasswordConfirmation($passwordConfirmation);
|
849 |
+
$validationErrorMessages = $customer->validateResetPassword();
|
850 |
if (is_array($validationErrorMessages)) {
|
851 |
$errorMessages = array_merge($errorMessages, $validationErrorMessages);
|
852 |
}
|
948 |
if ($this->getRequest()->isPost()) {
|
949 |
/** @var $customer Mage_Customer_Model_Customer */
|
950 |
$customer = $this->_getSession()->getCustomer();
|
951 |
+
$customer->setOldEmail($customer->getEmail());
|
952 |
/** @var $customerForm Mage_Customer_Model_Form */
|
953 |
$customerForm = $this->_getModel('customer/form');
|
954 |
$customerForm->setFormCode('customer_account_edit')
|
964 |
$customerForm->compactData($customerData);
|
965 |
$errors = array();
|
966 |
|
967 |
+
if (!$customer->validatePassword($this->getRequest()->getPost('current_password'))) {
|
968 |
+
$errors[] = $this->__('Invalid current password');
|
969 |
+
}
|
970 |
+
|
971 |
+
// If email change was requested then set flag
|
972 |
+
$isChangeEmail = ($customer->getOldEmail() != $customer->getEmail()) ? true : false;
|
973 |
+
$customer->setIsChangeEmail($isChangeEmail);
|
974 |
+
|
975 |
// If password change was requested then add it to common validation scheme
|
976 |
+
$customer->setIsChangePassword($this->getRequest()->getParam('change_password'));
|
977 |
+
|
978 |
+
if ($customer->getIsChangePassword()) {
|
979 |
$newPass = $this->getRequest()->getPost('password');
|
980 |
$confPass = $this->getRequest()->getPost('confirmation');
|
981 |
|
982 |
+
if (strlen($newPass)) {
|
983 |
+
/**
|
984 |
+
* Set entered password and its confirmation - they
|
985 |
+
* will be validated later to match each other and be of right length
|
986 |
+
*/
|
987 |
+
$customer->setPassword($newPass);
|
988 |
+
$customer->setPasswordConfirmation($confPass);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
989 |
} else {
|
990 |
+
$errors[] = $this->__('New password field cannot be empty.');
|
991 |
}
|
992 |
}
|
993 |
|
1009 |
|
1010 |
try {
|
1011 |
$customer->cleanPasswordsValidationData();
|
1012 |
+
|
1013 |
+
// Reset all password reset tokens if all data was sufficient and correct on email change
|
1014 |
+
if ($customer->getIsChangeEmail()) {
|
1015 |
+
$customer->setRpToken(null);
|
1016 |
+
$customer->setRpTokenCreatedAt(null);
|
1017 |
+
}
|
1018 |
+
|
1019 |
$customer->save();
|
1020 |
$this->_getSession()->setCustomer($customer)
|
1021 |
->addSuccess($this->__('The account information has been saved.'));
|
1022 |
|
1023 |
+
if ($customer->getIsChangeEmail() || $customer->getIsChangePassword()) {
|
1024 |
+
$customer->sendChangedPasswordOrEmail();
|
1025 |
+
}
|
1026 |
+
|
1027 |
$this->_redirect('customer/account');
|
1028 |
return;
|
1029 |
} catch (Mage_Core_Exception $e) {
|
app/code/core/Mage/Customer/controllers/AddressController.php
CHANGED
@@ -163,6 +163,9 @@ class Mage_Customer_AddressController extends Mage_Core_Controller_Front_Action
|
|
163 |
|
164 |
public function deleteAction()
|
165 |
{
|
|
|
|
|
|
|
166 |
$addressId = $this->getRequest()->getParam('id', false);
|
167 |
|
168 |
if ($addressId) {
|
163 |
|
164 |
public function deleteAction()
|
165 |
{
|
166 |
+
if (!$this->_validateFormKey()) {
|
167 |
+
return $this->_redirect('*/*/');
|
168 |
+
}
|
169 |
$addressId = $this->getRequest()->getParam('id', false);
|
170 |
|
171 |
if ($addressId) {
|
app/code/core/Mage/Customer/data/customer_setup/data-upgrade-1.6.2.0.4-1.6.2.0.5.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Customer
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
/** @var $installer Mage_Customer_Model_Entity_Setup */
|
28 |
+
$installer = $this;
|
29 |
+
|
30 |
+
$installer->startSetup();
|
31 |
+
$connection = $installer->getConnection();
|
32 |
+
|
33 |
+
$eavConfig = Mage::getSingleton('eav/config');
|
34 |
+
$customerEntityTypeId = $eavConfig->getEntityType('customer')->getEntityTypeId();
|
35 |
+
$customerAddressEntityTypeId = $eavConfig->getEntityType('customer_address')->getEntityTypeId();
|
36 |
+
|
37 |
+
$entityTypeIds = array($customerAddressEntityTypeId, $customerEntityTypeId);
|
38 |
+
|
39 |
+
$attributes = Mage::getResourceModel('eav/entity_attribute_collection')
|
40 |
+
->addFieldToFilter('frontend_input', 'multiselect')
|
41 |
+
->addFieldToFilter('entity_type_id', array('in' => $entityTypeIds))
|
42 |
+
->getItems();
|
43 |
+
|
44 |
+
foreach ($attributes as $attribute) {
|
45 |
+
$entityTypeId = $attribute->getEntityTypeId();
|
46 |
+
$attributeId = $attribute->getId();
|
47 |
+
$attributeTableOld = $installer->getAttributeTable($entityTypeId, $attributeId);
|
48 |
+
|
49 |
+
$installer->updateAttribute($entityTypeId, $attributeId, 'backend_type', 'text');
|
50 |
+
|
51 |
+
$attributeTableNew = $installer->getAttributeTable($entityTypeId, $attributeId);
|
52 |
+
|
53 |
+
if ($attributeTableOld != $attributeTableNew) {
|
54 |
+
$connection->disableTableKeys($attributeTableOld)
|
55 |
+
->disableTableKeys($attributeTableNew);
|
56 |
+
|
57 |
+
$select = $connection->select()
|
58 |
+
->from($attributeTableOld, array('entity_type_id', 'attribute_id', 'entity_id', 'value'))
|
59 |
+
->where('entity_type_id = ?', $entityTypeId)
|
60 |
+
->where('attribute_id = ?', $attributeId);
|
61 |
+
|
62 |
+
$query = $select->insertFromSelect($attributeTableNew,
|
63 |
+
array('entity_type_id', 'attribute_id', 'entity_id', 'value')
|
64 |
+
);
|
65 |
+
|
66 |
+
$connection->query($query);
|
67 |
+
|
68 |
+
$connection->delete($attributeTableOld,
|
69 |
+
$connection->quoteInto('entity_type_id = ?', $entityTypeId)
|
70 |
+
. $connection->quoteInto(' AND attribute_id = ?', $attributeId)
|
71 |
+
);
|
72 |
+
|
73 |
+
$connection->enableTableKeys($attributeTableOld)
|
74 |
+
->enableTableKeys($attributeTableNew);
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
$installer->endSetup();
|
app/code/core/Mage/Customer/etc/config.xml
CHANGED
@@ -28,7 +28,7 @@
|
|
28 |
<config>
|
29 |
<modules>
|
30 |
<Mage_Customer>
|
31 |
-
<version>1.6.2.0.
|
32 |
</Mage_Customer>
|
33 |
</modules>
|
34 |
<admin>
|
@@ -378,6 +378,9 @@
|
|
378 |
<form_attribute>
|
379 |
<table>customer_form_attribute</table>
|
380 |
</form_attribute>
|
|
|
|
|
|
|
381 |
</entities>
|
382 |
</customer_resource>
|
383 |
</models>
|
@@ -416,6 +419,11 @@
|
|
416 |
<file>password_new.html</file>
|
417 |
<type>html</type>
|
418 |
</customer_password_remind_email_template>
|
|
|
|
|
|
|
|
|
|
|
419 |
</email>
|
420 |
</template>
|
421 |
<events>
|
@@ -512,6 +520,10 @@
|
|
512 |
<email_confirmed_template>customer_create_account_email_confirmed_template</email_confirmed_template>
|
513 |
<vat_frontend_visibility>0</vat_frontend_visibility>
|
514 |
</create_account>
|
|
|
|
|
|
|
|
|
515 |
<default>
|
516 |
<group>1</group>
|
517 |
</default>
|
@@ -519,7 +531,7 @@
|
|
519 |
<forgot_email_identity>support</forgot_email_identity>
|
520 |
<forgot_email_template>customer_password_forgot_email_template</forgot_email_template>
|
521 |
<remind_email_template>customer_password_remind_email_template</remind_email_template>
|
522 |
-
<reset_link_expiration_period>
|
523 |
<require_admin_user_to_change_user_password>1</require_admin_user_to_change_user_password>
|
524 |
</password>
|
525 |
<address>
|
@@ -576,5 +588,24 @@ T: {{var telephone}}
|
|
576 |
<js_template><![CDATA[#{prefix} #{firstname} #{middlename} #{lastname} #{suffix}<br/>#{company}<br/>#{street0}<br/>#{street1}<br/>#{street2}<br/>#{street3}<br/>#{city}, #{region}, #{postcode}<br/>#{country_id}<br/>T: #{telephone}<br/>F: #{fax}<br/>VAT: #{vat_id}]]></js_template>
|
577 |
</address_templates>
|
578 |
</customer>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
579 |
</default>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
580 |
</config>
|
28 |
<config>
|
29 |
<modules>
|
30 |
<Mage_Customer>
|
31 |
+
<version>1.6.2.0.5</version>
|
32 |
</Mage_Customer>
|
33 |
</modules>
|
34 |
<admin>
|
378 |
<form_attribute>
|
379 |
<table>customer_form_attribute</table>
|
380 |
</form_attribute>
|
381 |
+
<flowpassword>
|
382 |
+
<table>customer_flowpassword</table>
|
383 |
+
</flowpassword>
|
384 |
</entities>
|
385 |
</customer_resource>
|
386 |
</models>
|
419 |
<file>password_new.html</file>
|
420 |
<type>html</type>
|
421 |
</customer_password_remind_email_template>
|
422 |
+
<customer_changed_account_password_or_email_template translate="label" module="customer">
|
423 |
+
<label>Changed Password or Email</label>
|
424 |
+
<file>password_or_email_changed.html</file>
|
425 |
+
<type>html</type>
|
426 |
+
</customer_changed_account_password_or_email_template>
|
427 |
</email>
|
428 |
</template>
|
429 |
<events>
|
520 |
<email_confirmed_template>customer_create_account_email_confirmed_template</email_confirmed_template>
|
521 |
<vat_frontend_visibility>0</vat_frontend_visibility>
|
522 |
</create_account>
|
523 |
+
<changed_account>
|
524 |
+
<password_or_email_identity>general</password_or_email_identity>
|
525 |
+
<password_or_email_template>customer_changed_account_password_or_email_template</password_or_email_template>
|
526 |
+
</changed_account>
|
527 |
<default>
|
528 |
<group>1</group>
|
529 |
</default>
|
531 |
<forgot_email_identity>support</forgot_email_identity>
|
532 |
<forgot_email_template>customer_password_forgot_email_template</forgot_email_template>
|
533 |
<remind_email_template>customer_password_remind_email_template</remind_email_template>
|
534 |
+
<reset_link_expiration_period>2</reset_link_expiration_period>
|
535 |
<require_admin_user_to_change_user_password>1</require_admin_user_to_change_user_password>
|
536 |
</password>
|
537 |
<address>
|
588 |
<js_template><![CDATA[#{prefix} #{firstname} #{middlename} #{lastname} #{suffix}<br/>#{company}<br/>#{street0}<br/>#{street1}<br/>#{street2}<br/>#{street3}<br/>#{city}, #{region}, #{postcode}<br/>#{country_id}<br/>T: #{telephone}<br/>F: #{fax}<br/>VAT: #{vat_id}]]></js_template>
|
589 |
</address_templates>
|
590 |
</customer>
|
591 |
+
<admin>
|
592 |
+
<security>
|
593 |
+
<forgot_password_flow_secure>1</forgot_password_flow_secure>
|
594 |
+
<forgot_password_email_times>5</forgot_password_email_times>
|
595 |
+
<forgot_password_ip_times>5</forgot_password_ip_times>
|
596 |
+
</security>
|
597 |
+
</admin>
|
598 |
</default>
|
599 |
+
<crontab>
|
600 |
+
<jobs>
|
601 |
+
<customer_flowpassword>
|
602 |
+
<schedule>
|
603 |
+
<cron_expr>0 0 1 * *</cron_expr>
|
604 |
+
</schedule>
|
605 |
+
<run>
|
606 |
+
<model>mage_customer/observer::deleteCustomerFlowPassword</model>
|
607 |
+
</run>
|
608 |
+
</customer_flowpassword>
|
609 |
+
</jobs>
|
610 |
+
</crontab>
|
611 |
</config>
|
app/code/core/Mage/Customer/etc/system.xml
CHANGED
@@ -250,6 +250,34 @@
|
|
250 |
</generate_human_friendly_id>
|
251 |
</fields>
|
252 |
</create_account>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
<password translate="label">
|
254 |
<label>Password Options</label>
|
255 |
<frontend_type>text</frontend_type>
|
@@ -286,7 +314,7 @@
|
|
286 |
<show_in_store>1</show_in_store>
|
287 |
</forgot_email_identity>
|
288 |
<reset_link_expiration_period translate="label comment">
|
289 |
-
<label>Recovery Link Expiration Period (
|
290 |
<comment>Please enter a number 1 or greater in this field.</comment>
|
291 |
<frontend_type>text</frontend_type>
|
292 |
<validate>required-entry validate-digits validate-digits-range digits-range-1-</validate>
|
@@ -492,5 +520,40 @@
|
|
492 |
</store_information>
|
493 |
</groups>
|
494 |
</general>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
495 |
</sections>
|
496 |
</config>
|
250 |
</generate_human_friendly_id>
|
251 |
</fields>
|
252 |
</create_account>
|
253 |
+
<changed_account translate="label">
|
254 |
+
<label>Change Account Data</label>
|
255 |
+
<frontend_type>text</frontend_type>
|
256 |
+
<sort_order>25</sort_order>
|
257 |
+
<show_in_default>1</show_in_default>
|
258 |
+
<show_in_website>1</show_in_website>
|
259 |
+
<show_in_store>1</show_in_store>
|
260 |
+
<fields>
|
261 |
+
<password_or_email_identity translate="label">
|
262 |
+
<label>Email Sender</label>
|
263 |
+
<frontend_type>select</frontend_type>
|
264 |
+
<source_model>adminhtml/system_config_source_email_identity</source_model>
|
265 |
+
<sort_order>10</sort_order>
|
266 |
+
<show_in_default>1</show_in_default>
|
267 |
+
<show_in_website>1</show_in_website>
|
268 |
+
<show_in_store>1</show_in_store>
|
269 |
+
</password_or_email_identity>
|
270 |
+
<password_or_email_template translate="label">
|
271 |
+
<label>Changed Email or Password Email Template</label>
|
272 |
+
<frontend_type>select</frontend_type>
|
273 |
+
<source_model>adminhtml/system_config_source_email_template</source_model>
|
274 |
+
<sort_order>20</sort_order>
|
275 |
+
<show_in_default>1</show_in_default>
|
276 |
+
<show_in_website>1</show_in_website>
|
277 |
+
<show_in_store>1</show_in_store>
|
278 |
+
</password_or_email_template>
|
279 |
+
</fields>
|
280 |
+
</changed_account>
|
281 |
<password translate="label">
|
282 |
<label>Password Options</label>
|
283 |
<frontend_type>text</frontend_type>
|
314 |
<show_in_store>1</show_in_store>
|
315 |
</forgot_email_identity>
|
316 |
<reset_link_expiration_period translate="label comment">
|
317 |
+
<label>Recovery Link Expiration Period (hours)</label>
|
318 |
<comment>Please enter a number 1 or greater in this field.</comment>
|
319 |
<frontend_type>text</frontend_type>
|
320 |
<validate>required-entry validate-digits validate-digits-range digits-range-1-</validate>
|
520 |
</store_information>
|
521 |
</groups>
|
522 |
</general>
|
523 |
+
<admin>
|
524 |
+
<groups>
|
525 |
+
<security>
|
526 |
+
<fields>
|
527 |
+
<forgot_password_flow_secure translate="label">
|
528 |
+
<label>Forgot password flow secure</label>
|
529 |
+
<frontend_type>select</frontend_type>
|
530 |
+
<source_model>adminhtml/system_config_source_customer_forgotpassword</source_model>
|
531 |
+
<sort_order>140</sort_order>
|
532 |
+
<show_in_default>1</show_in_default>
|
533 |
+
<show_in_website>1</show_in_website>
|
534 |
+
<show_in_store>1</show_in_store>
|
535 |
+
</forgot_password_flow_secure>
|
536 |
+
<forgot_password_ip_times translate="label comment">
|
537 |
+
<label>Forgot password requests to times per hour from 1 IP</label>
|
538 |
+
<frontend_type>text</frontend_type>
|
539 |
+
<sort_order>150</sort_order>
|
540 |
+
<show_in_default>1</show_in_default>
|
541 |
+
<show_in_website>1</show_in_website>
|
542 |
+
<show_in_store>1</show_in_store>
|
543 |
+
<depends><forgot_password_flow_secure separator=",">1,2</forgot_password_flow_secure></depends>
|
544 |
+
</forgot_password_ip_times>
|
545 |
+
<forgot_password_email_times translate="label">
|
546 |
+
<label>Forgot password requests to times per 24 hours from 1 e-mail</label>
|
547 |
+
<frontend_type>text</frontend_type>
|
548 |
+
<sort_order>160</sort_order>
|
549 |
+
<show_in_default>1</show_in_default>
|
550 |
+
<show_in_website>1</show_in_website>
|
551 |
+
<show_in_store>1</show_in_store>
|
552 |
+
<depends><forgot_password_flow_secure separator=",">1,3</forgot_password_flow_secure></depends>
|
553 |
+
</forgot_password_email_times>
|
554 |
+
</fields>
|
555 |
+
</security>
|
556 |
+
</groups>
|
557 |
+
</admin>
|
558 |
</sections>
|
559 |
</config>
|
app/code/core/Mage/Customer/sql/customer_setup/upgrade-1.6.2.0.4-1.6.2.0.5.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Customer
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
/* @var $installer Mage_Customer_Model_Entity_Setup */
|
28 |
+
$installer = $this;
|
29 |
+
$installer->startSetup();
|
30 |
+
|
31 |
+
$table = $installer->getConnection()
|
32 |
+
->newTable($installer->getTable('customer/flowpassword'))
|
33 |
+
->addColumn('flowpassword_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
34 |
+
'identity' => true,
|
35 |
+
'unsigned' => true,
|
36 |
+
'nullable' => false,
|
37 |
+
'primary' => true,
|
38 |
+
), 'Flow password Id')
|
39 |
+
->addColumn('ip', Varien_Db_Ddl_Table::TYPE_VARCHAR, 50, array(
|
40 |
+
'nullable' => false,
|
41 |
+
), 'User IP')
|
42 |
+
->addColumn('email', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255, array(
|
43 |
+
'nullable' => false,
|
44 |
+
), 'Requested email for change')
|
45 |
+
->addColumn('requested_date', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255, array(
|
46 |
+
'nullable' => false,
|
47 |
+
'default' => '0000-00-00 00:00:00',
|
48 |
+
), 'Requested date for change')
|
49 |
+
->addIndex($installer->getIdxName('customer/flowpassword', array('email')),
|
50 |
+
array('email'))
|
51 |
+
->addIndex($installer->getIdxName('customer/flowpassword', array('ip')),
|
52 |
+
array('ip'))
|
53 |
+
->addIndex($installer->getIdxName('customer/flowpassword', array('requested_date')),
|
54 |
+
array('requested_date'))
|
55 |
+
->setComment('Customer flow password');
|
56 |
+
$installer->getConnection()->createTable($table);
|
57 |
+
|
58 |
+
$installer->endSetup();
|
app/code/core/Mage/Dataflow/Model/Profile.php
CHANGED
@@ -64,10 +64,14 @@ class Mage_Dataflow_Model_Profile extends Mage_Core_Model_Abstract
|
|
64 |
|
65 |
protected function _afterLoad()
|
66 |
{
|
|
|
67 |
if (is_string($this->getGuiData())) {
|
68 |
-
|
69 |
-
|
70 |
-
|
|
|
|
|
|
|
71 |
}
|
72 |
$this->setGuiData($guiData);
|
73 |
|
@@ -127,7 +131,13 @@ class Mage_Dataflow_Model_Profile extends Mage_Core_Model_Abstract
|
|
127 |
protected function _afterSave()
|
128 |
{
|
129 |
if (is_string($this->getGuiData())) {
|
130 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
}
|
132 |
|
133 |
$profileHistory = Mage::getModel('dataflow/profile_history');
|
64 |
|
65 |
protected function _afterLoad()
|
66 |
{
|
67 |
+
$guiData = '';
|
68 |
if (is_string($this->getGuiData())) {
|
69 |
+
try {
|
70 |
+
$guiData = Mage::helper('core/unserializeArray')
|
71 |
+
->unserialize($this->getGuiData());
|
72 |
+
} catch (Exception $e) {
|
73 |
+
Mage::logException($e);
|
74 |
+
}
|
75 |
}
|
76 |
$this->setGuiData($guiData);
|
77 |
|
131 |
protected function _afterSave()
|
132 |
{
|
133 |
if (is_string($this->getGuiData())) {
|
134 |
+
try {
|
135 |
+
$guiData = Mage::helper('core/unserializeArray')
|
136 |
+
->unserialize($this->getGuiData());
|
137 |
+
$this->setGuiData($guiData);
|
138 |
+
} catch (Exception $e) {
|
139 |
+
Mage::logException($e);
|
140 |
+
}
|
141 |
}
|
142 |
|
143 |
$profileHistory = Mage::getModel('dataflow/profile_history');
|
app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php
CHANGED
@@ -32,7 +32,7 @@
|
|
32 |
* @author Magento Core Team <core@magentocommerce.com>
|
33 |
*/
|
34 |
class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Links
|
35 |
-
extends
|
36 |
{
|
37 |
/**
|
38 |
* Purchased Separately Attribute cache
|
@@ -242,6 +242,7 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Li
|
|
242 |
*/
|
243 |
protected function _prepareLayout()
|
244 |
{
|
|
|
245 |
$this->setChild(
|
246 |
'upload_button',
|
247 |
$this->getLayout()->createBlock('adminhtml/widget_button')->addData(array(
|
@@ -251,6 +252,10 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Li
|
|
251 |
'onclick' => 'Downloadable.massUploadByType(\'links\');Downloadable.massUploadByType(\'linkssample\')'
|
252 |
))
|
253 |
);
|
|
|
|
|
|
|
|
|
254 |
}
|
255 |
|
256 |
/**
|
@@ -270,33 +275,56 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Li
|
|
270 |
*/
|
271 |
public function getConfigJson($type='links')
|
272 |
{
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
281 |
)
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
$this->getConfig()->setHideUploadButton(true);
|
286 |
-
return Mage::helper('core')->jsonEncode($this->getConfig()->getData());
|
287 |
}
|
288 |
|
|
|
289 |
/**
|
290 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
291 |
*
|
292 |
-
* @
|
|
|
293 |
*/
|
294 |
public function getConfig()
|
295 |
{
|
296 |
-
|
297 |
-
$this->_config = new Varien_Object();
|
298 |
-
}
|
299 |
-
|
300 |
-
return $this->_config;
|
301 |
}
|
302 |
}
|
32 |
* @author Magento Core Team <core@magentocommerce.com>
|
33 |
*/
|
34 |
class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Links
|
35 |
+
extends Mage_Uploader_Block_Single
|
36 |
{
|
37 |
/**
|
38 |
* Purchased Separately Attribute cache
|
242 |
*/
|
243 |
protected function _prepareLayout()
|
244 |
{
|
245 |
+
parent::_prepareLayout();
|
246 |
$this->setChild(
|
247 |
'upload_button',
|
248 |
$this->getLayout()->createBlock('adminhtml/widget_button')->addData(array(
|
252 |
'onclick' => 'Downloadable.massUploadByType(\'links\');Downloadable.massUploadByType(\'linkssample\')'
|
253 |
))
|
254 |
);
|
255 |
+
$this->_addElementIdsMapping(array(
|
256 |
+
'container' => $this->getHtmlId() . '-new',
|
257 |
+
'delete' => $this->getHtmlId() . '-delete'
|
258 |
+
));
|
259 |
}
|
260 |
|
261 |
/**
|
275 |
*/
|
276 |
public function getConfigJson($type='links')
|
277 |
{
|
278 |
+
|
279 |
+
$this->getUploaderConfig()
|
280 |
+
->setFileParameterName($type)
|
281 |
+
->setTarget(
|
282 |
+
Mage::getModel('adminhtml/url')
|
283 |
+
->addSessionParam()
|
284 |
+
->getUrl('*/downloadable_file/upload', array('type' => $type, '_secure' => true))
|
285 |
+
);
|
286 |
+
$this->getMiscConfig()
|
287 |
+
->setReplaceBrowseWithRemove(true)
|
288 |
+
;
|
289 |
+
return Mage::helper('core')->jsonEncode(parent::getJsonConfig());
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* @return string
|
294 |
+
*/
|
295 |
+
public function getBrowseButtonHtml($type = '')
|
296 |
+
{
|
297 |
+
return $this->getChild('browse_button')
|
298 |
+
// Workaround for IE9
|
299 |
+
->setBeforeHtml(
|
300 |
+
'<div style="display:inline-block; " id="downloadable_link_{{id}}_' . $type . 'file-browse">'
|
301 |
)
|
302 |
+
->setAfterHtml('</div>')
|
303 |
+
->setId('downloadable_link_{{id}}_' . $type . 'file-browse_button')
|
304 |
+
->toHtml();
|
|
|
|
|
305 |
}
|
306 |
|
307 |
+
|
308 |
/**
|
309 |
+
* @return string
|
310 |
+
*/
|
311 |
+
public function getDeleteButtonHtml($type = '')
|
312 |
+
{
|
313 |
+
return $this->getChild('delete_button')
|
314 |
+
->setLabel('')
|
315 |
+
->setId('downloadable_link_{{id}}_' . $type . 'file-delete')
|
316 |
+
->setStyle('display:none; width:31px;')
|
317 |
+
->toHtml();
|
318 |
+
}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Retrieve config object
|
322 |
*
|
323 |
+
* @deprecated
|
324 |
+
* @return $this
|
325 |
*/
|
326 |
public function getConfig()
|
327 |
{
|
328 |
+
return $this;
|
|
|
|
|
|
|
|
|
329 |
}
|
330 |
}
|
app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php
CHANGED
@@ -32,7 +32,7 @@
|
|
32 |
* @author Magento Core Team <core@magentocommerce.com>
|
33 |
*/
|
34 |
class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Samples
|
35 |
-
extends
|
36 |
{
|
37 |
/**
|
38 |
* Class constructor
|
@@ -148,6 +148,7 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Sa
|
|
148 |
*/
|
149 |
protected function _prepareLayout()
|
150 |
{
|
|
|
151 |
$this->setChild(
|
152 |
'upload_button',
|
153 |
$this->getLayout()->createBlock('adminhtml/widget_button')
|
@@ -158,6 +159,11 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Sa
|
|
158 |
'onclick' => 'Downloadable.massUploadByType(\'samples\')'
|
159 |
))
|
160 |
);
|
|
|
|
|
|
|
|
|
|
|
161 |
}
|
162 |
|
163 |
/**
|
@@ -171,40 +177,59 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Sa
|
|
171 |
}
|
172 |
|
173 |
/**
|
174 |
-
*
|
175 |
*
|
176 |
* @return string
|
177 |
*/
|
178 |
public function getConfigJson()
|
179 |
{
|
180 |
-
$this->
|
181 |
-
->
|
182 |
-
->
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
));
|
191 |
-
$this->getConfig()->setReplaceBrowseWithRemove(true);
|
192 |
-
$this->getConfig()->setWidth('32');
|
193 |
-
$this->getConfig()->setHideUploadButton(true);
|
194 |
-
return Mage::helper('core')->jsonEncode($this->getConfig()->getData());
|
195 |
}
|
196 |
|
197 |
/**
|
198 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
*
|
200 |
-
* @
|
|
|
201 |
*/
|
202 |
public function getConfig()
|
203 |
{
|
204 |
-
|
205 |
-
$this->_config = new Varien_Object();
|
206 |
-
}
|
207 |
-
|
208 |
-
return $this->_config;
|
209 |
}
|
210 |
}
|
32 |
* @author Magento Core Team <core@magentocommerce.com>
|
33 |
*/
|
34 |
class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Samples
|
35 |
+
extends Mage_Uploader_Block_Single
|
36 |
{
|
37 |
/**
|
38 |
* Class constructor
|
148 |
*/
|
149 |
protected function _prepareLayout()
|
150 |
{
|
151 |
+
parent::_prepareLayout();
|
152 |
$this->setChild(
|
153 |
'upload_button',
|
154 |
$this->getLayout()->createBlock('adminhtml/widget_button')
|
159 |
'onclick' => 'Downloadable.massUploadByType(\'samples\')'
|
160 |
))
|
161 |
);
|
162 |
+
|
163 |
+
$this->_addElementIdsMapping(array(
|
164 |
+
'container' => $this->getHtmlId() . '-new',
|
165 |
+
'delete' => $this->getHtmlId() . '-delete'
|
166 |
+
));
|
167 |
}
|
168 |
|
169 |
/**
|
177 |
}
|
178 |
|
179 |
/**
|
180 |
+
* Retrieve config json
|
181 |
*
|
182 |
* @return string
|
183 |
*/
|
184 |
public function getConfigJson()
|
185 |
{
|
186 |
+
$this->getUploaderConfig()
|
187 |
+
->setFileParameterName('samples')
|
188 |
+
->setTarget(
|
189 |
+
Mage::getModel('adminhtml/url')
|
190 |
+
->addSessionParam()
|
191 |
+
->getUrl('*/downloadable_file/upload', array('type' => 'samples', '_secure' => true))
|
192 |
+
);
|
193 |
+
$this->getMiscConfig()
|
194 |
+
->setReplaceBrowseWithRemove(true)
|
195 |
+
;
|
196 |
+
return Mage::helper('core')->jsonEncode(parent::getJsonConfig());
|
|
|
|
|
|
|
|
|
197 |
}
|
198 |
|
199 |
/**
|
200 |
+
* @return string
|
201 |
+
*/
|
202 |
+
public function getBrowseButtonHtml()
|
203 |
+
{
|
204 |
+
return $this->getChild('browse_button')
|
205 |
+
// Workaround for IE9
|
206 |
+
->setBeforeHtml('<div style="display:inline-block; " id="downloadable_sample_{{id}}_file-browse">')
|
207 |
+
->setAfterHtml('</div>')
|
208 |
+
->setId('downloadable_sample_{{id}}_file-browse_button')
|
209 |
+
->toHtml();
|
210 |
+
}
|
211 |
+
|
212 |
+
|
213 |
+
/**
|
214 |
+
* @return string
|
215 |
+
*/
|
216 |
+
public function getDeleteButtonHtml()
|
217 |
+
{
|
218 |
+
return $this->getChild('delete_button')
|
219 |
+
->setLabel('')
|
220 |
+
->setId('downloadable_sample_{{id}}_file-delete')
|
221 |
+
->setStyle('display:none; width:31px;')
|
222 |
+
->toHtml();
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* Retrieve config object
|
227 |
*
|
228 |
+
* @deprecated
|
229 |
+
* @return $this
|
230 |
*/
|
231 |
public function getConfig()
|
232 |
{
|
233 |
+
return $this;
|
|
|
|
|
|
|
|
|
234 |
}
|
235 |
}
|
app/code/core/Mage/Downloadable/Helper/File.php
CHANGED
@@ -33,15 +33,35 @@
|
|
33 |
*/
|
34 |
class Mage_Downloadable_Helper_File extends Mage_Core_Helper_Abstract
|
35 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
public function __construct()
|
37 |
{
|
38 |
-
$
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
|
|
44 |
}
|
|
|
|
|
45 |
}
|
46 |
|
47 |
/**
|
@@ -152,628 +172,48 @@ class Mage_Downloadable_Helper_File extends Mage_Core_Helper_Abstract
|
|
152 |
return $file;
|
153 |
}
|
154 |
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
public function getFileType($filePath)
|
156 |
{
|
157 |
$ext = substr($filePath, strrpos($filePath, '.')+1);
|
158 |
return $this->_getFileTypeByExt($ext);
|
159 |
}
|
160 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
protected function _getFileTypeByExt($ext)
|
162 |
{
|
163 |
-
|
164 |
-
if (isset(self::$_mimeTypes[$type])) {
|
165 |
-
return self::$_mimeTypes[$type];
|
166 |
-
}
|
167 |
-
return 'application/octet-stream';
|
168 |
}
|
169 |
|
|
|
|
|
|
|
|
|
|
|
170 |
public function getAllFileTypes()
|
171 |
{
|
172 |
-
return array_values(
|
173 |
}
|
174 |
|
|
|
|
|
|
|
|
|
|
|
175 |
public function getAllMineTypes()
|
176 |
{
|
177 |
-
return
|
178 |
}
|
179 |
|
180 |
-
protected static $_mimeTypes =
|
181 |
-
array(
|
182 |
-
'x123' => 'application/vnd.lotus-1-2-3',
|
183 |
-
'x3dml' => 'text/vnd.in3d.3dml',
|
184 |
-
'x3g2' => 'video/3gpp2',
|
185 |
-
'x3gp' => 'video/3gpp',
|
186 |
-
'xace' => 'application/x-ace-compressed',
|
187 |
-
'xacu' => 'application/vnd.acucobol',
|
188 |
-
'xaep' => 'application/vnd.audiograph',
|
189 |
-
'xai' => 'application/postscript',
|
190 |
-
'xaif' => 'audio/x-aiff',
|
191 |
-
|
192 |
-
'xaifc' => 'audio/x-aiff',
|
193 |
-
'xaiff' => 'audio/x-aiff',
|
194 |
-
'xami' => 'application/vnd.amiga.ami',
|
195 |
-
'xapr' => 'application/vnd.lotus-approach',
|
196 |
-
'xasf' => 'video/x-ms-asf',
|
197 |
-
'xaso' => 'application/vnd.accpac.simply.aso',
|
198 |
-
'xasx' => 'video/x-ms-asf',
|
199 |
-
'xatom' => 'application/atom+xml',
|
200 |
-
'xatomcat' => 'application/atomcat+xml',
|
201 |
-
|
202 |
-
'xatomsvc' => 'application/atomsvc+xml',
|
203 |
-
'xatx' => 'application/vnd.antix.game-component',
|
204 |
-
'xau' => 'audio/basic',
|
205 |
-
'xavi' => 'video/x-msvideo',
|
206 |
-
'xbat' => 'application/x-msdownload',
|
207 |
-
'xbcpio' => 'application/x-bcpio',
|
208 |
-
'xbdm' => 'application/vnd.syncml.dm+wbxml',
|
209 |
-
'xbh2' => 'application/vnd.fujitsu.oasysprs',
|
210 |
-
'xbmi' => 'application/vnd.bmi',
|
211 |
-
|
212 |
-
'xbmp' => 'image/bmp',
|
213 |
-
'xbox' => 'application/vnd.previewsystems.box',
|
214 |
-
'xboz' => 'application/x-bzip2',
|
215 |
-
'xbtif' => 'image/prs.btif',
|
216 |
-
'xbz' => 'application/x-bzip',
|
217 |
-
'xbz2' => 'application/x-bzip2',
|
218 |
-
'xcab' => 'application/vnd.ms-cab-compressed',
|
219 |
-
'xccxml' => 'application/ccxml+xml',
|
220 |
-
'xcdbcmsg' => 'application/vnd.contact.cmsg',
|
221 |
-
|
222 |
-
'xcdkey' => 'application/vnd.mediastation.cdkey',
|
223 |
-
'xcdx' => 'chemical/x-cdx',
|
224 |
-
'xcdxml' => 'application/vnd.chemdraw+xml',
|
225 |
-
'xcdy' => 'application/vnd.cinderella',
|
226 |
-
'xcer' => 'application/pkix-cert',
|
227 |
-
'xcgm' => 'image/cgm',
|
228 |
-
'xchat' => 'application/x-chat',
|
229 |
-
'xchm' => 'application/vnd.ms-htmlhelp',
|
230 |
-
'xchrt' => 'application/vnd.kde.kchart',
|
231 |
-
|
232 |
-
'xcif' => 'chemical/x-cif',
|
233 |
-
'xcii' => 'application/vnd.anser-web-certificate-issue-initiation',
|
234 |
-
'xcil' => 'application/vnd.ms-artgalry',
|
235 |
-
'xcla' => 'application/vnd.claymore',
|
236 |
-
'xclkk' => 'application/vnd.crick.clicker.keyboard',
|
237 |
-
'xclkp' => 'application/vnd.crick.clicker.palette',
|
238 |
-
'xclkt' => 'application/vnd.crick.clicker.template',
|
239 |
-
'xclkw' => 'application/vnd.crick.clicker.wordbank',
|
240 |
-
'xclkx' => 'application/vnd.crick.clicker',
|
241 |
-
|
242 |
-
'xclp' => 'application/x-msclip',
|
243 |
-
'xcmc' => 'application/vnd.cosmocaller',
|
244 |
-
'xcmdf' => 'chemical/x-cmdf',
|
245 |
-
'xcml' => 'chemical/x-cml',
|
246 |
-
'xcmp' => 'application/vnd.yellowriver-custom-menu',
|
247 |
-
'xcmx' => 'image/x-cmx',
|
248 |
-
'xcom' => 'application/x-msdownload',
|
249 |
-
'xconf' => 'text/plain',
|
250 |
-
'xcpio' => 'application/x-cpio',
|
251 |
-
|
252 |
-
'xcpt' => 'application/mac-compactpro',
|
253 |
-
'xcrd' => 'application/x-mscardfile',
|
254 |
-
'xcrl' => 'application/pkix-crl',
|
255 |
-
'xcrt' => 'application/x-x509-ca-cert',
|
256 |
-
'xcsh' => 'application/x-csh',
|
257 |
-
'xcsml' => 'chemical/x-csml',
|
258 |
-
'xcss' => 'text/css',
|
259 |
-
'xcsv' => 'text/csv',
|
260 |
-
'xcurl' => 'application/vnd.curl',
|
261 |
-
|
262 |
-
'xcww' => 'application/prs.cww',
|
263 |
-
'xdaf' => 'application/vnd.mobius.daf',
|
264 |
-
'xdavmount' => 'application/davmount+xml',
|
265 |
-
'xdd2' => 'application/vnd.oma.dd2+xml',
|
266 |
-
'xddd' => 'application/vnd.fujixerox.ddd',
|
267 |
-
'xdef' => 'text/plain',
|
268 |
-
'xder' => 'application/x-x509-ca-cert',
|
269 |
-
'xdfac' => 'application/vnd.dreamfactory',
|
270 |
-
'xdis' => 'application/vnd.mobius.dis',
|
271 |
-
|
272 |
-
'xdjv' => 'image/vnd.djvu',
|
273 |
-
'xdjvu' => 'image/vnd.djvu',
|
274 |
-
'xdll' => 'application/x-msdownload',
|
275 |
-
'xdna' => 'application/vnd.dna',
|
276 |
-
'xdoc' => 'application/msword',
|
277 |
-
'xdot' => 'application/msword',
|
278 |
-
'xdp' => 'application/vnd.osgi.dp',
|
279 |
-
'xdpg' => 'application/vnd.dpgraph',
|
280 |
-
'xdsc' => 'text/prs.lines.tag',
|
281 |
-
|
282 |
-
'xdtd' => 'application/xml-dtd',
|
283 |
-
'xdvi' => 'application/x-dvi',
|
284 |
-
'xdwf' => 'model/vnd.dwf',
|
285 |
-
'xdwg' => 'image/vnd.dwg',
|
286 |
-
'xdxf' => 'image/vnd.dxf',
|
287 |
-
'xdxp' => 'application/vnd.spotfire.dxp',
|
288 |
-
'xecelp4800' => 'audio/vnd.nuera.ecelp4800',
|
289 |
-
'xecelp7470' => 'audio/vnd.nuera.ecelp7470',
|
290 |
-
'xecelp9600' => 'audio/vnd.nuera.ecelp9600',
|
291 |
-
|
292 |
-
'xecma' => 'application/ecmascript',
|
293 |
-
'xedm' => 'application/vnd.novadigm.edm',
|
294 |
-
'xedx' => 'application/vnd.novadigm.edx',
|
295 |
-
'xefif' => 'application/vnd.picsel',
|
296 |
-
'xei6' => 'application/vnd.pg.osasli',
|
297 |
-
'xeml' => 'message/rfc822',
|
298 |
-
'xeol' => 'audio/vnd.digital-winds',
|
299 |
-
'xeot' => 'application/vnd.ms-fontobject',
|
300 |
-
'xeps' => 'application/postscript',
|
301 |
-
|
302 |
-
'xesf' => 'application/vnd.epson.esf',
|
303 |
-
'xetx' => 'text/x-setext',
|
304 |
-
'xexe' => 'application/x-msdownload',
|
305 |
-
'xext' => 'application/vnd.novadigm.ext',
|
306 |
-
'xez' => 'application/andrew-inset',
|
307 |
-
'xez2' => 'application/vnd.ezpix-album',
|
308 |
-
'xez3' => 'application/vnd.ezpix-package',
|
309 |
-
'xfbs' => 'image/vnd.fastbidsheet',
|
310 |
-
'xfdf' => 'application/vnd.fdf',
|
311 |
-
|
312 |
-
'xfe_launch' => 'application/vnd.denovo.fcselayout-link',
|
313 |
-
'xfg5' => 'application/vnd.fujitsu.oasysgp',
|
314 |
-
'xfli' => 'video/x-fli',
|
315 |
-
'xflo' => 'application/vnd.micrografx.flo',
|
316 |
-
'xflw' => 'application/vnd.kde.kivio',
|
317 |
-
'xflx' => 'text/vnd.fmi.flexstor',
|
318 |
-
'xfly' => 'text/vnd.fly',
|
319 |
-
'xfnc' => 'application/vnd.frogans.fnc',
|
320 |
-
'xfpx' => 'image/vnd.fpx',
|
321 |
-
|
322 |
-
'xfsc' => 'application/vnd.fsc.weblaunch',
|
323 |
-
'xfst' => 'image/vnd.fst',
|
324 |
-
'xftc' => 'application/vnd.fluxtime.clip',
|
325 |
-
'xfti' => 'application/vnd.anser-web-funds-transfer-initiation',
|
326 |
-
'xfvt' => 'video/vnd.fvt',
|
327 |
-
'xfzs' => 'application/vnd.fuzzysheet',
|
328 |
-
'xg3' => 'image/g3fax',
|
329 |
-
'xgac' => 'application/vnd.groove-account',
|
330 |
-
'xgdl' => 'model/vnd.gdl',
|
331 |
-
|
332 |
-
'xghf' => 'application/vnd.groove-help',
|
333 |
-
'xgif' => 'image/gif',
|
334 |
-
'xgim' => 'application/vnd.groove-identity-message',
|
335 |
-
'xgph' => 'application/vnd.flographit',
|
336 |
-
'xgram' => 'application/srgs',
|
337 |
-
'xgrv' => 'application/vnd.groove-injector',
|
338 |
-
'xgrxml' => 'application/srgs+xml',
|
339 |
-
'xgtar' => 'application/x-gtar',
|
340 |
-
'xgtm' => 'application/vnd.groove-tool-message',
|
341 |
-
|
342 |
-
'xgtw' => 'model/vnd.gtw',
|
343 |
-
'xh261' => 'video/h261',
|
344 |
-
'xh263' => 'video/h263',
|
345 |
-
'xh264' => 'video/h264',
|
346 |
-
'xhbci' => 'application/vnd.hbci',
|
347 |
-
'xhdf' => 'application/x-hdf',
|
348 |
-
'xhlp' => 'application/winhlp',
|
349 |
-
'xhpgl' => 'application/vnd.hp-hpgl',
|
350 |
-
'xhpid' => 'application/vnd.hp-hpid',
|
351 |
-
|
352 |
-
'xhps' => 'application/vnd.hp-hps',
|
353 |
-
'xhqx' => 'application/mac-binhex40',
|
354 |
-
'xhtke' => 'application/vnd.kenameaapp',
|
355 |
-
'xhtm' => 'text/html',
|
356 |
-
'xhtml' => 'text/html',
|
357 |
-
'xhvd' => 'application/vnd.yamaha.hv-dic',
|
358 |
-
'xhvp' => 'application/vnd.yamaha.hv-voice',
|
359 |
-
'xhvs' => 'application/vnd.yamaha.hv-script',
|
360 |
-
'xice' => '#x-conference/x-cooltalk',
|
361 |
-
|
362 |
-
'xico' => 'image/x-icon',
|
363 |
-
'xics' => 'text/calendar',
|
364 |
-
'xief' => 'image/ief',
|
365 |
-
'xifb' => 'text/calendar',
|
366 |
-
'xifm' => 'application/vnd.shana.informed.formdata',
|
367 |
-
'xigl' => 'application/vnd.igloader',
|
368 |
-
'xigx' => 'application/vnd.micrografx.igx',
|
369 |
-
'xiif' => 'application/vnd.shana.informed.interchange',
|
370 |
-
'ximp' => 'application/vnd.accpac.simply.imp',
|
371 |
-
|
372 |
-
'xims' => 'application/vnd.ms-ims',
|
373 |
-
'xin' => 'text/plain',
|
374 |
-
'xipk' => 'application/vnd.shana.informed.package',
|
375 |
-
'xirm' => 'application/vnd.ibm.rights-management',
|
376 |
-
'xirp' => 'application/vnd.irepository.package+xml',
|
377 |
-
'xitp' => 'application/vnd.shana.informed.formtemplate',
|
378 |
-
'xivp' => 'application/vnd.immervision-ivp',
|
379 |
-
'xivu' => 'application/vnd.immervision-ivu',
|
380 |
-
'xjad' => 'text/vnd.sun.j2me.app-descriptor',
|
381 |
-
|
382 |
-
'xjam' => 'application/vnd.jam',
|
383 |
-
'xjava' => 'text/x-java-source',
|
384 |
-
'xjisp' => 'application/vnd.jisp',
|
385 |
-
'xjlt' => 'application/vnd.hp-jlyt',
|
386 |
-
'xjoda' => 'application/vnd.joost.joda-archive',
|
387 |
-
'xjpe' => 'image/jpeg',
|
388 |
-
'xjpeg' => 'image/jpeg',
|
389 |
-
'xjpg' => 'image/jpeg',
|
390 |
-
'xjpgm' => 'video/jpm',
|
391 |
-
|
392 |
-
'xjpgv' => 'video/jpeg',
|
393 |
-
'xjpm' => 'video/jpm',
|
394 |
-
'xjs' => 'application/javascript',
|
395 |
-
'xjson' => 'application/json',
|
396 |
-
'xkar' => 'audio/midi',
|
397 |
-
'xkarbon' => 'application/vnd.kde.karbon',
|
398 |
-
'xkfo' => 'application/vnd.kde.kformula',
|
399 |
-
'xkia' => 'application/vnd.kidspiration',
|
400 |
-
'xkml' => 'application/vnd.google-earth.kml+xml',
|
401 |
-
|
402 |
-
'xkmz' => 'application/vnd.google-earth.kmz',
|
403 |
-
'xkon' => 'application/vnd.kde.kontour',
|
404 |
-
'xksp' => 'application/vnd.kde.kspread',
|
405 |
-
'xlatex' => 'application/x-latex',
|
406 |
-
'xlbd' => 'application/vnd.llamagraphics.life-balance.desktop',
|
407 |
-
'xlbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml',
|
408 |
-
'xles' => 'application/vnd.hhe.lesson-player',
|
409 |
-
'xlist' => 'text/plain',
|
410 |
-
'xlog' => 'text/plain',
|
411 |
-
|
412 |
-
'xlrm' => 'application/vnd.ms-lrm',
|
413 |
-
'xltf' => 'application/vnd.frogans.ltf',
|
414 |
-
'xlvp' => 'audio/vnd.lucent.voice',
|
415 |
-
'xlwp' => 'application/vnd.lotus-wordpro',
|
416 |
-
'xm13' => 'application/x-msmediaview',
|
417 |
-
'xm14' => 'application/x-msmediaview',
|
418 |
-
'xm1v' => 'video/mpeg',
|
419 |
-
'xm2a' => 'audio/mpeg',
|
420 |
-
'xm3a' => 'audio/mpeg',
|
421 |
-
|
422 |
-
'xm3u' => 'audio/x-mpegurl',
|
423 |
-
'xm4u' => 'video/vnd.mpegurl',
|
424 |
-
'xmag' => 'application/vnd.ecowin.chart',
|
425 |
-
'xmathml' => 'application/mathml+xml',
|
426 |
-
'xmbk' => 'application/vnd.mobius.mbk',
|
427 |
-
'xmbox' => 'application/mbox',
|
428 |
-
'xmc1' => 'application/vnd.medcalcdata',
|
429 |
-
'xmcd' => 'application/vnd.mcd',
|
430 |
-
'xmdb' => 'application/x-msaccess',
|
431 |
-
|
432 |
-
'xmdi' => 'image/vnd.ms-modi',
|
433 |
-
'xmesh' => 'model/mesh',
|
434 |
-
'xmfm' => 'application/vnd.mfmp',
|
435 |
-
'xmgz' => 'application/vnd.proteus.magazine',
|
436 |
-
'xmid' => 'audio/midi',
|
437 |
-
'xmidi' => 'audio/midi',
|
438 |
-
'xmif' => 'application/vnd.mif',
|
439 |
-
'xmime' => 'message/rfc822',
|
440 |
-
'xmj2' => 'video/mj2',
|
441 |
-
|
442 |
-
'xmjp2' => 'video/mj2',
|
443 |
-
'xmlp' => 'application/vnd.dolby.mlp',
|
444 |
-
'xmmd' => 'application/vnd.chipnuts.karaoke-mmd',
|
445 |
-
'xmmf' => 'application/vnd.smaf',
|
446 |
-
'xmmr' => 'image/vnd.fujixerox.edmics-mmr',
|
447 |
-
'xmny' => 'application/x-msmoney',
|
448 |
-
'xmov' => 'video/quicktime',
|
449 |
-
'xmovie' => 'video/x-sgi-movie',
|
450 |
-
'xmp2' => 'audio/mpeg',
|
451 |
-
|
452 |
-
'xmp2a' => 'audio/mpeg',
|
453 |
-
'xmp3' => 'audio/mpeg',
|
454 |
-
'xmp4' => 'video/mp4',
|
455 |
-
'xmp4a' => 'audio/mp4',
|
456 |
-
'xmp4s' => 'application/mp4',
|
457 |
-
'xmp4v' => 'video/mp4',
|
458 |
-
'xmpc' => 'application/vnd.mophun.certificate',
|
459 |
-
'xmpe' => 'video/mpeg',
|
460 |
-
'xmpeg' => 'video/mpeg',
|
461 |
-
|
462 |
-
'xmpg' => 'video/mpeg',
|
463 |
-
'xmpg4' => 'video/mp4',
|
464 |
-
'xmpga' => 'audio/mpeg',
|
465 |
-
'xmpkg' => 'application/vnd.apple.installer+xml',
|
466 |
-
'xmpm' => 'application/vnd.blueice.multipass',
|
467 |
-
'xmpn' => 'application/vnd.mophun.application',
|
468 |
-
'xmpp' => 'application/vnd.ms-project',
|
469 |
-
'xmpt' => 'application/vnd.ms-project',
|
470 |
-
'xmpy' => 'application/vnd.ibm.minipay',
|
471 |
-
|
472 |
-
'xmqy' => 'application/vnd.mobius.mqy',
|
473 |
-
'xmrc' => 'application/marc',
|
474 |
-
'xmscml' => 'application/mediaservercontrol+xml',
|
475 |
-
'xmseq' => 'application/vnd.mseq',
|
476 |
-
'xmsf' => 'application/vnd.epson.msf',
|
477 |
-
'xmsh' => 'model/mesh',
|
478 |
-
'xmsi' => 'application/x-msdownload',
|
479 |
-
'xmsl' => 'application/vnd.mobius.msl',
|
480 |
-
'xmsty' => 'application/vnd.muvee.style',
|
481 |
-
|
482 |
-
'xmts' => 'model/vnd.mts',
|
483 |
-
'xmus' => 'application/vnd.musician',
|
484 |
-
'xmvb' => 'application/x-msmediaview',
|
485 |
-
'xmwf' => 'application/vnd.mfer',
|
486 |
-
'xmxf' => 'application/mxf',
|
487 |
-
'xmxl' => 'application/vnd.recordare.musicxml',
|
488 |
-
'xmxml' => 'application/xv+xml',
|
489 |
-
'xmxs' => 'application/vnd.triscape.mxs',
|
490 |
-
'xmxu' => 'video/vnd.mpegurl',
|
491 |
-
|
492 |
-
'xn-gage' => 'application/vnd.nokia.n-gage.symbian.install',
|
493 |
-
'xngdat' => 'application/vnd.nokia.n-gage.data',
|
494 |
-
'xnlu' => 'application/vnd.neurolanguage.nlu',
|
495 |
-
'xnml' => 'application/vnd.enliven',
|
496 |
-
'xnnd' => 'application/vnd.noblenet-directory',
|
497 |
-
'xnns' => 'application/vnd.noblenet-sealer',
|
498 |
-
'xnnw' => 'application/vnd.noblenet-web',
|
499 |
-
'xnpx' => 'image/vnd.net-fpx',
|
500 |
-
'xnsf' => 'application/vnd.lotus-notes',
|
501 |
-
|
502 |
-
'xoa2' => 'application/vnd.fujitsu.oasys2',
|
503 |
-
'xoa3' => 'application/vnd.fujitsu.oasys3',
|
504 |
-
'xoas' => 'application/vnd.fujitsu.oasys',
|
505 |
-
'xobd' => 'application/x-msbinder',
|
506 |
-
'xoda' => 'application/oda',
|
507 |
-
'xodc' => 'application/vnd.oasis.opendocument.chart',
|
508 |
-
'xodf' => 'application/vnd.oasis.opendocument.formula',
|
509 |
-
'xodg' => 'application/vnd.oasis.opendocument.graphics',
|
510 |
-
'xodi' => 'application/vnd.oasis.opendocument.image',
|
511 |
-
|
512 |
-
'xodp' => 'application/vnd.oasis.opendocument.presentation',
|
513 |
-
'xods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
514 |
-
'xodt' => 'application/vnd.oasis.opendocument.text',
|
515 |
-
'xogg' => 'application/ogg',
|
516 |
-
'xoprc' => 'application/vnd.palm',
|
517 |
-
'xorg' => 'application/vnd.lotus-organizer',
|
518 |
-
'xotc' => 'application/vnd.oasis.opendocument.chart-template',
|
519 |
-
'xotf' => 'application/vnd.oasis.opendocument.formula-template',
|
520 |
-
'xotg' => 'application/vnd.oasis.opendocument.graphics-template',
|
521 |
-
|
522 |
-
'xoth' => 'application/vnd.oasis.opendocument.text-web',
|
523 |
-
'xoti' => 'application/vnd.oasis.opendocument.image-template',
|
524 |
-
'xotm' => 'application/vnd.oasis.opendocument.text-master',
|
525 |
-
'xots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
|
526 |
-
'xott' => 'application/vnd.oasis.opendocument.text-template',
|
527 |
-
'xoxt' => 'application/vnd.openofficeorg.extension',
|
528 |
-
'xp10' => 'application/pkcs10',
|
529 |
-
'xp7r' => 'application/x-pkcs7-certreqresp',
|
530 |
-
'xp7s' => 'application/pkcs7-signature',
|
531 |
-
|
532 |
-
'xpbd' => 'application/vnd.powerbuilder6',
|
533 |
-
'xpbm' => 'image/x-portable-bitmap',
|
534 |
-
'xpcl' => 'application/vnd.hp-pcl',
|
535 |
-
'xpclxl' => 'application/vnd.hp-pclxl',
|
536 |
-
'xpct' => 'image/x-pict',
|
537 |
-
'xpcx' => 'image/x-pcx',
|
538 |
-
'xpdb' => 'chemical/x-pdb',
|
539 |
-
'xpdf' => 'application/pdf',
|
540 |
-
'xpfr' => 'application/font-tdpfr',
|
541 |
-
|
542 |
-
'xpgm' => 'image/x-portable-graymap',
|
543 |
-
'xpgn' => 'application/x-chess-pgn',
|
544 |
-
'xpgp' => 'application/pgp-encrypted',
|
545 |
-
'xpic' => 'image/x-pict',
|
546 |
-
'xpki' => 'application/pkixcmp',
|
547 |
-
'xpkipath' => 'application/pkix-pkipath',
|
548 |
-
'xplb' => 'application/vnd.3gpp.pic-bw-large',
|
549 |
-
'xplc' => 'application/vnd.mobius.plc',
|
550 |
-
'xplf' => 'application/vnd.pocketlearn',
|
551 |
-
|
552 |
-
'xpls' => 'application/pls+xml',
|
553 |
-
'xpml' => 'application/vnd.ctc-posml',
|
554 |
-
'xpng' => 'image/png',
|
555 |
-
'xpnm' => 'image/x-portable-anymap',
|
556 |
-
'xportpkg' => 'application/vnd.macports.portpkg',
|
557 |
-
'xpot' => 'application/vnd.ms-powerpoint',
|
558 |
-
'xppd' => 'application/vnd.cups-ppd',
|
559 |
-
'xppm' => 'image/x-portable-pixmap',
|
560 |
-
'xpps' => 'application/vnd.ms-powerpoint',
|
561 |
-
|
562 |
-
'xppt' => 'application/vnd.ms-powerpoint',
|
563 |
-
'xpqa' => 'application/vnd.palm',
|
564 |
-
'xprc' => 'application/vnd.palm',
|
565 |
-
'xpre' => 'application/vnd.lotus-freelance',
|
566 |
-
'xprf' => 'application/pics-rules',
|
567 |
-
'xps' => 'application/postscript',
|
568 |
-
'xpsb' => 'application/vnd.3gpp.pic-bw-small',
|
569 |
-
'xpsd' => 'image/vnd.adobe.photoshop',
|
570 |
-
'xptid' => 'application/vnd.pvi.ptid1',
|
571 |
-
|
572 |
-
'xpub' => 'application/x-mspublisher',
|
573 |
-
'xpvb' => 'application/vnd.3gpp.pic-bw-var',
|
574 |
-
'xpwn' => 'application/vnd.3m.post-it-notes',
|
575 |
-
'xqam' => 'application/vnd.epson.quickanime',
|
576 |
-
'xqbo' => 'application/vnd.intu.qbo',
|
577 |
-
'xqfx' => 'application/vnd.intu.qfx',
|
578 |
-
'xqps' => 'application/vnd.publishare-delta-tree',
|
579 |
-
'xqt' => 'video/quicktime',
|
580 |
-
'xra' => 'audio/x-pn-realaudio',
|
581 |
-
|
582 |
-
'xram' => 'audio/x-pn-realaudio',
|
583 |
-
'xrar' => 'application/x-rar-compressed',
|
584 |
-
'xras' => 'image/x-cmu-raster',
|
585 |
-
'xrcprofile' => 'application/vnd.ipunplugged.rcprofile',
|
586 |
-
'xrdf' => 'application/rdf+xml',
|
587 |
-
'xrdz' => 'application/vnd.data-vision.rdz',
|
588 |
-
'xrep' => 'application/vnd.businessobjects',
|
589 |
-
'xrgb' => 'image/x-rgb',
|
590 |
-
'xrif' => 'application/reginfo+xml',
|
591 |
-
|
592 |
-
'xrl' => 'application/resource-lists+xml',
|
593 |
-
'xrlc' => 'image/vnd.fujixerox.edmics-rlc',
|
594 |
-
'xrm' => 'application/vnd.rn-realmedia',
|
595 |
-
'xrmi' => 'audio/midi',
|
596 |
-
'xrmp' => 'audio/x-pn-realaudio-plugin',
|
597 |
-
'xrms' => 'application/vnd.jcp.javame.midlet-rms',
|
598 |
-
'xrnc' => 'application/relax-ng-compact-syntax',
|
599 |
-
'xrpss' => 'application/vnd.nokia.radio-presets',
|
600 |
-
'xrpst' => 'application/vnd.nokia.radio-preset',
|
601 |
-
|
602 |
-
'xrq' => 'application/sparql-query',
|
603 |
-
'xrs' => 'application/rls-services+xml',
|
604 |
-
'xrsd' => 'application/rsd+xml',
|
605 |
-
'xrss' => 'application/rss+xml',
|
606 |
-
'xrtf' => 'application/rtf',
|
607 |
-
'xrtx' => 'text/richtext',
|
608 |
-
'xsaf' => 'application/vnd.yamaha.smaf-audio',
|
609 |
-
'xsbml' => 'application/sbml+xml',
|
610 |
-
'xsc' => 'application/vnd.ibm.secure-container',
|
611 |
-
|
612 |
-
'xscd' => 'application/x-msschedule',
|
613 |
-
'xscm' => 'application/vnd.lotus-screencam',
|
614 |
-
'xscq' => 'application/scvp-cv-request',
|
615 |
-
'xscs' => 'application/scvp-cv-response',
|
616 |
-
'xsdp' => 'application/sdp',
|
617 |
-
'xsee' => 'application/vnd.seemail',
|
618 |
-
'xsema' => 'application/vnd.sema',
|
619 |
-
'xsemd' => 'application/vnd.semd',
|
620 |
-
'xsemf' => 'application/vnd.semf',
|
621 |
-
|
622 |
-
'xsetpay' => 'application/set-payment-initiation',
|
623 |
-
'xsetreg' => 'application/set-registration-initiation',
|
624 |
-
'xsfs' => 'application/vnd.spotfire.sfs',
|
625 |
-
'xsgm' => 'text/sgml',
|
626 |
-
'xsgml' => 'text/sgml',
|
627 |
-
'xsh' => 'application/x-sh',
|
628 |
-
'xshar' => 'application/x-shar',
|
629 |
-
'xshf' => 'application/shf+xml',
|
630 |
-
'xsilo' => 'model/mesh',
|
631 |
-
|
632 |
-
'xsit' => 'application/x-stuffit',
|
633 |
-
'xsitx' => 'application/x-stuffitx',
|
634 |
-
'xslt' => 'application/vnd.epson.salt',
|
635 |
-
'xsnd' => 'audio/basic',
|
636 |
-
'xspf' => 'application/vnd.yamaha.smaf-phrase',
|
637 |
-
'xspl' => 'application/x-futuresplash',
|
638 |
-
'xspot' => 'text/vnd.in3d.spot',
|
639 |
-
'xspp' => 'application/scvp-vp-response',
|
640 |
-
'xspq' => 'application/scvp-vp-request',
|
641 |
-
|
642 |
-
'xsrc' => 'application/x-wais-source',
|
643 |
-
'xsrx' => 'application/sparql-results+xml',
|
644 |
-
'xssf' => 'application/vnd.epson.ssf',
|
645 |
-
'xssml' => 'application/ssml+xml',
|
646 |
-
'xstf' => 'application/vnd.wt.stf',
|
647 |
-
'xstk' => 'application/hyperstudio',
|
648 |
-
'xstr' => 'application/vnd.pg.format',
|
649 |
-
'xsus' => 'application/vnd.sus-calendar',
|
650 |
-
'xsusp' => 'application/vnd.sus-calendar',
|
651 |
-
|
652 |
-
'xsv4cpio' => 'application/x-sv4cpio',
|
653 |
-
'xsv4crc' => 'application/x-sv4crc',
|
654 |
-
'xsvd' => 'application/vnd.svd',
|
655 |
-
'xswf' => 'application/x-shockwave-flash',
|
656 |
-
'xtao' => 'application/vnd.tao.intent-module-archive',
|
657 |
-
'xtar' => 'application/x-tar',
|
658 |
-
'xtcap' => 'application/vnd.3gpp2.tcap',
|
659 |
-
'xtcl' => 'application/x-tcl',
|
660 |
-
'xtex' => 'application/x-tex',
|
661 |
-
|
662 |
-
'xtext' => 'text/plain',
|
663 |
-
'xtif' => 'image/tiff',
|
664 |
-
'xtiff' => 'image/tiff',
|
665 |
-
'xtmo' => 'application/vnd.tmobile-livetv',
|
666 |
-
'xtorrent' => 'application/x-bittorrent',
|
667 |
-
'xtpl' => 'application/vnd.groove-tool-template',
|
668 |
-
'xtpt' => 'application/vnd.trid.tpt',
|
669 |
-
'xtra' => 'application/vnd.trueapp',
|
670 |
-
'xtrm' => 'application/x-msterminal',
|
671 |
-
|
672 |
-
'xtsv' => 'text/tab-separated-values',
|
673 |
-
'xtxd' => 'application/vnd.genomatix.tuxedo',
|
674 |
-
'xtxf' => 'application/vnd.mobius.txf',
|
675 |
-
'xtxt' => 'text/plain',
|
676 |
-
'xumj' => 'application/vnd.umajin',
|
677 |
-
'xunityweb' => 'application/vnd.unity',
|
678 |
-
'xuoml' => 'application/vnd.uoml+xml',
|
679 |
-
'xuri' => 'text/uri-list',
|
680 |
-
'xuris' => 'text/uri-list',
|
681 |
-
|
682 |
-
'xurls' => 'text/uri-list',
|
683 |
-
'xustar' => 'application/x-ustar',
|
684 |
-
'xutz' => 'application/vnd.uiq.theme',
|
685 |
-
'xuu' => 'text/x-uuencode',
|
686 |
-
'xvcd' => 'application/x-cdlink',
|
687 |
-
'xvcf' => 'text/x-vcard',
|
688 |
-
'xvcg' => 'application/vnd.groove-vcard',
|
689 |
-
'xvcs' => 'text/x-vcalendar',
|
690 |
-
'xvcx' => 'application/vnd.vcx',
|
691 |
-
|
692 |
-
'xvis' => 'application/vnd.visionary',
|
693 |
-
'xviv' => 'video/vnd.vivo',
|
694 |
-
'xvrml' => 'model/vrml',
|
695 |
-
'xvsd' => 'application/vnd.visio',
|
696 |
-
'xvsf' => 'application/vnd.vsf',
|
697 |
-
'xvss' => 'application/vnd.visio',
|
698 |
-
'xvst' => 'application/vnd.visio',
|
699 |
-
'xvsw' => 'application/vnd.visio',
|
700 |
-
'xvtu' => 'model/vnd.vtu',
|
701 |
-
|
702 |
-
'xvxml' => 'application/voicexml+xml',
|
703 |
-
'xwav' => 'audio/x-wav',
|
704 |
-
'xwax' => 'audio/x-ms-wax',
|
705 |
-
'xwbmp' => 'image/vnd.wap.wbmp',
|
706 |
-
'xwbs' => 'application/vnd.criticaltools.wbs+xml',
|
707 |
-
'xwbxml' => 'application/vnd.wap.wbxml',
|
708 |
-
'xwcm' => 'application/vnd.ms-works',
|
709 |
-
'xwdb' => 'application/vnd.ms-works',
|
710 |
-
'xwks' => 'application/vnd.ms-works',
|
711 |
-
|
712 |
-
'xwm' => 'video/x-ms-wm',
|
713 |
-
'xwma' => 'audio/x-ms-wma',
|
714 |
-
'xwmd' => 'application/x-ms-wmd',
|
715 |
-
'xwmf' => 'application/x-msmetafile',
|
716 |
-
'xwml' => 'text/vnd.wap.wml',
|
717 |
-
'xwmlc' => 'application/vnd.wap.wmlc',
|
718 |
-
'xwmls' => 'text/vnd.wap.wmlscript',
|
719 |
-
'xwmlsc' => 'application/vnd.wap.wmlscriptc',
|
720 |
-
'xwmv' => 'video/x-ms-wmv',
|
721 |
-
|
722 |
-
'xwmx' => 'video/x-ms-wmx',
|
723 |
-
'xwmz' => 'application/x-ms-wmz',
|
724 |
-
'xwpd' => 'application/vnd.wordperfect',
|
725 |
-
'xwpl' => 'application/vnd.ms-wpl',
|
726 |
-
'xwps' => 'application/vnd.ms-works',
|
727 |
-
'xwqd' => 'application/vnd.wqd',
|
728 |
-
'xwri' => 'application/x-mswrite',
|
729 |
-
'xwrl' => 'model/vrml',
|
730 |
-
'xwsdl' => 'application/wsdl+xml',
|
731 |
-
|
732 |
-
'xwspolicy' => 'application/wspolicy+xml',
|
733 |
-
'xwtb' => 'application/vnd.webturbo',
|
734 |
-
'xwvx' => 'video/x-ms-wvx',
|
735 |
-
'xx3d' => 'application/vnd.hzn-3d-crossword',
|
736 |
-
'xxar' => 'application/vnd.xara',
|
737 |
-
'xxbd' => 'application/vnd.fujixerox.docuworks.binder',
|
738 |
-
'xxbm' => 'image/x-xbitmap',
|
739 |
-
'xxdm' => 'application/vnd.syncml.dm+xml',
|
740 |
-
'xxdp' => 'application/vnd.adobe.xdp+xml',
|
741 |
-
|
742 |
-
'xxdw' => 'application/vnd.fujixerox.docuworks',
|
743 |
-
'xxenc' => 'application/xenc+xml',
|
744 |
-
'xxfdf' => 'application/vnd.adobe.xfdf',
|
745 |
-
'xxfdl' => 'application/vnd.xfdl',
|
746 |
-
'xxht' => 'application/xhtml+xml',
|
747 |
-
'xxhtml' => 'application/xhtml+xml',
|
748 |
-
'xxhvml' => 'application/xv+xml',
|
749 |
-
'xxif' => 'image/vnd.xiff',
|
750 |
-
'xxla' => 'application/vnd.ms-excel',
|
751 |
-
|
752 |
-
'xxlc' => 'application/vnd.ms-excel',
|
753 |
-
'xxlm' => 'application/vnd.ms-excel',
|
754 |
-
'xxls' => 'application/vnd.ms-excel',
|
755 |
-
'xxlt' => 'application/vnd.ms-excel',
|
756 |
-
'xxlw' => 'application/vnd.ms-excel',
|
757 |
-
'xxml' => 'application/xml',
|
758 |
-
'xxo' => 'application/vnd.olpc-sugar',
|
759 |
-
'xxop' => 'application/xop+xml',
|
760 |
-
'xxpm' => 'image/x-xpixmap',
|
761 |
-
|
762 |
-
'xxpr' => 'application/vnd.is-xpr',
|
763 |
-
'xxps' => 'application/vnd.ms-xpsdocument',
|
764 |
-
'xxsl' => 'application/xml',
|
765 |
-
'xxslt' => 'application/xslt+xml',
|
766 |
-
'xxsm' => 'application/vnd.syncml+xml',
|
767 |
-
'xxspf' => 'application/xspf+xml',
|
768 |
-
'xxul' => 'application/vnd.mozilla.xul+xml',
|
769 |
-
'xxvm' => 'application/xv+xml',
|
770 |
-
'xxvml' => 'application/xv+xml',
|
771 |
-
|
772 |
-
'xxwd' => 'image/x-xwindowdump',
|
773 |
-
'xxyz' => 'chemical/x-xyz',
|
774 |
-
'xzaz' => 'application/vnd.zzazz.deck+xml',
|
775 |
-
'xzip' => 'application/zip',
|
776 |
-
'xzmm' => 'application/vnd.handheld-entertainment+xml',
|
777 |
-
'xodt' => 'application/x-vnd.oasis.opendocument.spreadsheet'
|
778 |
-
);
|
779 |
}
|
33 |
*/
|
34 |
class Mage_Downloadable_Helper_File extends Mage_Core_Helper_Abstract
|
35 |
{
|
36 |
+
/**
|
37 |
+
* @see Mage_Uploader_Helper_File::getMimeTypes
|
38 |
+
* @var array
|
39 |
+
*/
|
40 |
+
protected $_mimeTypes;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @var Mage_Uploader_Helper_File
|
44 |
+
*/
|
45 |
+
protected $_fileHelper;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Populate self::_mimeTypes array with values that set in config or pre-defined
|
49 |
+
*/
|
50 |
public function __construct()
|
51 |
{
|
52 |
+
$this->_mimeTypes = $this->_getFileHelper()->getMimeTypes();
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @return Mage_Uploader_Helper_File
|
57 |
+
*/
|
58 |
+
protected function _getFileHelper()
|
59 |
+
{
|
60 |
+
if (!$this->_fileHelper) {
|
61 |
+
$this->_fileHelper = Mage::helper('uploader/file');
|
62 |
}
|
63 |
+
|
64 |
+
return $this->_fileHelper;
|
65 |
}
|
66 |
|
67 |
/**
|
172 |
return $file;
|
173 |
}
|
174 |
|
175 |
+
/**
|
176 |
+
* Get MIME type for $filePath
|
177 |
+
*
|
178 |
+
* @param $filePath
|
179 |
+
* @return string
|
180 |
+
*/
|
181 |
public function getFileType($filePath)
|
182 |
{
|
183 |
$ext = substr($filePath, strrpos($filePath, '.')+1);
|
184 |
return $this->_getFileTypeByExt($ext);
|
185 |
}
|
186 |
|
187 |
+
/**
|
188 |
+
* Get MIME type by file extension
|
189 |
+
*
|
190 |
+
* @param $ext
|
191 |
+
* @return string
|
192 |
+
* @deprecated
|
193 |
+
*/
|
194 |
protected function _getFileTypeByExt($ext)
|
195 |
{
|
196 |
+
return $this->_getFileHelper()->getMimeTypeByExtension($ext);
|
|
|
|
|
|
|
|
|
197 |
}
|
198 |
|
199 |
+
/**
|
200 |
+
* Get all MIME types
|
201 |
+
*
|
202 |
+
* @return array
|
203 |
+
*/
|
204 |
public function getAllFileTypes()
|
205 |
{
|
206 |
+
return array_values($this->getAllMineTypes());
|
207 |
}
|
208 |
|
209 |
+
/**
|
210 |
+
* Get list of all MIME types
|
211 |
+
*
|
212 |
+
* @return array
|
213 |
+
*/
|
214 |
public function getAllMineTypes()
|
215 |
{
|
216 |
+
return $this->_mimeTypes;
|
217 |
}
|
218 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
}
|
app/code/core/Mage/Eav/Block/Adminhtml/Attribute/Edit/Options/Abstract.php
CHANGED
@@ -170,12 +170,11 @@ abstract class Mage_Eav_Block_Adminhtml_Attribute_Edit_Options_Abstract extends
|
|
170 |
public function getLabelValues()
|
171 |
{
|
172 |
$values = array();
|
173 |
-
$values[0] = $this->getAttributeObject()->getFrontend()->getLabel();
|
174 |
-
// it can be array and cause bug
|
175 |
$frontendLabel = $this->getAttributeObject()->getFrontend()->getLabel();
|
176 |
if (is_array($frontendLabel)) {
|
177 |
-
|
178 |
}
|
|
|
179 |
$storeLabels = $this->getAttributeObject()->getStoreLabels();
|
180 |
foreach ($this->getStores() as $store) {
|
181 |
if ($store->getId() != 0) {
|
170 |
public function getLabelValues()
|
171 |
{
|
172 |
$values = array();
|
|
|
|
|
173 |
$frontendLabel = $this->getAttributeObject()->getFrontend()->getLabel();
|
174 |
if (is_array($frontendLabel)) {
|
175 |
+
return $frontendLabel;
|
176 |
}
|
177 |
+
$values[0] = $frontendLabel;
|
178 |
$storeLabels = $this->getAttributeObject()->getStoreLabels();
|
179 |
foreach ($this->getStores() as $store) {
|
180 |
if ($store->getId() != 0) {
|
app/code/core/Mage/Eav/Model/Entity/Abstract.php
CHANGED
@@ -808,13 +808,13 @@ abstract class Mage_Eav_Model_Entity_Abstract extends Mage_Core_Model_Resource_A
|
|
808 |
*
|
809 |
* @see Mage_Eav_Model_Entity_Abstract::getAttribute for $attribute format
|
810 |
* @param integer|string|Mage_Eav_Model_Entity_Attribute_Abstract $attribute
|
|
|
811 |
* @return boolean
|
812 |
*/
|
813 |
public function isAttributeStatic($attribute)
|
814 |
{
|
815 |
-
$attrInstance
|
816 |
-
$
|
817 |
-
return $attrInstance && $attrBackendStatic;
|
818 |
}
|
819 |
|
820 |
/**
|
@@ -1309,9 +1309,8 @@ abstract class Mage_Eav_Model_Entity_Abstract extends Mage_Core_Model_Resource_A
|
|
1309 |
$this->_attributeValuesToSave = array();
|
1310 |
$this->_attributeValuesToDelete = array();
|
1311 |
|
1312 |
-
extract($saveData);
|
1313 |
/**
|
1314 |
-
* Import variables
|
1315 |
*
|
1316 |
* @see Mage_Eav_Model_Entity_Attribute_Abstract::_collectSaveData()
|
1317 |
*
|
@@ -1321,6 +1320,12 @@ abstract class Mage_Eav_Model_Entity_Abstract extends Mage_Core_Model_Resource_A
|
|
1321 |
* @var array $update
|
1322 |
* @var array $delete
|
1323 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
1324 |
$adapter = $this->_getWriteAdapter();
|
1325 |
$insertEntity = true;
|
1326 |
$entityTable = $this->getEntityTable();
|
808 |
*
|
809 |
* @see Mage_Eav_Model_Entity_Abstract::getAttribute for $attribute format
|
810 |
* @param integer|string|Mage_Eav_Model_Entity_Attribute_Abstract $attribute
|
811 |
+
*
|
812 |
* @return boolean
|
813 |
*/
|
814 |
public function isAttributeStatic($attribute)
|
815 |
{
|
816 |
+
$attrInstance = $this->getAttribute($attribute);
|
817 |
+
return $attrInstance && $attrInstance->getBackend()->isStatic();
|
|
|
818 |
}
|
819 |
|
820 |
/**
|
1309 |
$this->_attributeValuesToSave = array();
|
1310 |
$this->_attributeValuesToDelete = array();
|
1311 |
|
|
|
1312 |
/**
|
1313 |
+
* Import variables from save data array
|
1314 |
*
|
1315 |
* @see Mage_Eav_Model_Entity_Attribute_Abstract::_collectSaveData()
|
1316 |
*
|
1320 |
* @var array $update
|
1321 |
* @var array $delete
|
1322 |
*/
|
1323 |
+
$newObject = $saveData['newObject'];
|
1324 |
+
$entityRow = $saveData['entityRow'];
|
1325 |
+
$insert = $saveData['insert'];
|
1326 |
+
$update = $saveData['update'];
|
1327 |
+
$delete = $saveData['delete'];
|
1328 |
+
|
1329 |
$adapter = $this->_getWriteAdapter();
|
1330 |
$insertEntity = true;
|
1331 |
$entityTable = $this->getEntityTable();
|
app/code/core/Mage/Eav/Model/Entity/Attribute.php
CHANGED
@@ -225,12 +225,12 @@ class Mage_Eav_Model_Entity_Attribute extends Mage_Eav_Model_Entity_Attribute_Ab
|
|
225 |
case 'text':
|
226 |
case 'gallery':
|
227 |
case 'media_image':
|
228 |
-
case 'multiselect':
|
229 |
$field = 'varchar';
|
230 |
break;
|
231 |
|
232 |
case 'image':
|
233 |
case 'textarea':
|
|
|
234 |
$field = 'text';
|
235 |
break;
|
236 |
|
@@ -272,6 +272,7 @@ class Mage_Eav_Model_Entity_Attribute extends Mage_Eav_Model_Entity_Attribute_Ab
|
|
272 |
case 'text':
|
273 |
case 'price':
|
274 |
case 'image':
|
|
|
275 |
$field = 'default_value_text';
|
276 |
break;
|
277 |
|
225 |
case 'text':
|
226 |
case 'gallery':
|
227 |
case 'media_image':
|
|
|
228 |
$field = 'varchar';
|
229 |
break;
|
230 |
|
231 |
case 'image':
|
232 |
case 'textarea':
|
233 |
+
case 'multiselect':
|
234 |
$field = 'text';
|
235 |
break;
|
236 |
|
272 |
case 'text':
|
273 |
case 'price':
|
274 |
case 'image':
|
275 |
+
case 'weight':
|
276 |
$field = 'default_value_text';
|
277 |
break;
|
278 |
|
app/code/core/Mage/Eav/Model/Entity/Attribute/Abstract.php
CHANGED
@@ -383,7 +383,10 @@ abstract class Mage_Eav_Model_Entity_Attribute_Abstract extends Mage_Core_Model_
|
|
383 |
$source = Mage::getModel($this->getSourceModel());
|
384 |
if (!$source) {
|
385 |
throw Mage::exception('Mage_Eav',
|
386 |
-
Mage::helper('eav')->__('Source model "%s" not found for attribute "%s"'
|
|
|
|
|
|
|
387 |
);
|
388 |
}
|
389 |
$this->_source = $source->setAttribute($this);
|
@@ -628,8 +631,14 @@ abstract class Mage_Eav_Model_Entity_Attribute_Abstract extends Mage_Core_Model_
|
|
628 |
break;
|
629 |
}
|
630 |
$prop = $describe[$this->getAttributeCode()];
|
|
|
|
|
|
|
|
|
|
|
|
|
631 |
$columns[$this->getAttributeCode()] = array(
|
632 |
-
'type' => $
|
633 |
'unsigned' => $prop['UNSIGNED'] ? true: false,
|
634 |
'is_null' => $prop['NULLABLE'],
|
635 |
'default' => $prop['DEFAULT'],
|
383 |
$source = Mage::getModel($this->getSourceModel());
|
384 |
if (!$source) {
|
385 |
throw Mage::exception('Mage_Eav',
|
386 |
+
Mage::helper('eav')->__('Source model "%s" not found for attribute "%s"',
|
387 |
+
$this->getSourceModel(),
|
388 |
+
$this->getAttributeCode()
|
389 |
+
)
|
390 |
);
|
391 |
}
|
392 |
$this->_source = $source->setAttribute($this);
|
631 |
break;
|
632 |
}
|
633 |
$prop = $describe[$this->getAttributeCode()];
|
634 |
+
$type = $prop['DATA_TYPE'];
|
635 |
+
if (isset($prop['PRECISION']) && isset($prop['SCALE'])) {
|
636 |
+
$type .= "({$prop['PRECISION']},{$prop['SCALE']})";
|
637 |
+
} else {
|
638 |
+
$type .= (isset($prop['LENGTH']) && $prop['LENGTH']) ? "({$prop['LENGTH']})" : "";
|
639 |
+
}
|
640 |
$columns[$this->getAttributeCode()] = array(
|
641 |
+
'type' => $type,
|
642 |
'unsigned' => $prop['UNSIGNED'] ? true: false,
|
643 |
'is_null' => $prop['NULLABLE'],
|
644 |
'default' => $prop['DEFAULT'],
|
app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Table.php
CHANGED
@@ -152,7 +152,7 @@ class Mage_Eav_Model_Entity_Attribute_Source_Table extends Mage_Eav_Model_Entity
|
|
152 |
|
153 |
if (Mage::helper('core')->useDbCompatibleMode()) {
|
154 |
$columns[$attributeCode] = array(
|
155 |
-
'type' => $isMulti ? '
|
156 |
'unsigned' => false,
|
157 |
'is_null' => true,
|
158 |
'default' => null,
|
@@ -171,7 +171,7 @@ class Mage_Eav_Model_Entity_Attribute_Source_Table extends Mage_Eav_Model_Entity
|
|
171 |
$type = ($isMulti) ? Varien_Db_Ddl_Table::TYPE_TEXT : Varien_Db_Ddl_Table::TYPE_INTEGER;
|
172 |
$columns[$attributeCode] = array(
|
173 |
'type' => $type,
|
174 |
-
'length' => $isMulti ? '
|
175 |
'unsigned' => false,
|
176 |
'nullable' => true,
|
177 |
'default' => null,
|
152 |
|
153 |
if (Mage::helper('core')->useDbCompatibleMode()) {
|
154 |
$columns[$attributeCode] = array(
|
155 |
+
'type' => $isMulti ? 'text' : 'int',
|
156 |
'unsigned' => false,
|
157 |
'is_null' => true,
|
158 |
'default' => null,
|
171 |
$type = ($isMulti) ? Varien_Db_Ddl_Table::TYPE_TEXT : Varien_Db_Ddl_Table::TYPE_INTEGER;
|
172 |
$columns[$attributeCode] = array(
|
173 |
'type' => $type,
|
174 |
+
'length' => $isMulti ? '65535' : null,
|
175 |
'unsigned' => false,
|
176 |
'nullable' => true,
|
177 |
'default' => null,
|
app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php
CHANGED
@@ -918,6 +918,7 @@ abstract class Mage_Eav_Model_Entity_Collection_Abstract extends Varien_Data_Col
|
|
918 |
/**
|
919 |
* Retrive all ids sql
|
920 |
*
|
|
|
921 |
* @return array
|
922 |
*/
|
923 |
public function getAllIdsSql()
|
@@ -1409,6 +1410,7 @@ abstract class Mage_Eav_Model_Entity_Collection_Abstract extends Varien_Data_Col
|
|
1409 |
foreach ($attribute as $attr) {
|
1410 |
parent::setOrder($attr, $dir);
|
1411 |
}
|
|
|
1412 |
}
|
1413 |
return parent::setOrder($attribute, $dir);
|
1414 |
}
|
918 |
/**
|
919 |
* Retrive all ids sql
|
920 |
*
|
921 |
+
* @deprecated
|
922 |
* @return array
|
923 |
*/
|
924 |
public function getAllIdsSql()
|
1410 |
foreach ($attribute as $attr) {
|
1411 |
parent::setOrder($attr, $dir);
|
1412 |
}
|
1413 |
+
return $this;
|
1414 |
}
|
1415 |
return parent::setOrder($attribute, $dir);
|
1416 |
}
|
app/code/core/Mage/ImportExport/Helper/Data.php
CHANGED
@@ -36,8 +36,9 @@ class Mage_ImportExport_Helper_Data extends Mage_Core_Helper_Data
|
|
36 |
/**
|
37 |
* XML path for config data
|
38 |
*/
|
39 |
-
const XML_PATH_EXPORT_LOCAL_VALID_PATH
|
40 |
-
const XML_PATH_BUNCH_SIZE
|
|
|
41 |
|
42 |
/**
|
43 |
* Maximum size of uploaded files.
|
@@ -69,4 +70,14 @@ class Mage_ImportExport_Helper_Data extends Mage_Core_Helper_Data
|
|
69 |
{
|
70 |
return (int)Mage::getStoreConfig(self::XML_PATH_BUNCH_SIZE);
|
71 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
}
|
36 |
/**
|
37 |
* XML path for config data
|
38 |
*/
|
39 |
+
const XML_PATH_EXPORT_LOCAL_VALID_PATH = 'general/file/importexport_local_valid_paths';
|
40 |
+
const XML_PATH_BUNCH_SIZE = 'general/file/bunch_size';
|
41 |
+
const XML_PATH_IMPORT_CONFIGURABLE_PAGE_SIZE = 'system/import_csv/configurable_page_size';
|
42 |
|
43 |
/**
|
44 |
* Maximum size of uploaded files.
|
70 |
{
|
71 |
return (int)Mage::getStoreConfig(self::XML_PATH_BUNCH_SIZE);
|
72 |
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Get page size for import configurable products
|
76 |
+
*
|
77 |
+
* @return int
|
78 |
+
*/
|
79 |
+
public function getImportConfigurablePageSize()
|
80 |
+
{
|
81 |
+
return (int)Mage::getStoreConfig(self::XML_PATH_IMPORT_CONFIGURABLE_PAGE_SIZE);
|
82 |
+
}
|
83 |
}
|
app/code/core/Mage/ImportExport/Model/Export.php
CHANGED
@@ -136,7 +136,9 @@ class Mage_ImportExport_Model_Export extends Mage_ImportExport_Model_Abstract
|
|
136 |
}
|
137 |
|
138 |
/**
|
139 |
-
* Export data.
|
|
|
|
|
140 |
*
|
141 |
* @throws Mage_Core_Exception
|
142 |
* @return string
|
@@ -168,6 +170,50 @@ class Mage_ImportExport_Model_Export extends Mage_ImportExport_Model_Abstract
|
|
168 |
}
|
169 |
}
|
170 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
/**
|
172 |
* Clean up already loaded attribute collection.
|
173 |
*
|
136 |
}
|
137 |
|
138 |
/**
|
139 |
+
* Export data and return contents of temporary file.
|
140 |
+
*
|
141 |
+
* @deprecated after ver 1.9.2.4 use $this->exportFile() instead
|
142 |
*
|
143 |
* @throws Mage_Core_Exception
|
144 |
* @return string
|
170 |
}
|
171 |
}
|
172 |
|
173 |
+
/**
|
174 |
+
* Export data and return temporary file through array.
|
175 |
+
*
|
176 |
+
* This method will return following array:
|
177 |
+
*
|
178 |
+
* array(
|
179 |
+
* 'rows' => count of written rows,
|
180 |
+
* 'value' => path to created file,
|
181 |
+
* 'type' => 'file'
|
182 |
+
* )
|
183 |
+
*
|
184 |
+
* @throws Mage_Core_Exception
|
185 |
+
* @return array
|
186 |
+
*/
|
187 |
+
public function exportFile()
|
188 |
+
{
|
189 |
+
if (isset($this->_data[self::FILTER_ELEMENT_GROUP])) {
|
190 |
+
$this->addLogComment(Mage::helper('importexport')->__('Begin export of %s', $this->getEntity()));
|
191 |
+
$result = $this->_getEntityAdapter()
|
192 |
+
->setWriter($this->_getWriter())
|
193 |
+
->exportFile();
|
194 |
+
|
195 |
+
if (isset($result['rows'])) {
|
196 |
+
if (!$result['rows']) {
|
197 |
+
Mage::throwException(
|
198 |
+
Mage::helper('importexport')->__('There is no data for export')
|
199 |
+
);
|
200 |
+
}
|
201 |
+
if ($result['rows']) {
|
202 |
+
$this->addLogComment(array(
|
203 |
+
Mage::helper('importexport')->__('Exported %s rows.', $result['rows']),
|
204 |
+
Mage::helper('importexport')->__('Export has been done.')
|
205 |
+
));
|
206 |
+
}
|
207 |
+
}
|
208 |
+
|
209 |
+
return $result;
|
210 |
+
} else {
|
211 |
+
Mage::throwException(
|
212 |
+
Mage::helper('importexport')->__('No filter data provided')
|
213 |
+
);
|
214 |
+
}
|
215 |
+
}
|
216 |
+
|
217 |
/**
|
218 |
* Clean up already loaded attribute collection.
|
219 |
*
|
app/code/core/Mage/ImportExport/Model/Export/Adapter/Abstract.php
CHANGED
@@ -47,6 +47,13 @@ abstract class Mage_ImportExport_Model_Export_Adapter_Abstract
|
|
47 |
*/
|
48 |
protected $_headerCols = null;
|
49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
/**
|
51 |
* Adapter object constructor.
|
52 |
*
|
@@ -124,6 +131,16 @@ abstract class Mage_ImportExport_Model_Export_Adapter_Abstract
|
|
124 |
return '';
|
125 |
}
|
126 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
/**
|
128 |
* Set column names.
|
129 |
*
|
47 |
*/
|
48 |
protected $_headerCols = null;
|
49 |
|
50 |
+
/**
|
51 |
+
* Count of rows
|
52 |
+
*
|
53 |
+
* @var int
|
54 |
+
*/
|
55 |
+
protected $_rowsCount = 0;
|
56 |
+
|
57 |
/**
|
58 |
* Adapter object constructor.
|
59 |
*
|
131 |
return '';
|
132 |
}
|
133 |
|
134 |
+
/**
|
135 |
+
* Get count of wrote lines
|
136 |
+
*
|
137 |
+
* @return int
|
138 |
+
*/
|
139 |
+
public function getRowsCount()
|
140 |
+
{
|
141 |
+
return $this->_rowsCount;
|
142 |
+
}
|
143 |
+
|
144 |
/**
|
145 |
* Set column names.
|
146 |
*
|
app/code/core/Mage/ImportExport/Model/Export/Adapter/Csv.php
CHANGED
@@ -125,6 +125,8 @@ class Mage_ImportExport_Model_Export_Adapter_Csv extends Mage_ImportExport_Model
|
|
125 |
$this->_enclosure
|
126 |
);
|
127 |
|
|
|
|
|
128 |
return $this;
|
129 |
}
|
130 |
|
125 |
$this->_enclosure
|
126 |
);
|
127 |
|
128 |
+
$this->_rowsCount++;
|
129 |
+
|
130 |
return $this;
|
131 |
}
|
132 |
|
app/code/core/Mage/ImportExport/Model/Export/Entity/Abstract.php
CHANGED
@@ -153,6 +153,27 @@ abstract class Mage_ImportExport_Model_Export_Entity_Abstract
|
|
153 |
*/
|
154 |
protected $_writer;
|
155 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
/**
|
157 |
* Constructor.
|
158 |
*
|
@@ -165,6 +186,20 @@ abstract class Mage_ImportExport_Model_Export_Entity_Abstract
|
|
165 |
$this->_connection = Mage::getSingleton('core/resource')->getConnection('write');
|
166 |
}
|
167 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
/**
|
169 |
* Initialize stores hash.
|
170 |
*
|
@@ -173,9 +208,11 @@ abstract class Mage_ImportExport_Model_Export_Entity_Abstract
|
|
173 |
protected function _initStores()
|
174 |
{
|
175 |
foreach (Mage::app()->getStores(true) as $store) {
|
176 |
-
$this->_storeIdToCode[$store->getId()]
|
|
|
177 |
}
|
178 |
ksort($this->_storeIdToCode); // to ensure that 'admin' store (ID is zero) goes first
|
|
|
179 |
|
180 |
return $this;
|
181 |
}
|
@@ -319,10 +356,28 @@ abstract class Mage_ImportExport_Model_Export_Entity_Abstract
|
|
319 |
/**
|
320 |
* Export process.
|
321 |
*
|
|
|
|
|
322 |
* @return string
|
323 |
*/
|
324 |
abstract public function export();
|
325 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
326 |
/**
|
327 |
* Clean up attribute collection.
|
328 |
*
|
@@ -367,7 +422,8 @@ abstract class Mage_ImportExport_Model_Export_Entity_Abstract
|
|
367 |
|
368 |
try {
|
369 |
foreach ($attribute->getSource()->getAllOptions(false) as $option) {
|
370 |
-
|
|
|
371 |
if (strlen($innerOption['value'])) { // skip ' -- Please Select -- ' option
|
372 |
$options[$innerOption['value']] = $innerOption[$index];
|
373 |
}
|
153 |
*/
|
154 |
protected $_writer;
|
155 |
|
156 |
+
/**
|
157 |
+
* Array of pairs store ID to its code.
|
158 |
+
*
|
159 |
+
* @var array
|
160 |
+
*/
|
161 |
+
protected $_storeIdToCode = array();
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Store Id-to-website
|
165 |
+
*
|
166 |
+
* @var array
|
167 |
+
*/
|
168 |
+
protected $_storeIdToWebsiteId = array();
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Website ID-to-code.
|
172 |
+
*
|
173 |
+
* @var array
|
174 |
+
*/
|
175 |
+
protected $_websiteIdToCode = array();
|
176 |
+
|
177 |
/**
|
178 |
* Constructor.
|
179 |
*
|
186 |
$this->_connection = Mage::getSingleton('core/resource')->getConnection('write');
|
187 |
}
|
188 |
|
189 |
+
/**
|
190 |
+
* Initialize website values.
|
191 |
+
*
|
192 |
+
* @return Mage_ImportExport_Model_Export_Entity_Customer
|
193 |
+
*/
|
194 |
+
protected function _initWebsites()
|
195 |
+
{
|
196 |
+
/** @var $website Mage_Core_Model_Website */
|
197 |
+
foreach (Mage::app()->getWebsites(true) as $website) {
|
198 |
+
$this->_websiteIdToCode[$website->getId()] = $website->getCode();
|
199 |
+
}
|
200 |
+
return $this;
|
201 |
+
}
|
202 |
+
|
203 |
/**
|
204 |
* Initialize stores hash.
|
205 |
*
|
208 |
protected function _initStores()
|
209 |
{
|
210 |
foreach (Mage::app()->getStores(true) as $store) {
|
211 |
+
$this->_storeIdToCode[$store->getId()] = $store->getCode();
|
212 |
+
$this->_storeIdToWebsiteId[$store->getId()] = $store->getWebsiteId();
|
213 |
}
|
214 |
ksort($this->_storeIdToCode); // to ensure that 'admin' store (ID is zero) goes first
|
215 |
+
sort($this->_storeIdToWebsiteId);
|
216 |
|
217 |
return $this;
|
218 |
}
|
356 |
/**
|
357 |
* Export process.
|
358 |
*
|
359 |
+
* @deprecated after ver 1.9.2.4 use $this->exportFile() instead
|
360 |
+
*
|
361 |
* @return string
|
362 |
*/
|
363 |
abstract public function export();
|
364 |
|
365 |
+
/**
|
366 |
+
* Export data and return temporary file through array.
|
367 |
+
*
|
368 |
+
* This method will return following array:
|
369 |
+
*
|
370 |
+
* array(
|
371 |
+
* 'rows' => count of written rows,
|
372 |
+
* 'value' => path to created file,
|
373 |
+
* 'type' => 'file'
|
374 |
+
* )
|
375 |
+
*
|
376 |
+
* @throws Mage_Core_Exception
|
377 |
+
* @return array
|
378 |
+
*/
|
379 |
+
abstract function exportFile();
|
380 |
+
|
381 |
/**
|
382 |
* Clean up attribute collection.
|
383 |
*
|
422 |
|
423 |
try {
|
424 |
foreach ($attribute->getSource()->getAllOptions(false) as $option) {
|
425 |
+
$innerOptions = is_array($option['value']) ? $option['value'] : array($option);
|
426 |
+
foreach ($innerOptions as $innerOption) {
|
427 |
if (strlen($innerOption['value'])) { // skip ' -- Please Select -- ' option
|
428 |
$options[$innerOption['value']] = $innerOption[$index];
|
429 |
}
|
app/code/core/Mage/ImportExport/Model/Export/Entity/Customer.php
CHANGED
@@ -75,20 +75,6 @@ class Mage_ImportExport_Model_Export_Entity_Customer extends Mage_ImportExport_M
|
|
75 |
*/
|
76 |
protected $_permanentAttributes = array(self::COL_EMAIL, self::COL_WEBSITE, self::COL_STORE);
|
77 |
|
78 |
-
/**
|
79 |
-
* Array of pairs store ID to its code.
|
80 |
-
*
|
81 |
-
* @var array
|
82 |
-
*/
|
83 |
-
protected $_storeIdToCode = array();
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Website ID-to-code.
|
87 |
-
*
|
88 |
-
* @var array
|
89 |
-
*/
|
90 |
-
protected $_websiteIdToCode = array();
|
91 |
-
|
92 |
/**
|
93 |
* Constructor.
|
94 |
*
|
@@ -132,51 +118,97 @@ class Mage_ImportExport_Model_Export_Entity_Customer extends Mage_ImportExport_M
|
|
132 |
}
|
133 |
|
134 |
/**
|
135 |
-
* Export process
|
|
|
|
|
136 |
*
|
137 |
* @return string
|
138 |
*/
|
139 |
public function export()
|
140 |
{
|
141 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
$validAttrCodes = $this->_getExportAttrCodes();
|
143 |
$writer = $this->getWriter();
|
144 |
$defaultAddrMap = Mage_ImportExport_Model_Import_Entity_Customer_Address::getDefaultAddressAttrMapping();
|
145 |
|
146 |
// prepare address data
|
147 |
-
$
|
148 |
-
$addrColNames
|
149 |
-
$customerAddrs
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
if (strlen($innerOption['value'])) { // skip ' -- Please Select -- ' option
|
161 |
-
$options[$innerOption['value']] = $innerOption['label'];
|
162 |
-
}
|
163 |
-
}
|
164 |
-
}
|
165 |
-
}
|
166 |
-
$addrAttributes[$attrCode] = $options;
|
167 |
$addrColNames[] = Mage_ImportExport_Model_Import_Entity_Customer_Address::getColNameForAttrCode($attrCode);
|
168 |
}
|
169 |
foreach (Mage::getResourceModel('customer/address_collection')->addAttributeToSelect('*') as $address) {
|
170 |
$addrRow = array();
|
171 |
|
172 |
-
|
|
|
|
|
|
|
|
|
173 |
if (null !== $address->getData($attrCode)) {
|
174 |
-
|
|
|
|
|
|
|
|
|
175 |
|
176 |
-
if ($
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
$value = $attrValues[$value];
|
178 |
}
|
179 |
-
$column = Mage_ImportExport_Model_Import_Entity_Customer_Address::getColNameForAttrCode($attrCode);
|
180 |
$addrRow[$column] = $value;
|
181 |
}
|
182 |
}
|
@@ -189,49 +221,108 @@ class Mage_ImportExport_Model_Export_Entity_Customer extends Mage_ImportExport_M
|
|
189 |
array('password'), $addrColNames,
|
190 |
array_keys($defaultAddrMap)
|
191 |
));
|
192 |
-
foreach ($collection as $
|
193 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
|
195 |
-
|
196 |
-
|
197 |
-
$attrValue = $item->getData($attrCode);
|
198 |
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
|
|
|
|
207 |
}
|
208 |
-
$
|
209 |
-
$
|
210 |
|
211 |
-
|
212 |
-
|
|
|
|
|
|
|
213 |
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
}
|
225 |
}
|
226 |
-
$writer->writeRow(array_merge($row, $addrRow['value']));
|
227 |
|
228 |
-
|
|
|
|
|
|
|
229 |
}
|
230 |
-
} else {
|
231 |
-
$writer->writeRow($row);
|
232 |
}
|
233 |
}
|
234 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
}
|
236 |
|
237 |
/**
|
@@ -247,7 +338,7 @@ class Mage_ImportExport_Model_Export_Entity_Customer extends Mage_ImportExport_M
|
|
247 |
$data = $this->_attributeOverrides[$attribute->getAttributeCode()];
|
248 |
|
249 |
if (isset($data['options_method']) && method_exists($this, $data['options_method'])) {
|
250 |
-
$data['filter_options'] = $this
|
251 |
}
|
252 |
$attribute->addData($data);
|
253 |
}
|
@@ -274,4 +365,152 @@ class Mage_ImportExport_Model_Export_Entity_Customer extends Mage_ImportExport_M
|
|
274 |
{
|
275 |
return 'customer';
|
276 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
277 |
}
|
75 |
*/
|
76 |
protected $_permanentAttributes = array(self::COL_EMAIL, self::COL_WEBSITE, self::COL_STORE);
|
77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
/**
|
79 |
* Constructor.
|
80 |
*
|
118 |
}
|
119 |
|
120 |
/**
|
121 |
+
* Export process and return contents of temporary file
|
122 |
+
*
|
123 |
+
* @deprecated after ver 1.9.2.4 use $this->exportFile() instead
|
124 |
*
|
125 |
* @return string
|
126 |
*/
|
127 |
public function export()
|
128 |
{
|
129 |
+
$this->_prepareExport();
|
130 |
+
|
131 |
+
return $this->getWriter()->getContents();
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Export process and return temporary file through array
|
136 |
+
*
|
137 |
+
* This method will return following array:
|
138 |
+
*
|
139 |
+
* array(
|
140 |
+
* 'rows' => count of written rows,
|
141 |
+
* 'value' => path to created file
|
142 |
+
* )
|
143 |
+
*
|
144 |
+
* @return array
|
145 |
+
*/
|
146 |
+
public function exportFile()
|
147 |
+
{
|
148 |
+
$this->_prepareExport();
|
149 |
+
|
150 |
+
$writer = $this->getWriter();
|
151 |
+
|
152 |
+
return array(
|
153 |
+
'rows' => $writer->getRowsCount(),
|
154 |
+
'value' => $writer->getDestination()
|
155 |
+
);
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Prepare data for export and write its to temporary file through writer.
|
160 |
+
*
|
161 |
+
* @return void
|
162 |
+
*/
|
163 |
+
protected function _prepareExport()
|
164 |
+
{
|
165 |
+
$collection = $this->_prepareEntityCollection(Mage::getResourceModel('customer/customer_collection'));
|
166 |
$validAttrCodes = $this->_getExportAttrCodes();
|
167 |
$writer = $this->getWriter();
|
168 |
$defaultAddrMap = Mage_ImportExport_Model_Import_Entity_Customer_Address::getDefaultAddressAttrMapping();
|
169 |
|
170 |
// prepare address data
|
171 |
+
$allAddressAttributeOptions = array();
|
172 |
+
$addrColNames = array();
|
173 |
+
$customerAddrs = array();
|
174 |
+
$addressAttributeCollection = Mage::getResourceModel('customer/address_attribute_collection')
|
175 |
+
->addSystemHiddenFilter()
|
176 |
+
->addExcludeHiddenFrontendFilter();
|
177 |
+
$addressAttributes = array();
|
178 |
+
$addrAttributeMultiSelect = array();
|
179 |
+
$customerAttributeMultiSelect = array();
|
180 |
|
181 |
+
foreach ($addressAttributeCollection as $attribute) {
|
182 |
+
$attrCode = $attribute->getAttributeCode();
|
183 |
+
$allAddressAttributeOptions[$attrCode] = $this->_getAddressAttributeOptions($attribute);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
$addrColNames[] = Mage_ImportExport_Model_Import_Entity_Customer_Address::getColNameForAttrCode($attrCode);
|
185 |
}
|
186 |
foreach (Mage::getResourceModel('customer/address_collection')->addAttributeToSelect('*') as $address) {
|
187 |
$addrRow = array();
|
188 |
|
189 |
+
if (empty($addressAttributes)) {
|
190 |
+
$addressAttributes = $address->getAttributes();
|
191 |
+
}
|
192 |
+
foreach ($allAddressAttributeOptions as $attrCode => $attrValues) {
|
193 |
+
$column = Mage_ImportExport_Model_Import_Entity_Customer_Address::getColNameForAttrCode($attrCode);
|
194 |
if (null !== $address->getData($attrCode)) {
|
195 |
+
if (!isset($addressAttributes[$attrCode])) {
|
196 |
+
$addressAttributes = array_merge($addressAttributes, $address->getAttributes());
|
197 |
+
}
|
198 |
+
$addressAttribute = $addressAttributes[$attrCode];
|
199 |
+
$value = $address->getData($attrCode);
|
200 |
|
201 |
+
if ($addressAttribute->getFrontendInput() == 'multiselect') {
|
202 |
+
$optionIds = explode(',', $value);
|
203 |
+
$optionTexts = array();
|
204 |
+
foreach ($optionIds as $optionId) {
|
205 |
+
$optionText = $addressAttribute->getSource()->getOptionText($optionId);
|
206 |
+
$optionTexts[$optionId] = $optionText;
|
207 |
+
}
|
208 |
+
$addrAttributeMultiSelect[$address['parent_id']][$address->getId()][$column] = $optionTexts;
|
209 |
+
} elseif ($attrValues) {
|
210 |
$value = $attrValues[$value];
|
211 |
}
|
|
|
212 |
$addrRow[$column] = $value;
|
213 |
}
|
214 |
}
|
221 |
array('password'), $addrColNames,
|
222 |
array_keys($defaultAddrMap)
|
223 |
));
|
224 |
+
foreach ($collection as $customerId => $customer) {
|
225 |
+
$customerAddress = array();
|
226 |
+
if (isset($customerAddrs[$customerId])) {
|
227 |
+
$customerAddress = $customerAddrs[$customerId];
|
228 |
+
}
|
229 |
+
$addressMultiselect= array();
|
230 |
+
if (isset($addrAttributeMultiSelect[$customerId])) {
|
231 |
+
$addressMultiselect = $addrAttributeMultiSelect[$customerId];
|
232 |
+
}
|
233 |
|
234 |
+
$row = $this->_prepareExportRow($customer, $customerAttributeMultiSelect);
|
235 |
+
$defaultAddrs = $this->_prepareDefaultAddress($customer);
|
|
|
236 |
|
237 |
+
$addrRow = array();
|
238 |
+
$currentAddressId = 0;
|
239 |
+
if (isset($customerAddrs[$customerId])) {
|
240 |
+
list($addressId, $addrRow) = $this->_getNextAddressRow($customerAddress);
|
241 |
+
$row = $this->_addDefaultAddressFields($defaultAddrs, $addressId, $row);
|
242 |
+
$addrRow = $this->_addNextAddressOptions($addressMultiselect, $addressId, $addrRow);
|
243 |
+
$currentAddressId = $addressId;
|
244 |
+
}
|
245 |
+
foreach ($customerAttributeMultiSelect as $column => &$multiSelectOptions) {
|
246 |
+
$row[$column] = array_shift($multiSelectOptions);
|
247 |
}
|
248 |
+
$writeRow = array_merge($row, $addrRow);
|
249 |
+
$writer->writeRow($writeRow);
|
250 |
|
251 |
+
$additionalRowsCount = $this->_getAdditionalRowsCount($customerAddress,
|
252 |
+
$addressMultiselect, $customerAttributeMultiSelect);
|
253 |
+
if ($additionalRowsCount) {
|
254 |
+
for ($i = 0; $i < $additionalRowsCount; $i++) {
|
255 |
+
$writeRow = array();
|
256 |
|
257 |
+
foreach ($customerAttributeMultiSelect as $column => &$multiSelectOptions) {
|
258 |
+
$writeRow[$column] = array_shift($multiSelectOptions);
|
259 |
+
}
|
260 |
+
if (!$this->_isExistMultiSelectOptions($addressMultiselect, $currentAddressId)) {
|
261 |
+
list($addressId, $addrRow) = $this->_getNextAddressRow($customerAddress);
|
262 |
+
$currentAddressId = $addressId;
|
263 |
+
$addrRow = $this->_addNextAddressOptions($addressMultiselect, $currentAddressId, $addrRow);
|
264 |
+
} else {
|
265 |
+
$addrRow = array();
|
266 |
+
$addrRow = $this->_addNextAddressOptions($addressMultiselect, $currentAddressId, $addrRow);
|
|
|
267 |
}
|
|
|
268 |
|
269 |
+
if ($addrRow) {
|
270 |
+
$writeRow = array_merge($writeRow, $addrRow);
|
271 |
+
}
|
272 |
+
$writer->writeRow($writeRow);
|
273 |
}
|
|
|
|
|
274 |
}
|
275 |
}
|
276 |
+
}
|
277 |
+
|
278 |
+
/**
|
279 |
+
* Get Additional Rows Count
|
280 |
+
*
|
281 |
+
* @param array $customerAddress
|
282 |
+
* @param array $addrMultiSelect
|
283 |
+
* @param array $customerMultiSelect
|
284 |
+
* @return int
|
285 |
+
*/
|
286 |
+
protected function _getAdditionalRowsCount($customerAddress, $addrMultiSelect, $customerMultiSelect)
|
287 |
+
{
|
288 |
+
$additionalRowsCount = count($customerAddress);
|
289 |
+
$addressRowCount = 0;
|
290 |
+
$allAddressRowCount = array();
|
291 |
+
|
292 |
+
foreach ($addrMultiSelect as $addressId => $addressAttributeOptions) {
|
293 |
+
foreach ($addressAttributeOptions as $options) {
|
294 |
+
$addressRowCount = max(count($options), $addressRowCount);
|
295 |
+
$allAddressRowCount[$addressId] = $addressRowCount;
|
296 |
+
}
|
297 |
+
$addressRowCount = 0;
|
298 |
+
}
|
299 |
+
|
300 |
+
$additionalRowsCount = max(array_sum($allAddressRowCount), $additionalRowsCount);
|
301 |
+
|
302 |
+
foreach ($customerMultiSelect as $options) {
|
303 |
+
$additionalRowsCount = max(count($options), $additionalRowsCount);
|
304 |
+
}
|
305 |
+
|
306 |
+
return $additionalRowsCount;
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Get Next Address Row
|
311 |
+
*
|
312 |
+
* @param array $customerAddress
|
313 |
+
* @return array
|
314 |
+
*/
|
315 |
+
protected function _getNextAddressRow(&$customerAddress)
|
316 |
+
{
|
317 |
+
if (!empty($customerAddress)) {
|
318 |
+
reset($customerAddress);
|
319 |
+
$addressId = key($customerAddress);
|
320 |
+
$addressRow = current($customerAddress);
|
321 |
+
unset($customerAddress[$addressId]);
|
322 |
+
|
323 |
+
return array($addressId, $addressRow);
|
324 |
+
}
|
325 |
+
return array(null, null);
|
326 |
}
|
327 |
|
328 |
/**
|
338 |
$data = $this->_attributeOverrides[$attribute->getAttributeCode()];
|
339 |
|
340 |
if (isset($data['options_method']) && method_exists($this, $data['options_method'])) {
|
341 |
+
$data['filter_options'] = $this->{$data['options_method']}();
|
342 |
}
|
343 |
$attribute->addData($data);
|
344 |
}
|
365 |
{
|
366 |
return 'customer';
|
367 |
}
|
368 |
+
|
369 |
+
/**
|
370 |
+
* Get Address Attributes
|
371 |
+
*
|
372 |
+
* @param $attribute
|
373 |
+
* @return array
|
374 |
+
*/
|
375 |
+
protected function _getAddressAttributeOptions($attribute)
|
376 |
+
{
|
377 |
+
$options = array();
|
378 |
+
$attrCode = $attribute->getAttributeCode();
|
379 |
+
|
380 |
+
if ($attribute->usesSource() && 'country_id' != $attrCode) {
|
381 |
+
foreach ($attribute->getSource()->getAllOptions(false) as $option) {
|
382 |
+
$innerOptions = is_array($option['value']) ? $option['value'] : array($option);
|
383 |
+
foreach ($innerOptions as $innerOption) {
|
384 |
+
// skip ' -- Please Select -- ' option
|
385 |
+
if (strlen($innerOption['value'])) {
|
386 |
+
$options[$innerOption['value']] = $innerOption['label'];
|
387 |
+
}
|
388 |
+
}
|
389 |
+
}
|
390 |
+
}
|
391 |
+
return $options;
|
392 |
+
}
|
393 |
+
|
394 |
+
/**
|
395 |
+
* Prepare Export Row
|
396 |
+
*
|
397 |
+
* @param Mage_Customer_Model_Customer $customer
|
398 |
+
* @param array $attributeMultiSelect
|
399 |
+
* @return array
|
400 |
+
*/
|
401 |
+
protected function _prepareExportRow($customer, &$attributeMultiSelect)
|
402 |
+
{
|
403 |
+
$row = array();
|
404 |
+
$validAttrCodes = $this->_getExportAttrCodes();
|
405 |
+
|
406 |
+
// go through all valid attribute codes
|
407 |
+
foreach ($validAttrCodes as $attrCode) {
|
408 |
+
$attribute = $customer->getAttribute($attrCode);
|
409 |
+
$attrValue = $customer->getData($attrCode);
|
410 |
+
|
411 |
+
if ($attribute && $attribute->getFrontendInput() == 'multiselect') {
|
412 |
+
$optionText = (array)$attribute->getSource()->getOptionText($attrValue);
|
413 |
+
if ($optionText) {
|
414 |
+
$attributeMultiSelect[$attrCode] = $optionText;
|
415 |
+
$attrValue = null;
|
416 |
+
}
|
417 |
+
} elseif (isset($this->_attributeValues[$attrCode])
|
418 |
+
&& isset($this->_attributeValues[$attrCode][$attrValue])
|
419 |
+
) {
|
420 |
+
$attrValue = $this->_attributeValues[$attrCode][$attrValue];
|
421 |
+
}
|
422 |
+
if (null !== $attrValue) {
|
423 |
+
$row[$attrCode] = $attrValue;
|
424 |
+
}
|
425 |
+
}
|
426 |
+
$row[self::COL_WEBSITE] = $this->_websiteIdToCode[$customer['website_id']];
|
427 |
+
$row[self::COL_STORE] = $this->_storeIdToCode[$customer['store_id']];
|
428 |
+
|
429 |
+
return $row;
|
430 |
+
}
|
431 |
+
|
432 |
+
/**
|
433 |
+
* Prepare Default Address
|
434 |
+
*
|
435 |
+
* @param Mage_Customer_Model_Customer $customer
|
436 |
+
* @return array
|
437 |
+
*/
|
438 |
+
protected function _prepareDefaultAddress($customer)
|
439 |
+
{
|
440 |
+
$defaultAddrMap = Mage_ImportExport_Model_Import_Entity_Customer_Address::getDefaultAddressAttrMapping();
|
441 |
+
$defaultAddrs = array();
|
442 |
+
|
443 |
+
foreach ($defaultAddrMap as $colName => $addrAttrCode) {
|
444 |
+
if (!empty($customer[$addrAttrCode])) {
|
445 |
+
$defaultAddrs[$customer[$addrAttrCode]][] = $colName;
|
446 |
+
}
|
447 |
+
}
|
448 |
+
return $defaultAddrs;
|
449 |
+
}
|
450 |
+
|
451 |
+
/**
|
452 |
+
* Add default fields to row
|
453 |
+
*
|
454 |
+
* @param $defaultAddrs
|
455 |
+
* @param $addressId
|
456 |
+
* @param $row
|
457 |
+
* @return mixed
|
458 |
+
*/
|
459 |
+
protected function _addDefaultAddressFields($defaultAddrs, $addressId, $row)
|
460 |
+
{
|
461 |
+
if (isset($defaultAddrs[$addressId])) {
|
462 |
+
foreach ($defaultAddrs[$addressId] as $colName) {
|
463 |
+
$row[$colName] = 1;
|
464 |
+
}
|
465 |
+
return $row;
|
466 |
+
}
|
467 |
+
return $row;
|
468 |
+
}
|
469 |
+
|
470 |
+
/**
|
471 |
+
* Get Next Address MultiSelect option
|
472 |
+
*
|
473 |
+
* @param array $addrAttributeMultiSelect
|
474 |
+
* @param int $addressId
|
475 |
+
* @param array $addrRow
|
476 |
+
* @return array
|
477 |
+
*/
|
478 |
+
protected function _addNextAddressOptions(&$addrAttributeMultiSelect, $addressId, $addrRow)
|
479 |
+
{
|
480 |
+
if (!isset($addrAttributeMultiSelect[$addressId])) {
|
481 |
+
return $addrRow;
|
482 |
+
}
|
483 |
+
$addrMultiSelectOption = &$addrAttributeMultiSelect[$addressId];
|
484 |
+
if (is_array($addrMultiSelectOption)) {
|
485 |
+
foreach ($addrMultiSelectOption as $column => &$options) {
|
486 |
+
$addrRow[$column] = array_shift($options);
|
487 |
+
}
|
488 |
+
}
|
489 |
+
return $addrRow;
|
490 |
+
}
|
491 |
+
|
492 |
+
/**
|
493 |
+
* Check if exist MultiSelect Options
|
494 |
+
*
|
495 |
+
* @param array $addrAttributeMultiSelect
|
496 |
+
* @param int $addressId
|
497 |
+
* @return bool
|
498 |
+
*/
|
499 |
+
protected function _isExistMultiSelectOptions($addrAttributeMultiSelect, $addressId)
|
500 |
+
{
|
501 |
+
$result = false;
|
502 |
+
if (!isset($addrAttributeMultiSelect[$addressId])) {
|
503 |
+
return $result;
|
504 |
+
}
|
505 |
+
$addrMultiSelectOption = $addrAttributeMultiSelect[$addressId];
|
506 |
+
if (is_array($addrMultiSelectOption)) {
|
507 |
+
foreach ($addrMultiSelectOption as $option) {
|
508 |
+
if (!empty($option)) {
|
509 |
+
$result = true;
|
510 |
+
break;
|
511 |
+
}
|
512 |
+
}
|
513 |
+
}
|
514 |
+
return $result;
|
515 |
+
}
|
516 |
}
|
app/code/core/Mage/ImportExport/Model/Export/Entity/Product.php
CHANGED
@@ -102,24 +102,18 @@ class Mage_ImportExport_Model_Export_Entity_Product extends Mage_ImportExport_Mo
|
|
102 |
protected $_productTypeModels = array();
|
103 |
|
104 |
/**
|
105 |
-
*
|
106 |
*
|
107 |
* @var array
|
108 |
*/
|
109 |
-
protected $
|
110 |
|
111 |
/**
|
112 |
-
*
|
113 |
*
|
114 |
* @var array
|
115 |
*/
|
116 |
-
protected $
|
117 |
-
|
118 |
-
/**
|
119 |
-
* Attribute types
|
120 |
-
* @var array
|
121 |
-
*/
|
122 |
-
protected $_attributeTypes = array();
|
123 |
|
124 |
/**
|
125 |
* Constructor.
|
@@ -546,11 +540,49 @@ class Mage_ImportExport_Model_Export_Entity_Product extends Mage_ImportExport_Mo
|
|
546 |
}
|
547 |
|
548 |
/**
|
549 |
-
* Export process.
|
|
|
|
|
550 |
*
|
551 |
* @return string
|
552 |
*/
|
553 |
public function export()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
554 |
{
|
555 |
//Execution time may be very long
|
556 |
set_time_limit(0);
|
@@ -637,7 +669,41 @@ class Mage_ImportExport_Model_Export_Entity_Product extends Mage_ImportExport_Mo
|
|
637 |
$this->_attributeValues[$attrCode],
|
638 |
array_flip($attrValue)
|
639 |
);
|
640 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
641 |
} else if (isset($this->_attributeValues[$attrCode][$attrValue])) {
|
642 |
$attrValue = $this->_attributeValues[$attrCode][$attrValue];
|
643 |
} else {
|
@@ -737,6 +803,7 @@ class Mage_ImportExport_Model_Export_Entity_Product extends Mage_ImportExport_Mo
|
|
737 |
);
|
738 |
|
739 |
foreach ($this->_storeIdToCode as $storeId => &$storeCode) {
|
|
|
740 |
$options = Mage::getResourceModel('catalog/product_option_collection')
|
741 |
->reset()
|
742 |
->addTitleToResult($storeId)
|
@@ -769,7 +836,7 @@ class Mage_ImportExport_Model_Export_Entity_Product extends Mage_ImportExport_Mo
|
|
769 |
}
|
770 |
$values = $option->getValues();
|
771 |
if ($values) {
|
772 |
-
$firstValue =
|
773 |
$priceType = $firstValue['price_type'] == 'percent' ? '%' : '';
|
774 |
|
775 |
if ($defaultStoreId == $storeId) {
|
@@ -788,8 +855,14 @@ class Mage_ImportExport_Model_Export_Entity_Product extends Mage_ImportExport_Mo
|
|
788 |
$row['_custom_option_store'] = $this->_storeIdToCode[$storeId];
|
789 |
}
|
790 |
$customOptionsDataPre[$productId][$optionId][] = $row;
|
|
|
791 |
}
|
792 |
foreach ($values as $value) {
|
|
|
|
|
|
|
|
|
|
|
793 |
$row = array();
|
794 |
$valuePriceType = $value['price_type'] == 'percent' ? '%' : '';
|
795 |
|
@@ -798,7 +871,7 @@ class Mage_ImportExport_Model_Export_Entity_Product extends Mage_ImportExport_Mo
|
|
798 |
$row['_custom_option_row_price'] = $value['price'] . $valuePriceType;
|
799 |
$row['_custom_option_row_sku'] = $value['sku'];
|
800 |
$row['_custom_option_row_sort'] = $value['sort_order'];
|
801 |
-
}
|
802 |
$row['_custom_option_row_title'] = $value['title'];
|
803 |
}
|
804 |
if ($row) {
|
@@ -905,94 +978,93 @@ class Mage_ImportExport_Model_Export_Entity_Product extends Mage_ImportExport_Mo
|
|
905 |
if (!empty($configurableData[$productId])) {
|
906 |
$dataRow = array_merge($dataRow, array_shift($configurableData[$productId]));
|
907 |
}
|
908 |
-
if(!empty($rowMultiselects[$productId])) {
|
909 |
-
foreach ($rowMultiselects[$productId] as $attrKey => $attrVal) {
|
910 |
-
if (
|
911 |
-
$dataRow[$attrKey] = array_shift($rowMultiselects[$productId][$attrKey]);
|
912 |
}
|
913 |
}
|
914 |
}
|
915 |
|
916 |
$writer->writeRow($dataRow);
|
917 |
-
|
918 |
-
|
919 |
-
$largestLinks = 0;
|
920 |
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
|
|
925 |
}
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
$additionalRowsCount = max($additionalRowsCount, count($rowTierPrices[$productId]));
|
934 |
-
}
|
935 |
-
if (!empty($rowGroupPrices[$productId])) {
|
936 |
-
$additionalRowsCount = max($additionalRowsCount, count($rowGroupPrices[$productId]));
|
937 |
-
}
|
938 |
-
if (!empty($mediaGalery[$productId])) {
|
939 |
-
$additionalRowsCount = max($additionalRowsCount, count($mediaGalery[$productId]));
|
940 |
-
}
|
941 |
-
if (!empty($customOptionsData[$productId])) {
|
942 |
-
$additionalRowsCount = max($additionalRowsCount, count($customOptionsData[$productId]));
|
943 |
-
}
|
944 |
-
if (!empty($configurableData[$productId])) {
|
945 |
-
$additionalRowsCount = max($additionalRowsCount, count($configurableData[$productId]));
|
946 |
-
}
|
947 |
-
if (!empty($rowMultiselects[$productId])) {
|
948 |
-
foreach($rowMultiselects[$productId] as $attributes) {
|
949 |
-
$additionalRowsCount = max($additionalRowsCount, count($attributes));
|
950 |
}
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
$
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
$dataRow = array_merge($dataRow, array_shift($rowGroupPrices[$productId]));
|
967 |
-
}
|
968 |
-
if (!empty($mediaGalery[$productId])) {
|
969 |
-
$dataRow = array_merge($dataRow, array_shift($mediaGalery[$productId]));
|
970 |
}
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
979 |
}
|
980 |
}
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
}
|
993 |
}
|
|
|
994 |
}
|
995 |
-
$writer->writeRow($dataRow);
|
996 |
}
|
997 |
}
|
998 |
}
|
@@ -1058,6 +1130,7 @@ class Mage_ImportExport_Model_Export_Entity_Product extends Mage_ImportExport_Mo
|
|
1058 |
$this->_attributeValues[$attribute->getAttributeCode()] = $this->getAttributeOptions($attribute);
|
1059 |
$this->_attributeTypes[$attribute->getAttributeCode()] =
|
1060 |
Mage_ImportExport_Model_Import::getAttributeType($attribute);
|
|
|
1061 |
}
|
1062 |
return $this;
|
1063 |
}
|
102 |
protected $_productTypeModels = array();
|
103 |
|
104 |
/**
|
105 |
+
* Attribute types
|
106 |
*
|
107 |
* @var array
|
108 |
*/
|
109 |
+
protected $_attributeTypes = array();
|
110 |
|
111 |
/**
|
112 |
+
* Attribute scopes
|
113 |
*
|
114 |
* @var array
|
115 |
*/
|
116 |
+
protected $_attributeScopes = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
|
118 |
/**
|
119 |
* Constructor.
|
540 |
}
|
541 |
|
542 |
/**
|
543 |
+
* Export process and return contents of temporary file.
|
544 |
+
*
|
545 |
+
* @deprecated after ver 1.9.2.4 use $this->exportFile() instead
|
546 |
*
|
547 |
* @return string
|
548 |
*/
|
549 |
public function export()
|
550 |
+
{
|
551 |
+
$this->_prepareExport();
|
552 |
+
|
553 |
+
return $this->getWriter()->getContents();
|
554 |
+
}
|
555 |
+
|
556 |
+
/**
|
557 |
+
* Export process and return temporary file through array.
|
558 |
+
*
|
559 |
+
* This method will return following array:
|
560 |
+
*
|
561 |
+
* array(
|
562 |
+
* 'rows' => count of written rows,
|
563 |
+
* 'value' => path to created file
|
564 |
+
* )
|
565 |
+
*
|
566 |
+
* @return array
|
567 |
+
*/
|
568 |
+
public function exportFile()
|
569 |
+
{
|
570 |
+
$this->_prepareExport();
|
571 |
+
|
572 |
+
$writer = $this->getWriter();
|
573 |
+
|
574 |
+
return array(
|
575 |
+
'rows' => $writer->getRowsCount(),
|
576 |
+
'value' => $writer->getDestination()
|
577 |
+
);
|
578 |
+
}
|
579 |
+
|
580 |
+
/**
|
581 |
+
* Prepare data for export.
|
582 |
+
*
|
583 |
+
* @return void
|
584 |
+
*/
|
585 |
+
protected function _prepareExport()
|
586 |
{
|
587 |
//Execution time may be very long
|
588 |
set_time_limit(0);
|
669 |
$this->_attributeValues[$attrCode],
|
670 |
array_flip($attrValue)
|
671 |
);
|
672 |
+
|
673 |
+
switch ($this->_attributeScopes[$attrCode]) {
|
674 |
+
case Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE:
|
675 |
+
if (isset($rowMultiselects[$itemId][0][$attrCode])
|
676 |
+
&& $attrValue == $rowMultiselects[$itemId][0][$attrCode]
|
677 |
+
) {
|
678 |
+
$attrValue = null;
|
679 |
+
}
|
680 |
+
break;
|
681 |
+
|
682 |
+
case Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL:
|
683 |
+
if ($storeId != $defaultStoreId) {
|
684 |
+
$attrValue = null;
|
685 |
+
}
|
686 |
+
break;
|
687 |
+
|
688 |
+
case Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE:
|
689 |
+
$websiteId = $this->_storeIdToWebsiteId[$storeId];
|
690 |
+
$websiteStoreId = array_search($websiteId, $this->_storeIdToWebsiteId);
|
691 |
+
if ((isset($rowMultiselects[$itemId][$websiteStoreId][$attrCode])
|
692 |
+
&& $attrValue == $rowMultiselects[$itemId][$websiteStoreId][$attrCode])
|
693 |
+
|| $attrValue == $rowMultiselects[$itemId][0][$attrCode]
|
694 |
+
) {
|
695 |
+
$attrValue = null;
|
696 |
+
}
|
697 |
+
break;
|
698 |
+
|
699 |
+
default:
|
700 |
+
break;
|
701 |
+
}
|
702 |
+
|
703 |
+
if ($attrValue) {
|
704 |
+
$rowMultiselects[$itemId][$storeId][$attrCode] = $attrValue;
|
705 |
+
$rowIsEmpty = false;
|
706 |
+
}
|
707 |
} else if (isset($this->_attributeValues[$attrCode][$attrValue])) {
|
708 |
$attrValue = $this->_attributeValues[$attrCode][$attrValue];
|
709 |
} else {
|
803 |
);
|
804 |
|
805 |
foreach ($this->_storeIdToCode as $storeId => &$storeCode) {
|
806 |
+
$skip = false;
|
807 |
$options = Mage::getResourceModel('catalog/product_option_collection')
|
808 |
->reset()
|
809 |
->addTitleToResult($storeId)
|
836 |
}
|
837 |
$values = $option->getValues();
|
838 |
if ($values) {
|
839 |
+
$firstValue = reset($values);
|
840 |
$priceType = $firstValue['price_type'] == 'percent' ? '%' : '';
|
841 |
|
842 |
if ($defaultStoreId == $storeId) {
|
855 |
$row['_custom_option_store'] = $this->_storeIdToCode[$storeId];
|
856 |
}
|
857 |
$customOptionsDataPre[$productId][$optionId][] = $row;
|
858 |
+
$skip = true;
|
859 |
}
|
860 |
foreach ($values as $value) {
|
861 |
+
if ($skip) {
|
862 |
+
$skip = false;
|
863 |
+
continue;
|
864 |
+
}
|
865 |
+
|
866 |
$row = array();
|
867 |
$valuePriceType = $value['price_type'] == 'percent' ? '%' : '';
|
868 |
|
871 |
$row['_custom_option_row_price'] = $value['price'] . $valuePriceType;
|
872 |
$row['_custom_option_row_sku'] = $value['sku'];
|
873 |
$row['_custom_option_row_sort'] = $value['sort_order'];
|
874 |
+
} else {
|
875 |
$row['_custom_option_row_title'] = $value['title'];
|
876 |
}
|
877 |
if ($row) {
|
978 |
if (!empty($configurableData[$productId])) {
|
979 |
$dataRow = array_merge($dataRow, array_shift($configurableData[$productId]));
|
980 |
}
|
981 |
+
if(!empty($rowMultiselects[$productId][$storeId])) {
|
982 |
+
foreach ($rowMultiselects[$productId][$storeId] as $attrKey => $attrVal) {
|
983 |
+
if (isset($rowMultiselects[$productId][$storeId][$attrKey])) {
|
984 |
+
$dataRow[$attrKey] = array_shift($rowMultiselects[$productId][$storeId][$attrKey]);
|
985 |
}
|
986 |
}
|
987 |
}
|
988 |
|
989 |
$writer->writeRow($dataRow);
|
990 |
+
// calculate largest links block
|
991 |
+
$largestLinks = 0;
|
|
|
992 |
|
993 |
+
if (isset($linksRows[$productId])) {
|
994 |
+
$linksRowsKeys = array_keys($linksRows[$productId]);
|
995 |
+
foreach ($linksRowsKeys as $linksRowsKey) {
|
996 |
+
$largestLinks = max($largestLinks, count($linksRows[$productId][$linksRowsKey]));
|
997 |
+
}
|
998 |
}
|
999 |
+
$additionalRowsCount = max(
|
1000 |
+
count($rowCategories[$productId]),
|
1001 |
+
count($rowWebsites[$productId]),
|
1002 |
+
$largestLinks
|
1003 |
+
);
|
1004 |
+
if (!empty($rowTierPrices[$productId])) {
|
1005 |
+
$additionalRowsCount = max($additionalRowsCount, count($rowTierPrices[$productId]));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1006 |
}
|
1007 |
+
if (!empty($rowGroupPrices[$productId])) {
|
1008 |
+
$additionalRowsCount = max($additionalRowsCount, count($rowGroupPrices[$productId]));
|
1009 |
+
}
|
1010 |
+
if (!empty($mediaGalery[$productId])) {
|
1011 |
+
$additionalRowsCount = max($additionalRowsCount, count($mediaGalery[$productId]));
|
1012 |
+
}
|
1013 |
+
if (!empty($customOptionsData[$productId])) {
|
1014 |
+
$additionalRowsCount = max($additionalRowsCount, count($customOptionsData[$productId]));
|
1015 |
+
}
|
1016 |
+
if (!empty($configurableData[$productId])) {
|
1017 |
+
$additionalRowsCount = max($additionalRowsCount, count($configurableData[$productId]));
|
1018 |
+
}
|
1019 |
+
if (!empty($rowMultiselects[$productId][$storeId])) {
|
1020 |
+
foreach($rowMultiselects[$productId][$storeId] as $attributes) {
|
1021 |
+
$additionalRowsCount = max($additionalRowsCount, count($attributes));
|
|
|
|
|
|
|
|
|
1022 |
}
|
1023 |
+
}
|
1024 |
+
if ($additionalRowsCount) {
|
1025 |
+
for ($i = 0; $i < $additionalRowsCount; $i++) {
|
1026 |
+
$dataRow = array();
|
1027 |
+
|
1028 |
+
$this->_updateDataWithCategoryColumns($dataRow, $rowCategories, $productId);
|
1029 |
+
if ($rowWebsites[$productId]) {
|
1030 |
+
$dataRow['_product_websites'] = $this
|
1031 |
+
->_websiteIdToCode[array_shift($rowWebsites[$productId])];
|
1032 |
+
}
|
1033 |
+
if (!empty($rowTierPrices[$productId])) {
|
1034 |
+
$dataRow = array_merge($dataRow, array_shift($rowTierPrices[$productId]));
|
1035 |
+
}
|
1036 |
+
if (!empty($rowGroupPrices[$productId])) {
|
1037 |
+
$dataRow = array_merge($dataRow, array_shift($rowGroupPrices[$productId]));
|
1038 |
+
}
|
1039 |
+
if (!empty($mediaGalery[$productId])) {
|
1040 |
+
$dataRow = array_merge($dataRow, array_shift($mediaGalery[$productId]));
|
1041 |
+
}
|
1042 |
+
foreach ($linkIdColPrefix as $linkId => &$colPrefix) {
|
1043 |
+
if (!empty($linksRows[$productId][$linkId])) {
|
1044 |
+
$linkData = array_shift($linksRows[$productId][$linkId]);
|
1045 |
+
$dataRow[$colPrefix . 'position'] = $linkData['position'];
|
1046 |
+
$dataRow[$colPrefix . 'sku'] = $linkData['sku'];
|
1047 |
+
|
1048 |
+
if (null !== $linkData['default_qty']) {
|
1049 |
+
$dataRow[$colPrefix . 'default_qty'] = $linkData['default_qty'];
|
1050 |
+
}
|
1051 |
}
|
1052 |
}
|
1053 |
+
if (!empty($customOptionsData[$productId])) {
|
1054 |
+
$dataRow = array_merge($dataRow, array_shift($customOptionsData[$productId]));
|
1055 |
+
}
|
1056 |
+
if (!empty($configurableData[$productId])) {
|
1057 |
+
$dataRow = array_merge($dataRow, array_shift($configurableData[$productId]));
|
1058 |
+
}
|
1059 |
+
if(!empty($rowMultiselects[$productId][$storeId])) {
|
1060 |
+
foreach($rowMultiselects[$productId][$storeId] as $attrKey=>$attrVal) {
|
1061 |
+
if(isset($rowMultiselects[$productId][$storeId][$attrKey])) {
|
1062 |
+
$dataRow[$attrKey] = array_shift($rowMultiselects[$productId][$storeId][$attrKey]);
|
1063 |
+
}
|
1064 |
}
|
1065 |
}
|
1066 |
+
$writer->writeRow($dataRow);
|
1067 |
}
|
|
|
1068 |
}
|
1069 |
}
|
1070 |
}
|
1130 |
$this->_attributeValues[$attribute->getAttributeCode()] = $this->getAttributeOptions($attribute);
|
1131 |
$this->_attributeTypes[$attribute->getAttributeCode()] =
|
1132 |
Mage_ImportExport_Model_Import::getAttributeType($attribute);
|
1133 |
+
$this->_attributeScopes[$attribute->getAttributeCode()] = $attribute->getIsGlobal();
|
1134 |
}
|
1135 |
return $this;
|
1136 |
}
|
app/code/core/Mage/ImportExport/Model/Export/Entity/Product/Type/Abstract.php
CHANGED
@@ -96,7 +96,7 @@ abstract class Mage_ImportExport_Model_Export_Entity_Product_Type_Abstract
|
|
96 |
$data = $this->_attributeOverrides[$attribute->getAttributeCode()];
|
97 |
|
98 |
if (isset($data['options_method']) && method_exists($this, $data['options_method'])) {
|
99 |
-
$data['filter_options'] = $this
|
100 |
}
|
101 |
$attribute->addData($data);
|
102 |
|
96 |
$data = $this->_attributeOverrides[$attribute->getAttributeCode()];
|
97 |
|
98 |
if (isset($data['options_method']) && method_exists($this, $data['options_method'])) {
|
99 |
+
$data['filter_options'] = $this->{$data['options_method']}();
|
100 |
}
|
101 |
$attribute->addData($data);
|
102 |
|
app/code/core/Mage/ImportExport/Model/Import/Entity/Customer.php
CHANGED
@@ -43,6 +43,7 @@ class Mage_ImportExport_Model_Import_Entity_Customer extends Mage_ImportExport_M
|
|
43 |
*/
|
44 |
const SCOPE_DEFAULT = 1;
|
45 |
const SCOPE_ADDRESS = -1;
|
|
|
46 |
|
47 |
/**
|
48 |
* Permanent column names.
|
@@ -50,9 +51,10 @@ class Mage_ImportExport_Model_Import_Entity_Customer extends Mage_ImportExport_M
|
|
50 |
* Names that begins with underscore is not an attribute. This name convention is for
|
51 |
* to avoid interference with same attribute name.
|
52 |
*/
|
53 |
-
const COL_EMAIL
|
54 |
-
const COL_WEBSITE
|
55 |
-
const COL_STORE
|
|
|
56 |
|
57 |
/**
|
58 |
* Error codes.
|
@@ -95,6 +97,13 @@ class Mage_ImportExport_Model_Import_Entity_Customer extends Mage_ImportExport_M
|
|
95 |
*/
|
96 |
protected $_attributes = array();
|
97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
/**
|
99 |
* Customer account sharing. TRUE - is global, FALSE - is per website.
|
100 |
*
|
@@ -276,7 +285,7 @@ class Mage_ImportExport_Model_Import_Entity_Customer extends Mage_ImportExport_M
|
|
276 |
{
|
277 |
$collection = Mage::getResourceModel('customer/attribute_collection')->addSystemHiddenFilterWithPasswordHash();
|
278 |
foreach ($collection as $attribute) {
|
279 |
-
$
|
280 |
'id' => $attribute->getId(),
|
281 |
'is_required' => $attribute->getIsRequired(),
|
282 |
'is_static' => $attribute->isStatic(),
|
@@ -284,6 +293,10 @@ class Mage_ImportExport_Model_Import_Entity_Customer extends Mage_ImportExport_M
|
|
284 |
'type' => Mage_ImportExport_Model_Import::getAttributeType($attribute),
|
285 |
'options' => $this->getAttributeOptions($attribute)
|
286 |
);
|
|
|
|
|
|
|
|
|
287 |
}
|
288 |
return $this;
|
289 |
}
|
@@ -363,6 +376,7 @@ class Mage_ImportExport_Model_Import_Entity_Customer extends Mage_ImportExport_M
|
|
363 |
$nextEntityId = Mage::getResourceHelper('importexport')->getNextAutoincrement($table);
|
364 |
$passId = $resource->getAttribute('password_hash')->getId();
|
365 |
$passTable = $resource->getAttribute('password_hash')->getBackend()->getTable();
|
|
|
366 |
|
367 |
while ($bunch = $this->_dataSourceModel->getNextBunch()) {
|
368 |
$entityRowsIn = array();
|
@@ -415,6 +429,11 @@ class Mage_ImportExport_Model_Import_Entity_Customer extends Mage_ImportExport_M
|
|
415 |
$value = $attrParams['options'][strtolower($value)];
|
416 |
} elseif ('datetime' == $attrParams['type']) {
|
417 |
$value = gmstrftime($strftimeFormat, strtotime($value));
|
|
|
|
|
|
|
|
|
|
|
418 |
} elseif ($backModel) {
|
419 |
$attribute->getBackend()->beforeSave($resource->setData($attrCode, $value));
|
420 |
$value = $resource->getData($attrCode);
|
@@ -429,6 +448,24 @@ class Mage_ImportExport_Model_Import_Entity_Customer extends Mage_ImportExport_M
|
|
429 |
if (isset($rowData['password']) && strlen($rowData['password'])) {
|
430 |
$attributes[$passTable][$entityId][$passId] = $resource->hashPassword($rowData['password']);
|
431 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
432 |
}
|
433 |
}
|
434 |
$this->_saveCustomerEntity($entityRowsIn, $entityRowsUp)->_saveCustomerAttributes($attributes);
|
@@ -521,7 +558,22 @@ class Mage_ImportExport_Model_Import_Entity_Customer extends Mage_ImportExport_M
|
|
521 |
*/
|
522 |
public function getRowScope(array $rowData)
|
523 |
{
|
524 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
525 |
}
|
526 |
|
527 |
/**
|
@@ -607,15 +659,17 @@ class Mage_ImportExport_Model_Import_Entity_Customer extends Mage_ImportExport_M
|
|
607 |
if (isset($this->_invalidRows[$rowNum])) {
|
608 |
$email = false; // mark row as invalid for next address rows
|
609 |
}
|
610 |
-
}
|
611 |
if (null === $email) { // first row is not SCOPE_DEFAULT
|
612 |
$this->addRowError(self::ERROR_EMAIL_IS_EMPTY, $rowNum);
|
613 |
} elseif (false === $email) { // SCOPE_DEFAULT row is invalid
|
614 |
$this->addRowError(self::ERROR_ROW_IS_ORPHAN, $rowNum);
|
615 |
}
|
616 |
}
|
617 |
-
|
618 |
-
|
|
|
|
|
619 |
|
620 |
return !isset($this->_invalidRows[$rowNum]);
|
621 |
}
|
43 |
*/
|
44 |
const SCOPE_DEFAULT = 1;
|
45 |
const SCOPE_ADDRESS = -1;
|
46 |
+
const SCOPE_OPTIONS = 2;
|
47 |
|
48 |
/**
|
49 |
* Permanent column names.
|
51 |
* Names that begins with underscore is not an attribute. This name convention is for
|
52 |
* to avoid interference with same attribute name.
|
53 |
*/
|
54 |
+
const COL_EMAIL = 'email';
|
55 |
+
const COL_WEBSITE = '_website';
|
56 |
+
const COL_STORE = '_store';
|
57 |
+
const COL_POSTCODE = '_address_postcode';
|
58 |
|
59 |
/**
|
60 |
* Error codes.
|
97 |
*/
|
98 |
protected $_attributes = array();
|
99 |
|
100 |
+
/**
|
101 |
+
* MultiSelect Attributes
|
102 |
+
*
|
103 |
+
* @var array
|
104 |
+
*/
|
105 |
+
protected $_multiSelectAttributes = array();
|
106 |
+
|
107 |
/**
|
108 |
* Customer account sharing. TRUE - is global, FALSE - is per website.
|
109 |
*
|
285 |
{
|
286 |
$collection = Mage::getResourceModel('customer/attribute_collection')->addSystemHiddenFilterWithPasswordHash();
|
287 |
foreach ($collection as $attribute) {
|
288 |
+
$attributeArray = array(
|
289 |
'id' => $attribute->getId(),
|
290 |
'is_required' => $attribute->getIsRequired(),
|
291 |
'is_static' => $attribute->isStatic(),
|
293 |
'type' => Mage_ImportExport_Model_Import::getAttributeType($attribute),
|
294 |
'options' => $this->getAttributeOptions($attribute)
|
295 |
);
|
296 |
+
$this->_attributes[$attribute->getAttributeCode()] = $attributeArray;
|
297 |
+
if (Mage_ImportExport_Model_Import::getAttributeType($attribute) == 'multiselect') {
|
298 |
+
$this->_multiSelectAttributes[$attribute->getAttributeCode()] = $attributeArray;
|
299 |
+
}
|
300 |
}
|
301 |
return $this;
|
302 |
}
|
376 |
$nextEntityId = Mage::getResourceHelper('importexport')->getNextAutoincrement($table);
|
377 |
$passId = $resource->getAttribute('password_hash')->getId();
|
378 |
$passTable = $resource->getAttribute('password_hash')->getBackend()->getTable();
|
379 |
+
$multiSelect = array();
|
380 |
|
381 |
while ($bunch = $this->_dataSourceModel->getNextBunch()) {
|
382 |
$entityRowsIn = array();
|
429 |
$value = $attrParams['options'][strtolower($value)];
|
430 |
} elseif ('datetime' == $attrParams['type']) {
|
431 |
$value = gmstrftime($strftimeFormat, strtotime($value));
|
432 |
+
} elseif ('multiselect' == $attrParams['type']) {
|
433 |
+
$value = (array)$attrParams['options'][strtolower($value)];
|
434 |
+
$attribute->getBackend()->beforeSave($resource->setData($attrCode, $value));
|
435 |
+
$value = $resource->getData($attrCode);
|
436 |
+
$multiSelect[$entityId][] = $value;
|
437 |
} elseif ($backModel) {
|
438 |
$attribute->getBackend()->beforeSave($resource->setData($attrCode, $value));
|
439 |
$value = $resource->getData($attrCode);
|
448 |
if (isset($rowData['password']) && strlen($rowData['password'])) {
|
449 |
$attributes[$passTable][$entityId][$passId] = $resource->hashPassword($rowData['password']);
|
450 |
}
|
451 |
+
} elseif (self::SCOPE_OPTIONS == $this->getRowScope($rowData)) {
|
452 |
+
foreach (array_intersect_key($rowData, $this->_attributes) as $attrCode => $value) {
|
453 |
+
$attribute = $resource->getAttribute($attrCode);
|
454 |
+
$attrParams = $this->_attributes[$attrCode];
|
455 |
+
if ($attrParams['type'] == 'multiselect') {
|
456 |
+
if (!isset($attrParams['options'][strtolower($value)])) {
|
457 |
+
continue;
|
458 |
+
}
|
459 |
+
$value = $attrParams['options'][strtolower($value)];
|
460 |
+
if (isset($multiSelect[$entityId])) {
|
461 |
+
$multiSelect[$entityId][] = $value;
|
462 |
+
$value = $multiSelect[$entityId];
|
463 |
+
}
|
464 |
+
$attribute->getBackend()->beforeSave($resource->setData($attrCode, $value));
|
465 |
+
$value = $resource->getData($attrCode);
|
466 |
+
$attributes[$attribute->getBackend()->getTable()][$entityId][$attrParams['id']] = $value;
|
467 |
+
}
|
468 |
+
}
|
469 |
}
|
470 |
}
|
471 |
$this->_saveCustomerEntity($entityRowsIn, $entityRowsUp)->_saveCustomerAttributes($attributes);
|
558 |
*/
|
559 |
public function getRowScope(array $rowData)
|
560 |
{
|
561 |
+
$foundOptions = false;
|
562 |
+
foreach ($this->_multiSelectAttributes as $attrCode => $attribute) {
|
563 |
+
if ($rowData[$attrCode]) {
|
564 |
+
$foundOptions = true;
|
565 |
+
}
|
566 |
+
}
|
567 |
+
|
568 |
+
$scope = self::SCOPE_OPTIONS;
|
569 |
+
if (strlen(trim($rowData[self::COL_EMAIL]))) {
|
570 |
+
$scope = self::SCOPE_DEFAULT;
|
571 |
+
} elseif ($foundOptions) {
|
572 |
+
$scope = self::SCOPE_OPTIONS;
|
573 |
+
} elseif (strlen(trim($rowData[self::COL_POSTCODE]))) {
|
574 |
+
$scope = self::SCOPE_ADDRESS;
|
575 |
+
}
|
576 |
+
return $scope;
|
577 |
}
|
578 |
|
579 |
/**
|
659 |
if (isset($this->_invalidRows[$rowNum])) {
|
660 |
$email = false; // mark row as invalid for next address rows
|
661 |
}
|
662 |
+
} elseif (self::SCOPE_OPTIONS != $rowScope) {
|
663 |
if (null === $email) { // first row is not SCOPE_DEFAULT
|
664 |
$this->addRowError(self::ERROR_EMAIL_IS_EMPTY, $rowNum);
|
665 |
} elseif (false === $email) { // SCOPE_DEFAULT row is invalid
|
666 |
$this->addRowError(self::ERROR_ROW_IS_ORPHAN, $rowNum);
|
667 |
}
|
668 |
}
|
669 |
+
|
670 |
+
if ($rowScope != self::SCOPE_OPTIONS) {
|
671 |
+
$this->_addressEntity->validateRow($rowData, $rowNum);
|
672 |
+
}
|
673 |
|
674 |
return !isset($this->_invalidRows[$rowNum]);
|
675 |
}
|
app/code/core/Mage/ImportExport/Model/Import/Entity/Customer/Address.php
CHANGED
@@ -175,6 +175,7 @@ class Mage_ImportExport_Model_Import_Entity_Customer_Address extends Mage_Import
|
|
175 |
$regionIdTable = $regionIdAttr->getBackend()->getTable();
|
176 |
$regionIdAttrId = $regionIdAttr->getId();
|
177 |
$isAppendMode = Mage_ImportExport_Model_Import::BEHAVIOR_APPEND == $this->_customer->getBehavior();
|
|
|
178 |
|
179 |
while ($bunch = $this->_dataSourceModel->getNextBunch()) {
|
180 |
$entityRows = array();
|
@@ -182,15 +183,17 @@ class Mage_ImportExport_Model_Import_Entity_Customer_Address extends Mage_Import
|
|
182 |
$defaults = array(); // customer default addresses (billing/shipping) data
|
183 |
|
184 |
foreach ($bunch as $rowNum => $rowData) {
|
185 |
-
|
186 |
-
|
187 |
-
) {
|
188 |
$customerId = $this->_customer->getCustomerId(
|
189 |
$rowData[Mage_ImportExport_Model_Import_Entity_Customer::COL_EMAIL],
|
190 |
$rowData[Mage_ImportExport_Model_Import_Entity_Customer::COL_WEBSITE]
|
191 |
);
|
192 |
}
|
193 |
-
if (
|
|
|
|
|
|
|
194 |
continue;
|
195 |
}
|
196 |
|
@@ -205,6 +208,9 @@ class Mage_ImportExport_Model_Import_Entity_Customer_Address extends Mage_Import
|
|
205 |
$value = $attrParams['options'][strtolower($rowData[$attrAlias])];
|
206 |
} elseif ('datetime' == $attrParams['type']) {
|
207 |
$value = gmstrftime($strftimeFormat, strtotime($rowData[$attrAlias]));
|
|
|
|
|
|
|
208 |
} else {
|
209 |
$value = $rowData[$attrAlias];
|
210 |
}
|
@@ -220,40 +226,56 @@ class Mage_ImportExport_Model_Import_Entity_Customer_Address extends Mage_Import
|
|
220 |
|
221 |
$entityId = $nextEntityId++;
|
222 |
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
|
|
|
|
|
|
|
|
236 |
}
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
|
|
243 |
}
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
257 |
}
|
258 |
}
|
259 |
}
|
@@ -486,4 +508,22 @@ class Mage_ImportExport_Model_Import_Entity_Customer_Address extends Mage_Import
|
|
486 |
}
|
487 |
return $rowIsValid;
|
488 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
489 |
}
|
175 |
$regionIdTable = $regionIdAttr->getBackend()->getTable();
|
176 |
$regionIdAttrId = $regionIdAttr->getId();
|
177 |
$isAppendMode = Mage_ImportExport_Model_Import::BEHAVIOR_APPEND == $this->_customer->getBehavior();
|
178 |
+
$multiSelect = array();
|
179 |
|
180 |
while ($bunch = $this->_dataSourceModel->getNextBunch()) {
|
181 |
$entityRows = array();
|
183 |
$defaults = array(); // customer default addresses (billing/shipping) data
|
184 |
|
185 |
foreach ($bunch as $rowNum => $rowData) {
|
186 |
+
$rowScope = $this->_getRowScope($rowData);
|
187 |
+
if ($rowScope == Mage_ImportExport_Model_Import_Entity_Customer::SCOPE_DEFAULT) {
|
|
|
188 |
$customerId = $this->_customer->getCustomerId(
|
189 |
$rowData[Mage_ImportExport_Model_Import_Entity_Customer::COL_EMAIL],
|
190 |
$rowData[Mage_ImportExport_Model_Import_Entity_Customer::COL_WEBSITE]
|
191 |
);
|
192 |
}
|
193 |
+
if ($rowScope != Mage_ImportExport_Model_Import_Entity_Customer::SCOPE_OPTIONS) {
|
194 |
+
$multiSelect = array();
|
195 |
+
}
|
196 |
+
if (!$customerId) {
|
197 |
continue;
|
198 |
}
|
199 |
|
208 |
$value = $attrParams['options'][strtolower($rowData[$attrAlias])];
|
209 |
} elseif ('datetime' == $attrParams['type']) {
|
210 |
$value = gmstrftime($strftimeFormat, strtotime($rowData[$attrAlias]));
|
211 |
+
} elseif ('multiselect' == $attrParams['type']) {
|
212 |
+
$value = $attrParams['options'][strtolower($rowData[$attrAlias])];
|
213 |
+
$multiSelect[$attrParams['id']][] = $value;
|
214 |
} else {
|
215 |
$value = $rowData[$attrAlias];
|
216 |
}
|
226 |
|
227 |
$entityId = $nextEntityId++;
|
228 |
|
229 |
+
if ($rowScope == Mage_ImportExport_Model_Import_Entity_Customer::SCOPE_DEFAULT
|
230 |
+
|| $rowScope == Mage_ImportExport_Model_Import_Entity_Customer::SCOPE_ADDRESS
|
231 |
+
) {
|
232 |
+
// entity table data
|
233 |
+
$entityRows[] = array(
|
234 |
+
'entity_id' => $entityId,
|
235 |
+
'entity_type_id' => $this->_entityTypeId,
|
236 |
+
'parent_id' => $customerId,
|
237 |
+
'created_at' => now(),
|
238 |
+
'updated_at' => now()
|
239 |
+
);
|
240 |
+
// attribute values
|
241 |
+
foreach ($this->_attributes as $attrAlias => $attrParams) {
|
242 |
+
if (isset($addressAttributes[$attrParams['id']])) {
|
243 |
+
$attributes[$attrParams['table']][$entityId][$attrParams['id']]
|
244 |
+
= $addressAttributes[$attrParams['id']];
|
245 |
+
}
|
246 |
}
|
247 |
+
// customer default addresses
|
248 |
+
foreach (self::getDefaultAddressAttrMapping() as $colName => $customerAttrCode) {
|
249 |
+
if (!empty($rowData[$colName])) {
|
250 |
+
$attribute = $customer->getAttribute($customerAttrCode);
|
251 |
+
$backendTable = $attribute->getBackend()->getTable();
|
252 |
+
$defaults[$backendTable][$customerId][$attribute->getId()] = $entityId;
|
253 |
+
}
|
254 |
}
|
255 |
+
// let's try to find region ID
|
256 |
+
if (!empty($rowData[$regionColName])) {
|
257 |
+
$countryNormalized = strtolower($rowData[$countryColName]);
|
258 |
+
$regionNormalized = strtolower($rowData[$regionColName]);
|
259 |
+
|
260 |
+
if (isset($this->_countryRegions[$countryNormalized][$regionNormalized])) {
|
261 |
+
$regionId = $this->_countryRegions[$countryNormalized][$regionNormalized];
|
262 |
+
$attributes[$regionIdTable][$entityId][$regionIdAttrId] = $regionId;
|
263 |
+
// set 'region' attribute value as default name
|
264 |
+
$tbl = $this->_attributes[$regionColName]['table'];
|
265 |
+
$regionColNameId = $this->_attributes[$regionColName]['id'];
|
266 |
+
$attributes[$tbl][$entityId][$regionColNameId] = $this->_regions[$regionId];
|
267 |
+
}
|
268 |
+
}
|
269 |
+
} else {
|
270 |
+
foreach (array_intersect_key($rowData, $this->_attributes) as $attrCode => $value) {
|
271 |
+
$attrParams = $this->_attributes[$attrCode];
|
272 |
+
if ($attrParams['type'] == 'multiselect') {
|
273 |
+
$value = '';
|
274 |
+
if (isset($multiSelect[$attrParams['id']])) {
|
275 |
+
$value = implode(',', $multiSelect[$attrParams['id']]);
|
276 |
+
}
|
277 |
+
$attributes[$this->_attributes[$attrCode]['table']][$entityId][$attrParams['id']] = $value;
|
278 |
+
}
|
279 |
}
|
280 |
}
|
281 |
}
|
508 |
}
|
509 |
return $rowIsValid;
|
510 |
}
|
511 |
+
|
512 |
+
/**
|
513 |
+
* Get current scope
|
514 |
+
*
|
515 |
+
* @param $rowData
|
516 |
+
* @return int
|
517 |
+
*/
|
518 |
+
protected function _getRowScope($rowData)
|
519 |
+
{
|
520 |
+
if (strlen(trim($rowData[Mage_ImportExport_Model_Import_Entity_Customer::COL_EMAIL]))) {
|
521 |
+
$scope = Mage_ImportExport_Model_Import_Entity_Customer::SCOPE_DEFAULT;
|
522 |
+
} elseif (strlen(trim($rowData[Mage_ImportExport_Model_Import_Entity_Customer::COL_POSTCODE]))) {
|
523 |
+
$scope = Mage_ImportExport_Model_Import_Entity_Customer::SCOPE_ADDRESS;
|
524 |
+
} else {
|
525 |
+
$scope = Mage_ImportExport_Model_Import_Entity_Customer::SCOPE_OPTIONS;
|
526 |
+
}
|
527 |
+
return $scope;
|
528 |
+
}
|
529 |
}
|
app/code/core/Mage/ImportExport/Model/Import/Entity/Product.php
CHANGED
@@ -422,6 +422,13 @@ class Mage_ImportExport_Model_Import_Entity_Product extends Mage_ImportExport_Mo
|
|
422 |
*/
|
423 |
protected $_fileUploader;
|
424 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
425 |
/**
|
426 |
* Constructor.
|
427 |
*
|
@@ -823,6 +830,9 @@ class Mage_ImportExport_Model_Import_Entity_Product extends Mage_ImportExport_Mo
|
|
823 |
);
|
824 |
|
825 |
$alreadyUsedProductIds = array();
|
|
|
|
|
|
|
826 |
while ($bunch = $this->_dataSourceModel->getNextBunch()) {
|
827 |
$customOptions = array(
|
828 |
'product_id' => array(),
|
@@ -833,7 +843,8 @@ class Mage_ImportExport_Model_Import_Entity_Product extends Mage_ImportExport_Mo
|
|
833 |
$typeTitleTable => array(),
|
834 |
$typeValueTable => array()
|
835 |
);
|
836 |
-
|
|
|
837 |
foreach ($bunch as $rowNum => $rowData) {
|
838 |
$this->_filterRowData($rowData);
|
839 |
if (!$this->isRowAllowedToImport($rowData, $rowNum)) {
|
@@ -844,6 +855,13 @@ class Mage_ImportExport_Model_Import_Entity_Product extends Mage_ImportExport_Mo
|
|
844 |
} elseif (!isset($productId)) {
|
845 |
continue;
|
846 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
847 |
if (!empty($rowData['_custom_option_store'])) {
|
848 |
if (!isset($this->_storeCodeToId[$rowData['_custom_option_store']])) {
|
849 |
continue;
|
@@ -920,41 +938,66 @@ class Mage_ImportExport_Model_Import_Entity_Product extends Mage_ImportExport_Mo
|
|
920 |
}
|
921 |
$prevOptionId = $nextOptionId++; // increment option id, but preserve value for $typeValueTable
|
922 |
}
|
923 |
-
if ($typeSpecific[$type] === true && !empty($rowData['_custom_option_row_title'])
|
924 |
-
&& empty($rowData['_custom_option_store'])) {
|
925 |
-
// complex CO option row
|
926 |
-
$customOptions[$typeValueTable][$prevOptionId][] = array(
|
927 |
-
'option_type_id' => $nextValueId,
|
928 |
-
'sort_order' => empty($rowData['_custom_option_row_sort'])
|
929 |
-
? 0 : abs($rowData['_custom_option_row_sort']),
|
930 |
-
'sku' => !empty($rowData['_custom_option_row_sku'])
|
931 |
-
? $rowData['_custom_option_row_sku'] : ''
|
932 |
-
);
|
933 |
-
if (!isset($customOptions[$typeTitleTable][$nextValueId][0])) { // ensure default title is set
|
934 |
-
$customOptions[$typeTitleTable][$nextValueId][0] = $rowData['_custom_option_row_title'];
|
935 |
-
}
|
936 |
-
$customOptions[$typeTitleTable][$nextValueId][$storeId] = $rowData['_custom_option_row_title'];
|
937 |
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
|
|
|
|
|
|
|
|
|
|
942 |
);
|
943 |
-
if (
|
944 |
-
$
|
945 |
}
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
951 |
$customOptions[$typePriceTable][$nextValueId][0] = $typePriceRow;
|
|
|
|
|
|
|
|
|
|
|
|
|
952 |
}
|
953 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
954 |
}
|
955 |
}
|
956 |
-
$nextValueId++;
|
957 |
}
|
|
|
958 |
if (!empty($rowData['_custom_option_title'])) {
|
959 |
if (!isset($customOptions[$titleTable][$prevOptionId][0])) { // ensure default title is set
|
960 |
$customOptions[$titleTable][$prevOptionId][0] = $rowData['_custom_option_title'];
|
@@ -1105,13 +1148,13 @@ class Mage_ImportExport_Model_Import_Entity_Product extends Mage_ImportExport_Mo
|
|
1105 |
$sku = $rowData[self::COL_SKU];
|
1106 |
}
|
1107 |
foreach ($this->_linkNameToId as $linkName => $linkId) {
|
1108 |
-
$productId = $this->_newSku[$sku]['entity_id'];
|
1109 |
-
$productIds[] = $productId;
|
1110 |
if (isset($rowData[$linkName . 'sku'])) {
|
1111 |
-
$
|
|
|
|
|
1112 |
|
1113 |
if ((isset($this->_newSku[$linkedSku]) || isset($this->_oldSku[$linkedSku]))
|
1114 |
-
|
1115 |
if (isset($this->_newSku[$linkedSku])) {
|
1116 |
$linkedId = $this->_newSku[$linkedSku]['entity_id'];
|
1117 |
} else {
|
@@ -1189,19 +1232,21 @@ class Mage_ImportExport_Model_Import_Entity_Product extends Mage_ImportExport_Mo
|
|
1189 |
);
|
1190 |
}
|
1191 |
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
$this->_connection->quoteInto('
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
$
|
1204 |
-
|
|
|
|
|
1205 |
}
|
1206 |
}
|
1207 |
$this->_connection->insertOnDuplicate($tableName, $tableData, array('value'));
|
@@ -1404,7 +1449,7 @@ class Mage_ImportExport_Model_Import_Entity_Product extends Mage_ImportExport_Mo
|
|
1404 |
if (!is_null($productType)) {
|
1405 |
$previousType = $productType;
|
1406 |
}
|
1407 |
-
if (!is_null($rowData[self::COL_ATTR_SET])) {
|
1408 |
$previousAttributeSet = $rowData[Mage_ImportExport_Model_Import_Entity_Product::COL_ATTR_SET];
|
1409 |
}
|
1410 |
if (self::SCOPE_NULL == $rowScope) {
|
@@ -1511,6 +1556,8 @@ class Mage_ImportExport_Model_Import_Entity_Product extends Mage_ImportExport_Mo
|
|
1511 |
// check website defaults already set
|
1512 |
if (!isset($attributes[$attrTable][$rowSku][$attrId][$rowStore])) {
|
1513 |
$storeIds = $this->_storeIdToWebsiteStoreIds[$rowStore];
|
|
|
|
|
1514 |
}
|
1515 |
} elseif (self::SCOPE_STORE == $attribute->getIsGlobal()) {
|
1516 |
$storeIds = array($rowStore);
|
@@ -2136,4 +2183,29 @@ class Mage_ImportExport_Model_Import_Entity_Product extends Mage_ImportExport_Mo
|
|
2136 |
}
|
2137 |
return $productIds;
|
2138 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2139 |
}
|
422 |
*/
|
423 |
protected $_fileUploader;
|
424 |
|
425 |
+
/**
|
426 |
+
* url_key attribute id
|
427 |
+
*
|
428 |
+
* @var int
|
429 |
+
*/
|
430 |
+
protected $_urlKeyAttributeId;
|
431 |
+
|
432 |
/**
|
433 |
* Constructor.
|
434 |
*
|
830 |
);
|
831 |
|
832 |
$alreadyUsedProductIds = array();
|
833 |
+
$lastStoreId = null;
|
834 |
+
$lastProductId = null;
|
835 |
+
$currentValueId = null;
|
836 |
while ($bunch = $this->_dataSourceModel->getNextBunch()) {
|
837 |
$customOptions = array(
|
838 |
'product_id' => array(),
|
843 |
$typeTitleTable => array(),
|
844 |
$typeValueTable => array()
|
845 |
);
|
846 |
+
$flagNewOption = true;
|
847 |
+
$firstKeyOption = null;
|
848 |
foreach ($bunch as $rowNum => $rowData) {
|
849 |
$this->_filterRowData($rowData);
|
850 |
if (!$this->isRowAllowedToImport($rowData, $rowNum)) {
|
855 |
} elseif (!isset($productId)) {
|
856 |
continue;
|
857 |
}
|
858 |
+
|
859 |
+
if ($lastProductId != $productId) {
|
860 |
+
$lastStoreId = Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID;
|
861 |
+
$currentValueId = null;
|
862 |
+
$lastProductId = $productId;
|
863 |
+
}
|
864 |
+
|
865 |
if (!empty($rowData['_custom_option_store'])) {
|
866 |
if (!isset($this->_storeCodeToId[$rowData['_custom_option_store']])) {
|
867 |
continue;
|
938 |
}
|
939 |
$prevOptionId = $nextOptionId++; // increment option id, but preserve value for $typeValueTable
|
940 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
941 |
|
942 |
+
if ($typeSpecific[$type] === true && !empty($rowData['_custom_option_row_title'])) {
|
943 |
+
if (empty($rowData['_custom_option_store'])) {
|
944 |
+
// complex CO option row
|
945 |
+
$customOptions[$typeValueTable][$prevOptionId][] = array(
|
946 |
+
'option_type_id' => $nextValueId,
|
947 |
+
'sort_order' => empty($rowData['_custom_option_row_sort'])
|
948 |
+
? 0 : abs($rowData['_custom_option_row_sort']),
|
949 |
+
'sku' => !empty($rowData['_custom_option_row_sku'])
|
950 |
+
? $rowData['_custom_option_row_sku'] : ''
|
951 |
);
|
952 |
+
if (!isset($customOptions[$typeTitleTable][$nextValueId][0])) { // ensure default title is set
|
953 |
+
$customOptions[$typeTitleTable][$nextValueId][0] = $rowData['_custom_option_row_title'];
|
954 |
}
|
955 |
+
$customOptions[$typeTitleTable][$nextValueId][$storeId] = $rowData['_custom_option_row_title'];
|
956 |
+
|
957 |
+
if (!empty($rowData['_custom_option_row_price'])) {
|
958 |
+
$typePriceRow = array(
|
959 |
+
'price' => (float) rtrim($rowData['_custom_option_row_price'], '%'),
|
960 |
+
'price_type' => 'fixed'
|
961 |
+
);
|
962 |
+
if ('%' == substr($rowData['_custom_option_row_price'], -1)) {
|
963 |
+
$typePriceRow['price_type'] = 'percent';
|
964 |
+
}
|
965 |
+
if ($priceIsGlobal) {
|
966 |
$customOptions[$typePriceTable][$nextValueId][0] = $typePriceRow;
|
967 |
+
} else {
|
968 |
+
// ensure default price is set
|
969 |
+
if (!isset($customOptions[$typePriceTable][$nextValueId][0])) {
|
970 |
+
$customOptions[$typePriceTable][$nextValueId][0] = $typePriceRow;
|
971 |
+
}
|
972 |
+
$customOptions[$typePriceTable][$nextValueId][$storeId] = $typePriceRow;
|
973 |
}
|
974 |
+
}
|
975 |
+
if ($flagNewOption) {
|
976 |
+
$firstKeyOption = $nextValueId;
|
977 |
+
$flagNewOption = false;
|
978 |
+
}
|
979 |
+
$nextValueId++;
|
980 |
+
} else {
|
981 |
+
$flagNewOption = true;
|
982 |
+
if ($lastStoreId != $storeId) {
|
983 |
+
if (!$firstKeyOption) {
|
984 |
+
reset($customOptions[$typeTitleTable]);
|
985 |
+
$firstKeyOption = key($customOptions[$typeTitleTable]);
|
986 |
+
}
|
987 |
+
$currentValueId = $firstKeyOption;
|
988 |
+
$lastStoreId = $storeId;
|
989 |
+
} else {
|
990 |
+
$currentValueId++;
|
991 |
+
}
|
992 |
+
|
993 |
+
$defaultValue = $customOptions[$typeTitleTable][$currentValueId][0];
|
994 |
+
if ($defaultValue != $rowData['_custom_option_row_title']) {
|
995 |
+
$customOptions[$typeTitleTable][$currentValueId][$storeId]
|
996 |
+
= $rowData['_custom_option_row_title'];
|
997 |
}
|
998 |
}
|
|
|
999 |
}
|
1000 |
+
|
1001 |
if (!empty($rowData['_custom_option_title'])) {
|
1002 |
if (!isset($customOptions[$titleTable][$prevOptionId][0])) { // ensure default title is set
|
1003 |
$customOptions[$titleTable][$prevOptionId][0] = $rowData['_custom_option_title'];
|
1148 |
$sku = $rowData[self::COL_SKU];
|
1149 |
}
|
1150 |
foreach ($this->_linkNameToId as $linkName => $linkId) {
|
|
|
|
|
1151 |
if (isset($rowData[$linkName . 'sku'])) {
|
1152 |
+
$productId = $this->_newSku[$sku]['entity_id'];
|
1153 |
+
$productIds[] = $productId;
|
1154 |
+
$linkedSku = $rowData[$linkName . 'sku'];
|
1155 |
|
1156 |
if ((isset($this->_newSku[$linkedSku]) || isset($this->_oldSku[$linkedSku]))
|
1157 |
+
&& $linkedSku != $sku) {
|
1158 |
if (isset($this->_newSku[$linkedSku])) {
|
1159 |
$linkedId = $this->_newSku[$linkedSku]['entity_id'];
|
1160 |
} else {
|
1232 |
);
|
1233 |
}
|
1234 |
|
1235 |
+
if ($attributeId == $this->_getUrlKeyAttributeId()) {
|
1236 |
+
/*
|
1237 |
+
If the store based values are not provided for a particular store,
|
1238 |
+
we default to the default scope values.
|
1239 |
+
In this case, remove all the existing store based values stored in the table.
|
1240 |
+
*/
|
1241 |
+
$where = $this->_connection->quoteInto('store_id NOT IN (?)', array_keys($storeValues)) .
|
1242 |
+
$this->_connection->quoteInto(' AND attribute_id = ?', $attributeId) .
|
1243 |
+
$this->_connection->quoteInto(' AND entity_id = ?', $productId) .
|
1244 |
+
$this->_connection->quoteInto(' AND entity_type_id = ?', $this->_entityTypeId);
|
1245 |
+
|
1246 |
+
$this->_connection->delete(
|
1247 |
+
$tableName, $where
|
1248 |
+
);
|
1249 |
+
}
|
1250 |
}
|
1251 |
}
|
1252 |
$this->_connection->insertOnDuplicate($tableName, $tableData, array('value'));
|
1449 |
if (!is_null($productType)) {
|
1450 |
$previousType = $productType;
|
1451 |
}
|
1452 |
+
if (isset($rowData[self::COL_ATTR_SET]) && !is_null($rowData[self::COL_ATTR_SET])) {
|
1453 |
$previousAttributeSet = $rowData[Mage_ImportExport_Model_Import_Entity_Product::COL_ATTR_SET];
|
1454 |
}
|
1455 |
if (self::SCOPE_NULL == $rowScope) {
|
1556 |
// check website defaults already set
|
1557 |
if (!isset($attributes[$attrTable][$rowSku][$attrId][$rowStore])) {
|
1558 |
$storeIds = $this->_storeIdToWebsiteStoreIds[$rowStore];
|
1559 |
+
} else {
|
1560 |
+
$storeIds = array($rowStore);
|
1561 |
}
|
1562 |
} elseif (self::SCOPE_STORE == $attribute->getIsGlobal()) {
|
1563 |
$storeIds = array($rowStore);
|
2183 |
}
|
2184 |
return $productIds;
|
2185 |
}
|
2186 |
+
|
2187 |
+
/**
|
2188 |
+
* Get product url_key attribute id
|
2189 |
+
*
|
2190 |
+
* @return null|int
|
2191 |
+
*/
|
2192 |
+
protected function _getUrlKeyAttributeId()
|
2193 |
+
{
|
2194 |
+
if ($this->_urlKeyAttributeId === null) {
|
2195 |
+
$adapter = $this->getConnection();
|
2196 |
+
$resource = $this->getResourceModel('eav/entity_attribute');
|
2197 |
+
|
2198 |
+
$select = $adapter->select()
|
2199 |
+
->from(
|
2200 |
+
$resource->getMainTable(),
|
2201 |
+
array('attribute_id')
|
2202 |
+
)
|
2203 |
+
->where('attribute_code = ?', 'url_key')
|
2204 |
+
->where('entity_type_id = ?', $this->_entityTypeId);
|
2205 |
+
|
2206 |
+
$this->_urlKeyAttributeId = $adapter->fetchOne($select);
|
2207 |
+
}
|
2208 |
+
|
2209 |
+
return $this->_urlKeyAttributeId;
|
2210 |
+
}
|
2211 |
}
|
app/code/core/Mage/ImportExport/Model/Import/Entity/Product/Type/Configurable.php
CHANGED
@@ -230,18 +230,34 @@ class Mage_ImportExport_Model_Import_Entity_Product_Type_Configurable
|
|
230 |
->getNode('global/catalog/product/type/configurable/allow_product_types')->children() as $type) {
|
231 |
$allowProductTypes[] = $type->getName();
|
232 |
}
|
233 |
-
|
|
|
234 |
->addFieldToFilter('type_id', $allowProductTypes)
|
235 |
-
->addAttributeToSelect(array_keys($this->_superAttributes))
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
}
|
246 |
}
|
247 |
}
|
230 |
->getNode('global/catalog/product/type/configurable/allow_product_types')->children() as $type) {
|
231 |
$allowProductTypes[] = $type->getName();
|
232 |
}
|
233 |
+
/** @var Mage_Catalog_Model_Resource_Product_Collection $collection */
|
234 |
+
$collection = Mage::getResourceModel('catalog/product_collection')
|
235 |
->addFieldToFilter('type_id', $allowProductTypes)
|
236 |
+
->addAttributeToSelect(array_keys($this->_superAttributes));
|
237 |
+
|
238 |
+
$collectionSize = $collection->getSize();
|
239 |
+
if ($collectionSize) {
|
240 |
+
$configPageSize = Mage::helper('importexport')->getImportConfigurablePageSize();
|
241 |
+
$pageSize = ($configPageSize > 0) ? $configPageSize : $collectionSize;
|
242 |
+
$page = 0;
|
243 |
+
$collection->setPageSize($pageSize);
|
244 |
+
while ($pageSize * $page < $collectionSize) {
|
245 |
+
$page++;
|
246 |
+
$collection->setCurPage($page);
|
247 |
+
|
248 |
+
foreach ($collection as $product) {
|
249 |
+
$attrSetName = $attrSetIdToName[$product->getAttributeSetId()];
|
250 |
+
|
251 |
+
$data = array_intersect_key(
|
252 |
+
$product->getData(),
|
253 |
+
$this->_superAttributes
|
254 |
+
);
|
255 |
+
foreach ($data as $attrCode => $value) {
|
256 |
+
$attrId = $this->_superAttributes[$attrCode]['id'];
|
257 |
+
$this->_skuSuperAttributeValues[$attrSetName][$product->getId()][$attrId] = $value;
|
258 |
+
}
|
259 |
+
}
|
260 |
+
$collection->clear();
|
261 |
}
|
262 |
}
|
263 |
}
|
app/code/core/Mage/ImportExport/Model/Import/Uploader.php
CHANGED
@@ -132,7 +132,7 @@ class Mage_ImportExport_Model_Import_Uploader extends Mage_Core_Model_File_Uploa
|
|
132 |
//run validate callbacks
|
133 |
foreach ($this->_validateCallbacks as $params) {
|
134 |
if (is_object($params['object']) && method_exists($params['object'], $params['method'])) {
|
135 |
-
$params['object']
|
136 |
}
|
137 |
}
|
138 |
}
|
132 |
//run validate callbacks
|
133 |
foreach ($this->_validateCallbacks as $params) {
|
134 |
if (is_object($params['object']) && method_exists($params['object'], $params['method'])) {
|
135 |
+
$params['object']->{$params['method']}($filePath);
|
136 |
}
|
137 |
}
|
138 |
}
|
app/code/core/Mage/ImportExport/controllers/Adminhtml/ExportController.php
CHANGED
@@ -81,9 +81,12 @@ class Mage_ImportExport_Adminhtml_ExportController extends Mage_Adminhtml_Contro
|
|
81 |
$model = Mage::getModel('importexport/export');
|
82 |
$model->setData($this->getRequest()->getParams());
|
83 |
|
|
|
|
|
|
|
84 |
return $this->_prepareDownloadResponse(
|
85 |
$model->getFileName(),
|
86 |
-
$
|
87 |
$model->getContentType()
|
88 |
);
|
89 |
} catch (Mage_Core_Exception $e) {
|
81 |
$model = Mage::getModel('importexport/export');
|
82 |
$model->setData($this->getRequest()->getParams());
|
83 |
|
84 |
+
$result = $model->exportFile();
|
85 |
+
$result['type'] = 'filename';
|
86 |
+
|
87 |
return $this->_prepareDownloadResponse(
|
88 |
$model->getFileName(),
|
89 |
+
$result,
|
90 |
$model->getContentType()
|
91 |
);
|
92 |
} catch (Mage_Core_Exception $e) {
|
app/code/core/Mage/ImportExport/etc/config.xml
CHANGED
@@ -139,6 +139,9 @@
|
|
139 |
<export_csv>
|
140 |
<escaping>1</escaping>
|
141 |
</export_csv>
|
|
|
|
|
|
|
142 |
</system>
|
143 |
<general>
|
144 |
<file>
|
139 |
<export_csv>
|
140 |
<escaping>1</escaping>
|
141 |
</export_csv>
|
142 |
+
<import_csv>
|
143 |
+
<configurable_page_size>1000</configurable_page_size>
|
144 |
+
</import_csv>
|
145 |
</system>
|
146 |
<general>
|
147 |
<file>
|
app/code/core/Mage/ImportExport/etc/system.xml
CHANGED
@@ -48,6 +48,25 @@
|
|
48 |
</escaping>
|
49 |
</fields>
|
50 |
</export_csv>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
</groups>
|
52 |
</system>
|
53 |
</sections>
|
48 |
</escaping>
|
49 |
</fields>
|
50 |
</export_csv>
|
51 |
+
<import_csv translate="label">
|
52 |
+
<label>Import CSV</label>
|
53 |
+
<show_in_default>1</show_in_default>
|
54 |
+
<show_in_website>1</show_in_website>
|
55 |
+
<show_in_store>1</show_in_store>
|
56 |
+
<sort_order>500</sort_order>
|
57 |
+
<fields>
|
58 |
+
<configurable_page_size translate="label,comment">
|
59 |
+
<label>Page size for import configurable products</label>
|
60 |
+
<frontend_type>text</frontend_type>
|
61 |
+
<validate>validate-number</validate>
|
62 |
+
<sort_order>1</sort_order>
|
63 |
+
<show_in_default>1</show_in_default>
|
64 |
+
<show_in_website>0</show_in_website>
|
65 |
+
<show_in_store>0</show_in_store>
|
66 |
+
<comment>This option will be ignore if it set less than 1.</comment>
|
67 |
+
</configurable_page_size>
|
68 |
+
</fields>
|
69 |
+
</import_csv>
|
70 |
</groups>
|
71 |
</system>
|
72 |
</sections>
|
app/code/core/Mage/Oauth/Model/Server.php
CHANGED
@@ -328,10 +328,10 @@ class Mage_Oauth_Model_Server
|
|
328 |
if (self::REQUEST_TOKEN == $this->_requestType) {
|
329 |
$this->_validateVerifierParam();
|
330 |
|
331 |
-
if ($this->_token->getVerifier()
|
332 |
$this->_throwException('', self::ERR_VERIFIER_INVALID);
|
333 |
}
|
334 |
-
if ($this->_token->getConsumerId()
|
335 |
$this->_throwException('', self::ERR_TOKEN_REJECTED);
|
336 |
}
|
337 |
if (Mage_Oauth_Model_Token::TYPE_REQUEST != $this->_token->getType()) {
|
@@ -544,7 +544,7 @@ class Mage_Oauth_Model_Server
|
|
544 |
$this->_request->getScheme() . '://' . $this->_request->getHttpHost() . $this->_request->getRequestUri()
|
545 |
);
|
546 |
|
547 |
-
if ($calculatedSign
|
548 |
$this->_throwException('', self::ERR_SIGNATURE_INVALID);
|
549 |
}
|
550 |
}
|
328 |
if (self::REQUEST_TOKEN == $this->_requestType) {
|
329 |
$this->_validateVerifierParam();
|
330 |
|
331 |
+
if (!hash_equals($this->_token->getVerifier(), $this->_protocolParams['oauth_verifier'])) {
|
332 |
$this->_throwException('', self::ERR_VERIFIER_INVALID);
|
333 |
}
|
334 |
+
if (!hash_equals($this->_token->getConsumerId(), $this->_consumer->getId())) {
|
335 |
$this->_throwException('', self::ERR_TOKEN_REJECTED);
|
336 |
}
|
337 |
if (Mage_Oauth_Model_Token::TYPE_REQUEST != $this->_token->getType()) {
|
544 |
$this->_request->getScheme() . '://' . $this->_request->getHttpHost() . $this->_request->getRequestUri()
|
545 |
);
|
546 |
|
547 |
+
if (!hash_equals($calculatedSign, $this->_protocolParams['oauth_signature'])) {
|
548 |
$this->_throwException('', self::ERR_SIGNATURE_INVALID);
|
549 |
}
|
550 |
}
|
app/code/core/Mage/Paygate/Model/Authorizenet.php
CHANGED
@@ -1273,8 +1273,10 @@ class Mage_Paygate_Model_Authorizenet extends Mage_Payment_Model_Method_Cc
|
|
1273 |
$uri = $this->getConfigData('cgi_url');
|
1274 |
$client->setUri($uri ? $uri : self::CGI_URL);
|
1275 |
$client->setConfig(array(
|
1276 |
-
'maxredirects'=>0,
|
1277 |
-
'timeout'=>30,
|
|
|
|
|
1278 |
//'ssltransport' => 'tcp',
|
1279 |
));
|
1280 |
foreach ($request->getData() as $key => $value) {
|
@@ -1543,7 +1545,11 @@ class Mage_Paygate_Model_Authorizenet extends Mage_Payment_Model_Method_Cc
|
|
1543 |
$uri = $this->getConfigData('cgi_url_td');
|
1544 |
$uri = $uri ? $uri : self::CGI_URL_TD;
|
1545 |
$client->setUri($uri);
|
1546 |
-
$client->setConfig(array(
|
|
|
|
|
|
|
|
|
1547 |
$client->setHeaders(array('Content-Type: text/xml'));
|
1548 |
$client->setMethod(Zend_Http_Client::POST);
|
1549 |
$client->setRawData($requestBody);
|
1273 |
$uri = $this->getConfigData('cgi_url');
|
1274 |
$client->setUri($uri ? $uri : self::CGI_URL);
|
1275 |
$client->setConfig(array(
|
1276 |
+
'maxredirects' => 0,
|
1277 |
+
'timeout' => 30,
|
1278 |
+
'verifyhost' => 2,
|
1279 |
+
'verifypeer' => true,
|
1280 |
//'ssltransport' => 'tcp',
|
1281 |
));
|
1282 |
foreach ($request->getData() as $key => $value) {
|
1545 |
$uri = $this->getConfigData('cgi_url_td');
|
1546 |
$uri = $uri ? $uri : self::CGI_URL_TD;
|
1547 |
$client->setUri($uri);
|
1548 |
+
$client->setConfig(array(
|
1549 |
+
'timeout' => 45,
|
1550 |
+
'verifyhost' => 2,
|
1551 |
+
'verifypeer' => true,
|
1552 |
+
));
|
1553 |
$client->setHeaders(array('Content-Type: text/xml'));
|
1554 |
$client->setMethod(Zend_Http_Client::POST);
|
1555 |
$client->setRawData($requestBody);
|
app/code/core/Mage/Payment/Block/Info/Checkmo.php
CHANGED
@@ -70,7 +70,13 @@ class Mage_Payment_Block_Info_Checkmo extends Mage_Payment_Block_Info
|
|
70 |
*/
|
71 |
protected function _convertAdditionalData()
|
72 |
{
|
73 |
-
$details =
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
if (is_array($details)) {
|
75 |
$this->_payableTo = isset($details['payable_to']) ? (string) $details['payable_to'] : '';
|
76 |
$this->_mailingAddress = isset($details['mailing_address']) ? (string) $details['mailing_address'] : '';
|
@@ -80,7 +86,7 @@ class Mage_Payment_Block_Info_Checkmo extends Mage_Payment_Block_Info
|
|
80 |
}
|
81 |
return $this;
|
82 |
}
|
83 |
-
|
84 |
public function toPdf()
|
85 |
{
|
86 |
$this->setTemplate('payment/info/pdf/checkmo.phtml');
|
70 |
*/
|
71 |
protected function _convertAdditionalData()
|
72 |
{
|
73 |
+
$details = false;
|
74 |
+
try {
|
75 |
+
$details = Mage::helper('core/unserializeArray')
|
76 |
+
->unserialize($this->getInfo()->getAdditionalData());
|
77 |
+
} catch (Exception $e) {
|
78 |
+
Mage::logException($e);
|
79 |
+
}
|
80 |
if (is_array($details)) {
|
81 |
$this->_payableTo = isset($details['payable_to']) ? (string) $details['payable_to'] : '';
|
82 |
$this->_mailingAddress = isset($details['mailing_address']) ? (string) $details['mailing_address'] : '';
|
86 |
}
|
87 |
return $this;
|
88 |
}
|
89 |
+
|
90 |
public function toPdf()
|
91 |
{
|
92 |
$this->setTemplate('payment/info/pdf/checkmo.phtml');
|
app/code/core/Mage/Payment/Model/Method/Cc.php
CHANGED
@@ -122,7 +122,7 @@ class Mage_Payment_Model_Method_Cc extends Mage_Payment_Model_Method_Abstract
|
|
122 |
// Visa
|
123 |
'VI' => '/^4[0-9]{12}([0-9]{3})?$/',
|
124 |
// Master Card
|
125 |
-
'MC' => '/^5[1-5][0-9]{14}$/',
|
126 |
// American Express
|
127 |
'AE' => '/^3[47][0-9]{13}$/',
|
128 |
// Discover Network
|
122 |
// Visa
|
123 |
'VI' => '/^4[0-9]{12}([0-9]{3})?$/',
|
124 |
// Master Card
|
125 |
+
'MC' => '/^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))$/',
|
126 |
// American Express
|
127 |
'AE' => '/^3[47][0-9]{13}$/',
|
128 |
// Discover Network
|
app/code/core/Mage/Paypal/Model/Api/Nvp.php
CHANGED
@@ -520,7 +520,8 @@ class Mage_Paypal_Model_Api_Nvp extends Mage_Paypal_Model_Api_Abstract
|
|
520 |
* @var array
|
521 |
*/
|
522 |
protected $_requiredResponseParams = array(
|
523 |
-
self::DO_DIRECT_PAYMENT
|
|
|
524 |
);
|
525 |
|
526 |
/**
|
520 |
* @var array
|
521 |
*/
|
522 |
protected $_requiredResponseParams = array(
|
523 |
+
self::DO_DIRECT_PAYMENT => array('ACK', 'CORRELATIONID', 'AMT'),
|
524 |
+
self::DO_EXPRESS_CHECKOUT_PAYMENT => array('ACK', 'CORRELATIONID', 'AMT'),
|
525 |
);
|
526 |
|
527 |
/**
|
app/code/core/Mage/Paypal/Model/Express/Checkout.php
CHANGED
@@ -947,7 +947,7 @@ class Mage_Paypal_Model_Express_Checkout
|
|
947 |
$shipping = $quote->isVirtual() ? null : $quote->getShippingAddress();
|
948 |
|
949 |
$customerId = $this->_lookupCustomerId();
|
950 |
-
if ($customerId) {
|
951 |
$this->getCustomerSession()->loginById($customerId);
|
952 |
return $this->_prepareCustomerQuote();
|
953 |
}
|
@@ -1063,4 +1063,26 @@ class Mage_Paypal_Model_Express_Checkout
|
|
1063 |
{
|
1064 |
return $this->_customerSession;
|
1065 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1066 |
}
|
947 |
$shipping = $quote->isVirtual() ? null : $quote->getShippingAddress();
|
948 |
|
949 |
$customerId = $this->_lookupCustomerId();
|
950 |
+
if ($customerId && !$this->_customerEmailExists($quote->getCustomerEmail())) {
|
951 |
$this->getCustomerSession()->loginById($customerId);
|
952 |
return $this->_prepareCustomerQuote();
|
953 |
}
|
1063 |
{
|
1064 |
return $this->_customerSession;
|
1065 |
}
|
1066 |
+
|
1067 |
+
/**
|
1068 |
+
* Check if customer email exists
|
1069 |
+
*
|
1070 |
+
* @param string $email
|
1071 |
+
* @return bool
|
1072 |
+
*/
|
1073 |
+
protected function _customerEmailExists($email)
|
1074 |
+
{
|
1075 |
+
$result = false;
|
1076 |
+
$customer = Mage::getModel('customer/customer');
|
1077 |
+
$websiteId = Mage::app()->getStore()->getWebsiteId();
|
1078 |
+
if (!is_null($websiteId)) {
|
1079 |
+
$customer->setWebsiteId($websiteId);
|
1080 |
+
}
|
1081 |
+
$customer->loadByEmail($email);
|
1082 |
+
if (!is_null($customer->getId())) {
|
1083 |
+
$result = true;
|
1084 |
+
}
|
1085 |
+
|
1086 |
+
return $result;
|
1087 |
+
}
|
1088 |
}
|
app/code/core/Mage/Paypal/Model/Resource/Payment/Transaction.php
CHANGED
@@ -52,6 +52,26 @@ class Mage_Paypal_Model_Resource_Payment_Transaction extends Mage_Core_Model_Res
|
|
52 |
$this->_init('paypal/payment_transaction', 'transaction_id');
|
53 |
}
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
/**
|
56 |
* Load the transaction object by specified txn_id
|
57 |
*
|
52 |
$this->_init('paypal/payment_transaction', 'transaction_id');
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
+
* @see Mage_Core_Model_Resource_Abstract::_unserializeField()
|
57 |
+
*/
|
58 |
+
protected function _unserializeField(Varien_Object $object, $field, $defaultValue = null)
|
59 |
+
{
|
60 |
+
$value = $object->getData($field);
|
61 |
+
if (empty($value)) {
|
62 |
+
$object->setData($field, $defaultValue);
|
63 |
+
} elseif (!is_array($value) && !is_object($value)) {
|
64 |
+
$unserializedValue = false;
|
65 |
+
try {
|
66 |
+
$unserializedValue = Mage::helper('core/unserializeArray')
|
67 |
+
->unserialize($value);
|
68 |
+
} catch (Exception $e) {
|
69 |
+
Mage::logException($e);
|
70 |
+
}
|
71 |
+
$object->setData($field, $unserializedValue);
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
/**
|
76 |
* Load the transaction object by specified txn_id
|
77 |
*
|
app/code/core/Mage/Persistent/Model/Persistent/Config.php
CHANGED
@@ -71,7 +71,9 @@ class Mage_Persistent_Model_Persistent_Config
|
|
71 |
if (is_null($this->_xmlConfig)) {
|
72 |
$filePath = $this->_configFilePath;
|
73 |
if (!is_file($filePath) || !is_readable($filePath)) {
|
74 |
-
|
|
|
|
|
75 |
}
|
76 |
$xml = file_get_contents($filePath);
|
77 |
$this->_xmlConfig = new Varien_Simplexml_Element($xml);
|
71 |
if (is_null($this->_xmlConfig)) {
|
72 |
$filePath = $this->_configFilePath;
|
73 |
if (!is_file($filePath) || !is_readable($filePath)) {
|
74 |
+
$io = new Varien_Io_File();
|
75 |
+
Mage::throwException(Mage::helper('persistent')->__('Cannot load configuration from file %s.',
|
76 |
+
$io->getFilteredPath($filePath)));
|
77 |
}
|
78 |
$xml = file_get_contents($filePath);
|
79 |
$this->_xmlConfig = new Varien_Simplexml_Element($xml);
|
app/code/core/Mage/Reports/Model/Product/Index/Abstract.php
CHANGED
@@ -65,7 +65,16 @@ abstract class Mage_Reports_Model_Product_Index_Abstract extends Mage_Core_Model
|
|
65 |
// Thanks to new performance tweaks it is possible to switch off visitor logging
|
66 |
// This check is needed to make sure report record has either visitor id or customer id
|
67 |
if ($this->hasVisitorId() || $this->hasCustomerId()) {
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
}
|
70 |
|
71 |
return $this;
|
@@ -223,7 +232,16 @@ abstract class Mage_Reports_Model_Product_Index_Abstract extends Mage_Core_Model
|
|
223 |
*/
|
224 |
public function registerIds($productIds)
|
225 |
{
|
226 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
227 |
$this->_getSession()->unsData($this->_countCacheKey);
|
228 |
return $this;
|
229 |
}
|
65 |
// Thanks to new performance tweaks it is possible to switch off visitor logging
|
66 |
// This check is needed to make sure report record has either visitor id or customer id
|
67 |
if ($this->hasVisitorId() || $this->hasCustomerId()) {
|
68 |
+
try {
|
69 |
+
parent::save();
|
70 |
+
} catch (Exception $exception) {
|
71 |
+
if ($this->hasCustomerId()) {
|
72 |
+
$this->updateCustomerFromVisitor();
|
73 |
+
parent::save();
|
74 |
+
} else {
|
75 |
+
Mage::logException($exception);
|
76 |
+
}
|
77 |
+
}
|
78 |
}
|
79 |
|
80 |
return $this;
|
232 |
*/
|
233 |
public function registerIds($productIds)
|
234 |
{
|
235 |
+
try {
|
236 |
+
$this->_getResource()->registerIds($this, $productIds);
|
237 |
+
} catch (Exception $exception) {
|
238 |
+
if ($this->hasCustomerId()) {
|
239 |
+
$this->updateCustomerFromVisitor();
|
240 |
+
$this->_getResource()->registerIds($this, $productIds);
|
241 |
+
} else {
|
242 |
+
Mage::logException($exception);
|
243 |
+
}
|
244 |
+
}
|
245 |
$this->_getSession()->unsData($this->_countCacheKey);
|
246 |
return $this;
|
247 |
}
|
app/code/core/Mage/Reports/Model/Resource/Helper/Mysql4.php
CHANGED
@@ -77,22 +77,44 @@ class Mage_Reports_Model_Resource_Helper_Mysql4 extends Mage_Core_Model_Resource
|
|
77 |
}
|
78 |
|
79 |
$columns = array(
|
80 |
-
'period'
|
81 |
-
'store_id'
|
82 |
-
'product_id'
|
83 |
-
'product_name'
|
84 |
-
'product_price'
|
85 |
);
|
86 |
|
87 |
if ($type == 'day') {
|
88 |
$columns['id'] = 't.id'; // to speed-up insert on duplicate key update
|
89 |
}
|
90 |
|
|
|
|
|
|
|
|
|
|
|
91 |
$cols = array_keys($columns);
|
92 |
$cols['total_qty'] = new Zend_Db_Expr('SUM(t.' . $column . ')');
|
|
|
93 |
$periodSubSelect->from(array('t' => $mainTable), $cols)
|
94 |
-
->group(array('t.store_id', $periodCol, 't.product_id'))
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
|
97 |
$cols = $columns;
|
98 |
$cols[$column] = 't.total_qty';
|
77 |
}
|
78 |
|
79 |
$columns = array(
|
80 |
+
'period' => 't.period',
|
81 |
+
'store_id' => 't.store_id',
|
82 |
+
'product_id' => 't.product_id',
|
83 |
+
'product_name' => 't.product_name',
|
84 |
+
'product_price' => 't.product_price',
|
85 |
);
|
86 |
|
87 |
if ($type == 'day') {
|
88 |
$columns['id'] = 't.id'; // to speed-up insert on duplicate key update
|
89 |
}
|
90 |
|
91 |
+
if ($column == 'qty_ordered')
|
92 |
+
{
|
93 |
+
$columns['product_type_id'] = 't.product_type_id';
|
94 |
+
}
|
95 |
+
|
96 |
$cols = array_keys($columns);
|
97 |
$cols['total_qty'] = new Zend_Db_Expr('SUM(t.' . $column . ')');
|
98 |
+
|
99 |
$periodSubSelect->from(array('t' => $mainTable), $cols)
|
100 |
+
->group(array('t.store_id', $periodCol, 't.product_id'));
|
101 |
+
|
102 |
+
if ($column == 'qty_ordered') {
|
103 |
+
$productTypesInExpr = $adapter->quoteInto(
|
104 |
+
't.product_type_id IN (?)',
|
105 |
+
Mage_Catalog_Model_Product_Type::getCompositeTypes()
|
106 |
+
);
|
107 |
+
$periodSubSelect->order(
|
108 |
+
array(
|
109 |
+
't.store_id',
|
110 |
+
$periodCol,
|
111 |
+
$adapter->getCheckSql($productTypesInExpr, 1, 0),
|
112 |
+
'total_qty DESC'
|
113 |
+
)
|
114 |
+
);
|
115 |
+
} else {
|
116 |
+
$periodSubSelect->order(array('t.store_id', $periodCol, 'total_qty DESC'));
|
117 |
+
}
|
118 |
|
119 |
$cols = $columns;
|
120 |
$cols[$column] = 't.total_qty';
|
app/code/core/Mage/Rss/Controller/Abstract.php
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Rss
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Rss abstract controller
|
29 |
+
*
|
30 |
+
* @category Mage
|
31 |
+
* @package Mage_Rss
|
32 |
+
* @author Magento Core Team <core@magentocommerce.com>
|
33 |
+
*/
|
34 |
+
class Mage_Rss_Controller_Abstract extends Mage_Core_Controller_Front_Action
|
35 |
+
{
|
36 |
+
/**
|
37 |
+
* Check feed enabled in config
|
38 |
+
*
|
39 |
+
* @param string $code
|
40 |
+
* @return boolean
|
41 |
+
*/
|
42 |
+
protected function isFeedEnable($code)
|
43 |
+
{
|
44 |
+
return $this->_getHelper('rss')->isRssEnabled()
|
45 |
+
&& Mage::getStoreConfig('rss/'. $code);
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Do check feed enabled and prepare response
|
50 |
+
*
|
51 |
+
* @param string $code
|
52 |
+
* @return boolean
|
53 |
+
*/
|
54 |
+
protected function checkFeedEnable($code)
|
55 |
+
{
|
56 |
+
if ($this->isFeedEnable($code)) {
|
57 |
+
$this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
|
58 |
+
return true;
|
59 |
+
} else {
|
60 |
+
$this->getResponse()->setHeader('HTTP/1.1', '404 Not Found');
|
61 |
+
$this->getResponse()->setHeader('Status', '404 File not found');
|
62 |
+
$this->_forward('nofeed', 'index', 'rss');
|
63 |
+
return false;
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Retrieve helper instance
|
69 |
+
*
|
70 |
+
* @param string $name
|
71 |
+
* @return Mage_Core_Helper_Abstract
|
72 |
+
*/
|
73 |
+
protected function _getHelper($name)
|
74 |
+
{
|
75 |
+
return Mage::helper($name);
|
76 |
+
}
|
77 |
+
}
|
app/code/core/Mage/Rss/controllers/CatalogController.php
CHANGED
@@ -32,55 +32,41 @@
|
|
32 |
* @author Magento Core Team <core@magentocommerce.com>
|
33 |
*/
|
34 |
|
35 |
-
class Mage_Rss_CatalogController extends
|
36 |
{
|
37 |
-
protected function isFeedEnable($code)
|
38 |
-
{
|
39 |
-
return Mage::getStoreConfig('rss/catalog/'.$code);
|
40 |
-
}
|
41 |
-
|
42 |
-
protected function checkFeedEnable($code)
|
43 |
-
{
|
44 |
-
if ($this->isFeedEnable($code)) {
|
45 |
-
$this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
|
46 |
-
return true;
|
47 |
-
} else {
|
48 |
-
$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
|
49 |
-
$this->getResponse()->setHeader('Status','404 File not found');
|
50 |
-
$this->_forward('nofeed','index','rss');
|
51 |
-
return false;
|
52 |
-
}
|
53 |
-
}
|
54 |
-
|
55 |
public function newAction()
|
56 |
{
|
57 |
-
$this->checkFeedEnable('new')
|
58 |
-
|
59 |
-
|
|
|
60 |
}
|
61 |
|
62 |
public function specialAction()
|
63 |
{
|
64 |
-
$this->checkFeedEnable('special')
|
65 |
-
|
66 |
-
|
|
|
67 |
}
|
68 |
|
69 |
public function salesruleAction()
|
70 |
{
|
71 |
-
$this->checkFeedEnable('salesrule')
|
72 |
-
|
73 |
-
|
|
|
74 |
}
|
75 |
|
76 |
public function tagAction()
|
77 |
{
|
78 |
-
if ($this->
|
79 |
$tagName = urldecode($this->getRequest()->getParam('tagName'));
|
80 |
$tagModel = Mage::getModel('tag/tag');
|
81 |
$tagModel->loadByName($tagName);
|
82 |
if ($tagModel->getId() && $tagModel->getStatus()==$tagModel->getApprovedStatus()) {
|
83 |
Mage::register('tag_model', $tagModel);
|
|
|
84 |
$this->loadLayout(false);
|
85 |
$this->renderLayout();
|
86 |
return;
|
@@ -91,21 +77,23 @@ class Mage_Rss_CatalogController extends Mage_Core_Controller_Front_Action
|
|
91 |
|
92 |
public function notifystockAction()
|
93 |
{
|
94 |
-
$this->
|
95 |
-
|
96 |
-
|
|
|
97 |
}
|
98 |
|
99 |
public function reviewAction()
|
100 |
{
|
101 |
-
$this->
|
102 |
-
|
103 |
-
|
|
|
104 |
}
|
105 |
|
106 |
public function categoryAction()
|
107 |
{
|
108 |
-
if ($this->checkFeedEnable('category')) {
|
109 |
$this->loadLayout(false);
|
110 |
$this->renderLayout();
|
111 |
}
|
@@ -119,11 +107,11 @@ class Mage_Rss_CatalogController extends Mage_Core_Controller_Front_Action
|
|
119 |
public function preDispatch()
|
120 |
{
|
121 |
$action = strtolower($this->getRequest()->getActionName());
|
122 |
-
if ($action == 'notifystock') {
|
123 |
$this->_currentArea = 'adminhtml';
|
124 |
Mage::helper('rss')->authAdmin('catalog/products');
|
125 |
}
|
126 |
-
if ($action == 'review') {
|
127 |
$this->_currentArea = 'adminhtml';
|
128 |
Mage::helper('rss')->authAdmin('catalog/reviews_ratings');
|
129 |
}
|
32 |
* @author Magento Core Team <core@magentocommerce.com>
|
33 |
*/
|
34 |
|
35 |
+
class Mage_Rss_CatalogController extends Mage_Rss_Controller_Abstract
|
36 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
public function newAction()
|
38 |
{
|
39 |
+
if ($this->checkFeedEnable('catalog/new')) {
|
40 |
+
$this->loadLayout(false);
|
41 |
+
$this->renderLayout();
|
42 |
+
}
|
43 |
}
|
44 |
|
45 |
public function specialAction()
|
46 |
{
|
47 |
+
if ($this->checkFeedEnable('catalog/special')) {
|
48 |
+
$this->loadLayout(false);
|
49 |
+
$this->renderLayout();
|
50 |
+
}
|
51 |
}
|
52 |
|
53 |
public function salesruleAction()
|
54 |
{
|
55 |
+
if ($this->checkFeedEnable('catalog/salesrule')) {
|
56 |
+
$this->loadLayout(false);
|
57 |
+
$this->renderLayout();
|
58 |
+
}
|
59 |
}
|
60 |
|
61 |
public function tagAction()
|
62 |
{
|
63 |
+
if ($this->isFeedEnable('catalog/tag')) {
|
64 |
$tagName = urldecode($this->getRequest()->getParam('tagName'));
|
65 |
$tagModel = Mage::getModel('tag/tag');
|
66 |
$tagModel->loadByName($tagName);
|
67 |
if ($tagModel->getId() && $tagModel->getStatus()==$tagModel->getApprovedStatus()) {
|
68 |
Mage::register('tag_model', $tagModel);
|
69 |
+
$this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
|
70 |
$this->loadLayout(false);
|
71 |
$this->renderLayout();
|
72 |
return;
|
77 |
|
78 |
public function notifystockAction()
|
79 |
{
|
80 |
+
if ($this->checkFeedEnable('catalog/notifystock')) {
|
81 |
+
$this->loadLayout(false);
|
82 |
+
$this->renderLayout();
|
83 |
+
}
|
84 |
}
|
85 |
|
86 |
public function reviewAction()
|
87 |
{
|
88 |
+
if ($this->checkFeedEnable('catalog/review')) {
|
89 |
+
$this->loadLayout(false);
|
90 |
+
$this->renderLayout();
|
91 |
+
}
|
92 |
}
|
93 |
|
94 |
public function categoryAction()
|
95 |
{
|
96 |
+
if ($this->checkFeedEnable('catalog/category')) {
|
97 |
$this->loadLayout(false);
|
98 |
$this->renderLayout();
|
99 |
}
|
107 |
public function preDispatch()
|
108 |
{
|
109 |
$action = strtolower($this->getRequest()->getActionName());
|
110 |
+
if ($action == 'notifystock' && $this->isFeedEnable('catalog/notifystock')) {
|
111 |
$this->_currentArea = 'adminhtml';
|
112 |
Mage::helper('rss')->authAdmin('catalog/products');
|
113 |
}
|
114 |
+
if ($action == 'review' && $this->isFeedEnable('catalog/review')) {
|
115 |
$this->_currentArea = 'adminhtml';
|
116 |
Mage::helper('rss')->authAdmin('catalog/reviews_ratings');
|
117 |
}
|
app/code/core/Mage/Rss/controllers/IndexController.php
CHANGED
@@ -30,7 +30,7 @@
|
|
30 |
* @file IndexController.php
|
31 |
* @author Magento Core Team <core@magentocommerce.com>
|
32 |
*/
|
33 |
-
class Mage_Rss_IndexController extends
|
34 |
{
|
35 |
/**
|
36 |
* Current wishlist
|
@@ -80,9 +80,7 @@ class Mage_Rss_IndexController extends Mage_Core_Controller_Front_Action
|
|
80 |
*/
|
81 |
public function wishlistAction()
|
82 |
{
|
83 |
-
if (
|
84 |
-
$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
|
85 |
-
$this->getResponse()->setHeader('Status','404 File not found');
|
86 |
$this->_forward('nofeed','index','rss');
|
87 |
return;
|
88 |
}
|
@@ -156,15 +154,4 @@ class Mage_Rss_IndexController extends Mage_Core_Controller_Front_Action
|
|
156 |
|
157 |
return $this->_customer;
|
158 |
}
|
159 |
-
|
160 |
-
/**
|
161 |
-
* Retrieve helper instance
|
162 |
-
*
|
163 |
-
* @param string $name
|
164 |
-
* @return Mage_Core_Helper_Abstract
|
165 |
-
*/
|
166 |
-
protected function _getHelper($name)
|
167 |
-
{
|
168 |
-
return Mage::helper($name);
|
169 |
-
}
|
170 |
}
|
30 |
* @file IndexController.php
|
31 |
* @author Magento Core Team <core@magentocommerce.com>
|
32 |
*/
|
33 |
+
class Mage_Rss_IndexController extends Mage_Rss_Controller_Abstract
|
34 |
{
|
35 |
/**
|
36 |
* Current wishlist
|
80 |
*/
|
81 |
public function wishlistAction()
|
82 |
{
|
83 |
+
if (!$this->isFeedEnable('wishlist/active')) {
|
|
|
|
|
84 |
$this->_forward('nofeed','index','rss');
|
85 |
return;
|
86 |
}
|
154 |
|
155 |
return $this->_customer;
|
156 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
}
|
app/code/core/Mage/Rss/controllers/OrderController.php
CHANGED
@@ -32,23 +32,25 @@
|
|
32 |
* @author Magento Core Team <core@magentocommerce.com>
|
33 |
*/
|
34 |
|
35 |
-
class Mage_Rss_OrderController extends
|
36 |
{
|
37 |
public function newAction()
|
38 |
{
|
39 |
-
$this->
|
40 |
-
|
41 |
-
|
|
|
42 |
}
|
43 |
|
44 |
public function customerAction()
|
45 |
{
|
46 |
-
if (
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
|
|
52 |
}
|
53 |
}
|
54 |
|
@@ -57,13 +59,15 @@ class Mage_Rss_OrderController extends Mage_Core_Controller_Front_Action
|
|
57 |
*/
|
58 |
public function statusAction()
|
59 |
{
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
|
|
|
|
67 |
}
|
68 |
$this->_forward('nofeed', 'index', 'rss');
|
69 |
}
|
@@ -76,7 +80,7 @@ class Mage_Rss_OrderController extends Mage_Core_Controller_Front_Action
|
|
76 |
public function preDispatch()
|
77 |
{
|
78 |
$action = strtolower($this->getRequest()->getActionName());
|
79 |
-
if ($action == 'new') {
|
80 |
$this->_currentArea = 'adminhtml';
|
81 |
Mage::helper('rss')->authAdmin('sales/order');
|
82 |
}
|
32 |
* @author Magento Core Team <core@magentocommerce.com>
|
33 |
*/
|
34 |
|
35 |
+
class Mage_Rss_OrderController extends Mage_Rss_Controller_Abstract
|
36 |
{
|
37 |
public function newAction()
|
38 |
{
|
39 |
+
if ($this->checkFeedEnable('order/new')) {
|
40 |
+
$this->loadLayout(false);
|
41 |
+
$this->renderLayout();
|
42 |
+
}
|
43 |
}
|
44 |
|
45 |
public function customerAction()
|
46 |
{
|
47 |
+
if ($this->checkFeedEnable('order/customer')) {
|
48 |
+
if (Mage::app()->getStore()->isCurrentlySecure()) {
|
49 |
+
Mage::helper('rss')->authFrontend();
|
50 |
+
} else {
|
51 |
+
$this->_redirect('rss/order/customer', array('_secure'=>true));
|
52 |
+
return $this;
|
53 |
+
}
|
54 |
}
|
55 |
}
|
56 |
|
59 |
*/
|
60 |
public function statusAction()
|
61 |
{
|
62 |
+
if ($this->isFeedEnable('order/status_notified')) {
|
63 |
+
$order = Mage::helper('rss/order')->getOrderByStatusUrlKey((string)$this->getRequest()->getParam('data'));
|
64 |
+
if (!is_null($order)) {
|
65 |
+
Mage::register('current_order', $order);
|
66 |
+
$this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
|
67 |
+
$this->loadLayout(false);
|
68 |
+
$this->renderLayout();
|
69 |
+
return;
|
70 |
+
}
|
71 |
}
|
72 |
$this->_forward('nofeed', 'index', 'rss');
|
73 |
}
|
80 |
public function preDispatch()
|
81 |
{
|
82 |
$action = strtolower($this->getRequest()->getActionName());
|
83 |
+
if ($action == 'new' && $this->isFeedEnable('order/new')) {
|
84 |
$this->_currentArea = 'adminhtml';
|
85 |
Mage::helper('rss')->authAdmin('sales/order');
|
86 |
}
|
app/code/core/Mage/Rss/data/rss_setup/data-install-1.6.0.0.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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@magento.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.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Rss
|
23 |
+
* @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
|
28 |
+
/* @var $installer Mage_Core_Model_Resource_Setup */
|
29 |
+
|
30 |
+
$installer = $this;
|
31 |
+
|
32 |
+
$this->deleteConfigData(Mage_Rss_Helper_Data::XML_PATH_RSS_ACTIVE);
|
33 |
+
|
34 |
+
$installer->endSetup();
|
app/code/core/Mage/Rss/etc/config.xml
CHANGED
@@ -47,10 +47,14 @@
|
|
47 |
<class>Mage_Rss_Block</class>
|
48 |
</rss>
|
49 |
</blocks>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
</global>
|
51 |
-
<admin>
|
52 |
-
|
53 |
-
</admin>
|
54 |
<adminhtml>
|
55 |
<translate>
|
56 |
<modules>
|
47 |
<class>Mage_Rss_Block</class>
|
48 |
</rss>
|
49 |
</blocks>
|
50 |
+
<resources>
|
51 |
+
<rss_setup>
|
52 |
+
<setup>
|
53 |
+
<module>Mage_Rss</module>
|
54 |
+
</setup>
|
55 |
+
</rss_setup>
|
56 |
+
</resources>
|
57 |
</global>
|
|
|
|
|
|
|
58 |
<adminhtml>
|
59 |
<translate>
|
60 |
<modules>
|
app/code/core/Mage/Rss/etc/system.xml
CHANGED
@@ -56,7 +56,6 @@
|
|
56 |
</active>
|
57 |
</fields>
|
58 |
</config>
|
59 |
-
|
60 |
<wishlist translate="label">
|
61 |
<label>Wishlist</label>
|
62 |
<frontend_type>text</frontend_type>
|
@@ -76,7 +75,6 @@
|
|
76 |
</active>
|
77 |
</fields>
|
78 |
</wishlist>
|
79 |
-
|
80 |
<catalog translate="label">
|
81 |
<label>Catalog</label>
|
82 |
<frontend_type>text</frontend_type>
|
@@ -130,10 +128,27 @@
|
|
130 |
<show_in_website>1</show_in_website>
|
131 |
<show_in_store>1</show_in_store>
|
132 |
</category>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
</fields>
|
134 |
</catalog>
|
135 |
-
|
136 |
-
<order>
|
137 |
<label>Order</label>
|
138 |
<frontend_type>text</frontend_type>
|
139 |
<sort_order>4</sort_order>
|
@@ -150,9 +165,73 @@
|
|
150 |
<show_in_website>1</show_in_website>
|
151 |
<show_in_store>1</show_in_store>
|
152 |
</status_notified>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
</fields>
|
154 |
</order>
|
155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
</groups>
|
157 |
</rss>
|
158 |
</sections>
|
56 |
</active>
|
57 |
</fields>
|
58 |
</config>
|
|
|
59 |
<wishlist translate="label">
|
60 |
<label>Wishlist</label>
|
61 |
<frontend_type>text</frontend_type>
|
75 |
</active>
|
76 |
</fields>
|
77 |
</wishlist>
|
|
|
78 |
<catalog translate="label">
|
79 |
<label>Catalog</label>
|
80 |
<frontend_type>text</frontend_type>
|
128 |
<show_in_website>1</show_in_website>
|
129 |
<show_in_store>1</show_in_store>
|
130 |
</category>
|
131 |
+
<notifystock translate="label">
|
132 |
+
<label>Stock Notification</label>
|
133 |
+
<frontend_type>select</frontend_type>
|
134 |
+
<source_model>adminhtml/system_config_source_enabledisable</source_model>
|
135 |
+
<sort_order>15</sort_order>
|
136 |
+
<show_in_default>1</show_in_default>
|
137 |
+
<show_in_website>1</show_in_website>
|
138 |
+
<show_in_store>1</show_in_store>
|
139 |
+
</notifystock>
|
140 |
+
<review translate="label">
|
141 |
+
<label>Review Notification</label>
|
142 |
+
<frontend_type>select</frontend_type>
|
143 |
+
<source_model>adminhtml/system_config_source_enabledisable</source_model>
|
144 |
+
<sort_order>16</sort_order>
|
145 |
+
<show_in_default>1</show_in_default>
|
146 |
+
<show_in_website>1</show_in_website>
|
147 |
+
<show_in_store>1</show_in_store>
|
148 |
+
</review>
|
149 |
</fields>
|
150 |
</catalog>
|
151 |
+
<order translate="label">
|
|
|
152 |
<label>Order</label>
|
153 |
<frontend_type>text</frontend_type>
|
154 |
<sort_order>4</sort_order>
|
165 |
<show_in_website>1</show_in_website>
|
166 |
<show_in_store>1</show_in_store>
|
167 |
</status_notified>
|
168 |
+
<new translate="label">
|
169 |
+
<label>New Order Notification</label>
|
170 |
+
<frontend_type>select</frontend_type>
|
171 |
+
<source_model>adminhtml/system_config_source_enabledisable</source_model>
|
172 |
+
<sort_order>20</sort_order>
|
173 |
+
<show_in_default>1</show_in_default>
|
174 |
+
<show_in_website>1</show_in_website>
|
175 |
+
<show_in_store>1</show_in_store>
|
176 |
+
</new>
|
177 |
+
<customer translate="label">
|
178 |
+
<label>Customer Order Notification</label>
|
179 |
+
<frontend_type>select</frontend_type>
|
180 |
+
<source_model>adminhtml/system_config_source_enabledisable</source_model>
|
181 |
+
<sort_order>30</sort_order>
|
182 |
+
<show_in_default>1</show_in_default>
|
183 |
+
<show_in_website>1</show_in_website>
|
184 |
+
<show_in_store>1</show_in_store>
|
185 |
+
</customer>
|
186 |
</fields>
|
187 |
</order>
|
188 |
+
<admin_catalog translate="label">
|
189 |
+
<label>Admin Catalog</label>
|
190 |
+
<frontend_type>text</frontend_type>
|
191 |
+
<sort_order>5</sort_order>
|
192 |
+
<show_in_default>1</show_in_default>
|
193 |
+
<show_in_website>1</show_in_website>
|
194 |
+
<show_in_store>1</show_in_store>
|
195 |
+
<fields>
|
196 |
+
<review translate="label">
|
197 |
+
<label>Review Notification</label>
|
198 |
+
<frontend_type>select</frontend_type>
|
199 |
+
<source_model>adminhtml/system_config_source_enabledisable</source_model>
|
200 |
+
<sort_order>10</sort_order>
|
201 |
+
<show_in_default>1</show_in_default>
|
202 |
+
<show_in_website>1</show_in_website>
|
203 |
+
<show_in_store>1</show_in_store>
|
204 |
+
</review>
|
205 |
+
<notifystock translate="label">
|
206 |
+
<label>Stock Notification</label>
|
207 |
+
<frontend_type>select</frontend_type>
|
208 |
+
<source_model>adminhtml/system_config_source_enabledisable</source_model>
|
209 |
+
<sort_order>20</sort_order>
|
210 |
+
<show_in_default>1</show_in_default>
|
211 |
+
<show_in_website>1</show_in_website>
|
212 |
+
<show_in_store>1</show_in_store>
|
213 |
+
</notifystock>
|
214 |
+
</fields>
|
215 |
+
</admin_catalog>
|
216 |
+
<admin_order translate="label">
|
217 |
+
<label>Admin Order</label>
|
218 |
+
<frontend_type>text</frontend_type>
|
219 |
+
<sort_order>6</sort_order>
|
220 |
+
<show_in_default>1</show_in_default>
|
221 |
+
<show_in_website>1</show_in_website>
|
222 |
+
<show_in_store>1</show_in_store>
|
223 |
+
<fields>
|
224 |
+
<new translate="label">
|
225 |
+
<label>New Order Notification</label>
|
226 |
+
<frontend_type>select</frontend_type>
|
227 |
+
<source_model>adminhtml/system_config_source_enabledisable</source_model>
|
228 |
+
<sort_order>10</sort_order>
|
229 |
+
<show_in_default>1</show_in_default>
|
230 |
+
<show_in_website>1</show_in_website>
|
231 |
+
<show_in_store>1</show_in_store>
|
232 |
+
</new>
|
233 |
+
</fields>
|
234 |
+
</admin_order>
|
235 |
</groups>
|
236 |
</rss>
|
237 |
</sections>
|
app/code/core/Mage/Sales/Helper/Guest.php
CHANGED
@@ -81,7 +81,7 @@ class Mage_Sales_Helper_Guest extends Mage_Core_Helper_Data
|
|
81 |
$billingAddress = $order->getBillingAddress();
|
82 |
if ((strtolower($lastName) != strtolower($billingAddress->getLastname()))
|
83 |
|| ($type == 'email'
|
84 |
-
&& strtolower($email) != strtolower($
|
85 |
|| ($type == 'zip'
|
86 |
&& (strtolower($zip) != strtolower($billingAddress->getPostcode())))
|
87 |
) {
|
81 |
$billingAddress = $order->getBillingAddress();
|
82 |
if ((strtolower($lastName) != strtolower($billingAddress->getLastname()))
|
83 |
|| ($type == 'email'
|
84 |
+
&& strtolower($email) != strtolower($order->getCustomerEmail()))
|
85 |
|| ($type == 'zip'
|
86 |
&& (strtolower($zip) != strtolower($billingAddress->getPostcode())))
|
87 |
) {
|
app/code/core/Mage/Sales/Model/Email/Template.php
CHANGED
@@ -33,7 +33,7 @@ class Mage_Sales_Model_Email_Template extends Mage_Core_Model_Email_Template
|
|
33 |
if (!$filename) {
|
34 |
return '';
|
35 |
}
|
36 |
-
extract($variables);
|
37 |
ob_start();
|
38 |
include $filename;
|
39 |
return ob_get_clean();
|
33 |
if (!$filename) {
|
34 |
return '';
|
35 |
}
|
36 |
+
extract($variables, EXTR_SKIP);
|
37 |
ob_start();
|
38 |
include $filename;
|
39 |
return ob_get_clean();
|
app/code/core/Mage/Sales/Model/Order.php
CHANGED
@@ -1255,7 +1255,11 @@ class Mage_Sales_Model_Order extends Mage_Sales_Model_Abstract
|
|
1255 |
if (!$asObject) {
|
1256 |
return $shippingMethod;
|
1257 |
} else {
|
1258 |
-
|
|
|
|
|
|
|
|
|
1259 |
return new Varien_Object(array(
|
1260 |
'carrier_code' => $carrierCode,
|
1261 |
'method' => $method
|
@@ -2021,7 +2025,12 @@ class Mage_Sales_Model_Order extends Mage_Sales_Model_Abstract
|
|
2021 |
*/
|
2022 |
public function hasShipments()
|
2023 |
{
|
2024 |
-
|
|
|
|
|
|
|
|
|
|
|
2025 |
}
|
2026 |
|
2027 |
/**
|
@@ -2031,7 +2040,12 @@ class Mage_Sales_Model_Order extends Mage_Sales_Model_Abstract
|
|
2031 |
*/
|
2032 |
public function hasCreditmemos()
|
2033 |
{
|
2034 |
-
|
|
|
|
|
|
|
|
|
|
|
2035 |
}
|
2036 |
|
2037 |
|
1255 |
if (!$asObject) {
|
1256 |
return $shippingMethod;
|
1257 |
} else {
|
1258 |
+
$segments = explode('_', $shippingMethod, 2);
|
1259 |
+
if (!isset($segments[1])) {
|
1260 |
+
$segments[1] = $segments[0];
|
1261 |
+
}
|
1262 |
+
list($carrierCode, $method) = $segments;
|
1263 |
return new Varien_Object(array(
|
1264 |
'carrier_code' => $carrierCode,
|
1265 |
'method' => $method
|
2025 |
*/
|
2026 |
public function hasShipments()
|
2027 |
{
|
2028 |
+
$result = false;
|
2029 |
+
$shipmentsCollection = $this->getShipmentsCollection();
|
2030 |
+
if ($shipmentsCollection) {
|
2031 |
+
$result = (bool)$shipmentsCollection->count();
|
2032 |
+
}
|
2033 |
+
return $result;
|
2034 |
}
|
2035 |
|
2036 |
/**
|
2040 |
*/
|
2041 |
public function hasCreditmemos()
|
2042 |
{
|
2043 |
+
$result = false;
|
2044 |
+
$creditmemosCollection = $this->getCreditmemosCollection();
|
2045 |
+
if ($creditmemosCollection) {
|
2046 |
+
$result = (bool)$creditmemosCollection->count();
|
2047 |
+
}
|
2048 |
+
return $result;
|
2049 |
}
|
2050 |
|
2051 |
|
app/code/core/Mage/Sales/Model/Order/Invoice/Total/Subtotal.php
CHANGED
@@ -40,9 +40,6 @@ class Mage_Sales_Model_Order_Invoice_Total_Subtotal extends Mage_Sales_Model_Ord
|
|
40 |
$subtotalInclTax= 0;
|
41 |
$baseSubtotalInclTax = 0;
|
42 |
|
43 |
-
$totalWeeeDiscount = 0;
|
44 |
-
$totalBaseWeeeDiscount = 0;
|
45 |
-
|
46 |
$order = $invoice->getOrder();
|
47 |
|
48 |
foreach ($invoice->getAllItems() as $item) {
|
@@ -52,50 +49,21 @@ class Mage_Sales_Model_Order_Invoice_Total_Subtotal extends Mage_Sales_Model_Ord
|
|
52 |
|
53 |
$item->calcRowTotal();
|
54 |
|
55 |
-
$subtotal
|
56 |
-
$baseSubtotal
|
57 |
-
$subtotalInclTax+= $item->getRowTotalInclTax();
|
58 |
-
$baseSubtotalInclTax += $item->getBaseRowTotalInclTax();
|
59 |
-
$totalWeeeDiscount += $item->getOrderItem()->getDiscountAppliedForWeeeTax();
|
60 |
-
$totalBaseWeeeDiscount += $item->getOrderItem()->getBaseDiscountAppliedForWeeeTax();
|
61 |
}
|
62 |
|
63 |
$allowedSubtotal = $order->getSubtotal() - $order->getSubtotalInvoiced();
|
64 |
$baseAllowedSubtotal = $order->getBaseSubtotal() - $order->getBaseSubtotalInvoiced();
|
65 |
-
$allowedSubtotalInclTax = $allowedSubtotal + $order->getHiddenTaxAmount() + $totalWeeeDiscount
|
66 |
-
+ $order->getTaxAmount() - $order->getTaxInvoiced() - $order->getHiddenTaxInvoiced();
|
67 |
-
$baseAllowedSubtotalInclTax = $baseAllowedSubtotal + $order->getBaseHiddenTaxAmount() + $totalBaseWeeeDiscount
|
68 |
-
+ $order->getBaseTaxAmount() - $order->getBaseTaxInvoiced() - $order->getBaseHiddenTaxInvoiced();
|
69 |
-
|
70 |
-
/**
|
71 |
-
* Check if shipping tax calculation is included to current invoice.
|
72 |
-
*/
|
73 |
-
$includeShippingTax = true;
|
74 |
-
foreach ($invoice->getOrder()->getInvoiceCollection() as $previousInvoice) {
|
75 |
-
if ($previousInvoice->getShippingAmount() && !$previousInvoice->isCanceled()) {
|
76 |
-
$includeShippingTax = false;
|
77 |
-
break;
|
78 |
-
}
|
79 |
-
}
|
80 |
-
|
81 |
-
if ($includeShippingTax) {
|
82 |
-
$allowedSubtotalInclTax -= $order->getShippingTaxAmount();
|
83 |
-
$baseAllowedSubtotalInclTax -= $order->getBaseShippingTaxAmount();
|
84 |
-
} else {
|
85 |
-
$allowedSubtotalInclTax += $order->getShippingHiddenTaxAmount();
|
86 |
-
$baseAllowedSubtotalInclTax += $order->getBaseShippingHiddenTaxAmount();
|
87 |
-
}
|
88 |
|
89 |
if ($invoice->isLast()) {
|
90 |
$subtotal = $allowedSubtotal;
|
91 |
$baseSubtotal = $baseAllowedSubtotal;
|
92 |
-
$subtotalInclTax = $allowedSubtotalInclTax;
|
93 |
-
$baseSubtotalInclTax = $baseAllowedSubtotalInclTax;
|
94 |
} else {
|
95 |
$subtotal = min($allowedSubtotal, $subtotal);
|
96 |
$baseSubtotal = min($baseAllowedSubtotal, $baseSubtotal);
|
97 |
-
$subtotalInclTax = min($allowedSubtotalInclTax, $subtotalInclTax);
|
98 |
-
$baseSubtotalInclTax = min($baseAllowedSubtotalInclTax, $baseSubtotalInclTax);
|
99 |
}
|
100 |
|
101 |
$invoice->setSubtotal($subtotal);
|
40 |
$subtotalInclTax= 0;
|
41 |
$baseSubtotalInclTax = 0;
|
42 |
|
|
|
|
|
|
|
43 |
$order = $invoice->getOrder();
|
44 |
|
45 |
foreach ($invoice->getAllItems() as $item) {
|
49 |
|
50 |
$item->calcRowTotal();
|
51 |
|
52 |
+
$subtotal += $item->getRowTotal();
|
53 |
+
$baseSubtotal += $item->getBaseRowTotal();
|
54 |
+
$subtotalInclTax += $item->getRowTotalInclTax() + $item->getWeeeTaxAppliedRowAmount();
|
55 |
+
$baseSubtotalInclTax += $item->getBaseRowTotalInclTax() + $item->getBaseWeeeTaxAppliedRowAmount();
|
|
|
|
|
56 |
}
|
57 |
|
58 |
$allowedSubtotal = $order->getSubtotal() - $order->getSubtotalInvoiced();
|
59 |
$baseAllowedSubtotal = $order->getBaseSubtotal() - $order->getBaseSubtotalInvoiced();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
if ($invoice->isLast()) {
|
62 |
$subtotal = $allowedSubtotal;
|
63 |
$baseSubtotal = $baseAllowedSubtotal;
|
|
|
|
|
64 |
} else {
|
65 |
$subtotal = min($allowedSubtotal, $subtotal);
|
66 |
$baseSubtotal = min($baseAllowedSubtotal, $baseSubtotal);
|
|
|
|
|
67 |
}
|
68 |
|
69 |
$invoice->setSubtotal($subtotal);
|
app/code/core/Mage/Sales/Model/Quote/Address/Total/Subtotal.php
CHANGED
@@ -111,7 +111,7 @@ class Mage_Sales_Model_Quote_Address_Total_Subtotal extends Mage_Sales_Model_Quo
|
|
111 |
$item->setPrice($finalPrice)
|
112 |
->setBaseOriginalPrice($finalPrice);
|
113 |
$item->calcRowTotal();
|
114 |
-
} else if (!$quoteItem->getParentItem()) {
|
115 |
$finalPrice = $product->getFinalPrice($quoteItem->getQty());
|
116 |
$item->setPrice($finalPrice)
|
117 |
->setBaseOriginalPrice($finalPrice);
|
111 |
$item->setPrice($finalPrice)
|
112 |
->setBaseOriginalPrice($finalPrice);
|
113 |
$item->calcRowTotal();
|
114 |
+
} else if (!$quoteItem->getParentItem() && !$item->getHasError()) {
|
115 |
$finalPrice = $product->getFinalPrice($quoteItem->getQty());
|
116 |
$item->setPrice($finalPrice)
|
117 |
->setBaseOriginalPrice($finalPrice);
|
app/code/core/Mage/Sales/Model/Quote/Item.php
CHANGED
@@ -507,7 +507,7 @@ class Mage_Sales_Model_Quote_Item extends Mage_Sales_Model_Quote_Item_Abstract
|
|
507 |
$itemOptionValue = $_itemOptionValue;
|
508 |
$optionValue = $_optionValue;
|
509 |
// looks like it does not break bundle selection qty
|
510 |
-
foreach (array('qty', 'uenc', 'form_key') as $key) {
|
511 |
unset($itemOptionValue[$key], $optionValue[$key]);
|
512 |
}
|
513 |
}
|
507 |
$itemOptionValue = $_itemOptionValue;
|
508 |
$optionValue = $_optionValue;
|
509 |
// looks like it does not break bundle selection qty
|
510 |
+
foreach (array('qty', 'uenc', 'form_key', 'item', 'original_qty') as $key) {
|
511 |
unset($itemOptionValue[$key], $optionValue[$key]);
|
512 |
}
|
513 |
}
|
app/code/core/Mage/Sales/Model/Quote/Item/Abstract.php
CHANGED
@@ -130,7 +130,10 @@ abstract class Mage_Sales_Model_Quote_Item_Abstract extends Mage_Core_Model_Abst
|
|
130 |
{
|
131 |
if ($parentItem) {
|
132 |
$this->_parentItem = $parentItem;
|
133 |
-
|
|
|
|
|
|
|
134 |
}
|
135 |
return $this;
|
136 |
}
|
130 |
{
|
131 |
if ($parentItem) {
|
132 |
$this->_parentItem = $parentItem;
|
133 |
+
// Prevent duplication of children in those are already set
|
134 |
+
if (!in_array($this, $parentItem->getChildren())) {
|
135 |
+
$parentItem->addChild($this);
|
136 |
+
}
|
137 |
}
|
138 |
return $this;
|
139 |
}
|
app/code/core/Mage/Sales/Model/Resource/Order/Payment.php
CHANGED
@@ -58,4 +58,28 @@ class Mage_Sales_Model_Resource_Order_Payment extends Mage_Sales_Model_Resource_
|
|
58 |
{
|
59 |
$this->_init('sales/order_payment', 'entity_id');
|
60 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
}
|
58 |
{
|
59 |
$this->_init('sales/order_payment', 'entity_id');
|
60 |
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Unserialize Varien_Object field in an object
|
64 |
+
*
|
65 |
+
* @param Mage_Core_Model_Abstract $object
|
66 |
+
* @param string $field
|
67 |
+
* @param mixed $defaultValue
|
68 |
+
*/
|
69 |
+
protected function _unserializeField(Varien_Object $object, $field, $defaultValue = null)
|
70 |
+
{
|
71 |
+
$value = $object->getData($field);
|
72 |
+
if (empty($value)) {
|
73 |
+
$object->setData($field, $defaultValue);
|
74 |
+
} elseif (!is_array($value) && !is_object($value)) {
|
75 |
+
$unserializedValue = false;
|
76 |
+
try {
|
77 |
+
$unserializedValue = Mage::helper('core/unserializeArray')
|
78 |
+
->unserialize($value);
|
79 |
+
} catch (Exception $e) {
|
80 |
+
Mage::logException($e);
|
81 |
+
}
|
82 |
+
$object->setData($field, $unserializedValue);
|
83 |
+
}
|
84 |
+
}
|
85 |
}
|
app/code/core/Mage/Sales/Model/Resource/Order/Payment/Transaction.php
CHANGED
@@ -52,6 +52,30 @@ class Mage_Sales_Model_Resource_Order_Payment_Transaction extends Mage_Sales_Mod
|
|
52 |
$this->_init('sales/payment_transaction', 'transaction_id');
|
53 |
}
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
/**
|
56 |
* Update transactions in database using provided transaction as parent for them
|
57 |
* have to repeat the business logic to avoid accidental injection of wrong transactions
|