From 33cb60b77667da649eca0c53c49282909dd32adc Mon Sep 17 00:00:00 2001 From: Kevin Ottley Date: Tue, 24 Mar 2015 17:13:00 -0400 Subject: [PATCH] 3.2.5 --- composer.json | 2 +- composer.lock | 1778 +++++++++++++++ composer.phar | Bin 0 -> 1049776 bytes .../commands/HostingMigrateCommand.php | 131 +- .../components/ApplicationComponent.php | 12 +- core/protected/components/Checkout.php | 2 +- core/protected/components/Controller.php | 281 ++- .../components/CustomPageUrlRule.php | 57 +- core/protected/components/DbConnection.php | 3 +- core/protected/components/FBIdentity.php | 202 +- core/protected/components/HtmlToText.php | 85 +- core/protected/components/HttpRequest.php | 11 +- core/protected/components/Shipping.php | 35 +- core/protected/components/ShoppingCart.php | 260 ++- core/protected/components/Theme.php | 49 +- core/protected/components/UserIdentity.php | 37 +- .../protected/components/WebServiceAction.php | 18 +- core/protected/components/WebUser.php | 34 +- core/protected/components/WsExtension.php | 82 +- core/protected/components/WsSoapException.php | 2 +- core/protected/components/helpers.php | 1939 +++++++++++------ core/protected/components/zip.php | 2 + core/protected/config/wsver.php | 6 +- core/protected/controllers/CartController.php | 9 +- .../controllers/InstallController.php | 1 - .../controllers/LegacysoapController.php | 27 +- .../controllers/MyaccountController.php | 75 +- core/protected/controllers/SoapController.php | 8 +- .../umber/assets/customized/_base.scss | 224 -- .../umber/assets/customized/brooklyn2014.scss | 4 - .../extensions/umber/assets/docs.scss | 379 ---- .../umber/assets/lib/_clearfix-hack | 26 - .../umber/assets/lib/_normalize.scss | 408 ---- .../umber/assets/mixins/_animations.scss | 35 - .../umber/assets/mixins/_arrows.scss | 78 - .../umber/assets/mixins/_borders.scss | 6 - .../umber/assets/mixins/_flexbox.scss | 47 - .../assets/mixins/_html5-input-types.scss | 87 - .../umber/assets/mixins/_keyframes.scss | 15 - .../umber/assets/mixins/_placeholders.scss | 6 - .../umber/assets/mixins/_transitions.scss | 13 - .../extensions/umber/assets/modal/.DS_Store | Bin 12292 -> 0 bytes .../umber/assets/modal/_address_blocks.scss | 172 -- .../umber/assets/modal/_animations.scss | 40 - .../umber/assets/modal/_basic_modal.scss | 422 ---- .../assets/modal/_browsers_unistyle.scss | 16 - .../extensions/umber/assets/modal/_cart.scss | 481 ---- .../umber/assets/modal/_cartadd.scss | 440 ---- .../umber/assets/modal/_checkout.scss | 218 -- .../umber/assets/modal/_checkout_begin.scss | 70 - .../umber/assets/modal/_checkout_confirm.scss | 408 ---- .../umber/assets/modal/_checkout_forms.scss | 174 -- .../umber/assets/modal/_checkout_payment.scss | 405 ---- .../assets/modal/_checkout_shipping.scss | 108 - .../umber/assets/modal/_checkout_sidebar.scss | 136 -- .../assets/modal/_checkout_thankyou.scss | 199 -- .../umber/assets/modal/_config.scss | 154 -- .../umber/assets/modal/_estimator.scss | 308 --- .../extensions/umber/assets/modal/_icons.scss | 29 - .../extensions/umber/assets/modal/_lines.scss | 143 -- .../assets/modal/_modal_overlay_shared.scss | 439 ---- .../umber/assets/modal/_overlay.scss | 325 --- .../umber/assets/modal/_override_legacy.scss | 196 -- .../umber/assets/modal/_overview.scss | 177 -- .../extensions/umber/assets/modal/_print.scss | 31 - .../extensions/umber/assets/modal/_promo.scss | 109 - .../umber/assets/modal/_spinner.scss | 104 - .../extensions/umber/assets/modal/_tooltip | 34 - .../umber/assets/modal/_wishlist.scss | 228 -- .../umber/assets/modal/_wishlist_view.scss | 256 --- .../extensions/umber/assets/modal/modal.scss | 108 - .../umber/assets/theme/_config.scss | 76 - .../umber/assets/theme/_footer.scss | 153 -- .../umber/assets/theme/_header.scss | 89 - .../umber/assets/theme/_products.scss | 121 - .../umber/assets/theme/_search.scss | 13 - .../extensions/umber/assets/theme/basic.scss | 59 - .../extensions/umber/assets/wsmodal.js | 31 +- core/protected/extensions/wscron/wscron.php | 39 +- .../assets/flags/{cze.gif => cs.gif} | Bin .../assets/flags/{jp.gif => ja.gif} | Bin .../assets/flags/{swe.gif => sv.gif} | Bin .../extensions/wspayment/WsPayment.php | 4 +- .../extensions/wsshipping/WsShipping.php | 4 +- .../extensions/wsshipping/usps/usps.php | 334 ++- core/protected/extensions/wstheme/WsTheme.php | 7 +- core/protected/helpers/ImagesType.php | 14 +- ...01446_WS_3110_remove_schema_config_key.php | 35 + ..._160451_WS_3851_delete_abandoned_carts.php | 43 + ...9_WS_3851_add_index_xlsws_carts_id_str.php | 14 + .../migrations/m150317_151011_log_cleanup.php | 21 + core/protected/models/Cart.php | 146 +- core/protected/models/Customer.php | 246 ++- core/protected/models/Images.php | 54 +- core/protected/models/Log.php | 28 +- core/protected/models/Product.php | 34 +- core/protected/models/ProductQtyPricing.php | 19 +- core/protected/models/Tax.php | 117 +- core/protected/models/TaxCode.php | 5 +- core/protected/models/Wishlist.php | 126 +- core/protected/models/forms/LoginForm.php | 99 +- .../admin/controllers/SystemController.php | 49 +- .../admin/controllers/ThemeController.php | 4 +- .../admin/controllers/UpgradeController.php | 18 +- .../modules/admin/views/system/info.php | 9 - .../modules/admin/views/theme/manage.php | 27 +- .../views-cities3/myaccount/address.php | 7 +- .../views-cities3/myaccount/edit.php | 10 +- .../views-cities3/myaccount/password.php | 10 +- core/protected/views-cities3/search/index.php | 62 +- core/protected/views-cities3/site/login.php | 41 +- .../views-cities3/wishlist/_edititem.php | 78 +- .../views-cities3/wishlist/_sharelist.php | 54 +- .../views-cities3/wishlist/search.php | 80 +- images/README.md | 3 + images/breadcrumbs_home.png | Bin 3090 -> 0 bytes images/favicon-32x32.png | Bin 871 -> 0 bytes images/lock.png | Bin 259 -> 0 bytes images/ls-logo1002x.png | Bin 2639 -> 0 bytes images/webstore-logo2x.png | Bin 10270 -> 0 bytes 120 files changed, 4987 insertions(+), 9802 deletions(-) create mode 100644 composer.lock create mode 100755 composer.phar delete mode 100755 core/protected/extensions/umber/assets/customized/_base.scss delete mode 100644 core/protected/extensions/umber/assets/customized/brooklyn2014.scss delete mode 100755 core/protected/extensions/umber/assets/docs.scss delete mode 100644 core/protected/extensions/umber/assets/lib/_clearfix-hack delete mode 100755 core/protected/extensions/umber/assets/lib/_normalize.scss delete mode 100644 core/protected/extensions/umber/assets/mixins/_animations.scss delete mode 100644 core/protected/extensions/umber/assets/mixins/_arrows.scss delete mode 100644 core/protected/extensions/umber/assets/mixins/_borders.scss delete mode 100644 core/protected/extensions/umber/assets/mixins/_flexbox.scss delete mode 100755 core/protected/extensions/umber/assets/mixins/_html5-input-types.scss delete mode 100755 core/protected/extensions/umber/assets/mixins/_keyframes.scss delete mode 100644 core/protected/extensions/umber/assets/mixins/_placeholders.scss delete mode 100644 core/protected/extensions/umber/assets/mixins/_transitions.scss delete mode 100644 core/protected/extensions/umber/assets/modal/.DS_Store delete mode 100644 core/protected/extensions/umber/assets/modal/_address_blocks.scss delete mode 100755 core/protected/extensions/umber/assets/modal/_animations.scss delete mode 100755 core/protected/extensions/umber/assets/modal/_basic_modal.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_browsers_unistyle.scss delete mode 100755 core/protected/extensions/umber/assets/modal/_cart.scss delete mode 100755 core/protected/extensions/umber/assets/modal/_cartadd.scss delete mode 100755 core/protected/extensions/umber/assets/modal/_checkout.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_checkout_begin.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_checkout_confirm.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_checkout_forms.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_checkout_payment.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_checkout_shipping.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_checkout_sidebar.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_checkout_thankyou.scss delete mode 100755 core/protected/extensions/umber/assets/modal/_config.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_estimator.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_icons.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_lines.scss delete mode 100755 core/protected/extensions/umber/assets/modal/_modal_overlay_shared.scss delete mode 100755 core/protected/extensions/umber/assets/modal/_overlay.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_override_legacy.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_overview.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_print.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_promo.scss delete mode 100755 core/protected/extensions/umber/assets/modal/_spinner.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_tooltip delete mode 100755 core/protected/extensions/umber/assets/modal/_wishlist.scss delete mode 100644 core/protected/extensions/umber/assets/modal/_wishlist_view.scss delete mode 100755 core/protected/extensions/umber/assets/modal/modal.scss delete mode 100755 core/protected/extensions/umber/assets/theme/_config.scss delete mode 100755 core/protected/extensions/umber/assets/theme/_footer.scss delete mode 100755 core/protected/extensions/umber/assets/theme/_header.scss delete mode 100755 core/protected/extensions/umber/assets/theme/_products.scss delete mode 100755 core/protected/extensions/umber/assets/theme/_search.scss delete mode 100755 core/protected/extensions/umber/assets/theme/basic.scss rename core/protected/extensions/wslangflags/assets/flags/{cze.gif => cs.gif} (100%) rename core/protected/extensions/wslangflags/assets/flags/{jp.gif => ja.gif} (100%) rename core/protected/extensions/wslangflags/assets/flags/{swe.gif => sv.gif} (100%) create mode 100644 core/protected/migrations/m150304_201446_WS_3110_remove_schema_config_key.php create mode 100644 core/protected/migrations/m150312_160451_WS_3851_delete_abandoned_carts.php create mode 100644 core/protected/migrations/m150312_160529_WS_3851_add_index_xlsws_carts_id_str.php create mode 100644 core/protected/migrations/m150317_151011_log_cleanup.php create mode 100644 images/README.md delete mode 100644 images/breadcrumbs_home.png delete mode 100644 images/favicon-32x32.png delete mode 100644 images/lock.png delete mode 100644 images/ls-logo1002x.png delete mode 100644 images/webstore-logo2x.png diff --git a/composer.json b/composer.json index 21088460..d1d317f9 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "require-dev": { "phploc/phploc": "*", "phpmd/phpmd" : "@stable", - "phpunit/phpunit": "4.4.*", + "phpunit/phpunit": "4.4.1", "phpunit/phpunit-selenium": ">=1.2", "phpunit/dbunit": ">=1.2", "phpunit/phpunit-story": "*", diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..bca1f3db --- /dev/null +++ b/composer.lock @@ -0,0 +1,1778 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "b0dcbd828d2302b61c1c4c93209ee625", + "packages": [], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "2.0.*@ALPHA" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Instantiator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2014-10-13 12:58:55" + }, + { + "name": "nikic/php-parser", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "ac05ef6f95bf8361549604b6031c115f92f39528" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ac05ef6f95bf8361549604b6031c115f92f39528", + "reference": "ac05ef6f95bf8361549604b6031c115f92f39528", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "files": [ + "lib/bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2015-01-18 11:29:59" + }, + { + "name": "pdepend/pdepend", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/pdepend/pdepend.git", + "reference": "1b0acf162da4f30237987e61e177a57f78e3d87e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/1b0acf162da4f30237987e61e177a57f78e3d87e", + "reference": "1b0acf162da4f30237987e61e177a57f78e3d87e", + "shasum": "" + }, + "require": { + "symfony/config": ">=2.4", + "symfony/dependency-injection": ">=2.4", + "symfony/filesystem": ">=2.4" + }, + "require-dev": { + "phpunit/phpunit": "4.*@stable", + "squizlabs/php_codesniffer": "@stable" + }, + "bin": [ + "src/bin/pdepend" + ], + "type": "library", + "autoload": { + "psr-0": { + "PDepend\\": "src/main/php/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Official version of pdepend to be handled with Composer", + "time": "2014-12-04 12:38:39" + }, + { + "name": "phploc/phploc", + "version": "2.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phploc.git", + "reference": "322ad07c112d5c6832abed4269d648cacff5959b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/322ad07c112d5c6832abed4269d648cacff5959b", + "reference": "322ad07c112d5c6832abed4269d648cacff5959b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/finder-facade": "~1.1", + "sebastian/git": "~1.0", + "sebastian/version": "~1.0", + "symfony/console": "~2.2" + }, + "bin": [ + "phploc" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "A tool for quickly measuring the size of a PHP project.", + "homepage": "https://github.com/sebastianbergmann/phploc", + "time": "2014-06-25 08:11:02" + }, + { + "name": "phpmd/phpmd", + "version": "2.1.3", + "source": { + "type": "git", + "url": "https://github.com/phpmd/phpmd.git", + "reference": "1a485d9db869137af5e9678bd844568c92998b25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/1a485d9db869137af5e9678bd844568c92998b25", + "reference": "1a485d9db869137af5e9678bd844568c92998b25", + "shasum": "" + }, + "require": { + "pdepend/pdepend": "2.0.*", + "php": ">=5.3.0", + "symfony/config": "2.5.*", + "symfony/dependency-injection": "2.5.*", + "symfony/filesystem": "2.5.*" + }, + "bin": [ + "src/bin/phpmd" + ], + "type": "library", + "autoload": { + "psr-0": { + "PHPMD\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Official version of PHPMD handled with Composer.", + "time": "2014-09-25 15:56:22" + }, + { + "name": "phpunit/dbunit", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/dbunit.git", + "reference": "a5891b7a9c4f21587a51f9bc4e8f7042b741b480" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/a5891b7a9c4f21587a51f9bc4e8f7042b741b480", + "reference": "a5891b7a9c4f21587a51f9bc4e8f7042b741b480", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "ext-simplexml": "*", + "php": ">=5.3.3", + "phpunit/phpunit": ">=3.7.0@stable", + "symfony/yaml": ">=2.1.0" + }, + "bin": [ + "composer/bin/dbunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "DbUnit port for PHP/PHPUnit to support database interaction testing.", + "homepage": "https://github.com/sebastianbergmann/dbunit/", + "keywords": [ + "database", + "testing", + "xunit" + ], + "time": "2014-03-26 11:25:06" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.0.14", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca158276c1200cc27f5409a5e338486bc0b4fc94", + "reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "~1.0", + "sebastian/version": "~1.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4.1" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2014-12-26 13:28:33" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.3.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "File/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2013-10-10 15:34:57" + }, + { + "name": "phpunit/php-invoker", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "8696484458cb43eed025ab46260846de5b74655c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/8696484458cb43eed025ab46260846de5b74655c", + "reference": "8696484458cb43eed025ab46260846de5b74655c", + "shasum": "" + }, + "require": { + "ext-pcntl": "*", + "php": ">=5.2.7", + "phpunit/php-timer": ">=1.0.4,<1.1.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for invoking callables with a timeout.", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "time": "2013-07-16 05:20:21" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2014-01-30 17:20:04" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2013-08-02 07:42:54" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74", + "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2015-01-17 09:51:32" + }, + { + "name": "phpunit/phpunit", + "version": "4.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "6a5e49a86ce5e33b8d0657abe145057fc513543a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6a5e49a86ce5e33b8d0657abe145057fc513543a", + "reference": "6a5e49a86ce5e33b8d0657abe145057fc513543a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpunit/php-code-coverage": "~2.0", + "phpunit/php-file-iterator": "~1.3.2", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "~1.0.2", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.0", + "sebastian/diff": "~1.1", + "sebastian/environment": "~1.1", + "sebastian/exporter": "~1.0", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2014-12-28 07:57:05" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "c63d2367247365f688544f0d500af90a11a44c65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65", + "reference": "c63d2367247365f688544f0d500af90a11a44c65", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "~1.0,>=1.0.1", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.3" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2014-10-03 05:12:11" + }, + { + "name": "phpunit/phpunit-selenium", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/giorgiosironi/phpunit-selenium.git", + "reference": "c84dd7ca214563868ce216123b7ae9c792beb262" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/giorgiosironi/phpunit-selenium/zipball/c84dd7ca214563868ce216123b7ae9c792beb262", + "reference": "c84dd7ca214563868ce216123b7ae9c792beb262", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-dom": "*", + "php": ">=5.3.3", + "phpunit/phpunit": "~3.7|~4.0", + "sebastian/comparator": "~1.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + }, + { + "name": "Giorgio Sironi", + "email": "info@giorgiosironi.com", + "role": "developer" + } + ], + "description": "Selenium Server integration for PHPUnit", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "selenium", + "testing", + "xunit" + ], + "time": "2014-11-02 09:23:27" + }, + { + "name": "phpunit/phpunit-story", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/phpunit/phpunit-story.git", + "reference": "b8579ada6ede4fd2f4b49e8549a8a176606cae68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpunit/phpunit-story/zipball/b8579ada6ede4fd2f4b49e8549a8a176606cae68", + "reference": "b8579ada6ede4fd2f4b49e8549a8a176606cae68", + "shasum": "" + }, + "require": { + "ext-spl": "*", + "php": ">=5.2.7", + "phpunit/phpunit": ">=3.6.0RC1@stable" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Story extension for PHPUnit to facilitate Behaviour-Driven Development.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "BDD", + "TDD", + "xunit" + ], + "time": "2013-04-02 16:07:28" + }, + { + "name": "sebastian/comparator", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "c484a80f97573ab934e37826dba0135a3301b26a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c484a80f97573ab934e37826dba0135a3301b26a", + "reference": "c484a80f97573ab934e37826dba0135a3301b26a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.1", + "sebastian/exporter": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2014-11-16 21:32:38" + }, + { + "name": "sebastian/diff", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "5843509fed39dee4b356a306401e9dd1a931fec7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7", + "reference": "5843509fed39dee4b356a306401e9dd1a931fec7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2014-08-15 10:29:00" + }, + { + "name": "sebastian/environment", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e6c71d918088c251b181ba8b3088af4ac336dd7", + "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2014-10-25 08:00:45" + }, + { + "name": "sebastian/exporter", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c7d59948d6e82818e1bdff7cadb6c34710eb7dc0", + "reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2014-09-10 00:51:36" + }, + { + "name": "sebastian/finder-facade", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/finder-facade.git", + "reference": "1e396fda3449fce9df032749fa4fa2619e0347e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/1e396fda3449fce9df032749fa4fa2619e0347e0", + "reference": "1e396fda3449fce9df032749fa4fa2619e0347e0", + "shasum": "" + }, + "require": { + "symfony/finder": ">=2.2.0", + "theseer/fdomdocument": ">=1.3.1" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", + "homepage": "https://github.com/sebastianbergmann/finder-facade", + "time": "2013-05-28 06:10:03" + }, + { + "name": "sebastian/git", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/git.git", + "reference": "a99fbc102e982c1404041ef3e4d431562b29bcba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/git/zipball/a99fbc102e982c1404041ef3e4d431562b29bcba", + "reference": "a99fbc102e982c1404041ef3e4d431562b29bcba", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple wrapper for Git", + "homepage": "http://www.github.com/sebastianbergmann/git", + "keywords": [ + "git" + ], + "time": "2013-08-04 09:35:29" + }, + { + "name": "sebastian/global-state", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2014-10-06 09:23:50" + }, + { + "name": "sebastian/version", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/a77d9123f8e809db3fbdea15038c27a95da4058b", + "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2014-12-15 14:25:24" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "b301c98f19414d836fdaa678648745fcca5aeb4f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/b301c98f19414d836fdaa678648745fcca5aeb4f", + "reference": "b301c98f19414d836fdaa678648745fcca5aeb4f", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.1.2" + }, + "bin": [ + "scripts/phpcs", + "scripts/phpcbf" + ], + "type": "library", + "autoload": { + "classmap": [ + "CodeSniffer.php", + "CodeSniffer/CLI.php", + "CodeSniffer/Exception.php", + "CodeSniffer/File.php", + "CodeSniffer/Fixer.php", + "CodeSniffer/Report.php", + "CodeSniffer/Reporting.php", + "CodeSniffer/Sniff.php", + "CodeSniffer/Tokens.php", + "CodeSniffer/Reports/", + "CodeSniffer/Tokenizers/", + "CodeSniffer/DocGenerators/", + "CodeSniffer/Standards/AbstractPatternSniff.php", + "CodeSniffer/Standards/AbstractScopeSniff.php", + "CodeSniffer/Standards/AbstractVariableSniff.php", + "CodeSniffer/Standards/IncorrectPatternException.php", + "CodeSniffer/Standards/Generic/Sniffs/", + "CodeSniffer/Standards/MySource/Sniffs/", + "CodeSniffer/Standards/PEAR/Sniffs/", + "CodeSniffer/Standards/PSR1/Sniffs/", + "CodeSniffer/Standards/PSR2/Sniffs/", + "CodeSniffer/Standards/Squiz/Sniffs/", + "CodeSniffer/Standards/Zend/Sniffs/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "http://www.squizlabs.com/php-codesniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2015-01-21 22:44:05" + }, + { + "name": "symfony/config", + "version": "v2.5.9", + "target-dir": "Symfony/Component/Config", + "source": { + "type": "git", + "url": "https://github.com/symfony/Config.git", + "reference": "c7309e33b719433d5cf3845d0b5b9608609d8c8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Config/zipball/c7309e33b719433d5cf3845d0b5b9608609d8c8e", + "reference": "c7309e33b719433d5cf3845d0b5b9608609d8c8e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/filesystem": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Config\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Config Component", + "homepage": "http://symfony.com", + "time": "2015-01-03 08:01:13" + }, + { + "name": "symfony/console", + "version": "v2.6.3", + "target-dir": "Symfony/Component/Console", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "6ac6491ff60c0e5a941db3ccdc75a07adbb61476" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/6ac6491ff60c0e5a941db3ccdc75a07adbb61476", + "reference": "6ac6491ff60c0e5a941db3ccdc75a07adbb61476", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/process": "~2.1" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Console Component", + "homepage": "http://symfony.com", + "time": "2015-01-06 17:50:02" + }, + { + "name": "symfony/dependency-injection", + "version": "v2.5.9", + "target-dir": "Symfony/Component/DependencyInjection", + "source": { + "type": "git", + "url": "https://github.com/symfony/DependencyInjection.git", + "reference": "b04e6782962f8e3312274fd16fb6b37a8210a1c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/b04e6782962f8e3312274fd16fb6b37a8210a1c3", + "reference": "b04e6782962f8e3312274fd16fb6b37a8210a1c3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/config": "~2.2", + "symfony/expression-language": "~2.4,>=2.4.10", + "symfony/yaml": "~2.1" + }, + "suggest": { + "symfony/config": "", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\DependencyInjection\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "http://symfony.com", + "time": "2015-01-05 08:51:41" + }, + { + "name": "symfony/filesystem", + "version": "v2.5.9", + "target-dir": "Symfony/Component/Filesystem", + "source": { + "type": "git", + "url": "https://github.com/symfony/Filesystem.git", + "reference": "d3c24d7d6e9c342008d8421b2fade460311647ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/d3c24d7d6e9c342008d8421b2fade460311647ea", + "reference": "d3c24d7d6e9c342008d8421b2fade460311647ea", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Filesystem\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "http://symfony.com", + "time": "2015-01-03 21:04:44" + }, + { + "name": "symfony/finder", + "version": "v2.6.3", + "target-dir": "Symfony/Component/Finder", + "source": { + "type": "git", + "url": "https://github.com/symfony/Finder.git", + "reference": "16513333bca64186c01609961a2bb1b95b5e1355" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Finder/zipball/16513333bca64186c01609961a2bb1b95b5e1355", + "reference": "16513333bca64186c01609961a2bb1b95b5e1355", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Finder\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Finder Component", + "homepage": "http://symfony.com", + "time": "2015-01-03 08:01:59" + }, + { + "name": "symfony/yaml", + "version": "v2.6.3", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "82462a90848a52c2533aa6b598b107d68076b018" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/82462a90848a52c2533aa6b598b107d68076b018", + "reference": "82462a90848a52c2533aa6b598b107d68076b018", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2015-01-03 15:33:07" + }, + { + "name": "theseer/directoryscanner", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/DirectoryScanner.git", + "reference": "b1406a99f5e4b1761c84d9e98127c03871bb7b0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/DirectoryScanner/zipball/b1406a99f5e4b1761c84d9e98127c03871bb7b0e", + "reference": "b1406a99f5e4b1761c84d9e98127c03871bb7b0e", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A recursive directory scanner and filter", + "time": "2014-11-25 14:27:49" + }, + { + "name": "theseer/fdomdocument", + "version": "1.6.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/fDOMDocument.git", + "reference": "d08cf070350f884c63fc9078d27893c2ab6c7cef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/d08cf070350f884c63fc9078d27893c2ab6c7cef", + "reference": "d08cf070350f884c63fc9078d27893c2ab6c7cef", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "lib-libxml": "*", + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "lead" + } + ], + "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", + "homepage": "https://github.com/theseer/fDOMDocument", + "time": "2014-09-13 10:57:19" + }, + { + "name": "theseer/fxsl", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/fXSL.git", + "reference": "a9246376c713156e55c080782d4104bb07d4b899" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/fXSL/zipball/a9246376c713156e55c080782d4104bb07d4b899", + "reference": "a9246376c713156e55c080782d4104bb07d4b899", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xsl": "*", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "An XSL wrapper / extension to the PHP 5.x XSLTProcessor with Exception and extended Callback support", + "time": "2014-11-27 20:08:52" + }, + { + "name": "theseer/phpdox", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/theseer/phpdox.git", + "reference": "0693cc0d7dcbb5651fe8cbc768dee50ee611c6d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/phpdox/zipball/0693cc0d7dcbb5651fe8cbc768dee50ee611c6d0", + "reference": "0693cc0d7dcbb5651fe8cbc768dee50ee611c6d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-iconv": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xsl": "*", + "nikic/php-parser": ">=1.0.2", + "php": ">=5.3.3", + "phpunit/php-timer": ">=1.0.4", + "theseer/directoryscanner": ">=1.3.0", + "theseer/fdomdocument": ">=1.6.0", + "theseer/fxsl": ">=1.1" + }, + "bin": [ + "phpdox" + ], + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A fast Documentation generator for PHP Code using standard technology (SRC, DOCBLOCK, XML and XSLT) with event based processing", + "time": "2015-01-15 16:57:14" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "phpmd/phpmd": 0, + "theseer/phpdox": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/composer.phar b/composer.phar new file mode 100755 index 0000000000000000000000000000000000000000..8ad22b591aec501e1f04e5440f6f82044e7583e5 GIT binary patch literal 1049776 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

DZ{(l@N9N%k?T1 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…bv_U>?h)~Bm<^%O)br{ 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

+uF*qZ}9pKU7|j4aPZ3QJ8bolNtQ4l6R@L{g9Y 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 PfBpXLQLon<#AW;!WECnl literal 0 HcmV?d00001 diff --git a/core/protected/commands/HostingMigrateCommand.php b/core/protected/commands/HostingMigrateCommand.php index 0f150fa6..b21fd93e 100644 --- a/core/protected/commands/HostingMigrateCommand.php +++ b/core/protected/commands/HostingMigrateCommand.php @@ -45,37 +45,89 @@ class HostingMigrateCommand extends MigrateCommand */ public function beforeAction($action, $params) { - if (empty($this->dbhost) || - empty($this->dbuser) || - empty($this->dbpass) || - empty($this->dbname) || - empty($this->hosting) || - !$this->validHostingSwitch($this->hosting) + if ($this->validHostingSwitch($this->hosting) === false || + $this->validateDbCliArgs($action) === false ) { - echo "\n*error halting*\n\n usage: yiic hostingmigrate $action --dbhost=127.0.0.1 --dbuser=root --dbpass=mypass --dbname=webstore --hosting=M\n\n"; - echo " Note, --hosting flag can take one of three values: M for Multi-tenant, S for Single tenant, and T for Multi-tenant staging\n"; - echo " These flags will set configuration keys specific to those environments.\n"; - echo "\n"; return false; } - $this->setDbForMigration(); - $this->connectionID = "dbmt"; $this->migrationTable = 'xlsws_migrations'; return parent::beforeAction($action, $params); - } + /** + * Ensure the --hosting command line argument is present and valid. + * If not, display an error message. + * + * @param $str + * @return bool + */ protected function validHostingSwitch($str) { - $arrAllowed = array('M','T','S'); - return in_array($str,$arrAllowed); + $strError = "\n*error halting*\n"; + $strError .= "\t--hosting flag takes one of three values:\n"; + $strError .= "\tM for Multi-tenant (Retail), T for Multi-tenant staging (Retail), S for Single tenant (Onsite), and N for Non-Hosted (Onsite)\n"; + + if (empty($str)) + { + $strError .= "\t--hosting flag MUST be present.\n\n"; + echo $strError; + return false; + } + + $arrAllowed = array('M','T','S','N'); + if (in_array($str, $arrAllowed) === false) + { + echo $strError . "\n"; + return false; + } + + return true; } + /** - * Establish database component for multitenant. + * Ensure the required database credentials are present if passed on the command line: + * If not, display an error + * + * @param $action + * @return bool + */ + protected function validateDbCliArgs($action) + { + // if any one of these is present... + if (!empty($this->dbhost) || + !empty($this->dbuser) || + !empty($this->dbpass) || + !empty($this->dbname) + ) + { + // ...then they must ALL be present + if (empty($this->dbhost) || + empty($this->dbuser) || + empty($this->dbpass) || + empty($this->dbname) + ) + { + echo "\n*error halting*\n"; + echo "\tusage: yiic hostingmigrate $action --dbhost=127.0.0.1 --dbuser=root --dbpass=mypass --dbname=webstore --hosting=M\n"; + echo "\t--hosting flag takes one of three values:\n"; + echo "\tM for Multi-tenant (Retail), T for Multi-tenant staging (Retail), S for Single tenant (Onsite), and N for Non-Hosted (Onsite)\n\n"; + echo "You must include all database credentials when passing them.\n"; + echo "Or else,\n\n\tusage: yiic hostingmigrate $action --hosting=M --interactive=0\n\n"; + return false; + } + + $this->setDbForMigration(); + $this->connectionID = "dbmt"; + } + + return true; + } + /** + * Establish database component for passed in credentials. * * @return void */ @@ -103,36 +155,47 @@ protected function setDbForMigration() */ public function actionUp($args) { + $component = $this->connectionID; + switch ($this->hosting) { case 'S': - $intVer = Yii::app()->dbmt->createCommand("SELECT key_value FROM xlsws_configuration WHERE `key_name` = 'DATABASE_SCHEMA_VERSION'")->queryScalar(); + + $intVer = Yii::app()->$component->createCommand("SELECT key_value FROM xlsws_configuration WHERE `key_name` = 'DATABASE_SCHEMA_VERSION'")->queryScalar(); if($intVer !== false && (int)$intVer < 447) - { - // Override certain migrations to support legacy schema order - $this->migrationPath = Yii::getPathOfAlias('application.migrations.legacy'); - // Execute yii migrations - parent::actionUp($args); - - // Point to standard migrations for next migration leg - $this->migrationPath = Yii::getPathOfAlias('application.migrations'); - - // Reset migration position to non-legacy - Yii::app()->db->createCommand()->truncateTable('xlsws_migrations'); - $this->actionMark(array('m140429_224114_update_configuration')); + { + // Override certain migrations to support legacy schema order + $this->migrationPath = Yii::getPathOfAlias('application.migrations.legacy'); + // Execute yii migrations + parent::actionUp($args); + + // Point to standard migrations for next migration leg + $this->migrationPath = Yii::getPathOfAlias('application.migrations'); + + // Reset migration position to non-legacy + Yii::app()->$component->createCommand()->truncateTable('xlsws_migrations'); + + $this->actionMark(array('m140429_224114_update_configuration')); } parent::actionUp($args); - Yii::app()->dbmt->createCommand("UPDATE xlsws_configuration SET `key_value` = 1 WHERE `key_name` = 'LIGHTSPEED_HOSTING'")->execute(); - Yii::app()->dbmt->createCommand("UPDATE xlsws_configuration SET `key_value` = 1 WHERE `key_name` = 'ENABLE_SSL'")->execute(); + Yii::app()->$component->createCommand("UPDATE xlsws_configuration SET `key_value` = 1 WHERE `key_name` = 'LIGHTSPEED_HOSTING'")->execute(); + Yii::app()->$component->createCommand("UPDATE xlsws_configuration SET `key_value` = 1 WHERE `key_name` = 'ENABLE_SSL'")->execute(); break; case 'M': case 'T': parent::actionUp($args); - Yii::app()->dbmt->createCommand("UPDATE xlsws_configuration SET `key_value` = 1 WHERE `key_name` = 'LIGHTSPEED_MT'")->execute(); - Yii::app()->dbmt->createCommand("UPDATE xlsws_configuration SET `key_value` = 1 WHERE `key_name` = 'LIGHTSPEED_HOSTING'")->execute(); - Yii::app()->dbmt->createCommand("UPDATE xlsws_configuration SET `key_value` = 1 WHERE `key_name` = 'ENABLE_SSL'")->execute(); + Yii::app()->$component->createCommand("UPDATE xlsws_configuration SET `key_value` = 1 WHERE `key_name` = 'LIGHTSPEED_MT'")->execute(); + Yii::app()->$component->createCommand("UPDATE xlsws_configuration SET `key_value` = 1 WHERE `key_name` = 'LIGHTSPEED_HOSTING'")->execute(); + Yii::app()->$component->createCommand("UPDATE xlsws_configuration SET `key_value` = 1 WHERE `key_name` = 'ENABLE_SSL'")->execute(); + break; + + case 'N': + // yiic hostingmigrate up --hosted=N === yiic migrate up + // i.e. if no command line arguments defining a specific database + // are present, this does the same thing as yiic migrate up + parent::actionUp($args); break; } } diff --git a/core/protected/components/ApplicationComponent.php b/core/protected/components/ApplicationComponent.php index dd5db151..bf293bec 100644 --- a/core/protected/components/ApplicationComponent.php +++ b/core/protected/components/ApplicationComponent.php @@ -2,11 +2,9 @@ /* * Empty event handlers so we can extend without causing errors */ -class ApplicationComponent extends CApplicationComponent { - - - - //For CEventProduct,CEventPhoto,CEventOrder +class ApplicationComponent extends CApplicationComponent +{ + // For CEventProduct,CEventPhoto,CEventOrder. public function onSaveProduct($event) {} public function onUpdateInventory($event) {} public function onActionProductView($event) {} @@ -24,6 +22,4 @@ public function onActionVerifyProductUpdate($event) {} public function onActionListOrders($event) {} public function onFlushTable($event) {} - - -} \ No newline at end of file +} diff --git a/core/protected/components/Checkout.php b/core/protected/components/Checkout.php index 615f5798..378853cd 100644 --- a/core/protected/components/Checkout.php +++ b/core/protected/components/Checkout.php @@ -82,7 +82,7 @@ public static function emailReceipts($objCart) $objEmail->htmlbody = $strHtmlBody; $objEmail->cart_id = $objCart->id; $objEmail->subject = $strSubject; - $orderEmail = _xls_get_conf('ORDER_FROM',''); + $orderEmail = _xls_get_conf('ORDER_FROM', ''); $objEmail->to = empty($orderEmail) ? _xls_get_conf('EMAIL_FROM') : $orderEmail; // If we get back false, it means conversion failed which 99.9% of diff --git a/core/protected/components/Controller.php b/core/protected/components/Controller.php index fc84f472..e84cb67c 100644 --- a/core/protected/components/Controller.php +++ b/core/protected/components/Controller.php @@ -9,24 +9,24 @@ class Controller extends CController * @var string the default layout for the controller view. Defaults to '//layouts/column1', * meaning using a single column layout. See 'protected/views/layouts/column1.php'. */ - public $layout='//layouts/column2'; + public $layout = '//layouts/column2'; + /** * @var array context menu items. This property will be assigned to {@link CMenu::items}. */ - public $menu=array(); + public $menu = array(); + /** * @var array the breadcrumbs of the current page. The value of this property will * be assigned to {@link CBreadcrumbs::links}. Please refer to {@link CBreadcrumbs::links} * for more details on how to specify this property. */ - public $breadcrumbs=array(); + public $breadcrumbs = array(); public $menuwidget; protected $_canonicalUrl; - public $LoadSharing=0; - /* These are public variables that are used in our layout, so we have to define them. */ public $pageDescription; @@ -49,11 +49,15 @@ class Controller extends CController public $gridProductsPerRow = 3; public $gridProductsRows; + + // @codingStandardsIgnoreStart - this variable is used in view files, + // cannot easily be changed. public $custom_page_content; + // @codingStandardsIgnoreEnd /* Support lightweight repeated calls to getMenuTree by caching the result * for the lifetime of the component object. */ - private $objFullTree = null; + private $_objFullTree = null; /** * Dynamically load the configuration settings for the client and @@ -63,25 +67,32 @@ public static function initParams() { defined('DEFAULT_THEME') or define('DEFAULT_THEME', 'brooklyn2014'); - $Params = CHtml::listData(Configuration::model()->findAll(),'key_name','key_value'); + $params = CHtml::listData(Configuration::model()->findAll(), 'key_name', 'key_value'); - foreach ($Params as $key => $value) + foreach ($params as $key => $value) { Yii::app()->params->add($key, $value); } if(isset(Yii::app()->params['THEME'])) - Yii::app()->theme=Yii::app()->params['THEME']; - else Yii::app()->theme=DEFAULT_THEME; + { + Yii::app()->theme = Yii::app()->params['THEME']; + } else { + Yii::app()->theme = DEFAULT_THEME; + } + if(isset(Yii::app()->params['LANG_CODE'])) - Yii::app()->language=Yii::app()->params['LANG_CODE']; - else Yii::app()->language = "en"; - Yii::app()->params->add('listPerPage',Yii::app()->params['PRODUCTS_PER_PAGE']); + { + Yii::app()->language = Yii::app()->params['LANG_CODE']; + } else { + Yii::app()->language = "en"; + } + + Yii::app()->params->add('listPerPage', Yii::app()->params['PRODUCTS_PER_PAGE']); //Based on logging setting, set log level dynamically and possibly turn on debug mode switch (Yii::app()->params['DEBUG_LOGGING']) { - case 'info': $logLevel = "error,warning,info"; break; @@ -94,17 +105,18 @@ public static function initParams() default: $logLevel = "error,warning"; break; - } foreach(Yii::app()->getComponent('log')->routes as $route) + { $route->levels = $logLevel; + } Yii::app()->setViewPath(Yii::getPathOfAlias('application')."/views-cities"); - Yii::app()->name = Yii::app()->params['STORE_NAME']; + Yii::app()->name = Yii::app()->params['STORE_NAME']; - if(Yii::app()->params['LIGHTSPEED_CLOUD']=='-1') + if(Yii::app()->params['LIGHTSPEED_CLOUD'] == '-1') { //We should never see this, this means our cloud cache file is bad $strHostfile = realpath(dirname(__FILE__)).'/../../../config/cloud/'.$_SERVER['HTTP_HOST'].".php"; @@ -112,7 +124,6 @@ public static function initParams() Yii::app()->request->redirect(Yii::app()->createUrl('site/index')); } - } /** * Load anything we need globally, such as items we're going to use in our main.php template. @@ -125,32 +136,41 @@ public function init() self::initParams(); if(isset($_GET['nosni'])) - Yii::app()->user->setFlash('warning',Yii::t('global','NOTE: Your older operating system does not support certain security features this site uses. You have been redirected to {link} for your session which will ensure your information is properly protected.',array('{link}'=>"".Yii::app()->params['LIGHTSPEED_HOSTING_LIGHTSPEED_URL'].""))); + { + Yii::app()->user->setFlash('warning', Yii::t('global', 'NOTE: Your older operating system does not support certain security features this site uses. You have been redirected to {link} for your session which will ensure your information is properly protected.', array('{link}' => "".Yii::app()->params['LIGHTSPEED_HOSTING_LIGHTSPEED_URL'].""))); + } $filename = Yii::getPathOfAlias('webroot.themes').DIRECTORY_SEPARATOR.DEFAULT_THEME; - if(!file_exists($filename) && _xls_get_conf('LIGHTSPEED_MT',0)=='0') + if(!file_exists($filename) && _xls_get_conf('LIGHTSPEED_MT', 0) == '0') { if(!downloadTheme(DEFAULT_THEME)) + { die("missing ".DEFAULT_THEME); + } else + { $this->redirect(Yii::app()->createUrl("site/index")); + } } + if(!Yii::app()->theme) { if(_xls_get_conf('THEME')) { //We can't find our theme for some reason, switch back to default _xls_set_conf('THEME', DEFAULT_THEME); - _xls_set_conf('CHILD_THEME','light'); + _xls_set_conf('CHILD_THEME', 'light'); Yii::log( "Couldn't find our theme, switched back to " . DEFAULT_THEME . " for emergency", 'error', 'application.' . __CLASS__ . "." . __FUNCTION__ ); $this->redirect(Yii::app()->createUrl('site/index')); - - } else + } + else + { die("you have no theme set"); + } } if (isset($_GET['theme']) && isset($_GET['themekey'])) @@ -175,19 +195,23 @@ public function init() $this->buildBootstrap(); if(_xls_facebook_login()) + { $this->getFacebookLogin(); + } if (Yii::app()->params['STORE_OFFLINE'] != '0' || Yii::app()->params['INSTALLED'] != '1') { if (isset($_GET['offline'])) + { Yii::app()->session['STORE_OFFLINE'] = _xls_number_only($_GET['offline']); + } //If uninstalled on a new Multitenant store, direct to license acceptance to get going if (Yii::app()->params['INSTALLED'] != '1' && Yii::app()->params['LIGHTSPEED_MT'] == '1') { $url = Yii::app()->createUrl("admin/license"); - $url = str_replace("https:","http:",$url); - $this->redirect($url,true); + $url = str_replace("https:", "http:", $url); + $this->redirect($url, true); } if (Yii::app()->session['STORE_OFFLINE'] != Yii::app()->params['STORE_OFFLINE'] || @@ -202,16 +226,22 @@ public function init() $strViewset = Yii::app()->theme->info->viewset; if(!empty($strViewset)) + { Yii::app()->setViewPath(Yii::getPathOfAlias('application')."/views-".$strViewset); + } $strLayoutFile = Yii::app()->theme->config->layoutFile; if(empty($strLayoutFile)) + { $strLayoutFile = "column2"; //This is for backwards compatibility only + } if(Yii::app()->theme && file_exists('webroot.themes.'.Yii::app()->theme->name.'.layouts.'.$strLayoutFile)) - $this->layout='webroot.themes.'.Yii::app()->theme->name.'.layouts.'.$strLayoutFile; - else + { + $this->layout = 'webroot.themes.'.Yii::app()->theme->name.'.layouts.'.$strLayoutFile; + } else { $this->layout = $strLayoutFile; + } //Set defaults $this->getUserLanguage(); @@ -223,9 +253,9 @@ public function init() $pageHeaderImage = Yii::app()->params['HEADER_IMAGE']; - if (substr($pageHeaderImage,0,4) != "http") + if (substr($pageHeaderImage, 0, 4) != "http") { - if (substr($pageHeaderImage,0,2) != "//") + if (substr($pageHeaderImage, 0, 2) != "//") { $this->pageAbsoluteHeaderImage = Yii::app()->createAbsoluteUrl($pageHeaderImage, array(), Yii::app()->params['ENABLE_SSL'] ? 'https' : 'http'); // we prefix with baseUrl to handle instances where Web Store is installed in a sub folder @@ -237,10 +267,7 @@ public function init() $this->pageAbsoluteHeaderImage = Yii::app()->params['ENABLE_SSL'] ? 'https:' . $pageHeaderImage : 'http:' . $pageHeaderImage; $this->pageHeaderImage = $pageHeaderImage; } - } - - else - { + } else { $this->pageAbsoluteHeaderImage = $pageHeaderImage; $this->pageHeaderImage = $pageHeaderImage; } @@ -251,14 +278,14 @@ public function init() //Run other functions to create some data we always need $this->buildGoogle(); $this->buildSidebars(); - if (_xls_get_conf('SHOW_SHARING',0)) + if (_xls_get_conf('SHOW_SHARING', 0)) + { $this->buildSharing(); + } $this->buildAccessWarning(); - $this->gridProductsPerRow = _xls_get_conf('PRODUCTS_PER_ROW',3); - - + $this->gridProductsPerRow = _xls_get_conf('PRODUCTS_PER_ROW', 3); Yii::app()->clientScript->registerMetaTag( "Lightspeed Web Store " . XLSWS_VERSION, @@ -273,19 +300,23 @@ public function init() * Default canonical url generator, will remove all get params beside 'id' and generates an absolute url. * If the canonical url was already set in a child controller, it will be taken instead. */ - public function getCanonicalUrl() { - if ($this->_canonicalUrl === null) { + public function getCanonicalUrl() + { + if ($this->_canonicalUrl === null) + { $params = array(); - if (isset($_GET['id'])) { + if (isset($_GET['id'])) + { //just keep the id, because it identifies our model pages $params = array('id' => $_GET['id']); } + $this->_canonicalUrl = Yii::app()->createAbsoluteUrl($this->route, $params); } + return $this->_canonicalUrl; } - /** * Override URL if needed */ @@ -293,10 +324,8 @@ public function setCanonicalUrl($strUrl) { $this->_canonicalUrl = $strUrl; } - protected function getUserLanguage() { - $app = Yii::app(); if (isset($_POST['_lang'])) @@ -316,8 +345,8 @@ protected function getUserLanguage() else { // 'fr_FR' becomes 'fr' - $app->language = substr(Yii::app()->getRequest()->getPreferredLanguage(),0,2); - $app->session['_lang'] = substr(Yii::app()->getRequest()->getPreferredLanguage(),0,2); + $app->language = substr(Yii::app()->getRequest()->getPreferredLanguage(), 0, 2); + $app->session['_lang'] = substr(Yii::app()->getRequest()->getPreferredLanguage(), 0, 2); } } @@ -331,11 +360,14 @@ protected function buildGoogle() { $this->pageGoogleVerify = _xls_get_conf('GOOGLE_VERIFY'); $this->pageGoogleFonts = _xls_get_conf('GOOGLE_FONTS_LINK'); + if (Yii::app()->theme->info->GoogleFonts) + { $this->pageGoogleFonts .= ''; + } - $this->pageGoogleFonts = str_replace("http://","//",$this->pageGoogleFonts); + $this->pageGoogleFonts = str_replace("http://", "//", $this->pageGoogleFonts); } /** @@ -350,23 +382,21 @@ protected function buildSidebars() { } protected function buildSharing() { - $this->sharingHeader = $this->renderPartial('/site/_sharing_header',null,true); - $this->sharingFooter = $this->renderPartial('/site/_sharing_footer',null,true); - - + $this->sharingHeader = $this->renderPartial('/site/_sharing_header', null, true); + $this->sharingFooter = $this->renderPartial('/site/_sharing_footer', null, true); } protected function buildBootstrap() { - Yii::setPathOfAlias('bootstrap',null); + Yii::setPathOfAlias('bootstrap', null); $strBootstrap = Yii::app()->theme->info->bootstrap; if(!isset($strBootstrap)) { - Yii::app()->setComponent('bootstrap',array( - 'class'=>'ext.bootstrap.components.Bootstrap', - 'responsiveCss'=>true, + Yii::app()->setComponent('bootstrap', array( + 'class' => 'ext.bootstrap.components.Bootstrap', + 'responsiveCss' => true, )); Yii::setPathOfAlias('bootstrap', dirname(__FILE__).DIRECTORY_SEPARATOR.'../extensions/bootstrap'); Yii::app()->bootstrap->init(); @@ -381,25 +411,25 @@ protected function buildBootstrap() 'bootstrap', dirname(__FILE__).DIRECTORY_SEPARATOR.'../extensions/'.Yii::app()->theme->info->bootstrap ); - Yii::app()->setComponent('bootstrap',array( - 'class'=>'ext.'.Yii::app()->theme->info->bootstrap.'.components.Bootstrap' + Yii::app()->setComponent('bootstrap', array( + 'class' => 'ext.'.Yii::app()->theme->info->bootstrap.'.components.Bootstrap' )); Yii::app()->bootstrap->init(); } - } protected function buildAccessWarning() { try { - Yii::app()->setComponent('wsaccesswarning' ,array( - 'class'=>'ext.wsaccesswarning.wsaccesswarning' + Yii::app()->setComponent('wsaccesswarning', array( + 'class' => 'ext.wsaccesswarning.wsaccesswarning' )); Yii::app()->wsaccesswarning->displayAccessWarning(); } + catch(Exception $ex) { Yii::log("Failed to load wsaccesswarning extension", 'error', 'application.'.__CLASS__.".".__FUNCTION__); @@ -413,18 +443,18 @@ protected function getloginDialog() { /* This is our modal login dialog box */ if (Yii::app()->user->isGuest) { - $this->beginWidget('zii.widgets.jui.CJuiDialog',array( - 'id'=>'LoginForm', - 'options'=>array( - 'title'=>Yii::t('global','Redirecting to Login...'), - 'autoOpen'=>false, - 'modal'=>'true', - 'width'=>'300', - 'height'=>'0', - 'resizable'=>false, - 'position'=>'center', - 'draggable'=>false, - 'open'=>'js:function(){window.location.href="'.$this->createUrl("site/login").'";}', + $this->beginWidget('zii.widgets.jui.CJuiDialog', array( + 'id' => 'LoginForm', + 'options' => array( + 'title' => Yii::t('global', 'Redirecting to Login...'), + 'autoOpen' => false, + 'modal' => 'true', + 'width' => '300', + 'height' => '0', + 'resizable' => false, + 'position' => 'center', + 'draggable' => false, + 'open' => 'js:function(){window.location.href="'.$this->createUrl("site/login").'";}', ), )); @@ -440,16 +470,15 @@ protected function getFacebookLogin() //Facebook integration $fbArray = require(YiiBase::getPathOfAlias('application.config').'/_wsfacebook.php'); - $fbArray['appId']=Yii::app()->params['FACEBOOK_APPID']; - $fbArray['secret']=Yii::app()->params['FACEBOOK_SECRET']; - Yii::app()->setComponent('facebook',$fbArray); - + $fbArray['appId'] = Yii::app()->params['FACEBOOK_APPID']; + $fbArray['secret'] = Yii::app()->params['FACEBOOK_SECRET']; + Yii::app()->setComponent('facebook', $fbArray); if (Yii::app()->user->isGuest) { $userid = Yii::app()->facebook->getUser(); - if ($userid>0) + if ($userid > 0) { $results = Yii::app()->facebook->api('/'.$userid); if(!isset($results['email'])) @@ -458,26 +487,31 @@ protected function getFacebookLogin() Yii::app()->facebook->destroySession(); $this->redirect(Yii::app()->createUrl("site/index")); } - $identity=new FBIdentity($results['email'],$userid); //we user userid in the password field + + $identity = new FBIdentity($results['email'], $userid); //we user userid in the password field $identity->authenticate(); - if($identity->errorCode===UserIdentity::ERROR_NONE) + if($identity->errorCode === UserIdentity::ERROR_NONE) { - Yii::app()->user->login($identity,0); + Yii::app()->user->login($identity, 0); $this->redirect(Yii::app()->createUrl("site/index")); } } } if(isset(Yii::app()->user->facebook)) + { if(Yii::app()->user->facebook) - $this->logoutUrl = Yii::app()->facebook->getLogoutUrl(); - + { + $this->logoutUrl = Yii::app()->facebook->getLogoutUrl(); + } + } } public function setReturnUrl() { Yii::app()->session['returnUrl'] = $this->CanonicalUrl; } + public function getReturnUrl() { return Yii::app()->session['returnUrl']; @@ -494,7 +528,9 @@ public function getReturnUrl() protected function createBookends($model) { if (count($model) == 0 || Yii::app()->theme->config->disableGridRowDivs) + { return $model; + } $ct = -1; $next = 0; @@ -502,31 +538,37 @@ protected function createBookends($model) { $ct++; if ($ct == 0) + { $model[$ct]->rowBookendFront = true; + } + if ($next == 1) { $model[$ct]->rowBookendFront = true; $next = 0; } + if ((1 + $ct) % $this->gridProductsPerRow == 0) { $model[$ct]->rowBookendBack = true; $next = 1; } } + $model[count($model) - 1]->rowBookendBack = true; //Last item must always close div return $model; } protected function afterRender($view, &$output) { - parent::afterRender($view,$output); + parent::afterRender($view, $output); //Yii::app()->facebook->addJsCallback($js); // use this if you are registering any $js code you want to run asyc - if (_xls_facebook_login()) + { Yii::app()->facebook->initJs($output); // this initializes the Facebook JS SDK on all pages - //Yii::app()->facebook->renderOGMetaTags(); //we don't need this because it was already in our _main.php + } + return true; } @@ -540,25 +582,23 @@ public function getMenuTree() $objTree = Category::GetTree() + CustomPage::GetTree(); ksort($objTree); - if(_xls_get_conf('ENABLE_FAMILIES', 0)>0) + if(_xls_get_conf('ENABLE_FAMILIES', 0) > 0) { - $families = Family::GetTree(); $familyMenu['families_brands_menu'] = array( - 'text'=>CHtml::link(Yii::app()->params['ENABLE_FAMILIES_MENU_LABEL'],$this->createUrl("search/browse",array('brand'=>'*'))), - 'label'=>Yii::app()->params['ENABLE_FAMILIES_MENU_LABEL'], - 'link'=>$this->createUrl("search/browse",array('brand'=>'*')), - 'url'=>$this->createUrl("search/browse",array('brand'=>'*')), - 'id'=>0, - 'child_count'=>count($families), - 'hasChildren'=>1, - 'children'=>$families, - 'items'=>$families + 'text' => CHtml::link(Yii::app()->params['ENABLE_FAMILIES_MENU_LABEL'], $this->createUrl("search/browse", array('brand' => '*'))), + 'label' => Yii::app()->params['ENABLE_FAMILIES_MENU_LABEL'], + 'link' => $this->createUrl("search/browse", array('brand' => '*')), + 'url' => $this->createUrl("search/browse", array('brand' => '*')), + 'id' => 0, + 'child_count' => count($families), + 'hasChildren' => 1, + 'children' => $families, + 'items' => $families ); switch (_xls_get_conf('ENABLE_FAMILIES', 0)) { - case 3: $objFullTree = $families + $objTree; ksort($objFullTree); @@ -569,13 +609,13 @@ public function getMenuTree() case 1: $objFullTree = $objTree + $familyMenu; break; //onbottom - } + } else { + $objFullTree = $objTree; + } - } else $objFullTree = $objTree; - - $this->objFullTree = $objFullTree; - return $this->objFullTree; + $this->_objFullTree = $objFullTree; + return $this->_objFullTree; } /** @@ -585,18 +625,25 @@ public function getMenuTree() */ public function getMenuTreeTop() { - if ($this->objFullTree === null) - $this->objFullTree = $this->MenuTree; + if ($this->_objFullTree === null) + { + $this->_objFullTree = $this->MenuTree; + } - foreach($this->objFullTree as $key => $menuItem) + foreach($this->_objFullTree as $key => $menuItem) { if(isset($menuItem['children'])) - unset($this->objFullTree[$key]['children']); + { + unset($this->_objFullTree[$key]['children']); + } + if(isset($menuItem['items'])) - unset($this->objFullTree[$key]['items']); + { + unset($this->_objFullTree[$key]['items']); + } } - return $this->objFullTree; + return $this->_objFullTree; } /** @@ -608,9 +655,9 @@ public function getMenuTreeTop() * @param string $ampersand * @return string */ - public function createAbsoluteUrl($route,$params=array(),$schema='',$ampersand='&') + public function createAbsoluteUrl($route, $params = array(), $schema = '', $ampersand = '&') { - return Yii::app()->createAbsoluteUrl($route,$params,$schema,$ampersand); + return Yii::app()->createAbsoluteUrl($route, $params, $schema, $ampersand); } /** @@ -620,7 +667,10 @@ public function createAbsoluteUrl($route,$params=array(),$schema='',$ampersand=' public function getIsCloud() { if (Yii::app()->params['LIGHTSPEED_CLOUD'] > 0) + { return true; + } + return false; } @@ -631,7 +681,10 @@ public function getIsCloud() public function getIsMT() { if (Yii::app()->params['LIGHTSPEED_MT'] > 0) + { return true; + } + return false; } @@ -641,14 +694,17 @@ public function getIsMT() */ public function getIsHosted() { - if(Yii::app()->params['LIGHTSPEED_HOSTING']>0) + if(Yii::app()->params['LIGHTSPEED_HOSTING'] > 0) + { return true; + } + return false; } protected function verifyPreviewThemeKey($strThemeName, $strKey) { - return ($strKey === substr(md5($strThemeName.gmdate('d')),0,10)); + return ($strKey === substr(md5($strThemeName.gmdate('d')), 0, 10)); } protected function registerPreviewThemeScript($strThemeName, $strkey) @@ -659,8 +715,7 @@ protected function registerPreviewThemeScript($strThemeName, $strkey) $script .= "$('div.product_cell_label').each(function(elem) { $(this).attr('onclick', $(this).attr('onclick').substring(0,$(this).attr('onclick').length-1) + '?theme=$strThemeName&themekey=$strkey\"'); });"; $script .= "$('div.wishlistnew').each(function(elem) { $(this).attr('onclick', $(this).attr('onclick').substring(0,$(this).attr('onclick').length-1) + '?theme=$strThemeName&themekey=$strkey\"'); });"; - Yii::app()->clientScript->registerScript('themepreview',$script,CClientScript::POS_END); - + Yii::app()->clientScript->registerScript('themepreview', $script, CClientScript::POS_END); } /** diff --git a/core/protected/components/CustomPageUrlRule.php b/core/protected/components/CustomPageUrlRule.php index 616db958..e7d2893d 100644 --- a/core/protected/components/CustomPageUrlRule.php +++ b/core/protected/components/CustomPageUrlRule.php @@ -5,60 +5,71 @@ class CustomPageUrlRule extends CBaseUrlRule { public $connectionID = 'db'; - public function createUrl($manager,$route,$params,$ampersand) + public function createUrl($manager, $route, $params, $ampersand) { - if ($route=="site/index") { - - $ct=0; + if ($route == "site/index") + { + $ct = 0; $retString = ""; - foreach ($params as $key=>$val) + foreach ($params as $key => $val) + { $retString .= ($ct++ > 0 ? $ampersand : "?").$key."=".$val; + } return $retString; } - if ($route==='search/browse') + if ($route === 'search/browse') { //This route may be a category view or a searchfield search - $ct=0; - if (isset($params['cat'])) { + $ct = 0; + if (isset($params['cat'])) + { $retString = $params['cat']; unset($params['cat']); } elseif (isset($params['search/browse'])) $retString = "search/browse"; - else $retString = 'search/browse'; + else { + $retString = 'search/browse'; + } - foreach ($params as $key=>$val) + foreach ($params as $key => $val) + { if ($val != 'cat' && $val != '') + { $retString .= ($ct++ > 0 ? $ampersand : "?").$key."=".$val; + } + } return $retString; } - if($route=="custompage/index") + if($route == "custompage/index") { $id = $params['id']; $objCatTest = Category::LoadByRequestUrl($id); if (!is_null($objCatTest)) + { $id .= "/".URLPattern::CustomPage; //avoid conflicting Custom Page and Product URL + } + return $id; } - return false; // this rule does not apply } - public function parseUrl($manager,$request,$pathInfo,$rawPathInfo) + public function parseUrl($manager, $request, $pathInfo, $rawPathInfo) { $pathInfo = urlencode($pathInfo); if (preg_match('/^[a-zA-Z0-9%()\-_\.]+$/', $pathInfo, $matches)) { - - if (!empty($matches)) { - + if (!empty($matches)) + { $objCategory = Category::LoadByRequestUrl($matches[0]); - if ($objCategory instanceof Category) { + if ($objCategory instanceof Category) + { $_GET['cat'] = $matches[0]; return 'search/browse'; } @@ -69,17 +80,19 @@ public function parseUrl($manager,$request,$pathInfo,$rawPathInfo) $_GET['id'] = $objCustomPage->request_url; //Reserved keyword for contact us form - if ($matches[0]=="contact-us") + if ($matches[0] == "contact-us") + { return "custompage/contact"; - else - return "custompage/index"; + } else { + return "custompage/index"; + } } else { return false; } } - } + return false; // this rule does not apply } -} \ No newline at end of file +} diff --git a/core/protected/components/DbConnection.php b/core/protected/components/DbConnection.php index 97cdcf76..e2a321c2 100644 --- a/core/protected/components/DbConnection.php +++ b/core/protected/components/DbConnection.php @@ -3,5 +3,4 @@ class DbConnection extends CDbConnection { public $ttl; - -} \ No newline at end of file +} diff --git a/core/protected/components/FBIdentity.php b/core/protected/components/FBIdentity.php index b0a16150..c1b81967 100755 --- a/core/protected/components/FBIdentity.php +++ b/core/protected/components/FBIdentity.php @@ -6,119 +6,115 @@ */ class FBIdentity extends CUserIdentity { - const ERROR_DUAL_ACCOUNTS = 100; - const ERROR_NOT_APPROVED=101; - - //inherit username, password - /** - * - * @var type int - */ - public $_id; - - /** - * Overrided parent method - * @return type - */ - public function getId() - { - return $this->_id; - } - - /** - * Authenticate user - * @return type - */ - public function authenticate() - { - - $user = Customer::model()->findByAttributes(array('facebook'=>$this->password)); - if($user instanceof Customer) - { - - $this->loginHousekeeping($user); - } - else - { - //We didn't find the Facebook ID in the database, but let's see if the user has an account already - - $user = Customer::model()->findByAttributes(array('email'=>$this->username)); - if($user instanceof Customer ) //We found an existing account under this email - { - if(is_null($user->facebook)) - {//We found an account, merge them - $user->facebook = $this->password; - $user->save(); - $this->loginHousekeeping($user); - } else { - //Somehow we've found an existing account with an email from facebook but not the same ID - //Clear Facebook ID and bail, this is a serious conflict - $user->facebook = $this->password; - $user->save(); - $this->redirect(Yii::app()->homeUrl); - } - - } else { - - //New user to our site using Facebook, so set up an account - $model = new Customer(); - $model->scenario = 'createfb'; - $results = Yii::app()->facebook->api('/me'); - $model->first_name = $results['first_name']; - $model->last_name = $results['last_name']; - $model->email = $results['email']; - $model->email_repeat = $results['email']; - $model->record_type = Customer::REGISTERED; + const ERROR_NOT_APPROVED = 101; + + /** + * + * @var type int + */ + private $_id; + + /** + * Overrided parent method + * @return type + */ + public function getId() + { + return $this->_id; + } + + /** + * Authenticate user + * @return type + */ + public function authenticate() + { + + $user = Customer::model()->findByAttributes(array('facebook' => $this->password)); + if($user instanceof Customer) + { + $this->loginHousekeeping($user); + } else { + //We didn't find the Facebook ID in the database, but let's see if the user has an account already + + $user = Customer::model()->findByAttributes(array('email' => $this->username)); + if($user instanceof Customer) + { + //We found an existing account under this email + if(is_null($user->facebook)) + { + //We found an account, merge them + $user->facebook = $this->password; + $user->save(); + $this->loginHousekeeping($user); + } else { + //Somehow we've found an existing account with an email from facebook but not the same ID + //Clear Facebook ID and bail, this is a serious conflict + $user->facebook = $this->password; + $user->save(); + $this->redirect(Yii::app()->homeUrl); + } + } else { + //New user to our site using Facebook, so set up an account + $model = new Customer(); + $model->scenario = 'createfb'; + $results = Yii::app()->facebook->api('/me'); + $model->first_name = $results['first_name']; + $model->last_name = $results['last_name']; + $model->email = $results['email']; + $model->email_repeat = $results['email']; + $model->record_type = Customer::REGISTERED; $model->newsletter_subscribe = 1; - $model->facebook = $results['id']; - - if(_xls_get_conf('MODERATE_REGISTRATION',0)==1) - { - $this->errorCode = self::ERROR_NOT_APPROVED; - $model->allow_login=Customer::UNAPPROVED_USER; - } - else - { - $model->allow_login=Customer::NORMAL_USER; - if(!$model->save()) - { - Yii::log("Error creating Facebook account ". - print_r($model->getErrors(),true), 'error', 'application.'.__CLASS__.".".__FUNCTION__); - - die("A serious error has occurred creating a Facebook account"); - } - - $this->loginHousekeeping($model); - } - - } - + $model->facebook = $results['id']; + + if(_xls_get_conf('MODERATE_REGISTRATION', 0) == 1) + { + $this->errorCode = self::ERROR_NOT_APPROVED; + $model->allow_login = Customer::UNAPPROVED_USER; + } else { + $model->allow_login = Customer::NORMAL_USER; + if(!$model->save()) + { + Yii::log( + "Error creating Facebook account ". + print_r($model->getErrors(), true), + 'error', + 'application.'.__CLASS__.".".__FUNCTION__ + ); + + die("A serious error has occurred creating a Facebook account"); + } + + $this->loginHousekeeping($model); + } + } + } - } - return $this->errorCode; - } + } protected function loginHousekeeping($user) - { + { - $this->_id = $user->id; + $this->_id = $user->id; - $this->setState('fullname', $user->first_name.' '.$user->last_name); - $this->setState('firstname', $user->first_name); - $this->setState('profilephoto',Yii::app()->facebook->getProfilePicture('square')); - $this->setState('facebook',true); + $this->setState('fullname', $user->first_name.' '.$user->last_name); + $this->setState('firstname', $user->first_name); + $this->setState('profilephoto', Yii::app()->facebook->getProfilePicture('square')); + $this->setState('facebook', true); - $user->last_login = new CDbExpression('NOW()'); + $user->last_login = new CDbExpression('NOW()'); - if ($user->allow_login == Customer::ADMIN_USER) - $this->setState('role', 'admin'); - else - $this->setState('role', 'user'); + if ($user->allow_login == Customer::ADMIN_USER) + { + $this->setState('role', 'admin'); + } else { + $this->setState('role', 'user'); + } - $user->save(); - $this->errorCode = self::ERROR_NONE; - } + $user->save(); + $this->errorCode = self::ERROR_NONE; + } } diff --git a/core/protected/components/HtmlToText.php b/core/protected/components/HtmlToText.php index 3461ffae..d774285d 100644 --- a/core/protected/components/HtmlToText.php +++ b/core/protected/components/HtmlToText.php @@ -26,16 +26,18 @@ * @param html the input HTML * @return the HTML converted, as best as possible, to text */ -class HtmlToText { - - +class HtmlToText +{ + // @codingStandardsIgnoreStart public function convert_html_to_text($html) { + // @codingStandardsIgnoreEnd $html = $this->fix_newlines($html); $doc = new DOMDocument(); try { $doc->loadHTML($html); } + catch (Exception $e) { Yii::log("Error creating plain text email from receipt ".$e, 'error', 'application.'.__CLASS__.".".__FUNCTION__); @@ -61,7 +63,9 @@ public function convert_html_to_text($html) { * @param text text with any number of \r, \r\n and \n combinations * @return the fixed text */ + // @codingStandardsIgnoreStart public function fix_newlines($text) { + // @codingStandardsIgnoreEnd // replace \r\n to \n $text = str_replace("\r\n", "\n", $text); // remove \rs @@ -70,44 +74,66 @@ public function fix_newlines($text) { return $text; } + // @codingStandardsIgnoreStart public function next_child_name($node) { + // @codingStandardsIgnoreEnd // get the next child $nextNode = $node->nextSibling; - while ($nextNode != null) { - if ($nextNode instanceof DOMElement) { + while ($nextNode != null) + { + if ($nextNode instanceof DOMElement) + { break; } + $nextNode = $nextNode->nextSibling; } + $nextName = null; - if ($nextNode instanceof DOMElement && $nextNode != null) { + if ($nextNode instanceof DOMElement && $nextNode != null) + { $nextName = strtolower($nextNode->nodeName); } return $nextName; } - public function prev_child_name($node) { + + // @codingStandardsIgnoreStart + public function prev_child_name($node) + // @codingStandardsIgnoreEnd + { // get the previous child $nextNode = $node->previousSibling; - while ($nextNode != null) { - if ($nextNode instanceof DOMElement) { + while ($nextNode != null) + { + if ($nextNode instanceof DOMElement) + { break; } + $nextNode = $nextNode->previousSibling; } + $nextName = null; - if ($nextNode instanceof DOMElement && $nextNode != null) { + if ($nextNode instanceof DOMElement && $nextNode != null) + { $nextName = strtolower($nextNode->nodeName); } return $nextName; } - public function iterate_over_node($node) { - if ($node instanceof DOMText) { + // @codingStandardsIgnoreStart + public function iterate_over_node($node) + // @codingStandardsIgnoreEnd + { + if ($node instanceof DOMText) + { return preg_replace("/\\s+/im", " ", $node->wholeText); } - if ($node instanceof DOMDocumentType) { + + if ($node instanceof DOMDocumentType) + { // ignore return ""; } @@ -118,7 +144,8 @@ public function iterate_over_node($node) { $name = strtolower($node->nodeName); // start whitespace - switch ($name) { + switch ($name) + { case "hr": return "------\n"; @@ -156,16 +183,20 @@ public function iterate_over_node($node) { //$output .= "[$name,$nextName]"; if($node->childNodes) - for ($i = 0; $i < $node->childNodes->length; $i++) { - $n = $node->childNodes->item($i); + { + for ($i = 0; $i < $node->childNodes->length; $i++) + { + $n = $node->childNodes->item($i); - $text = $this->iterate_over_node($n); + $text = $this->iterate_over_node($n); - $output .= $text; + $output .= $text; + } } // end whitespace - switch ($name) { + switch ($name) + { case "style": case "head": case "title": @@ -187,25 +218,32 @@ public function iterate_over_node($node) { case "br": // add one line if ($nextName != "div") + { $output .= "\n"; + } break; case "div": // add one line only if the next child isn't a div if ($nextName != "div" && $nextName != null) + { $output .= "\n"; + } break; case "a": // links are returned in [text](link) format $href = $node->getAttribute("href"); - if ($href == null) { + if ($href == null) + { // it doesn't link anywhere - if ($node->getAttribute("name") != null) { + if ($node->getAttribute("name") != null) + { $output = "[$output]"; } } else { - if ($href == $output) { + if ($href == $output) + { // link to the same address: just use link $output; } else { @@ -215,7 +253,8 @@ public function iterate_over_node($node) { } // does the next node require additional whitespace? - switch ($nextName) { + switch ($nextName) + { case "h1": case "h2": case "h3": case "h4": case "h5": case "h6": $output .= "\n"; break; diff --git a/core/protected/components/HttpRequest.php b/core/protected/components/HttpRequest.php index 3c67dd35..78eed6ad 100644 --- a/core/protected/components/HttpRequest.php +++ b/core/protected/components/HttpRequest.php @@ -25,7 +25,7 @@ protected function normalizeRequest() foreach($this->enableCsrfValidationRoutes as $route) { - if(strpos($url,$route) === 0) + if(strpos($url, $route) === 0) { $enableValidation = true; break; @@ -34,7 +34,7 @@ protected function normalizeRequest() if (!$enableValidation) { - Yii::app()->detachEventHandler('onBeginRequest',array($this,'validateCsrfToken')); + Yii::app()->detachEventHandler('onBeginRequest', array($this,'validateCsrfToken')); } } } @@ -52,9 +52,10 @@ public function getCsrfToken() $csrfToken = $session->itemAt($this->csrfTokenName); if($csrfToken === null) { - $csrfToken = sha1(uniqid(mt_rand(),true)); + $csrfToken = sha1(uniqid(mt_rand(), true)); $session->add($this->csrfTokenName, $csrfToken); } + $this->_csrfToken = $csrfToken; } @@ -77,7 +78,7 @@ public function validateCsrfToken($event) { $tokenFromSession = $session->itemAt($this->csrfTokenName); $tokenFromPost = $_POST[$this->csrfTokenName]; - $valid=$tokenFromSession === $tokenFromPost; + $valid = $tokenFromSession === $tokenFromPost; } else { @@ -91,4 +92,4 @@ public function validateCsrfToken($event) } } } -} \ No newline at end of file +} diff --git a/core/protected/components/Shipping.php b/core/protected/components/Shipping.php index e0ada909..72a6316e 100644 --- a/core/protected/components/Shipping.php +++ b/core/protected/components/Shipping.php @@ -195,10 +195,10 @@ protected static function addRatesToShippingProviders($arrShippingProvider) */ public static function getCartScenarios($checkoutForm) { - $logLevel = 'error'; + $logLevel = 'info'; if (CPropertyValue::ensureBoolean(_xls_get_conf('DEBUG_SHIPPING', false)) === true) { - $logLevel = 'info'; + $logLevel = 'error'; } // TODO: This, and the setting of hasTaxModeChanged, should be @@ -210,6 +210,16 @@ public static function getCartScenarios($checkoutForm) // values so we need to save the current value. $savedTaxId = Yii::app()->shoppingcart->tax_code_id; $cart = Yii::app()->shoppingcart->getModel(); + + // The call to setTaxCodeByCheckoutForm() on the shopping cart will call + // recalculateAndSave(). That call is going to add taxes on shipping by + // calling updateTaxShipping(). The first run will have the correct values. + // On later runs, we will have taxes set in the shopping cart and add more + // when we call updateTaxShipping(). Plus, we used to also make a call to + // recalculateAndSave() while going through the shipping providers. Then we + // would call AddTaxes() which would add taxes on top of taxes. + $cart->updateTaxExclusive(); + $savedStorePickup = $cart->blnStorePickup; // Get the list of shipping modules. @@ -242,8 +252,6 @@ public static function getCartScenarios($checkoutForm) $cart->blnStorePickup = false; } - $cart->recalculateAndSave(); - // Get the "shipping" product, which may vary from module to module. $strShippingProduct = $shippingProvider['component']->LsProduct; Yii::log( @@ -271,18 +279,19 @@ public static function getCartScenarios($checkoutForm) { $priorityPrice = $priority['price']; $includeTaxInShippingPrice = false; + $shippingTaxValues = array(); if (Yii::app()->params['SHIPPING_TAXABLE'] == '1') { - $taxes = Tax::CalculatePricesWithTax( + $shippingTaxPrices = Tax::calculatePricesWithTax( $priority['price'], Yii::app()->shoppingcart->tax_code_id, $intShipProductLsid ); - Yii::log("Shipping Taxes retrieved " . print_r($taxes, true), $logLevel, 'application.'.__CLASS__.".".__FUNCTION__); - // TODO: WS-3525 Refactor Tax::CalculatePricesWithTax to return an associative array. - $taxOnShipping = $taxes[1]; + Yii::log("Shipping Taxes retrieved " . print_r($shippingTaxPrices, true), $logLevel, 'application.'.__CLASS__.".".__FUNCTION__); + + $shippingTaxValues = $shippingTaxPrices['arrTaxValues']; if (Yii::app()->params['TAX_INCLUSIVE_PRICING'] == '1') { $includeTaxInShippingPrice = true; @@ -290,9 +299,11 @@ public static function getCartScenarios($checkoutForm) if ($includeTaxInShippingPrice === true) { - $priorityPrice = $taxes[0]; - } else { - Yii::app()->shoppingcart->AddTaxes($taxOnShipping); + $priorityPrice = $shippingTaxPrices['fltSellTotalWithTax']; + } + else + { + Yii::app()->shoppingcart->AddTaxes($shippingTaxValues); } } @@ -339,7 +350,7 @@ public static function getCartScenarios($checkoutForm) // Remove shipping taxes to accommodate the next shipping priority in the loop. if (Yii::app()->params['SHIPPING_TAXABLE'] == '1' && $includeTaxInShippingPrice === false) { - Yii::app()->shoppingcart->SubtractTaxes($taxOnShipping); + Yii::app()->shoppingcart->SubtractTaxes($shippingTaxValues); } } } diff --git a/core/protected/components/ShoppingCart.php b/core/protected/components/ShoppingCart.php index 1d328d53..e2dc4fe5 100644 --- a/core/protected/components/ShoppingCart.php +++ b/core/protected/components/ShoppingCart.php @@ -84,22 +84,13 @@ public function getModel() if (is_null($objCart)) { // TODO: We should probably fix this behaviour: - // If we don't use InitializeCart() here, then we end up with a tax_code_id=NULL, + // If we don't use initialize() here, then we end up with a tax_code_id=NULL, // which is fine, except that in models/Cart.php beforeValidate() we explicitly set // the tax_code_id to use the NOTAX tax code if tax_code_id is null. In the case // of TAX_INCLUSIVE stores, this is definitely not what we want. - $objCart = Cart::InitializeCart(); - if ($intCustomerId !== null) - { - //Set the customer_id here so that setTaxCodeByDefaultShippingAddress() - //will pick it up later on and load the cart with customer info. - $objCart->customer_id = $intCustomerId; - Yii::app()->user->setState('cartid', $objCart->id); - } + $objCart = Cart::initialize($objCustomer); } - } - else - { + } else { $objCart = Cart::model()->findByPk($intSessionCartId); //We don't want to create a new cart if the cart is currently active in session @@ -118,17 +109,20 @@ public function getModel() $objCart->cart_type ), 'error', - 'application.' . __CLASS__ . "." . __FUNCTION__ + 'application.'.__CLASS__.".".__FUNCTION__ ); - $objCart = Cart::InitializeCart(); - Yii::app()->user->setState('cartid', $objCart->id); + $objCart = Cart::initialize($objCustomer); } } if ($intCustomerId !== null) { - $objCart->customer_id = $intCustomerId; //Need this for recalulateAndSave() + $objCart->customer_id = $intCustomerId; + } + + if ($objCart->item_count > 0) + { $objCart->recalculateAndSave(); } @@ -138,6 +132,7 @@ public function getModel() return $this->_model; } + /** * Since calling our model doesn't necessarily really create a db record (to avoid blank carts all over the place), * this function purposely creates a record when we need one (i.e. when adding a product to the cart) @@ -145,11 +140,10 @@ public function getModel() protected function createCart() { $intCartId = Yii::app()->user->getState('cartid'); - Yii::log("Creating cart, existing id is " . $intCartId, 'info', 'application.' . __CLASS__ . "." . __FUNCTION__); + Yii::log("Creating cart, existing id is " . $intCartId, 'info', 'application.'.__CLASS__.".".__FUNCTION__); if (empty($intCartId) && !Yii::app()->isCommonSSL) { - $objCustomer = Customer::GetCurrent(); $intCustomerid = null; @@ -163,9 +157,10 @@ protected function createCart() { $objCart = Cart::LoadLastCartInProgress($intCustomerid); } + if (is_null($objCart)) { - $objCart = Cart::InitializeCart(); + $objCart = Cart::initializeAndSave(); } $this->_model = $objCart; @@ -179,8 +174,8 @@ public function getIsActive() { return false; } - else return true; + return true; } /** @@ -193,23 +188,19 @@ public function loginMerge($objCartToMerge = null) if (is_null($objCartToMerge) === false) { $objCartInProgress = $objCartToMerge; - } - else - { + } else { $objCartInProgress = Cart::LoadLastCartInProgress(Yii::app()->user->id, $this->id); } - if ($objCartInProgress) + if ($objCartInProgress instanceof Cart) { - Yii::log("Found prior cart " . $objCartInProgress->id, 'info', 'application.' . __CLASS__ . "." . __FUNCTION__); + Yii::log("Found prior cart " . $objCartInProgress->id, 'info', 'application.'.__CLASS__.".".__FUNCTION__); if (count($this->cartItems) == 0) { $this->_model = $objCartInProgress; $arrPastItems = array(); - } - else - { + } else { $arrPastItems = $objCartInProgress->cartItems; } @@ -220,7 +211,7 @@ public function loginMerge($objCartToMerge = null) { $objProduct = Product::model()->findbyPk($objItem->product_id); - //we strip any discount from another cart usu. promo code + // We strip any discount from another cart usu. promo code. $retVal = $this->model->AddProduct( $objProduct, $objItem->qty, @@ -242,7 +233,8 @@ public function loginMerge($objCartToMerge = null) } } - //If we aren't being passed a cart from a share (that we don't want to delete), then remove the old cart in progress + // If we aren't being passed a cart from a share (that we don't + // want to delete), then remove the old cart in progress. if (is_null($objCartToMerge)) { Yii::app()->user->setFlash('success', Yii::t('cart', 'Your prior cart has been restored.')); @@ -251,19 +243,21 @@ public function loginMerge($objCartToMerge = null) $this->model->UpdateMissingProducts(); } - } - $this->model->customer_id = Yii::app()->user->id; - $this->model->datetime_cre = new CDbExpression('NOW()'); //Reset time to current time - if (!$this->model->save()) - { - Yii::log("Error saving cart " . print_r($this->model->getErrors(), true), 'error', 'application.' . __CLASS__ . "." . __FUNCTION__); + $this->model->customer_id = Yii::app()->user->id; + $this->model->datetime_cre = new CDbExpression('NOW()'); //Reset time to current time + if (!$this->model->save()) + { + Yii::log("Error saving cart " . print_r($this->model->getErrors(), true), 'error', 'application.' . __CLASS__ . "." . __FUNCTION__); + } + + $this->recalculateAndSave(); + $this->_model = Cart::model()->findByPk($this->id); + Yii::app()->user->setState('cartid', $this->id); + return true; } - $this->recalculateAndSave(); - $this->_model = Cart::model()->findByPk($this->id); - Yii::app()->user->setState('cartid', $this->id); - return true; + return false; } /** @@ -289,7 +283,7 @@ public function loginQuote($objDocument = null) // Merge in items from our quote to the cart. if (count($arrPastItems) > 0) { - foreach ($arrPastItems as $objItem) + foreach($arrPastItems as $objItem) { $objProduct = Product::model()->findbyPk($objItem->product_id); $retVal = $this->model->AddProduct( @@ -314,7 +308,11 @@ public function loginQuote($objDocument = null) $this->model->datetime_cre = new CDbExpression('NOW()'); //Reset time to current time if (!$this->model->save()) { - Yii::log("Error saving cart " . print_r($this->model->getErrors(), true), 'error', 'application.' . __CLASS__ . "." . __FUNCTION__); + Yii::log( + "Error saving cart ".print_r($this->model->getErrors(), true), + 'error', + 'application.'.__CLASS__.".".__FUNCTION__ + ); } $this->recalculateAndSave(); @@ -340,20 +338,20 @@ public function verifyPrices() foreach ($this->cartItems as $item) { - //Make sure our object is current and not cached through our relations + // Make sure our object is current and not cached through our relations. $objProduct = Product::model()->findByPk($item->product_id); if ($item->sell_base != $objProduct->PriceValue) { $strFlash .= Yii::t( - 'cart', - 'The item {item} in your cart has {updown} in price to {price}.', - array( - '{item}' => $item->description, - '{updown}' => ($item->sell_base > $objProduct->PriceValue ? Yii::t('cart', 'decreased') : Yii::t('cart', 'increased')), - '{price}' => $objProduct->getPrice(1, $this->IsTaxIn) - ) - ) . '
'; + 'cart', + 'The item {item} in your cart has {updown} in price to {price}.', + array( + '{item}' => $item->description, + '{updown}' => ($item->sell_base > $objProduct->PriceValue ? Yii::t('cart', 'decreased') : Yii::t('cart', 'increased')), + '{price}' => $objProduct->getPrice(1, $this->IsTaxIn) + ) + ) . '
'; $arrItem['product'] = $objProduct; $arrItem['qty'] = $item->qty; @@ -393,6 +391,7 @@ public function getName() return $this->model->name; } + public function getCartQty() { @@ -423,7 +422,6 @@ public function assign($id) Yii::app()->user->setState('cartid', $id); $this->setModelById($id); } - /** * Add a product to the cart. Defaults to qty 1 unless specified * @param $mixProduct @@ -435,7 +433,8 @@ public function assign($id) public function addProduct($mixProduct, $intQuantity = 1, $intGiftItemId = null, $auto = null) { $cartid = Yii::app()->user->getState('cartid'); - if (empty($cartid)) + + if (empty($cartid) && is_null($this->model)) { $this->createCart(); } @@ -443,9 +442,7 @@ public function addProduct($mixProduct, $intQuantity = 1, $intGiftItemId = null, if ($mixProduct instanceof Product) { $objProduct = $mixProduct; - } - else - { + } else { $objProduct = Product::model()->findByPk($mixProduct); } @@ -466,23 +463,22 @@ public function addProduct($mixProduct, $intQuantity = 1, $intGiftItemId = null, if (is_numeric($retVal) && is_null($auto)) //prevent circular logic adding { - foreach ($objProduct->productRelateds as $objProductAdditional) + foreach($objProduct->productRelateds as $objProductAdditional) { if (isset($objProductAdditional->related) && $objProductAdditional->related->IsAddable && $objProductAdditional->autoadd == 1 && - $objProductAdditional->related->master_model == 0 - ) + $objProductAdditional->related->master_model == 0) { $this->addProduct($objProductAdditional->related, $objProductAdditional->qty, null, true); } } } - return $retVal; + return $retVal; } - else return false; + return false; } /** @@ -509,8 +505,9 @@ public function save() $retVal = $this->model->save(); if (!$retVal) { - Yii::log("Error saving cart " . print_r($this->model->getErrors()), 'error', 'application.' . __CLASS__ . "." . __FUNCTION__); + Yii::log("Error saving cart " . print_r($this->model->getErrors()), 'error', 'application.'.__CLASS__.".".__FUNCTION__); } + return $retVal; } @@ -518,12 +515,13 @@ public function getErrors() { return $this->model->getErrors(); } - /** * Create a Link to view the cart after checkout. Used for receipt viewing. * @return mixed */ + // @codingStandardsIgnoreStart public function GenerateLink() + // @codingStandardsIgnoreEnd { return $this->model->GenerateLink(); } @@ -550,8 +548,10 @@ public function clearCart() { WishlistItem::model()->updateByPk($item->wishlist_item, array('cart_item_id' => null)); } + $item->delete(); } + $this->model->fk_promo_id = null; $this->model->save(); $this->model->refresh(); @@ -561,7 +561,9 @@ public function clearCart() return true; } + // @codingStandardsIgnoreStart public function UpdateMissingProducts() + // @codingStandardsIgnoreEnd { if (Yii::app()->user->getState('cartid') > 0 && isset($this->_model)) { @@ -589,9 +591,16 @@ public function removePromoCode() */ public function revalidatePromoCode() { + if (is_null($this->id)) + { + // If id is null then the cart has yet to be saved, which means it contains + // no products and therefore there is no promocode to be revalidated. + return; + } + if (isset($this->model) === false) { - // No Cart object, cannot revalidate. + // If model isn't set then there is no Cart object, cannot revalidate. return; } @@ -627,7 +636,9 @@ public function releaseCart() $this->_model = null; } + // @codingStandardsIgnoreStart public function UpdateItemQuantity($objItem, $qty) + // @codingStandardsIgnoreEnd { $this->clearCachedShipping(); return $this->model->UpdateItemQuantity($objItem, _xls_number_only($qty)); @@ -639,9 +650,7 @@ public function applyPromoCode($mixCode) if ($mixCode instanceof PromoCode) { $objPromoCode = $mixCode; - } - else - { + } else { $objPromoCode = PromoCode::LoadByCode($mixCode); } @@ -652,7 +661,7 @@ public function applyPromoCode($mixCode) } } - //These are pass-through functions which go currently to our cart object + // These are pass-through functions which go currently to our cart object. /** * True - cart should display tax inclusive prices @@ -688,7 +697,9 @@ public function completeUpdatePromoCode() $this->model->completeUpdatePromoCode(); } + // @codingStandardsIgnoreStart public function SetIdStr() + // @codingStandardsIgnoreEnd { $this->model->SetIdStr(); } @@ -708,17 +719,14 @@ public function assignCustomer($mixCustomer) if (is_numeric($mixCustomer)) { $objCustomer = Customer::model()->findByPk($mixCustomer); - } - else - { + } else { $objCustomer = $mixCustomer; } if ($objCustomer instanceof Customer) { - Yii::log("Assigning customer id #" . $objCustomer->id, 'info', 'application.' . __CLASS__ . "." . __FUNCTION__); + Yii::log("Assigning customer id #" . $objCustomer->id, 'info', 'application.'.__CLASS__.".".__FUNCTION__); $this->model->customer_id = $objCustomer->id; - $this->model->save(); return true; } @@ -735,12 +743,16 @@ public function recalculateAndSave() $this->model->recalculateAndSave(); } + // @codingStandardsIgnoreStart public function RecalculateInventoryOnCartItems() + // @codingStandardsIgnoreEnd { $this->model->RecalculateInventoryOnCartItems(); } + // @codingStandardsIgnoreStart public function UpdateWishList() + // @codingStandardsIgnoreEnd { $this->model->UpdateWishList(); } @@ -800,6 +812,77 @@ public static function displayNoTaxMessage() return false; } + /** + * Erase expired carts and their associated items. + * A cart is considered expired if + * 1. it was last modified over CART_LIFE days ago AND + * 2. it has no id_str associated with it AND + * 3. it is of type cart, giftregistry or awaitpayment AND + * 4. it has no items in it OR + * 5. it has no customer_id associated with it + * + * 1. AND 2. AND 3. AND (4. OR 5.) + * + * @return int The number of carts + items that were erased. + */ + public static function eraseExpired() { + // Erase carts older than CART_LIFE days. + $cartLife = CPropertyValue::ensureInteger(_xls_get_conf('CART_LIFE', 30)); + + // We can't use the class constants directly in the call to + // bindParam(), put them in variables first. + $cartType = CPropertyValue::ensureInteger(CartType::cart); + $giftRegistryType = CPropertyValue::ensureInteger(CartType::giftregistry); + $awaitPaymentType = CPropertyValue::ensureInteger(CartType::awaitpayment); + + $deleteSql = " + DELETE c, ci + FROM xlsws_cart c + LEFT JOIN xlsws_cart_item ci + ON c.id = ci.cart_id + WHERE + (c.customer_id IS NULL OR ci.id IS NULL) AND + (c.cart_type IN (:cart, :giftregistry, :awaitpayment) AND + c.modified < CURDATE() - INTERVAL :cartlife DAY AND + c.id_str IS NULL)"; + $deleteCommand = Yii::app()->db->createcommand($deleteSql); + $deleteCommand->bindparam(":cart", $cartType, PDO::PARAM_INT); + $deleteCommand->bindparam(":giftregistry", $giftRegistryType, PDO::PARAM_INT); + $deleteCommand->bindparam(":awaitpayment", $awaitPaymentType, PDO::PARAM_INT); + $deleteCommand->bindparam(":cartlife", $cartLife, PDO::PARAM_INT); + + $transaction = Yii::app()->db->beginTransaction(); + try + { + Yii::app()->db->createCommand("set foreign_key_checks = 0")->execute(); + $numErased = $deleteCommand->execute(); + Yii::app()->db->createCommand("set foreign_key_checks = 1")->execute(); + $transaction->commit(); + } catch(Exception $e) { + $transaction->rollback(); + } + + return $numErased; + } + + /** + * Optimize the tables related to the shopping cart. + * This is an administrative function and should be called with care. + * + * @return void + */ + public static function optimizeTables() { + Yii::app()->db->createCommand("OPTIMIZE table xlsws_cart")->execute(); + Yii::app()->db->createCommand("OPTIMIZE table xlsws_cart_item")->execute(); + Yii::app()->db->createCommand("OPTIMIZE table xlsws_customer")->execute(); + Yii::app()->db->createCommand("OPTIMIZE table xlsws_wish_list")->execute(); + Yii::app()->db->createCommand("OPTIMIZE table xlsws_wish_list_items")->execute(); + Yii::app()->db->createCommand("OPTIMIZE table xlsws_product")->execute(); + Yii::app()->db->createCommand("OPTIMIZE table xlsws_product_related")->execute(); + Yii::app()->db->createCommand("OPTIMIZE table xlsws_category")->execute(); + Yii::app()->db->createCommand("OPTIMIZE table xlsws_product_category_assn")->execute(); + } + /** * Check to see if the cart contains items that have quantity discounts * applied to them. If there is one element that those this method will @@ -832,8 +915,10 @@ public function displayPromoLine() * @param string $strName * @return int|mixed */ - public function __get($strName) { - switch ($strName) { + public function __get($strName) + { + switch ($strName) + { case 'attributes': return $this->model->attributes; @@ -850,7 +935,7 @@ public function __get($strName) { case 'TotalItemCount': case 'totalItemCount': - return $this->model->totalItemCount; + return $this->model->TotalItemCount; case 'tax1name': case 'tax1Name': @@ -891,9 +976,6 @@ public function __get($strName) { case 'TaxTotal': return $this->model->TaxTotal; - case 'IsTaxIn': - return $this->getIsTaxIn(); - case 'taxTotalFormatted': return _xls_currency($this->model->TaxTotal); case 'subtotal': @@ -914,8 +996,7 @@ public function __get($strName) { return $this->model->Taxes; case 'Total': - case 'total': - return $this->model->total; + return $this->total; case 'TotalFormatted': case 'totalFormatted': @@ -1006,7 +1087,7 @@ public function __get($strName) { return self::calculateOriginalSubtotal(); default: - //As a clever trick to get to our model through the component, + // As a clever trick to get to our model through the component. if (isset($this->model) && $strName != "model" && $this->model->hasAttribute($strName)) { return $this->model->$strName; @@ -1016,7 +1097,9 @@ public function __get($strName) { } + // @codingStandardsIgnoreStart private function calculateOriginalSubtotal() + // @codingStandardsIgnoreEnd { $originalSubTotal = 0; if ($this->model->cartItems) @@ -1035,19 +1118,20 @@ private function calculateOriginalSubtotal() * @param mixed $mixValue * @return mixed */ - public function __set($strName, $mixValue) { - switch ($strName) { - + public function __set($strName, $mixValue) + { + switch ($strName) + { case 'cartItems': return $this->model->cartItems; default: - //As a clever trick to get to our model through the component, + // As a clever trick to get to our model through the component, if ($strName != "model" && $this->model->hasAttribute($strName)) { - $this->model->__set($strName,$mixValue); + $this->model->__set($strName, $mixValue); } else { - return parent::__set($strName,$mixValue); + return parent::__set($strName, $mixValue); } } } diff --git a/core/protected/components/Theme.php b/core/protected/components/Theme.php index 672a1f90..5c197950 100644 --- a/core/protected/components/Theme.php +++ b/core/protected/components/Theme.php @@ -12,10 +12,11 @@ public static function hasAdminForm($strThemeName) { $model = Yii::app()->getComponent('wstheme')->getAdminModel($strThemeName); if($model) + { return true; - else + } else { return false; - + } } /** @@ -25,7 +26,7 @@ public static function hasAdminForm($strThemeName) */ public function getCssUrl($cssFile) { - //Just in case someone passed the .css as part of the $cssFile + // Just in case someone passed the .css as part of the $cssFile if (substr($cssFile, strlen($cssFile) - 4, 4) == ".css") { $cssFile = substr($cssFile, 0, -4); @@ -48,7 +49,7 @@ public function getCssUrl($cssFile) return parent::getBaseUrl()."/css/".$cssFile.".css"; } else { return str_replace("http:", "", _xls_custom_css_folder()). - "_customcss/".Yii::app()->theme->name."/".$cssFile.".css"; + "_customcss/" . Yii::app()->theme->name . "/" . $cssFile . ".css"; } } } else { @@ -68,7 +69,6 @@ public function cssUrl($cssFile) } - /** * Pass along theme config from the xlsws_modules table * @return ThemeConfig @@ -97,11 +97,11 @@ public function getInfo() { return new ThemeInfo(); } - - } +// @codingStandardsIgnoreStart class ThemeConfig +// @codingStandardsIgnoreEnd { /* @@ -115,11 +115,11 @@ public function __get($name) default: $arrConfig = Yii::app()->getComponent('wstheme')->getConfigValues(Yii::app()->theme->name); if(isset($arrConfig[$name])) + { return $arrConfig[$name]; - else return (_xls_get_conf($name,null)); + } + return (_xls_get_conf($name, null)); } - - } /* @@ -129,45 +129,48 @@ public function __set($name, $mixValue) { $arrConfig = Yii::app()->getComponent('wstheme')->getConfigValues(Yii::app()->theme->name); - $arrConfig[$name]=$mixValue; + $arrConfig[$name] = $mixValue; Yii::app()->getComponent('wstheme')->setConfigValues($arrConfig); return true; - } - - } + +// @codingStandardsIgnoreStart class ThemeInfo +// @codingStandardsIgnoreEnd { - /* - * Get a key from the module. If it's not defined, use the xlsws_configuration as a backup + * Get a key from the module. If it's not defined, use the + * xlsws_configuration as a backup */ public function __get($name) { switch($name) { - case 'cssfiles': $model = Yii::app()->getComponent('wstheme')->getAdminModel(Yii::app()->theme->name); if(!$model) + { return array('base','style'); + } + $form = new $model; $strCss = $form->cssfiles; - return explode(",",$strCss); + return explode(",", $strCss); break; default: $model = Yii::app()->getComponent('wstheme')->getAdminModel(Yii::app()->theme->name); - if(!$model) return null; - $form = new $model; - return $form->$name; + if(!$model) + { + return null; + } + $form = new $model(); + return $form->$name; } - } - } diff --git a/core/protected/components/UserIdentity.php b/core/protected/components/UserIdentity.php index fdfd8002..1a8e9c87 100644 --- a/core/protected/components/UserIdentity.php +++ b/core/protected/components/UserIdentity.php @@ -10,8 +10,8 @@ class UserIdentity extends CUserIdentity private $_id; - const ERROR_NOT_APPROVED=101; - const ERROR_PASSWORD_FACEBOOK=102; + const ERROR_NOT_APPROVED = 101; + const ERROR_PASSWORD_FACEBOOK = 102; /** @@ -23,24 +23,23 @@ public function authenticate() $user = $this->getCustomerRecord(); - if (!($user instanceof Customer) || $user->email !== $this->username) { + if (!($user instanceof Customer) || $user->email !== $this->username) + { $this->errorCode = self::ERROR_USERNAME_INVALID; } elseif ($user->allow_login != Customer::NORMAL_USER && $user->allow_login != Customer::ADMIN_USER) { $this->errorCode = self::ERROR_NOT_APPROVED; - } elseif (!$user->authenticate($this->password)) { - //is this an account that was set up via facebook login and doesn't have its own password? - if ($user->password=="facebook") + if ($user->password == "facebook") + { $this->errorCode = self::ERROR_PASSWORD_FACEBOOK; - else + } else { $this->errorCode = self::ERROR_PASSWORD_INVALID; - + } } else { - $this->successfullyLogin($user); - } + return !$this->errorCode; } @@ -48,7 +47,6 @@ public function authenticate() protected function hash($string) { return md5($string); - } public function getId() @@ -59,16 +57,19 @@ public function getId() public function getIsAdmin() { if ($this->_id) - if ($this->getState('role', 'customer')=="admin") + { + if ($this->getState('role', 'customer') == "admin") + { return true; + } + } return false; - } protected function getCustomerRecord() { - return Customer::model()->findByAttributes(array('email' => $this->username,'record_type'=>Customer::REGISTERED)); + return Customer::model()->findByAttributes(array('email' => $this->username,'record_type' => Customer::REGISTERED)); } protected function successfullyLogin($user) @@ -80,9 +81,11 @@ protected function successfullyLogin($user) $this->setState('profilephoto', Yii::app()->theme->baseUrl."/css/images/loginhead.png"); if ($user->allow_login == Customer::ADMIN_USER) + { $this->setState('role', 'admin'); - else + } else { $this->setState('role', 'user'); + } // Update the password storage format if ($user->password == $this->hash($this->password) || @@ -100,7 +103,7 @@ protected function successfullyLogin($user) if (!$user->save()) { - Yii::log("ERROR Saving user record ".print_r($user->getErrors(),true), 'error', 'application.'.__CLASS__.".".__FUNCTION__); + Yii::log("ERROR Saving user record ".print_r($user->getErrors(), true), 'error', 'application.'.__CLASS__.".".__FUNCTION__); } } -} \ No newline at end of file +} diff --git a/core/protected/components/WebServiceAction.php b/core/protected/components/WebServiceAction.php index 6688e342..853ab6fc 100644 --- a/core/protected/components/WebServiceAction.php +++ b/core/protected/components/WebServiceAction.php @@ -13,19 +13,19 @@ class WebServiceAction extends CWebServiceAction public function run() { - $hostInfo=Yii::app()->getRequest()->getHostInfo(); - $controller=$this->getController(); - $this->serviceUrl=$controller->createAbsoluteUrl($this->getId()); - $this->wsdlUrl=$controller->createAbsoluteUrl($this->getId())."?wsdl"; + $hostInfo = Yii::app()->getRequest()->getHostInfo(); + $controller = $this->getController(); + $this->serviceUrl = $controller->createAbsoluteUrl($this->getId()); + $this->wsdlUrl = $controller->createAbsoluteUrl($this->getId())."?wsdl"; //To reverse this wsdl thing, we do some trickery if(!isset($_GET['wsdl'])) - $_GET[$this->serviceVar]='1'; - else + { + $_GET[$this->serviceVar] = '1'; + } else { unset($_GET['wsdl']); + } parent::run(); } - - -} \ No newline at end of file +} diff --git a/core/protected/components/WebUser.php b/core/protected/components/WebUser.php index f6ece8ac..0fd15f02 100644 --- a/core/protected/components/WebUser.php +++ b/core/protected/components/WebUser.php @@ -41,9 +41,9 @@ public function getIsGuest() protected function afterLogin($fromCookie) { - if(!$fromCookie) + if (!$fromCookie) { - //Assign the user to the cart, if logged in + // Assign the user to the cart, if logged in Yii::app()->shoppingcart->assignCustomer(Yii::app()->user->id); // If the user is not a guest user, then update the tax destination @@ -57,18 +57,25 @@ protected function afterLogin($fromCookie) Yii::app()->shoppingcart->setTaxCodeByDefaultShippingAddress(); } - //Since we have successfully logged in, see if we have a cart in progress - Yii::app()->shoppingcart->loginMerge(); + // Since we have successfully logged in, see if we have a cart in progress + $cartInProgressFound = Yii::app()->shoppingcart->loginMerge(); - //Verify prices haven't changed - Yii::app()->shoppingcart->verifyPrices(); - - Yii::log("Cart ID is ".Yii::app()->shoppingcart->id, 'info', 'application.'.__CLASS__.".".__FUNCTION__); + // Recalculate and update the cart if prices of any cart items have changed + if ($cartInProgressFound === true) + { + Yii::app()->shoppingcart->verifyPrices(); + Yii::log("Cart ID is ".Yii::app()->shoppingcart->id, 'info', 'application.'.__CLASS__.".".__FUNCTION__); + } - //Display no-tax message if the customer's default shipping address is - //in no-tax destination in tax-inclusive mode - ShoppingCart::displayNoTaxMessage(); - } else { + // Display no-tax message if the customer's default shipping address is + // in no-tax destination in tax-inclusive mode + if (Yii::app()->params['TAX_INCLUSIVE_PRICING'] == 1) + { + ShoppingCart::displayNoTaxMessage(); + } + } + else + { Yii::log("User Login using cookie", 'info', 'application.'.__CLASS__.".".__FUNCTION__); } } @@ -94,8 +101,7 @@ protected function beforeLogout() try { $objCart->save(); - } - catch (Exception $objExc) { + } catch (Exception $objExc) { Yii::log('Failed to save cart with : ' . $objExc, 'error', 'application.'.__CLASS__.".".__FUNCTION__); } } diff --git a/core/protected/components/WsExtension.php b/core/protected/components/WsExtension.php index 35c96308..b272c94f 100644 --- a/core/protected/components/WsExtension.php +++ b/core/protected/components/WsExtension.php @@ -1,8 +1,7 @@ CheckoutForm = $mixForm; @@ -141,7 +156,7 @@ public function name() } else { - $strName = $this->strModuleName; + $strName = $this->_strModuleName; } if (isset($config['live'])) @@ -166,7 +181,7 @@ public function customer() { * * @return string */ - public function admin_name() { + public function adminName() { return $this->defaultName; } @@ -186,8 +201,12 @@ public function info() { * @param Cart $cart * @return string */ + // @codingStandardsIgnoreStart + // Renaming this could break custom payment methods. + // TODO: This method does not appear to be called anywhere, remove it. public function payment_method(Cart $cart) { + // @codingStandardsIgnoreEnd $config = $this->Config; if (isset($config['ls_payment_method'])) @@ -240,8 +259,11 @@ public function getAdminModelName() * */ public function getConfigValues($strClass = null) { + if (is_null($strClass)) + { + $strClass = get_class($this); + } - if (is_null($strClass)) $strClass = get_class($this); $arr = array(); $objModule = Modules::model()->findByAttributes(array('module' => $strClass)); @@ -291,7 +313,7 @@ public function getDefaultConfiguration() public function getVersion() { - return $this->version; + return $this->_version; } public function getAdminNameNormal() @@ -322,13 +344,13 @@ public function check() return false; } - //Remove possible "null" string which should be same as not set - if (isset($this->config['restrictcountry']) && $this->config['restrictcountry']=="null") + // Remove possible "null" string which should be same as not set + if (isset($this->config['restrictcountry']) && $this->config['restrictcountry'] == "null") { unset($this->config['restrictcountry']); } - //Check possible scenarios why we would not offer this type of shipping + // Check possible scenarios why we would not offer this type of shipping if (isset($this->config['restrictcountry'])) //we have a country restriction { switch($this->config['restrictcountry']) { @@ -342,7 +364,6 @@ public function check() return true; } } - return false; break; @@ -351,7 +372,6 @@ public function check() { return false; } - break; case 'AUNZ': @@ -359,7 +379,6 @@ public function check() { return false; } - break; case 'OUTSIDE': @@ -367,7 +386,6 @@ public function check() { return false; } - break; default: @@ -452,9 +470,13 @@ public function process() { * @param Cart $cart * @return unknown_type */ + // @codingStandardsIgnoreStart + // Renaming this could break custom payment methods. + // TODO: This does not appear to be used anywhere, remove it. public function paid_amount(Cart $cart) { - if ($this->admin_name() == "Cash On Delivery") + // @codingStandardsIgnoreEnd + if ($this->adminName() == "Cash On Delivery") { return 0.00; } @@ -471,7 +493,11 @@ public function paid_amount(Cart $cart) * * @return bool */ + // @codingStandardsIgnoreStart + // Renaming this could break custom payment methods. + // TODO: This does not appear to be used anywhere, remove it. public function uses_jumper() { + // @codingStandardsIgnoreEnd return false; } @@ -489,18 +515,20 @@ public function uses_jumper() { * - success => true| false * - output => */ + // @codingStandardsIgnoreStart + // Renaming this to respect coding standards could break custom payment integrations. public function gateway_response_process() { + // @codingStandardsIgnoreEnd return false; } - public function __get($strName) { switch ($strName) { case 'Name': return $this->name(); case 'AdminName': - return $this->admin_name(); + return $this->adminName(); case 'DefaultName': return $this->defaultName; @@ -537,4 +565,4 @@ public function __set($strName, $mixValue) { } } -} \ No newline at end of file +} diff --git a/core/protected/components/WsSoapException.php b/core/protected/components/WsSoapException.php index be3294dc..4e20bc36 100644 --- a/core/protected/components/WsSoapException.php +++ b/core/protected/components/WsSoapException.php @@ -18,4 +18,4 @@ public function __construct($message, $code = 0, Exception $previous = null) public function __toString() { return __CLASS__ . ": [{$this->code}]: {$this->message}\n"; } -} \ No newline at end of file +} diff --git a/core/protected/components/helpers.php b/core/protected/components/helpers.php index 3565af55..15f8b7f8 100644 --- a/core/protected/components/helpers.php +++ b/core/protected/components/helpers.php @@ -16,18 +16,24 @@ * @param mix optional default in case key is not found * @return string key value */ -function _xls_get_conf($strKey, $mixDefault = ""){ +// @codingStandardsIgnoreStart +function _xls_get_conf($strKey, $mixDefault = "") +// @codingStandardsIgnoreEnd +{ if (isset(Yii::app()->params[$strKey])) - return Yii::app()->params[$strKey]; - else { + return Yii::app()->params[$strKey]; + } else { $objKey = Configuration::model()->find('key_name=?', array($strKey)); - if (!$objKey) return $mixDefault; - else return $objKey->key_value; - } - + if (!$objKey) + { + return $mixDefault; + } else { + return $objKey->key_value; + } + } } /** @@ -36,29 +42,31 @@ function _xls_get_conf($strKey, $mixDefault = ""){ * @param string $strUrlPath optional * @return string url */ -function _xls_site_url($strUrlPath = '') { +// @codingStandardsIgnoreStart +function _xls_site_url($strUrlPath = '') +// @codingStandardsIgnoreEnd +{ Yii::log("Function deprecated, should use \$this->createAbsoluteUrl instead", 'info', 'application.'.__CLASS__.".".__FUNCTION__); return Yii::app()->createAbsoluteUrl($strUrlPath); - } +// @codingStandardsIgnoreStart function _xls_theme_config($strThemeName) +// @codingStandardsIgnoreEnd { - if(Theme::hasAdminForm($strThemeName)) + { return Yii::app()->getComponent('wstheme')->getAdminModel($strThemeName); - - - - + } $fnOptions = YiiBase::getPathOfAlias('webroot')."/themes/".$strThemeName."/config.xml"; if (file_exists($fnOptions)) { $strXml = file_get_contents($fnOptions); return new SimpleXMLElement($strXml); - } else return null; - + } else { + return null; + } } @@ -69,7 +77,6 @@ function _xls_theme_config($strThemeName) */ function getFile($url) { - $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_VERBOSE, 0); @@ -82,54 +89,71 @@ function getFile($url) $resp = curl_exec($ch); curl_close($ch); return $resp; - } - /** * Download latest theme. We call this during install and also on the off chance that the default suddenly * goes missing. */ function downloadTheme($strTheme) { - $jLatest= getFile("http://"._xls_get_conf('LIGHTSPEED_UPDATER','updater.lightspeedretail.com')."/site/latesttheme/".XLSWS_VERSIONBUILD."/".$strTheme); + $jLatest = getFile("http://"._xls_get_conf('LIGHTSPEED_UPDATER', 'updater.lightspeedretail.com')."/site/latesttheme/".XLSWS_VERSIONBUILD."/".$strTheme); $result = json_decode($jLatest); if(empty($result)) - { Yii::log("ERROR attempting to locate latesttheme ".$strTheme." from Lightspeed", 'error', 'application.'.__CLASS__.".".__FUNCTION__); + { + Yii::log( + "ERROR attempting to locate latesttheme ".$strTheme." from Lightspeed", + 'error', + 'application.'.__CLASS__.".".__FUNCTION__ + ); return false; } $strWebstoreInstall = "http://cdn.lightspeedretail.com/webstore/themes/".$result->latest->filename; $data = getFile($strWebstoreInstall); - if (stripos($data,"404 - Not Found")>0 || empty($data)){ + if (stripos($data, "404 - Not Found") > 0 || empty($data)) + { Yii::log("ERROR downloading theme ".$strTheme." from Lightspeed CDN", 'error', 'application.'.__CLASS__.".".__FUNCTION__); return false; } - $f=file_put_contents("themes/".$result->latest->title.".zip", $data); + $f = file_put_contents("themes/".$result->latest->title.".zip", $data); if ($f) { require_once( YiiBase::getPathOfAlias('application.components'). '/zip.php'); - extractZip($result->latest->title.".zip",'',YiiBase::getPathOfAlias('webroot.themes')); + extractZip($result->latest->title.".zip", '', YiiBase::getPathOfAlias('webroot.themes')); @unlink("themes/".$result->latest->title.".zip"); - } - else { + } else { Yii::log("ERROR saving themes/".$result->latest->title.".zip", 'error', 'application.'.__CLASS__.".".__FUNCTION__); return false; } + return true; } + +// @codingStandardsIgnoreStart function _xls_regionalize($str) +// @codingStandardsIgnoreEnd { $c = Yii::app()->params['DEFAULT_COUNTRY']; switch ($str) { case 'color': - if ($c==224) return 'color'; else return 'colour'; + if ($c == 224) + { + return 'color'; + } else { + return 'colour'; + } case 'check': - if ($c==224) return 'check'; else return 'cheque'; + if ($c == 224) + { + return 'check'; + } else { + return 'cheque'; + } default: return $str; @@ -143,7 +167,9 @@ function _xls_regionalize($str) * @param $url * @return string */ +// @codingStandardsIgnoreStart function _xls_url_common_to_custom($url) +// @codingStandardsIgnoreEnd { return str_replace( "https://".Yii::app()->params['LIGHTSPEED_HOSTING_LIGHTSPEED_URL'], @@ -158,7 +184,9 @@ function _xls_url_common_to_custom($url) * @param $url * @return string */ +// @codingStandardsIgnoreStart function _xls_url_custom_to_common($url) +// @codingStandardsIgnoreEnd { return str_replace( "http://".Yii::app()->params['LIGHTSPEED_HOSTING_CUSTOM_URL'], @@ -174,16 +202,24 @@ function _xls_url_custom_to_common($url) * @param boolean ssl_attempt * @return string url */ -function _xls_site_dir($ssl_attempt = false) { +// @codingStandardsIgnoreStart +function _xls_site_dir($sslAttempt = false) +// @codingStandardsIgnoreEnd +{ $strSsl = 'http://'; $strHost = $_SERVER['HTTP_HOST'] . Yii::app()->getBaseUrl(false); - if ($ssl_attempt || + if ($sslAttempt || (isset($_SERVER['HTTPS']) && - ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == '1'))) + ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == '1'))) + { $strSsl = 'https://'; + } - if (substr($strHost,-1)=="/") $strHost = substr($strHost, 0, -1); + if (substr($strHost, -1) == "/") + { + $strHost = substr($strHost, 0, -1); + } return $strSsl . $strHost; } @@ -194,19 +230,20 @@ function _xls_site_dir($ssl_attempt = false) { * @param mix optional default in case key is not found * @return string key value */ -function _sp($strString, $strLocation = "global"){ +function _sp($strString, $strLocation = "global") +{ return Yii::t($strLocation, $strString); } -function _qalert($strString) { error_log($strString); -// $cs = Yii::app()->clientScript; -// $cs->registerScript('my_script', 'alert("'.$strString.'");', CClientScript::POS_READY); -// $this->render('any_view'); - +function _qalert($strString) +{ + error_log($strString); } +// @codingStandardsIgnoreStart function _xls_parse_name($strName) +// @codingStandardsIgnoreEnd { Yii::import('ext.HumanNameParser.*'); require_once('Name.php'); @@ -219,50 +256,61 @@ function _xls_parse_name($strName) /* * Get all active event handles for a given event */ +// @codingStandardsIgnoreStart function _xls_get_events($strEventHandler) +// @codingStandardsIgnoreEnd { - $obj = new Modules(); $obj->category = $strEventHandler; - $obj->active=1; + $obj->active = 1; $dataProvider = $obj->searchEvents(); $objModules = $dataProvider->getData(); foreach ($objModules as $module) { - //See if the extension actually exists either in custom file or our core + // See if the extension actually exists either in custom file or our core if(file_exists(Yii::getPathOfAlias('custom.extensions.'.$module->module.".".$module->module).".php")) + { Yii::import('custom.extensions.'.$module->module.".".$module->module); - elseif(file_exists(Yii::getPathOfAlias('ext.'.$module->module.".".$module->module).".php")) + } elseif(file_exists(Yii::getPathOfAlias('ext.'.$module->module.".".$module->module).".php")) + { Yii::import('ext.'.$module->module.".".$module->module); + } } return $objModules; } -function _xls_raise_events($strEvent,$objEvent) +// @codingStandardsIgnoreStart +function _xls_raise_events($strEvent, $objEvent) +// @codingStandardsIgnoreEnd { - - //Attach event handlers + // Attach event handlers $objModules = _xls_get_events($strEvent); foreach ($objModules as $objModule) { $objModule->instanceHandle = new $objModule->module; - $objModule->instanceHandle->attachEventHandler($objEvent->onAction,array($objModule->instanceHandle,$objEvent->onAction)); + $objModule->instanceHandle->attachEventHandler($objEvent->onAction, array($objModule->instanceHandle,$objEvent->onAction)); } - //Raise events - foreach ($objModules as $objModule) { + // Raise events + foreach ($objModules as $objModule) + { Yii::log('Running event '.$strEvent.' '.$objModule->module, 'trace', 'application.'.__CLASS__.".".__FUNCTION__); - $objModule->instanceHandle->raiseEvent($objEvent->onAction,$objEvent); + $objModule->instanceHandle->raiseEvent($objEvent->onAction, $objEvent); } } +// @codingStandardsIgnoreStart function _xls_facebook_login() +// @codingStandardsIgnoreEnd { if (!empty(Yii::app()->params['FACEBOOK_APPID']) && !empty(Yii::app()->params['FACEBOOK_SECRET'])) + { return true; - else return false; + } else { + return false; + } } /** @@ -297,18 +345,23 @@ function _xls_facebook_login() * [1] => Last Name cannot be blank. * ) */ +// @codingStandardsIgnoreStart function _xls_convert_errors($arrErrors) +// @codingStandardsIgnoreEnd { return array_reduce( $arrErrors, - function ($collectedErrors, $attributeErrors) { + function ($collectedErrors, $attributeErrors) + { return array_unique(array_merge($collectedErrors, $attributeErrors)); }, array() ); } +// @codingStandardsIgnoreStart function _xls_convert_errors_display($arrErrors) +// @codingStandardsIgnoreEnd { $strReturn = "\n"; foreach ($arrErrors as $value) @@ -319,48 +372,60 @@ function _xls_convert_errors_display($arrErrors) return $strReturn; } -//from http://bavotasan.com/2011/convert-hex-color-to-rgb-using-php/ -function hex2rgb($hex) { +// from http://bavotasan.com/2011/convert-hex-color-to-rgb-using-php/ +function hex2rgb($hex) +{ $hex = str_replace("#", "", $hex); - if(strlen($hex) == 3) { - $r = hexdec(substr($hex,0,1).substr($hex,0,1)); - $g = hexdec(substr($hex,1,1).substr($hex,1,1)); - $b = hexdec(substr($hex,2,1).substr($hex,2,1)); + if(strlen($hex) == 3) + { + $r = hexdec(substr($hex, 0, 1).substr($hex, 0, 1)); + $g = hexdec(substr($hex, 1, 1).substr($hex, 1, 1)); + $b = hexdec(substr($hex, 2, 1).substr($hex, 2, 1)); } else { - $r = hexdec(substr($hex,0,2)); - $g = hexdec(substr($hex,2,2)); - $b = hexdec(substr($hex,4,2)); + $r = hexdec(substr($hex, 0, 2)); + $g = hexdec(substr($hex, 2, 2)); + $b = hexdec(substr($hex, 4, 2)); } + $rgb = array($r, $g, $b); - //return implode(",", $rgb); // returns the rgb values separated by commas +// return implode(",", $rgb); // returns the rgb values separated by commas return $rgb; // returns an array with the rgb values } -function json_encode_with_relations(array $models, $attributeNames) { +// @codingStandardsIgnoreStart +function json_encode_with_relations(array $models, $attributeNames) +// @codingStandardsIgnoreEnd +{ $attributeNames = explode(',', $attributeNames); $rows = array(); //the rows to output - foreach ($models as $model) { + foreach ($models as $model) + { $row = array(); //you will be copying in model attribute values to this array - foreach ($attributeNames as $name) { + foreach ($attributeNames as $name) + { $name = trim($name); //in case of spaces around commas $row[$name] = CHtml::value($model, $name); //this function walks the relations } + $rows[] = $row; } return CJSON::encode($rows); - } -function _xls_get_sort_order() { - $strProperty = _xls_get_conf('PRODUCT_SORT_FIELD' , 'Name'); +// @codingStandardsIgnoreStart +function _xls_get_sort_order() +// @codingStandardsIgnoreEnd +{ + $strProperty = _xls_get_conf('PRODUCT_SORT_FIELD', 'Name'); $blnAscend = true; - if ($strProperty[0] == '-') { - $strProperty = substr($strProperty,1); + if ($strProperty[0] == '-') + { + $strProperty = substr($strProperty, 1); $blnAscend = false; } @@ -379,16 +444,23 @@ function _xls_get_sort_order() { * @param string $filename * @return pointer */ -function _xls_fopen_w($filename) { +// @codingStandardsIgnoreStart +function _xls_fopen_w($filename) +// @codingStandardsIgnoreEnd +{ $dir = dirname($filename); if (!file_exists($filename) && !is_writable($dir)) + { return false; + } if (file_exists($filename) && !is_writable($filename)) + { return false; + } - $fp = fopen($filename , 'w'); + $fp = fopen($filename, 'w'); return $fp; } @@ -398,15 +470,10 @@ function _xls_fopen_w($filename) { * @param string $name :: Path relative to the template folder * @return string :: Converted path relative to __SITEROOT__ */ -function templateNamed($name) { +function templateNamed($name) +{ $file = Yii::app()->theme->baseUrl . '/'.$name; return $file; -// -// if(!file_exists($file)) { -// QApplication::Log(E_ERROR,"Template ".$file." not found - site cannot continue"); -// die("Template file missing. Check System Log for details."); -// } -// else return $file; } /** @@ -415,14 +482,21 @@ function templateNamed($name) { * @param string $camel :: String you wish to convert * @return string :: Converted string corresponding to a table field */ -function _xls_convert_camel($camel) { +// @codingStandardsIgnoreStart +function _xls_convert_camel($camel) +// @codingStandardsIgnoreEnd +{ $output = ""; - preg_match_all('/[A-Z][^A-Z]*/',$camel,$results); - for ($i=0; $i < count($results[0]);$i++) { + preg_match_all('/[A-Z][^A-Z]*/', $camel, $results); + + for ($i = 0; $i < count($results[0]); $i++) + { if ($i) + { $output .= "_" . $results[0][$i]; - else + } else { $output .= $results[0][$i]; + } } return strtolower($output); @@ -442,9 +516,11 @@ function camelize($string, $pascalCase = true) $string = ucwords($string); $string = str_replace(' ', '', $string); - if (!$pascalCase) { + if (!$pascalCase) + { return lcfirst($string); } + return $string; } @@ -455,9 +531,10 @@ function camelize($string, $pascalCase = true) * @return int(bool) */ function isValidEmail($email) { - $validator=new CEmailValidator; + $validator = new CEmailValidator; - if(!$validator->validateValue($email)){ + if(!$validator->validateValue($email)) + { return false; } @@ -466,10 +543,8 @@ function isValidEmail($email) { if (is_bool($atIndex) && !$atIndex) { $isValid = false; - } - else - { - $domain = substr($email, $atIndex+1); + } else { + $domain = substr($email, $atIndex + 1); $local = substr($email, 0, $atIndex); $localLen = strlen($local); $domainLen = strlen($domain); @@ -478,49 +553,53 @@ function isValidEmail($email) { // local part length exceeded $isValid = false; } - else if ($domainLen < 1 || $domainLen > 255) + elseif ($domainLen < 1 || $domainLen > 255) { // domain part length exceeded $isValid = false; } - else if ($local[0] == '.' || $local[$localLen-1] == '.') + elseif ($local[0] == '.' || $local[$localLen - 1] == '.') { // local part starts or ends with '.' $isValid = false; } - else if (preg_match('/\\.\\./', $local)) + elseif (preg_match('/\\.\\./', $local)) { // local part has two consecutive dots $isValid = false; } - else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) + elseif (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) { // character not valid in domain part $isValid = false; } - else if (preg_match('/\\.\\./', $domain)) + elseif (preg_match('/\\.\\./', $domain)) { // domain part has two consecutive dots $isValid = false; } - else if - (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', - str_replace("\\\\","",$local))) - { + elseif (!preg_match( + '/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', + str_replace("\\\\", "", $local) + )) { // character not valid in local part unless // local part is quoted - if (!preg_match('/^"(\\\\"|[^"])+"$/', - str_replace("\\\\","",$local))) + if (!preg_match( + '/^"(\\\\"|[^"])+"$/', + str_replace("\\\\", "", $local) + )) { $isValid = false; } } - if ($isValid && !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A"))) - { - // domain not found in DNS - $isValid = false; - } - } + + if ($isValid && !(checkdnsrr($domain, "MX") || checkdnsrr($domain, "A"))) + { + // domain not found in DNS + $isValid = false; + } + } + return $isValid; } @@ -533,7 +612,8 @@ function isValidEmail($email) { function toCharArray($input) { $len = strlen($input); - for ($j=0;$j<$len;$j++) { + for ($j = 0; $j < $len; $j++) + { $char[$j] = substr($input, $j, 1); } @@ -546,11 +626,16 @@ function toCharArray($input) { * @param array $arr The array * @return array */ -function values_as_keys($arr) { //ToDo: only used in Admin panel +// @codingStandardsIgnoreStart +function values_as_keys($arr) +// @codingStandardsIgnoreEnd +{ + // TODO: only used in Admin panel $ret = array(); reset($arr); - foreach($arr as $val) { + foreach($arr as $val) + { $ret[$val] = $val; } @@ -565,7 +650,10 @@ function values_as_keys($arr) { //ToDo: only used in Admin panel * @param string $val * @return array */ -function _xls_comma_to_array($val) { +// @codingStandardsIgnoreStart +function _xls_comma_to_array($val) +// @codingStandardsIgnoreEnd +{ return _xls_delim_to_array($val, ','); } @@ -575,17 +663,23 @@ function _xls_comma_to_array($val) { * @param string $val * @return array */ -function _xls_delim_to_array($val , $delim = ',') { - $arr = explode($delim , trim($val)); +// @codingStandardsIgnoreStart +function _xls_delim_to_array($val, $delim = ',') +// @codingStandardsIgnoreEnd +{ + $arr = explode($delim, trim($val)); $ret = array(); - while(list( , $item) = each($arr)) { + while(list( , $item) = each($arr)) + { if(trim($item) != '') + { $ret[$item] = $item; + } } + return $ret; } - /** * Convert a string or 1 dimensional array * to a 2 dimensional array. @@ -595,7 +689,9 @@ function _xls_delim_to_array($val , $delim = ',') { * @param $arr * @return array */ +// @codingStandardsIgnoreStart function _xls_make2dimArray($arr) +// @codingStandardsIgnoreEnd { if (is_array($arr) === false) { @@ -607,7 +703,8 @@ function _xls_make2dimArray($arr) { // 1 dimension array $newArr = array(); - foreach ($arr as $key => $item) { + foreach ($arr as $key => $item) + { $newArr[$key] = array($item); } @@ -624,7 +721,10 @@ function _xls_make2dimArray($arr) * @param string $value :: The value to be contained by the input * @return string :: An input HTML tag */ -function _xls_make_hidden($name , $value) { +// @codingStandardsIgnoreStart +function _xls_make_hidden($name, $value) +// @codingStandardsIgnoreEnd +{ return "\n"; } @@ -633,9 +733,11 @@ function _xls_make_hidden($name , $value) { * * @param unknown_type $msg */ -function _xls_log($msg,$blnSysLogOnly = false) { - - Yii::log($msg, CLogger::LEVEL_ERROR, 'application'); +// @codingStandardsIgnoreStart +function _xls_log($msg, $blnSysLogOnly = false) +// @codingStandardsIgnoreEnd +{ + Yii::log($msg, CLogger::LEVEL_ERROR, 'application'); } /** @@ -643,35 +745,46 @@ function _xls_log($msg,$blnSysLogOnly = false) { * * @return string "hostname ; ipaddress" */ -function _xls_get_ip() { +// @codingStandardsIgnoreStart +function _xls_get_ip() +// @codingStandardsIgnoreEnd +{ $hname = @gethostbyaddr($_SERVER["REMOTE_ADDR"]); - if(strcmp($hname , $_SERVER["REMOTE_ADDR"]) != 0) { + if(strcmp($hname, $_SERVER["REMOTE_ADDR"]) != 0) + { $hname .= " ( " . $_SERVER["REMOTE_ADDR"] . " ) "; } - if(isset($_SERVER["HTTP_X_FORWARDED_FOR"])) { + if(isset($_SERVER["HTTP_X_FORWARDED_FOR"])) + { $pname = @gethostbyaddr($_SERVER["HTTP_X_FORWARDED_FOR"]); - if( strcmp($pname , $_SERVER["HTTP_X_FORWARDED_FOR"]) != 0) { + if(strcmp($pname, $_SERVER["HTTP_X_FORWARDED_FOR"]) != 0) + { $pname .= " ( " . $_SERVER["HTTP_X_FORWARDED_FOR"] . " ) "; } - $hname = $pname . " ; Proxy " . $hname ; + + $hname = $pname . " ; Proxy " . $hname; } + return trim($hname); } - /** * Return values of an array as value and key (itself) * * @param array $arr The array * @return array */ -function _xls_values_as_keys($arr) { +// @codingStandardsIgnoreStart +function _xls_values_as_keys($arr) +// @codingStandardsIgnoreEnd +{ $ret = array(); reset($arr); - foreach($arr as $val) { + foreach($arr as $val) + { $ret[$val] = $val; } @@ -686,10 +799,18 @@ function _xls_values_as_keys($arr) { * @param string $mixDefault * @return bool */ -function _xls_set_conf($strKey, $mixDefault = "") { +// @codingStandardsIgnoreStart +function _xls_set_conf($strKey, $mixDefault = "") +// @codingStandardsIgnoreEnd +{ $conf = Configuration::LoadByKey($strKey); Yii::app()->params[$strKey] = $mixDefault; - if(!$conf) return false; + + if(!$conf) + { + return false; + } + $conf->key_value = $mixDefault; $conf->modified = new CDbExpression('NOW()'); $conf->save(); @@ -707,40 +828,53 @@ function _xls_set_conf($strKey, $mixDefault = "") { * @param string $options * @param int $sort_order */ -function _xls_insert_conf($key , $title, $value, $helper_text, - $config_type, $options, $sort_order = NULL,$template_specific = 0) { - +// @codingStandardsIgnoreStart +function _xls_insert_conf( +// @codingStandardsIgnoreEnd + $key, + $title, + $value, + $helperText, + $configType, + $options, + $sortOrder = NULL, + $templateSpecific = 0 +) { $conf = Configuration::LoadByKey($key); if(!$conf) + { $conf = new Configuration(); + } $conf->key_name = $key; $conf->title = $title; $conf->key_value = $value; - $conf->helper_text = $helper_text; - $conf->configuration_type_id = $config_type; + $conf->helper_text = $helperText; + $conf->configuration_type_id = $configType; $conf->options = $options; $query = <<findBySql($query); + if(!$sortOrder) + { + $sortOrder = Configuration::model()->findBySql($query); + } - $conf->sort_order = $sort_order; - $conf->template_specific = $template_specific; + $conf->sort_order = $sortOrder; + $conf->template_specific = $templateSpecific; $conf->created = new CDbExpression('NOW()'); $conf->modified = new CDbExpression('NOW()'); if (!$conf->save()) + { print_r($conf->getErrors()); - - + } } /** @@ -749,11 +883,14 @@ function _xls_insert_conf($key , $title, $value, $helper_text, * @param string $zip * @return $zip */ -function _xls_zip_fix($zip) { +// @codingStandardsIgnoreStart +function _xls_zip_fix($zip) +// @codingStandardsIgnoreEnd +{ $zip = trim($zip); - $zip = str_replace(" " , "" , $zip); + $zip = str_replace(" ", "", $zip); $zip = strtoupper($zip); - $zip = preg_replace('/\-[0-9][0-9][0-9][0-9]/','',$zip); + $zip = preg_replace('/\-[0-9][0-9][0-9][0-9]/', '', $zip); return $zip; } @@ -765,16 +902,24 @@ function _xls_zip_fix($zip) { * @param string $zippreg * @return boolean */ -function _xls_validate_zip($zip , $zippreg = '') { +// @codingStandardsIgnoreStart +function _xls_validate_zip($zip, $zippreg = '') +// @codingStandardsIgnoreEnd +{ if(!$zippreg) + { return true; + } $zip = _xls_zip_fix($zip); if(preg_match($zippreg, $zip)) + { return true; - else + } + else { return false; + } } /** @@ -784,15 +929,21 @@ function _xls_validate_zip($zip , $zippreg = '') { * @param string $ext :: Filter to a given file extension * @return array */ -function _xls_read_dir($dir , $ext = FALSE) { +// @codingStandardsIgnoreStart +function _xls_read_dir($dir, $ext = FALSE) { +// @codingStandardsIgnoreEnd $ret = array(); - $handle=opendir($dir); + $handle = opendir($dir); while (false !== ($file = readdir($handle))) - if ($file != "." && $file != ".." && - ($ext ? stristr($file , $ext) : TRUE)) + { + if ($file != "." && $file != ".." && + ($ext ? stristr($file, $ext) : TRUE)) + { $ret[$file] = $file; + } + } closedir($handle); return $ret; @@ -805,10 +956,16 @@ function _xls_read_dir($dir , $ext = FALSE) { * @param mix $value * @return void */ -function _xls_stack_add($key, $value) { +// @codingStandardsIgnoreStart +function _xls_stack_add($key, $value) +// @codingStandardsIgnoreEnd +{ if(!isset($_SESSION['stack_vars'][$key])) + { $_SESSION['stack_vars'][$key] = array(); - $_SESSION['stack_vars'][$key][]=$value; + } + + $_SESSION['stack_vars'][$key][] = $value; } /** @@ -818,7 +975,10 @@ function _xls_stack_add($key, $value) { * @param mix $value * @return void */ -function _xls_stack_put($key, $value) { +// @codingStandardsIgnoreStart +function _xls_stack_put($key, $value) +// @codingStandardsIgnoreEnd +{ $_SESSION['stack_vars'][$key] = array($value); } @@ -829,16 +989,21 @@ function _xls_stack_put($key, $value) { * @param string $key * return mix or false */ -function _xls_stack_get($key) { - if(isset($_SESSION['stack_vars'][$key])) { +// @codingStandardsIgnoreStart +function _xls_stack_get($key) +// @codingStandardsIgnoreEnd +{ + if(isset($_SESSION['stack_vars'][$key])) + { $intItemCount = count($_SESSION['stack_vars'][$key]); if ($intItemCount > 0) + { return $_SESSION['stack_vars'][$key][$intItemCount - 1]; - } - - else + } + } else { return false; + } } /** @@ -847,10 +1012,13 @@ function _xls_stack_get($key) { * @param string $key * return mix or false */ -function _xls_stack_pop($key) { +// @codingStandardsIgnoreStart +function _xls_stack_pop($key) +// @codingStandardsIgnoreEnd +{ if(isset($_SESSION['stack_vars'][$key]) && - (count($_SESSION['stack_vars'][$key])>0)) { - + (count($_SESSION['stack_vars'][$key]) > 0)) + { end($_SESSION['stack_vars'][$key]); $index = key($_SESSION['stack_vars'][$key]); @@ -858,23 +1026,35 @@ function _xls_stack_pop($key) { unset($_SESSION['stack_vars'][$key][$index]); if(count($_SESSION['stack_vars'][$key]) == 0) + { $_SESSION['stack_vars'][$key] = array(); + } return $val; - }else + }else { return false; + } } -function _xls_stack_remove($key) { +// @codingStandardsIgnoreStart +function _xls_stack_remove($key) +// @codingStandardsIgnoreEnd +{ + + while (_xls_stack_pop($key)) + { + } - while (_xls_stack_pop($key)) { } unset($_SESSION['stack_vars'][$key]); return true; } /** * Clear $_SESSION['stack_vars'] */ -function _xls_stack_removeall() { +// @codingStandardsIgnoreStart +function _xls_stack_removeall() +// @codingStandardsIgnoreEnd +{ unset($_SESSION['stack_vars']); } @@ -884,7 +1064,10 @@ function _xls_stack_removeall() { * @param string $msg * @param string $redirect */ -function _xls_display_msg($msg) { +// @codingStandardsIgnoreStart +function _xls_display_msg($msg) +// @codingStandardsIgnoreEnd +{ _xls_stack_add('msg', _sp($msg)); _rd(_xls_site_url('msg/'.XLSURL::KEY_PAGE)); @@ -896,11 +1079,17 @@ function _xls_display_msg($msg) { * @param string $key * return mix or false */ -function _xls_remember_url($strUrl) { //Yii::app()->session['crumbtrail'] +// @codingStandardsIgnoreStart +function _xls_remember_url($strUrl) +// @codingStandardsIgnoreEnd +{ //Yii::app()->session['crumbtrail'] if (empty($strUrl)) + { unset(Yii::app()->session['last_url']); - else - Yii::app()->session['last_url'] = $strUrl; + } + else { + Yii::app()->session['last_url'] = $strUrl; + } } /** @@ -909,11 +1098,17 @@ function _xls_remember_url($strUrl) { //Yii::app()->session['crumbtrail'] * @param string $key * return mix or false */ -function _xls_get_remembered_url() { +// @codingStandardsIgnoreStart +function _xls_get_remembered_url() +// @codingStandardsIgnoreEnd +{ if (isset(Yii::app()->session['last_url'])) + { return (Yii::app()->session['last_url']); - else + } + else { return null; + } } /** @@ -921,14 +1116,19 @@ function _xls_get_remembered_url() { * * @param string $msg */ -function _xls_require_login($msg = false) { +// @codingStandardsIgnoreStart +function _xls_require_login($msg = false) +// @codingStandardsIgnoreEnd +{ $uri = $_SERVER['REQUEST_URI']; if(!$msg) + { $msg = "You are required to login to access this page."; + } - _xls_stack_add('login_msg' , _sp($msg)); - _xls_stack_add('login_redirect_uri' , $uri); + _xls_stack_add('login_msg', _sp($msg)); + _xls_stack_add('login_redirect_uri', $uri); _rd(_xls_site_url('login/'.XLSURL::KEY_PAGE.'/')); } @@ -940,24 +1140,27 @@ function _xls_require_login($msg = false) { * @param string $adde * @return array */ -function _xls_mail_name($name , $adde) { +// @codingStandardsIgnoreStart +function _xls_mail_name($name, $adde) +// @codingStandardsIgnoreEnd +{ return $name . ' <' . $adde . '>'; } +// @codingStandardsIgnoreStart function _xls_send_email($id, $hideJson = false) +// @codingStandardsIgnoreEnd { - $objMail = EmailQueue::model()->findByPk($id); - if ($objMail instanceof EmailQueue) { - - - $orderEmail = _xls_get_conf('ORDER_FROM',''); + if ($objMail instanceof EmailQueue) + { + $orderEmail = _xls_get_conf('ORDER_FROM', ''); $from = empty($orderEmail) ? _xls_get_conf('EMAIL_FROM') : $orderEmail; - Yii::app()->setComponent('Smtpmail',null); - $mail=Yii::app()->Smtpmail; + Yii::app()->setComponent('Smtpmail', null); + $mail = Yii::app()->Smtpmail; //$mail->CharSet="utf-8"; - $mail->Debugoutput="error_log"; + $mail->Debugoutput = "error_log"; $mail->IsSMTP(); $mail->Username = Yii::app()->params['EMAIL_SMTP_USERNAME']; $mail->Password = _xls_decrypt(Yii::app()->params['EMAIL_SMTP_PASSWORD']); @@ -965,61 +1168,97 @@ function _xls_send_email($id, $hideJson = false) $mail->Port = Yii::app()->params['EMAIL_SMTP_PORT']; $SMTPSecure = ""; - if(Yii::app()->params['EMAIL_SMTP_SECURITY_MODE']=='0') + if(Yii::app()->params['EMAIL_SMTP_SECURITY_MODE'] == '0') + { + if (Yii::app()->params['EMAIL_SMTP_PORT'] == "465") + { + $SMTPSecure = "ssl"; + } + + if (Yii::app()->params['EMAIL_SMTP_PORT'] == "587") + { + $SMTPSecure = "tls"; + } + } + + if(_xls_get_conf('EMAIL_SMTP_SECURITY_MODE') == '1') + { + $SMTPSecure = ""; + } + + if(_xls_get_conf('EMAIL_SMTP_SECURITY_MODE') == '2') { - if (Yii::app()->params['EMAIL_SMTP_PORT']=="465") $SMTPSecure = "ssl"; - if (Yii::app()->params['EMAIL_SMTP_PORT']=="587") $SMTPSecure = "tls"; + $SMTPSecure = "ssl"; } - if(_xls_get_conf('EMAIL_SMTP_SECURITY_MODE')=='1') $SMTPSecure = ""; - if(_xls_get_conf('EMAIL_SMTP_SECURITY_MODE')=='2') $SMTPSecure = "ssl"; - if(_xls_get_conf('EMAIL_SMTP_SECURITY_MODE')=='3') $SMTPSecure = "tls"; + if(_xls_get_conf('EMAIL_SMTP_SECURITY_MODE') == '3') + { + $SMTPSecure = "tls"; + } - $mail->SMTPAuth = true; + $mail->SMTPAuth = true; $mail->AuthType = "LOGIN"; - if(_xls_get_conf('EMAIL_SMTP_AUTH_PLAIN','0')=='1') + if(_xls_get_conf('EMAIL_SMTP_AUTH_PLAIN', '0') == '1') + { $mail->AuthType = "PLAIN"; + } + if(empty(Yii::app()->params['EMAIL_SMTP_PASSWORD'])) { Yii::log("Password for SMTP blank, turning off SMTP Authentication", 'info', 'application.'.__CLASS__.".".__FUNCTION__); - $mail->SMTPAuth = false; + $mail->SMTPAuth = false; $mail->Username = ''; $mail->Password = ''; } - $mail->SMTPDebug=1; + + $mail->SMTPDebug = 1; $mail->SMTPSecure = $SMTPSecure; $mail->Host = Yii::app()->params['EMAIL_SMTP_SERVER']; $mail->SetFrom($from, Yii::app()->params['STORE_NAME']); $mail->Subject = $objMail->subject; - $mail->ClearAllRecipients(); + $mail->ClearAllRecipients(); $mail->AddAddress($objMail->to); if(!empty(Yii::app()->params['EMAIL_BCC'])) + { if($objMail->to != Yii::app()->params['EMAIL_BCC'] && $objMail->to == $from) + { $mail->AddCC(Yii::app()->params['EMAIL_BCC']); + } + } - $mail->MsgHTML($objMail->htmlbody); + $mail->MsgHTML($objMail->htmlbody); $blnResult = $mail->Send(); $mail->Password = '*password removed for logging*'; //replace the real password before logging - Yii::log("Contents of mail ".print_r($mail,true), 'info', 'application.'.__CLASS__.".".__FUNCTION__); + Yii::log("Contents of mail ".print_r($mail, true), 'info', 'application.'.__CLASS__.".".__FUNCTION__); if($blnResult) { Yii::log("Sent email to ".$objMail->to." successfully.", 'info', 'application.'.__CLASS__.".".__FUNCTION__); $objMail->delete(); - Yii::log("Email removed from queue", 'info', 'application.'.__CLASS__.".".__FUNCTION__); - if (!$hideJson) echo json_encode("success"); - } - else - { + Yii::log("Email removed from queue", 'info', 'application.'.__CLASS__.".".__FUNCTION__); + if (!$hideJson) + { + echo json_encode("success"); + } + } else { $objMail->sent_attempts += 1; $objMail->save(); - Yii::log("Sending email failed ID ".$id." ".$objMail->to." ". - print_r($mail->ErrorInfo,true), 'error', 'application.'.__CLASS__.".".__FUNCTION__); - if (!$hideJson) echo json_encode("failure"); + Yii::log( + "Sending email failed ID ".$id." ".$objMail->to." ". + print_r($mail->ErrorInfo, true), + 'error', + 'application.'.__CLASS__.".".__FUNCTION__ + ); + + if (!$hideJson) + { + echo json_encode("failure"); + } } } + return $blnResult; } @@ -1030,18 +1269,30 @@ function _xls_send_email($id, $hideJson = false) * @param string $templatefile * @param mixed $vars */ -function _xls_mail_body_from_template($templatefile, $vars) { - if(!file_exists($templatefile)) { - _xls_log(_sp("FATAL ERROR : e-mail template file not found") . - $templatefile); +// @codingStandardsIgnoreStart +function _xls_mail_body_from_template($templatefile, $vars) +// @codingStandardsIgnoreEnd +{ + if(!file_exists($templatefile)) + { + _xls_log( + _sp("FATAL ERROR : e-mail template file not found") . + $templatefile + ); + return ""; } try { extract($vars); } catch (Exception $exc) { - _xls_log(_sp("FATAL ERROR : problem extracting e-mail" . - " variables in") . " " . print_r($vars , true)); + _xls_log( + _sp( + "FATAL ERROR : problem extracting e-mail" . + " variables in" + ) . " " . print_r($vars, true) + ); + return ""; } @@ -1063,7 +1314,10 @@ function _xls_mail_body_from_template($templatefile, $vars) { * @param memory reference to array value * @return string */ -function _xls_trim(&$value) { +// @codingStandardsIgnoreStart +function _xls_trim(&$value) +// @codingStandardsIgnoreEnd +{ $value = trim($value); } @@ -1074,11 +1328,18 @@ function _xls_trim(&$value) { * @param array to search in * @return boolean true or false */ -function _xls_array_search($needle, $haystack) { - foreach($haystack as $elem) { - if(preg_match('/' . $elem.'/',$needle)) +// @codingStandardsIgnoreStart +function _xls_array_search($needle, $haystack) +// @codingStandardsIgnoreEnd +{ + foreach($haystack as $elem) + { + if(preg_match('/' . $elem.'/', $needle)) + { return true; + } } + return false; } @@ -1089,22 +1350,36 @@ function _xls_array_search($needle, $haystack) { * @param array to search in * @return boolean true or false */ -function _xls_array_search_begin($needle, $haystack) { - foreach($haystack as $elem) { - if(preg_match('/^' . $elem .'/',$needle)) +// @codingStandardsIgnoreStart +function _xls_array_search_begin($needle, $haystack) +// @codingStandardsIgnoreEnd +{ + foreach($haystack as $elem) + { + if(preg_match('/^' . $elem .'/', $needle)) + { return true; + } } + return false; } -function _xls_array_search_restrict_begin($needle, $haystack) { - foreach($haystack as $elem) { - $elem = preg_quote($elem,'/'); - $elem = substr_replace($elem, '', strpos($elem,"\\"), (strpos($elem,"\\")-strlen($elem)+1)); - if(preg_match('/^' . $elem .'/',$needle)) - return true; - } - return false; +// @codingStandardsIgnoreStart +function _xls_array_search_restrict_begin($needle, $haystack) +// @codingStandardsIgnoreEnd +{ + foreach($haystack as $elem) + { + $elem = preg_quote($elem, '/'); + $elem = substr_replace($elem, '', strpos($elem, "\\"), (strpos($elem, "\\") - strlen($elem) + 1)); + if(preg_match('/^' . $elem .'/', $needle)) + { + return true; + } + } + + return false; } /** @@ -1114,16 +1389,26 @@ function _xls_array_search_restrict_begin($needle, $haystack) { * @param float $num * @return string */ -function _xls_currency($num, $strCountry = null) { +// @codingStandardsIgnoreStart +function _xls_currency($num, $strCountry = null) +// @codingStandardsIgnoreEnd +{ if(function_exists('_custom_currency')) + { return _custom_currency($num); + } if (!is_numeric($num)) + { return $num; + } if (is_null($strCountry)) - $strCountry=_xls_get_conf('CURRENCY_DEFAULT','USD'); - return Yii::app()->numberFormatter->formatCurrency($num,$strCountry); + { + $strCountry = _xls_get_conf('CURRENCY_DEFAULT', 'USD'); + } + + return Yii::app()->numberFormatter->formatCurrency($num, $strCountry); } @@ -1133,65 +1418,76 @@ function _xls_currency($num, $strCountry = null) { * @param string $path * @return string */ -function _xls_remove_leading_slash($path) { - if(substr($path , 0 , 1) == '/') - return substr($path , 1); - else +// @codingStandardsIgnoreStart +function _xls_remove_leading_slash($path) +// @codingStandardsIgnoreEnd +{ + if(substr($path, 0, 1) == '/') + { + return substr($path, 1); + } + else { return $path; + } } - /** * Return the URL Parser Object * Useful if we need to find out URL properties to make decisions somewhere * * @return object */ -function _xls_url_object() { +// @codingStandardsIgnoreStart +function _xls_url_object() +// @codingStandardsIgnoreEnd +{ $objUrl = XLSURL::getInstance(); return $objUrl; } - - - - -//Makes our SEO hyphenated string from passed string -//Used to build anything that will be in a URL. -//Same as seo_name plus lower case conversion and removing spaces -function _xls_seo_url($string) { +// Makes our SEO hyphenated string from passed string +// Used to build anything that will be in a URL. +// Same as seo_name plus lower case conversion and removing spaces +// @codingStandardsIgnoreStart +function _xls_seo_url($string) +// @codingStandardsIgnoreEnd +{ return mb_strtolower(trim(_xls_seo_name($string), '-'), 'UTF-8'); } -//Makes our SEO hyphenated string from passed string -//Used to build anything that will be in a Name. -function _xls_seo_name($string) { - $string = str_replace(array('\n','\r',chr(13),'%'),'',$string); - $string = str_replace('\'','',$string); - $string = str_replace('"','',$string); - $string = str_replace(array(',','?','!','.'),'',$string); - $string = str_replace("&","and",$string); - $string = str_replace("%","pct",$string); - $string = str_replace("#","No",$string); - $string = str_replace("+","and",$string); - $string = str_replace(array(" ",'/'),"-",$string); - $string = preg_replace("`\[.*\]`U","",$string); - $string = preg_replace('`&(amp;)?#?[A-Za-z0-9]+;`i','-',$string); - //$string = htmlentities($string, ENT_COMPAT, 'utf-8'); - $string = preg_replace("`&([a-z])(acute|uml|circ|grave|ring|cedil|slash|tilde|caron|lig|quot|rsquo);`i","\\1", $string); - $string = str_replace('-amp-','-and-',$string); - $string = preg_replace( array("`[^a-z0-9{Cyrillic}{Greek}{Japanese}{Chinese}{Korean}{Hebrew}{Arabic}]/u`i","`[-]+`") , "-", $string); +// Makes our SEO hyphenated string from passed string +// Used to build anything that will be in a Name. +// @codingStandardsIgnoreStart +function _xls_seo_name($string) +// @codingStandardsIgnoreEnd +{ + $string = str_replace(array('\n', '\r', chr(13), '%'), '', $string); + $string = str_replace('\'', '', $string); + $string = str_replace('"', '', $string); + $string = str_replace(array(',', '?', '!', '.'), '', $string); + $string = str_replace("&", "and", $string); + $string = str_replace("%", "pct", $string); + $string = str_replace("#", "No", $string); + $string = str_replace("+", "and", $string); + $string = str_replace(array(" ", '/'), "-", $string); + $string = preg_replace("`\[.*\]`U", "", $string); + $string = preg_replace('`&(amp;)?#?[A-Za-z0-9]+;`i', '-', $string); + $string = preg_replace("`&([a-z])(acute|uml|circ|grave|ring|cedil|slash|tilde|caron|lig|quot|rsquo);`i", "\\1", $string); + $string = str_replace('-amp-', '-and-', $string); + $string = preg_replace(array("`[^a-z0-9{Cyrillic}{Greek}{Japanese}{Chinese}{Korean}{Hebrew}{Arabic}]/u`i", "`[-]+`"), "-", $string); return trim($string, '- '); } - /** * Escape backslashes, used for Google Conversion item description * @return string */ -function _xls_jssafe_name($string) { - $string = str_replace('\'','\\\'',$string); - $string = str_replace('&','&',$string); +// @codingStandardsIgnoreStart +function _xls_jssafe_name($string) +// @codingStandardsIgnoreEnd +{ + $string = str_replace('\'', '\\\'', $string); + $string = str_replace('&', '&', $string); return trim($string); } @@ -1199,9 +1495,12 @@ function _xls_jssafe_name($string) { * Escape backslashes, used for Google Conversion item description * @return string */ -function _xls_ajaxclean($string) { +// @codingStandardsIgnoreStart +function _xls_ajaxclean($string) +// @codingStandardsIgnoreEnd +{ $string = trim($string); - $string = str_replace('\'','\\\'',$string); + $string = str_replace('\'', '\\\'', $string); $string = str_replace(array("\r", "\n", "\t"), '', $string); return trim($string); } @@ -1210,8 +1509,11 @@ function _xls_ajaxclean($string) { * Replace double quote with single quote for Meta tags * @return string */ -function _xls_meta_safe($string) { - $string = str_replace('"','\'',$string); +// @codingStandardsIgnoreStart +function _xls_meta_safe($string) +// @codingStandardsIgnoreEnd +{ + $string = str_replace('"', '\'', $string); //$string = str_replace("&","and",$string); return trim($string); } @@ -1221,26 +1523,40 @@ function _xls_meta_safe($string) { * Get the ID of the current customer object * @return int */ -function _xls_get_current_customer_id() { +// @codingStandardsIgnoreStart +function _xls_get_current_customer_id() +// @codingStandardsIgnoreEnd +{ $blnLoggedIn = !Yii::app()->user->isGuest; if ($blnLoggedIn) + { return Yii::app()->user->GetId(); - else return null; + } else { + return null; + } } /** * Get the Full Name of the current customer object * @return string */ -function _xls_get_current_customer_name() { +// @codingStandardsIgnoreStart +function _xls_get_current_customer_name() +// @codingStandardsIgnoreEnd +{ $blnLoggedIn = !Yii::app()->user->isGuest; - if ($blnLoggedIn) { - if (strlen(Yii::app()->user->fullname)<13) return Yii::app()->user->fullname; - else return _xls_truncate(Yii::app()->user->firstname,13); - + if ($blnLoggedIn) + { + if (strlen(Yii::app()->user->fullname) < 13) + { + return Yii::app()->user->fullname; + } else { + return _xls_truncate(Yii::app()->user->firstname, 13); + } + } else { + return "My Account"; } - else return "My Account"; } /** @@ -1249,14 +1565,19 @@ function _xls_get_current_customer_name() { * @param string $filename (path) * @return string $filename (fqdn path) */ -function _xls_get_url_resource($filename) { +// @codingStandardsIgnoreStart +function _xls_get_url_resource($filename) +// @codingStandardsIgnoreEnd +{ $fl = mb_strtolower($filename); - if(substr($fl , 0 , 7) == 'http://' || - substr($fl , 0 , 8) == 'https://') + if(substr($fl, 0, 7) == 'http://' || + substr($fl, 0, 8) == 'https://') + { return $filename; + } - $filename = str_replace( __DOCROOT__ , '' , $filename); - $filename = str_replace( __SUBDIRECTORY__ , '' , $filename); + $filename = str_replace(__DOCROOT__, '', $filename); + $filename = str_replace(__SUBDIRECTORY__, '', $filename); $filename = __VIRTUAL_DIRECTORY__ . __SUBDIRECTORY__ . $filename; return $filename; @@ -1266,7 +1587,10 @@ function _xls_get_url_resource($filename) { * Do a permanent 301 redirect * */ -function _xls_301($strUrl) { +// @codingStandardsIgnoreStart +function _xls_301($strUrl) +// @codingStandardsIgnoreEnd +{ header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$strUrl); exit(); @@ -1276,24 +1600,32 @@ function _xls_301($strUrl) { * Do a 404 fail * */ -function _xls_404() { - throw new CHttpException(404,'The requested page does not exist.'); +// @codingStandardsIgnoreStart +function _xls_404() +// @codingStandardsIgnoreEnd +{ + throw new CHttpException(404, 'The requested page does not exist.'); } /** * Redirect to a given URL * @param string $url */ -function _rd($url = '') { +function _rd($url = '') +{ - if(empty($url)) { + if(empty($url)) + { $url = $_SERVER["REQUEST_URI"]; //_xls_site_url will append subfolder again so get rid of it here - if (__SUBDIRECTORY__) $url = substr($url,strlen(__SUBDIRECTORY__),999); + if (__SUBDIRECTORY__) + { + $url = substr($url, strlen(__SUBDIRECTORY__), 999); + } } + header("Location: "._xls_site_url($url)); exit(); - } @@ -1303,8 +1635,9 @@ function _rd($url = '') { * @param CustomerAddress $objAddress * @return null|string */ - +// @codingStandardsIgnoreStart function _xls_string_address($objAddress) +// @codingStandardsIgnoreEnd { if ($objAddress instanceof CustomerAddress === false) { @@ -1328,23 +1661,25 @@ function _xls_string_address($objAddress) * * @return string */ - +// @codingStandardsIgnoreStart function _xls_html_storeaddress() +// @codingStandardsIgnoreEnd { $str = ''; $str .= Yii::app()->params['STORE_ADDRESS1'] . '
'; - $str .= Yii::app()->params['STORE_ADDRESS2'] ? Yii::app()->params['STORE_ADDRESS2'] . '
' : ''; - $str .= Yii::app()->params['STORE_CITY'] ? Yii::app()->params['STORE_CITY'] . ', ' : ''; - $str .= Yii::app()->params['STORE_STATE'] ? State::CodeById(Yii::app()->params['STORE_STATE']) . '
' : ''; + $str .= Yii::app()->params['STORE_ADDRESS2'] ? Yii::app()->params['STORE_ADDRESS2'] . '
' : ''; + $str .= Yii::app()->params['STORE_CITY'] ? Yii::app()->params['STORE_CITY'] . ', ' : ''; + $str .= Yii::app()->params['STORE_STATE'] ? State::CodeById(Yii::app()->params['STORE_STATE']) . '
' : ''; $intIdCountry = Yii::app()->params['STORE_COUNTRY']; if (is_null($intIdCountry) === false) { if (Country::CodeById($intIdCountry) !== _xls_country()) { - $str .= Yii::app()->params['STORE_COUNTRY'] ? Country::CountryById(Yii::app()->params['STORE_COUNTRY']) . '
' : ''; + $str .= Yii::app()->params['STORE_COUNTRY'] ? Country::CountryById(Yii::app()->params['STORE_COUNTRY']) . '
' : ''; } } - $str .= Yii::app()->params['STORE_ZIP'] ? Yii::app()->params['STORE_ZIP'] : ''; + + $str .= Yii::app()->params['STORE_ZIP'] ? Yii::app()->params['STORE_ZIP'] : ''; return $str; } @@ -1355,7 +1690,9 @@ function _xls_html_storeaddress() * @param ShoppingCart $objCart * @return string */ +// @codingStandardsIgnoreStart function _xls_html_storepickupdetails($objCart) +// @codingStandardsIgnoreEnd { if ($objCart === null) { @@ -1368,7 +1705,6 @@ function _xls_html_storepickupdetails($objCart) $str .= $objCart->shipaddress->first_name . ' ' . $objCart->shipaddress->last_name . '
'; $str .= $objCart->shipaddress->store_pickup_email ? $objCart->shipaddress->store_pickup_email : $objCart->customer->email; $str .= $objCart->shipaddress->phone ? '
' . $objCart->shipaddress->phone : ''; - } else { @@ -1389,13 +1725,15 @@ function _xls_html_storepickupdetails($objCart) * @param ShoppingCart $objCart * @return string */ +// @codingStandardsIgnoreStart function _xls_html_shippingaddress($objCart) +// @codingStandardsIgnoreEnd { if ($objCart === null) { $objCart = Yii::app()->shoppingcart; } - + $str = ''; $str .= $objCart->shipaddress->address1 . '
'; $str .= $objCart->shipaddress->address2 ? $objCart->shipaddress->address2 . '
' : ''; @@ -1418,7 +1756,9 @@ function _xls_html_shippingaddress($objCart) * @param ShoppingCart $objCart * @return string */ +// @codingStandardsIgnoreStart function _xls_html_billingaddress($objCart) +// @codingStandardsIgnoreEnd { if ($objCart === null) { @@ -1429,9 +1769,11 @@ function _xls_html_billingaddress($objCart) { return ''; } - + if ($objCart->shipaddress_id == $objCart->billaddress_id) + { return _xls_html_shippingaddress($objCart); + } $str = ''; $str .= $objCart->billaddress->address1 . '
'; @@ -1458,11 +1800,16 @@ function _xls_html_billingaddress($objCart) * @param int $len * @param string $etc */ -function _xls_truncate($text,$len,$etc = "…") { +// @codingStandardsIgnoreStart +function _xls_truncate($text, $len, $etc = "…") +// @codingStandardsIgnoreEnd +{ if(function_exists('_custom_truncate')) - return _custom_truncate($text,$len,$etc); + { + return _custom_truncate($text, $len, $etc); + } - return _xls_string_smart_truncate($text , $len , $etc); + return _xls_string_smart_truncate($text, $len, $etc); } /** @@ -1473,13 +1820,17 @@ function _xls_truncate($text,$len,$etc = "…") { * @param string $strEncoding * @return mb_string $strOut */ +// @codingStandardsIgnoreStart function _xls_string_smart_truncate($strText, $intLimit, $etc, - $strEncoding = "utf-8") { +// @codingStandardsIgnoreEnd + $strEncoding = "utf-8") +{ $strOut = rtrim($strText); // if the text length is longer than the limit set - if (mb_strlen($strOut, $strEncoding) > $intLimit) { + if (mb_strlen($strOut, $strEncoding) > $intLimit) + { $strStop = XLS_TRUNCATE_PUNCTUATIONS; $strStop .= html_entity_decode("»", ENT_COMPAT, "utf-8"); @@ -1491,23 +1842,31 @@ function _xls_string_smart_truncate($strText, $intLimit, $etc, $intChars = 0; - for ($i = $intLimit-1; $i >= 0; $i--) { + for ($i = $intLimit - 1; $i >= 0; $i--) + { if (mb_strpos($strStop, $charArray[$i]) || ctype_space($charArray[$i])) + { $posStop = $i; - else { + } else { if ($intChars > 0) + { break; + } + $intChars++; } } if (!is_null($posStop) && ($posStop != 0)) + { $intLimit = $posStop; + } $strOut = mb_substr($strOut, 0, $intLimit, $strEncoding); $strOut .= html_entity_decode($etc, ENT_COMPAT, "utf-8"); } + return $strOut; } @@ -1518,16 +1877,21 @@ function _xls_string_smart_truncate($strText, $intLimit, $etc, * @param string $strEncoding * @return mb_string $strOut */ -function _xls_string_split($strText, $strEncoding = "utf-8") { +// @codingStandardsIgnoreStart +function _xls_string_split($strText, $strEncoding = "utf-8") +// @codingStandardsIgnoreEnd +{ $intLength = mb_strlen($strText, $strEncoding); $charArray = array(); // start from the left and chop off one character a time - while ($intLength) { + while ($intLength) + { $charArray[] = mb_substr($strText, 0, 1, $strEncoding); $strText = mb_substr($strText, 1, $intLength, $strEncoding); $intLength = mb_strlen($strText, $strEncoding); } + return $charArray; } @@ -1536,7 +1900,10 @@ function _xls_string_split($strText, $strEncoding = "utf-8") { * @param string $string * @return string */ -function _xls_number_only($string ) { +// @codingStandardsIgnoreStart +function _xls_number_only($string) +// @codingStandardsIgnoreEnd +{ return preg_replace('/[^0-9]/', '', $string); } @@ -1545,7 +1912,10 @@ function _xls_number_only($string ) { * @param string $string * @return string */ -function _xls_letters_only($string ) { +// @codingStandardsIgnoreStart +function _xls_letters_only($string) +// @codingStandardsIgnoreEnd +{ return preg_replace('/[^A-Za-z]/', '', $string); } @@ -1555,7 +1925,10 @@ function _xls_letters_only($string ) { * @param string $string * @return string */ -function _xls_clean_currency($string) { +// @codingStandardsIgnoreStart +function _xls_clean_currency($string) +// @codingStandardsIgnoreEnd +{ return preg_replace('/[^0-9\.\-]/', '', $string); } @@ -1564,7 +1937,10 @@ function _xls_clean_currency($string) { * @param string $url * @param int $delay */ -function _xls_add_meta_redirect($url , $delay = 60) { +// @codingStandardsIgnoreStart +function _xls_add_meta_redirect($url, $delay = 60) +// @codingStandardsIgnoreEnd +{ _xls_stack_add( 'xls_meta_redirect', array('url' => $url , 'delay' => $delay) @@ -1575,39 +1951,52 @@ function _xls_add_meta_redirect($url , $delay = 60) { * Set the page title * @param string $title */ -function _xls_add_page_title($title) { +// @codingStandardsIgnoreStart +function _xls_add_page_title($title) +// @codingStandardsIgnoreEnd +{ global $strPageTitle; $strPageTitle = $title; - _xls_stack_put('xls_page_title',$title); + _xls_stack_put('xls_page_title', $title); } /** * Set the page title combined with storename (or other wildcard pattern) * @param string $title */ -function _xls_add_formatted_page_title($title) { - - _xls_stack_put('xls_page_title', - _xls_get_formatted_page_title($title)); - +// @codingStandardsIgnoreStart +function _xls_add_formatted_page_title($title) +// @codingStandardsIgnoreEnd +{ + _xls_stack_put( + 'xls_page_title', + _xls_get_formatted_page_title($title) + ); } /** * Set the page title combined with storename (or other wildcard pattern) * @param string $title */ -function _xls_get_formatted_page_title($title,$meta = null) { - - if(is_null($meta)) $meta = _xls_get_conf('SEO_CUSTOMPAGE_TITLE'); +// @codingStandardsIgnoreStart +function _xls_get_formatted_page_title($title, $meta = null) +// @codingStandardsIgnoreEnd +{ + if(is_null($meta)) + { + $meta = _xls_get_conf('SEO_CUSTOMPAGE_TITLE'); + } return - Yii::t('global',$meta, - array( - '{name}'=>$title, - '{storename}'=>_xls_get_conf('STORE_NAME','Lightspeed Web Store'), - '{storetagline}'=>_xls_get_conf('STORE_TAGLINE','Amazing products available to order online!'), - )); - + Yii::t( + 'global', + $meta, + array( + '{name}' => $title, + '{storename}' => _xls_get_conf('STORE_NAME', 'Lightspeed Web Store'), + '{storetagline}' => _xls_get_conf('STORE_TAGLINE', 'Amazing products available to order online!'), + ) + ); } /** @@ -1615,22 +2004,32 @@ function _xls_get_formatted_page_title($title,$meta = null) { * Note that this doesn't populate orderid or customername, that has to be done in skeleton * @param string $title */ -function _xls_format_email_subject($key='EMAIL_SUBJECT_CUSTOMER',$customer="", $orderid="") { +// @codingStandardsIgnoreStart +function _xls_format_email_subject($key = 'EMAIL_SUBJECT_CUSTOMER', $customer = "", $orderid = "") +// @codingStandardsIgnoreEnd +{ $strPattern = _xls_get_conf($key); - return Yii::t('email',$strPattern, - array( - '{customername}'=>$customer, - '{orderid}'=>$orderid, - '{storename}'=>_xls_get_conf('STORE_NAME','Lightspeed Web Store'), - )); + return + Yii::t( + 'email', + $strPattern, + array( + '{customername}' => $customer, + '{orderid}' => $orderid, + '{storename}' => _xls_get_conf('STORE_NAME', 'Lightspeed Web Store'), + ) + ); } /** * Add meta description to the stack_vars stack * @param string $desc */ -function _xls_add_meta_desc($desc) { +// @codingStandardsIgnoreStart +function _xls_add_meta_desc($desc) +// @codingStandardsIgnoreEnd +{ _xls_stack_put('xls_meta_desc', strip_tags($desc)); } @@ -1638,12 +2037,17 @@ function _xls_add_meta_desc($desc) { * Save crumbtrail to session * @param array $arrCrumbs */ -function _xls_set_crumbtrail($arrCrumbs = null) { +// @codingStandardsIgnoreStart +function _xls_set_crumbtrail($arrCrumbs = null) +// @codingStandardsIgnoreEnd +{ if($arrCrumbs) + { Yii::app()->session['crumbtrail'] = $arrCrumbs; - else + } else { unset(Yii::app()->session['crumbtrail']); + } } /** @@ -1651,16 +2055,28 @@ function _xls_set_crumbtrail($arrCrumbs = null) { * @param string $type * @return $array */ -function _xls_get_crumbtrail($type = 'full') { +// @codingStandardsIgnoreStart +function _xls_get_crumbtrail($type = 'full') +// @codingStandardsIgnoreEnd +{ - if (!isset(Yii::app()->session['crumbtrail'])) return array(); + if (!isset(Yii::app()->session['crumbtrail'])) + { + return array(); + } - if ($type=='full') return Yii::app()->session['crumbtrail']; + if ($type == 'full') + { + return Yii::app()->session['crumbtrail']; + } $arrCrumbs = Yii::app()->session['crumbtrail']; $retArray = array(); foreach ($arrCrumbs as $crumb) - $retArray[] = $crumb['name']; + { + $retArray[] = $crumb['name']; + } + return $retArray; } @@ -1670,7 +2086,10 @@ function _xls_get_crumbtrail($type = 'full') { * @param int $intProductRowid * @return $string */ -function _xls_get_googlecategory($intProductRowid) { +// @codingStandardsIgnoreStart +function _xls_get_googlecategory($intProductRowid) +// @codingStandardsIgnoreEnd +{ $objGoogle = Yii::app()->db->createCommand( "SELECT d.name0, extra @@ -1678,46 +2097,49 @@ function _xls_get_googlecategory($intProductRowid) { LEFT JOIN ".Category::model()->tableName()." AS b ON a.category_id=b.id LEFT JOIN ".CategoryIntegration::model()->tableName()." AS c ON a.category_id=c.category_id LEFT JOIN ".CategoryGoogle::model()->tableName()." as d ON c.foreign_id=d.id - WHERE c.module='google' AND a.product_id=".$intProductRowid)->queryRow(); - + WHERE c.module='google' AND a.product_id=".$intProductRowid + )->queryRow(); $strLine = $objGoogle['name0']; - $strLine = str_replace("&","&",$strLine); - $strLine = str_replace(">",">",$strLine); + $strLine = str_replace("&", "&", $strLine); + $strLine = str_replace(">", ">", $strLine); $arrGoogle = array(); $arrGoogle['Category'] = trim($strLine); if (!empty($objGoogle['extra'])) { - $arrX = explode(",",$objGoogle['extra']); + $arrX = explode(",", $objGoogle['extra']); $arrGoogle['Gender'] = $arrX[0]; $arrGoogle['Age'] = $arrX[1]; } return $arrGoogle; - } -function _xls_get_googleparentcategory($intProductRowid) { - +// @codingStandardsIgnoreStart +function _xls_get_googleparentcategory($intProductRowid) +// @codingStandardsIgnoreEnd +{ $arrTrailFull = Category::GetTrailByProductId($intProductRowid); $objCat = Category::model()->findbyPk($arrTrailFull[0]['key']); $objPar = $objCat->integration->google; - - if ($objPar) { + if ($objPar) + { $strLine = $objPar->name0; $strMeta = $objPar->extra; - } else $strLine=""; - $strLine = str_replace("&","&",$strLine); - $strLine = str_replace(">",">",$strLine); + } else { + $strLine = ""; + } + $strLine = str_replace("&", "&", $strLine); + $strLine = str_replace(">", ">", $strLine); $arrGoogle = array(); $arrGoogle['Category'] = trim($strLine); if (!empty($strMeta)) { - $arrX = explode(",",$strMeta); + $arrX = explode(",", $strMeta); $arrGoogle['Gender'] = $arrX[0]; $arrGoogle['Age'] = $arrX[1]; } @@ -1731,7 +2153,10 @@ function _xls_get_googleparentcategory($intProductRowid) { * Return the Web Store's version * @return string */ -function _xls_version() { // LEGACY +// @codingStandardsIgnoreStart +function _xls_version() +// @codingStandardsIgnoreEnd +{ // LEGACY return XLSWS_VERSION; } @@ -1739,32 +2164,48 @@ function _xls_version() { // LEGACY * Are we being browsed on an iDevice (checks for both devices) * @return bool */ -function _xls_is_idevice() { - if (_xls_is_ipad() || _xls_is_iphone()) return true; - else return false; +// @codingStandardsIgnoreStart +function _xls_is_idevice() +// @codingStandardsIgnoreEnd +{ + if (_xls_is_ipad() || _xls_is_iphone()) + { + return true; + } else { + return false; + } } /** * Are we being browsed on an iPad * @return bool */ -function _xls_is_ipad() { - +// @codingStandardsIgnoreStart +function _xls_is_ipad() +// @codingStandardsIgnoreEnd +{ if(isset($_SERVER['HTTP_USER_AGENT'])) - return (bool) strpos($_SERVER['HTTP_USER_AGENT'],'iPad'); - else return false; + { + return (bool) strpos($_SERVER['HTTP_USER_AGENT'], 'iPad'); + } else { + return false; + } } /** * Are we being browsed on an iPhone/Ipod Touch * @return bool */ -function _xls_is_iphone() { - +// @codingStandardsIgnoreStart +function _xls_is_iphone() +// @codingStandardsIgnoreEnd +{ if(isset($_SERVER['HTTP_USER_AGENT']) && - (strpos($_SERVER['HTTP_USER_AGENT'],'iPhone') || - strpos($_SERVER['HTTP_USER_AGENT'],'iPod'))) + (strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone') || + strpos($_SERVER['HTTP_USER_AGENT'], 'iPod'))) + { return true; + } return false; } @@ -1775,82 +2216,93 @@ function _xls_is_iphone() { * @param string $strLangCode * @param string $strCountryCode (optional) */ +// @codingStandardsIgnoreStart function _xls_lang_init($strLangCode, $strCountryCode = '') +// @codingStandardsIgnoreEnd { - if (Yii::app()->language != $strLangCode) { - + if (Yii::app()->language != $strLangCode) + { Yii::app()->language = $strLangCode; if (!empty($strCountryCode)) + { Yii::app()->session['country_code'] = $strCountryCode; + } return; } } +// @codingStandardsIgnoreStart function _xls_avail_languages() +// @codingStandardsIgnoreEnd { - $data = array(); - foreach (explode(",", _xls_get_conf('LANG_OPTIONS','en_us')) as $cLine) { + foreach (explode(",", _xls_get_conf('LANG_OPTIONS', 'en_us')) as $cLine) + { list ($cKey, $cValue) = explode(':', $cLine, 2); $data[$cKey] = $cValue; } - return $data; + return $data; } +// @codingStandardsIgnoreStart function _xls_check_version() +// @codingStandardsIgnoreEnd { - if(!Yii::app()->theme) return false; + if(!Yii::app()->theme) + { + return false; + } - $url = "http://"._xls_get_conf('LIGHTSPEED_UPDATER','updater.lightspeedretail.com'); + $url = "http://"._xls_get_conf('LIGHTSPEED_UPDATER', 'updater.lightspeedretail.com'); Yii::log("Checking Version (and reporting stats) to $url", 'info', 'application.'.__CLASS__.".".__FUNCTION__); $storeurl = Yii::app()->createAbsoluteUrl("/"); - $storeurl = str_replace("http://","",$storeurl); - $storeurl = str_replace("https://","",$storeurl); + $storeurl = str_replace("http://", "", $storeurl); + $storeurl = str_replace("https://", "", $storeurl); $strTheme = Yii::app()->theme->name; - $strThemeVersion = - (Yii::app()->theme->info->noupdate ? "noupdate" : Yii::app()->theme->info->version); + $strThemeVersion = (Yii::app()->theme->info->noupdate ? "noupdate" : Yii::app()->theme->info->version); if(isset($_SERVER['SERVER_SOFTWARE'])) - $serversoftware=$_SERVER['SERVER_SOFTWARE']; - else - $serversoftware=""; + { + $serversoftware = $_SERVER['SERVER_SOFTWARE']; + } + else { + $serversoftware = ""; + } $data['webstore'] = array( 'version' => XLSWS_VERSIONBUILD, 'customer' => $storeurl, - 'type' => (_xls_get_conf('LIGHTSPEED_HOSTING')==1 ? "hosted" : "self"), - 'track' => (_xls_get_conf('AUTO_UPDATE_TRACK','0')==1 ? "beta" : "release"), - 'autoupdate' => (_xls_get_conf('AUTO_UPDATE','1')==1 ? "1" : "0"), + 'type' => (_xls_get_conf('LIGHTSPEED_HOSTING') == 1 ? "hosted" : "self"), + 'track' => (_xls_get_conf('AUTO_UPDATE_TRACK', '0') == 1 ? "beta" : "release"), + 'autoupdate' => (_xls_get_conf('AUTO_UPDATE', '1') == 1 ? "1" : "0"), 'theme' => $strTheme, - 'serversoftware'=> $serversoftware, + 'serversoftware' => $serversoftware, 'themeversion' => $strThemeVersion, - 'schema' => _xls_get_conf('DATABASE_SCHEMA_VERSION'), + 'schema' => _xls_get_conf('DATABASE_SCHEMA_VERSION', '447'), 'cid' => _xls_get_conf('LIGHTSPEED_CID'), 'phpversion' => PHP_VERSION, 'themefiles' => _xls_theme_report(), 'configuration' => _xls_configuration_report() - ); - if(Yii::app()->params['LIGHTSPEED_MT']=='1') + if(Yii::app()->params['LIGHTSPEED_MT'] == '1') { - //Since we could have two urls on multitenant, just grab the original one - $data['webstore']['customer']=Yii::app()->params['LIGHTSPEED_HOSTING_LIGHTSPEED_URL']; - $data['webstore']['type']="mt-pro"; - if(Yii::app()->params['LIGHTSPEED_CLOUD']>0) + // Since we could have two urls on multitenant, just grab the original one + $data['webstore']['customer'] = Yii::app()->params['LIGHTSPEED_HOSTING_LIGHTSPEED_URL']; + $data['webstore']['type'] = "mt-pro"; + if(Yii::app()->params['LIGHTSPEED_CLOUD'] > 0) { - $data['webstore']['type']="mt-cloud"; - $data['webstore']['cid']=Yii::app()->params['LIGHTSPEED_CLOUD']; + $data['webstore']['type'] = "mt-cloud"; + $data['webstore']['cid'] = Yii::app()->params['LIGHTSPEED_CLOUD']; } - } - Yii::log("sending to stats ".print_r($data,true), 'trace', 'application.'.__CLASS__.".".__FUNCTION__); + Yii::log("sending to stats ".print_r($data, true), 'trace', 'application.'.__CLASS__.".".__FUNCTION__); $json = json_encode($data); $ch = curl_init($url); @@ -1863,20 +2315,25 @@ function _xls_check_version() curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); - curl_setopt($ch, CURLOPT_HTTPHEADER, - array("Content-type: application/json")); + curl_setopt( + $ch, + CURLOPT_HTTPHEADER, + array("Content-type: application/json") + ); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $json); $resp = curl_exec($ch); curl_close($ch); - if(Yii::app()->params['LIGHTSPEED_HOSTING'] != 1 && _xls_check_migrations()) { $oXML = json_decode($resp); if (!empty($oXML) && isset($oXML->webstore)) + { $oXML->webstore->schema = "update"; + } + $resp = json_encode($oXML); } @@ -1888,58 +2345,78 @@ function _xls_check_version() * * @return bool */ +// @codingStandardsIgnoreStart function _xls_check_migrations() +// @codingStandardsIgnoreEnd { $arrFiles = glob(Yii::getPathOfAlias('application').'/migrations/*.php'); $arrMigrations = preg_grep('/(m(\d{6}_\d{6})_.*?)\.php$/', $arrFiles); $intCount = Yii::app()->db->createCommand("select count(*) from xlsws_migrations")->queryScalar(); - return ((count($arrMigrations)+1) > $intCount); - + return ((count($arrMigrations) + 1) > $intCount); } -//In order to evaluate view layer changes impact, we need to know -//what files have changed in a customer theme. (This is useful for -//judging risk during the development process) -//We simply take an md5 hash of each file in the theme and compare -//it to the hash of our original shipping file. Contents of the file -//are not sent. +// In order to evaluate view layer changes impact, we need to know +// what files have changed in a customer theme. (This is useful for +// judging risk during the development process) +// We simply take an md5 hash of each file in the theme and compare +// it to the hash of our original shipping file. Contents of the file +// are not sent. +// @codingStandardsIgnoreStart function _xls_theme_report() +// @codingStandardsIgnoreEnd { $retVal = getThemeFiles(YiiBase::getPathOfAlias('webroot.themes').'/'.Yii::app()->theme->name); return serialize($retVal); } -function getThemeFiles($dir) { - +// @codingStandardsIgnoreStart +function getThemeFiles($dir) +// @codingStandardsIgnoreEnd +{ $files = array(); - if ($handle = opendir($dir)) { - while (false !== ($file = readdir($handle))) { - if ($file != "." && $file != "..") { - if(is_dir($dir.'/'.$file)) { + if ($handle = opendir($dir)) + { + while (false !== ($file = readdir($handle))) + { + if ($file != "." && $file != "..") + { + if(is_dir($dir.'/'.$file)) + { $dir2 = $dir.'/'.$file; $files[] = getThemeFiles($dir2); } else { - //We only care about php and css files - if(substr($file,-4)==".php" || substr($file,-4)==".css" ) - $files[] = str_replace(YiiBase::getPathOfAlias('webroot.themes').'/'.Yii::app()->theme->name."/","",$dir). - '/'.$file.",".md5_file($dir.'/'.$file); + // We only care about php and css files + if(substr($file, -4) == ".php" || substr($file, -4) == ".css") + { + $files[] = str_replace( + YiiBase::getPathOfAlias('webroot.themes').'/'.Yii::app()->theme->name."/", + "", + $dir + ) . '/'.$file.",".md5_file($dir.'/'.$file); + } } } } + closedir($handle); } return array_flat($files); } -function array_flat($array) { - $tmp=array(); - foreach($array as $a) { - if(is_array($a)) { +// @codingStandardsIgnoreStart +function array_flat($array) +// @codingStandardsIgnoreEnd +{ + $tmp = array(); + foreach($array as $a) + { + if(is_array($a)) + { $tmp = array_merge($tmp, array_flat($a)); } else { @@ -1951,11 +2428,13 @@ function array_flat($array) { } +// @codingStandardsIgnoreStart function _xls_configuration_report() +// @codingStandardsIgnoreEnd { - //In order to make impact decisions, report how these configuration keys are set - //This array will report either the value or simply if they are set (in cases of sensitive data) - $_arrKeysToReport = array( + // In order to make impact decisions, report how these configuration keys are set + // This array will report either the value or simply if they are set (in cases of sensitive data) + $arrKeysToReport = array( 'EMAIL_FROM' => 'value', 'CURRENCY_DEFAULT' => 'value', 'FACEBOOK_APPID' => 'boolean', @@ -1967,43 +2446,54 @@ function _xls_configuration_report() 'LANG_MENU' => 'value' ); - //Report active modules + // Report active modules $retVal = CHtml::listData(Modules::model()->findAllByAttributes(array('active' => 1)), 'module', 'active'); - //How big are some of these tables, affects upgrade processing time when we have to add indexes, etc. Trying to avoid timeouts. + // How big are some of these tables, affects upgrade processing time when we have to add indexes, etc. Trying to avoid timeouts. $retVal['CART_LIFE'] = Yii::app()->db->createCommand("SELECT count(*) as thecount FROM xlsws_cart WHERE cart_type=4 AND modified > '".date("Y-m-d", strtotime("-30 DAYS"))."'")->queryScalar(); $retVal['WEB_PRODUCTS'] = Yii::app()->db->createCommand("SELECT count(*) as thecount FROM xlsws_product WHERE web=1")->queryScalar(); $retVal['TOTAL_PRODUCTS'] = Yii::app()->db->createCommand("SELECT count(*) as thecount FROM xlsws_product")->queryScalar(); $retVal['TOTAL_CATEGORIES'] = Yii::app()->db->createCommand("SELECT count(*) as thecount FROM xlsws_category")->queryScalar(); - foreach ($_arrKeysToReport as $key => $value) + foreach ($arrKeysToReport as $key => $value) + { $retVal[$key] = ($value == "boolean" ? (empty(Yii::app()->params[$key]) ? 0 : 1) : Yii::app()->params[$key]); + } return serialize($retVal); } +// @codingStandardsIgnoreStart function _xls_parse_language($string) +// @codingStandardsIgnoreEnd { $pattern = "|<".Yii::app()->language.".*>(.*)language.">|U"; - preg_match_all($pattern, $string, $output); - if (is_array($output) && count($output)>0 && count($output[1])>0) - return $output[1][0]; - else + if (is_array($output) && count($output) > 0 && count($output[1]) > 0) { - $patternDefaultLang = "/^(.*?)<\b(".str_replace(",","|",_xls_get_conf('LANGUAGES','en')).")/"; + return $output[1][0]; + } else { + $patternDefaultLang = "/^(.*?)<\b(".str_replace(",", "|", _xls_get_conf('LANGUAGES', 'en')).")/"; preg_match_all($patternDefaultLang, $string, $output); - if (is_array($output) && count($output)>0 && count($output[1])>0) + + if (is_array($output) && count($output) > 0 && count($output[1]) > 0) + { return $output[1][0]; + } } return $string; } + +// @codingStandardsIgnoreStart function _xls_parse_language_serialized($string) +// @codingStandardsIgnoreEnd { $output = @unserialize($string); if (empty($output) || !is_array($output)) - $output = array(Yii::app()->language => $string); + { + $output = array(Yii::app()->language => $string); + } return $output; } @@ -2013,13 +2503,18 @@ function _xls_parse_language_serialized($string) * @param string $text * @param boolean $key */ -function _xls_key_encrypt($text , $key = false) { +// @codingStandardsIgnoreStart +function _xls_key_encrypt($text, $key = false) +// @codingStandardsIgnoreEnd +{ if(!$key) - $key = _xls_get_conf('LSKEY' , 'password'); + { + $key = _xls_get_conf('LSKEY', 'password'); + } $text = trim($text); - $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); - $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); + $ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); + $iv = mcrypt_create_iv($ivSize, MCRYPT_RAND); $enc = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv); return $enc; @@ -2030,21 +2525,29 @@ function _xls_key_encrypt($text , $key = false) { * @param string $enc * @param boolean $key */ -function _xls_key_decrypt($enc , $key = false) { +// @codingStandardsIgnoreStart +function _xls_key_decrypt($enc, $key = false) +// @codingStandardsIgnoreEnd +{ if(!$key) - $key = _xls_get_conf('LSKEY' , 'password'); + { + $key = _xls_get_conf('LSKEY', 'password'); + } - $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); - $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); + $ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); + $iv = mcrypt_create_iv($ivSize, MCRYPT_RAND); $crypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $enc, MCRYPT_MODE_ECB, $iv); return trim($crypttext); } +// @codingStandardsIgnoreStart function _xls_encrypt($msg) +// @codingStandardsIgnoreEnd { - if(file_exists(YiiBase::getPathOfAlias('config')."/wskeys.php")) { + if(file_exists(YiiBase::getPathOfAlias('config')."/wskeys.php")) + { $existingKeys = require(YiiBase::getPathOfAlias('config')."/wskeys.php"); $pass = $existingKeys['key']; $salt = $existingKeys['salt']; @@ -2055,14 +2558,17 @@ function _xls_encrypt($msg) return $encrypted; } - else die("missing wskeys"); - - + else { + die("missing wskeys"); + } } +// @codingStandardsIgnoreStart function _xls_decrypt($msg) +// @codingStandardsIgnoreEnd { - if(file_exists(YiiBase::getPathOfAlias('config')."/wskeys.php")) { + if(file_exists(YiiBase::getPathOfAlias('config')."/wskeys.php")) + { $existingKeys = require(YiiBase::getPathOfAlias('config')."/wskeys.php"); $pass = $existingKeys['key']; $salt = $existingKeys['salt']; @@ -2075,95 +2581,154 @@ function _xls_decrypt($msg) return $decrypted; } - else die("missing wskeys"); + else { + die("missing wskeys"); + } } /** * Return an array containing a list of timezone names */ -function _xls_timezones() { +// @codingStandardsIgnoreStart +function _xls_timezones() +// @codingStandardsIgnoreEnd +{ $zones = array('Africa','America','Antarctica','Arctic','Asia', 'Atlantic','Australia','Europe','Indian','Pacific','Canada','US'); $results = array(); - foreach (timezone_identifiers_list() as $zone) { + foreach (timezone_identifiers_list() as $zone) + { // Split the value into 0=>Continent, 1=>City $zone = explode('/', $zone); - if (in_array($zone[0],$zones)) + if (in_array($zone[0], $zones)) + { if (isset($zone[1]) != '') + { $results[] = implode('/', $zone); + } + } } + $results = array_combine($results, $results); return $results; } -/** Determine whether to show the captcha to the user - */ -function _xls_show_captcha($strPage = "checkout") { - switch ($strPage) { - case 'register': $strKey = "CAPTCHA_REGISTRATION"; break; - case 'contactus': $strKey = "CAPTCHA_CONTACTUS"; break; +/** + * Determine whether to show the captcha to the user + */ +// @codingStandardsIgnoreStart +function _xls_show_captcha($strPage = "checkout") +// @codingStandardsIgnoreEnd +{ + switch ($strPage) + { + case 'register': + $strKey = "CAPTCHA_REGISTRATION"; + break; + case 'contactus': + $strKey = "CAPTCHA_CONTACTUS"; + break; case 'checkout': - default: $strKey = "CAPTCHA_CHECKOUT"; break; + default: + $strKey = "CAPTCHA_CHECKOUT"; + break; } - if (_xls_get_conf($strKey , '0')=='2' || (Yii::app()->user->isGuest && _xls_get_conf($strKey , '0')=='1')) + if (_xls_get_conf($strKey, '0') == '2' || (Yii::app()->user->isGuest && _xls_get_conf($strKey, '0') == '1')) + { return true; - else return false; - + } else { + return false; + } } +// @codingStandardsIgnoreStart function _xls_country() +// @codingStandardsIgnoreEnd { - $objCountry = Country::Load(_xls_get_conf('DEFAULT_COUNTRY',39)); + $objCountry = Country::Load(_xls_get_conf('DEFAULT_COUNTRY', 39)); return $objCountry->code; - } -function _xls_recalculate_inventory() { - - $strField = (_xls_get_conf('INVENTORY_FIELD_TOTAL','')==1 ? "inventory_total" : "inventory"); - +// @codingStandardsIgnoreStart +function _xls_recalculate_inventory() +// @codingStandardsIgnoreEnd +{ + $strField = (_xls_get_conf('INVENTORY_FIELD_TOTAL', '') == 1 ? "inventory_total" : "inventory"); $dbC = Yii::app()->db->createCommand(); $dbC->setFetchMode(PDO::FETCH_OBJ);//fetch each row as Object $dbC->select()->from(Product::model()->tableName())->where('web=1 AND '.$strField.'>0 AND - inventory_reserved=0 AND inventory_avail=0 AND - master_model=0')->order('id')->limit(1000); - - foreach ($dbC->queryAll() as $item) { + inventory_reserved=0 AND inventory_avail=0 AND + master_model=0')->order('id')->limit(1000); - $objProduct = Product::model()->findByPk($item->id); - $objProduct->inventory_reserved=$objProduct->CalculateReservedInventory(); - $objProduct->inventory_avail=$objProduct->inventory; - $objProduct->save(); - } + foreach ($dbC->queryAll() as $item) + { + $objProduct = Product::model()->findByPk($item->id); + $objProduct->inventory_reserved = $objProduct->CalculateReservedInventory(); + $objProduct->inventory_avail = $objProduct->inventory; + $objProduct->save(); + } - $ctPic=Yii::app()->db->createCommand("SELECT count(*) as thecount FROM xlsws_product WHERE web=1 AND ".$strField.">0 AND inventory_reserved=0 AND inventory_avail=0 AND master_model=0")->queryScalar(); + $ctPic = Yii::app()->db->createCommand("SELECT count(*) as thecount FROM xlsws_product WHERE web=1 AND ".$strField.">0 AND inventory_reserved=0 AND inventory_avail=0 AND master_model=0")->queryScalar(); return $ctPic; +} +// @codingStandardsIgnoreStart +function mb_pathinfo($filepath, $portion = null) +// @codingStandardsIgnoreEnd +{ + preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $filepath, $m); + if(isset($m[1])) + { + $ret['dirname'] = $m[1]; + } + if(isset($m[2])) + { + $ret['basename'] = $m[2]; + } + if(isset($m[5])) + { + $ret['extension'] = $m[5]; + } -} + if(isset($m[3])) + { + $ret['filename'] = $m[3]; + } + if ($portion == PATHINFO_DIRNAME) + { + return $ret['dirname']; + } + + if ($portion == PATHINFO_BASENAME) + { + return $ret['basename']; + } + + if ($portion == PATHINFO_EXTENSION) + { + return $ret['extension']; + } + + if ($portion == PATHINFO_FILENAME) + { + return $ret['filename']; + } -function mb_pathinfo($filepath,$portion = null) { - preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im',$filepath,$m); - if(isset($m[1])) $ret['dirname']=$m[1]; - if(isset($m[2])) $ret['basename']=$m[2]; - if(isset($m[5])) $ret['extension']=$m[5]; - if(isset($m[3])) $ret['filename']=$m[3]; - if ($portion==PATHINFO_DIRNAME) return $ret['dirname']; - if ($portion==PATHINFO_BASENAME) return $ret['basename']; - if ($portion==PATHINFO_EXTENSION) return $ret['extension']; - if ($portion==PATHINFO_FILENAME) return $ret['filename']; return $ret; } + +// @codingStandardsIgnoreStart function convert_number_to_words($number) +// @codingStandardsIgnoreEnd { $hyphen = $negative = "-"; $conjunction = "and"; @@ -2171,212 +2736,264 @@ function convert_number_to_words($number) $decimal = "."; $dictionary = array( 0 => 'Zero', - 1 => 'One', - 2 => 'Two', - 3 => 'Three', - 4 => 'Four', - 5 => 'Five', - 6 => 'Six', - 7 => 'Seven', - 8 => 'Eight', - 9 => 'Nine', - 10 => 'Ten', - 11 => 'Eleven', - 12 => 'Twelve', - 13 => 'Thirteen', - 14 => 'Fourteen', - 15 => 'Fifteen', - 16 => 'Sixteen', - 17 => 'Seventeen', - 18 => 'Eighteen', - 19 => 'Nineteen', - 20 => 'Twenty', - 30 => 'Thirty', - 40 => 'Fourty', - 50 => 'Fifty', - 60 => 'Sixty', - 70 => 'Seventy', - 80 => 'Eighty', - 90 => 'Ninety', - 100 => 'Hundred', - 1000 => 'Thousand', - 1000000 => 'Million', - 1000000000 => 'Billion', - 1000000000000 => 'Trillion', - 1000000000000000 => 'Quadrillion', - 1000000000000000000 => 'Quintillion' - ); - - if (!is_numeric($number)) { - return false; - } - - if (($number >= 0 && (int) $number < 0) || (int) $number < 0 - PHP_INT_MAX) { - // overflow - trigger_error( - 'convert_number_to_words only accepts numbers between -' . PHP_INT_MAX . ' and ' . PHP_INT_MAX, - E_USER_WARNING - ); - return false; - } - - if ($number < 0) { - return $negative . convert_number_to_words(abs($number)); - } - - $string = $fraction = null; - - if (strpos($number, '.') !== false) { - list($number, $fraction) = explode('.', $number); - } - - switch (true) { - case $number < 21: - $string = $dictionary[$number]; - break; - case $number < 100: - $tens = ((int) ($number / 10)) * 10; - $units = $number % 10; - $string = $dictionary[$tens]; - if ($units) { - $string .= $hyphen . $dictionary[$units]; - } - break; - case $number < 1000: - $hundreds = $number / 100; - $remainder = $number % 100; - $string = $dictionary[$hundreds] . ' ' . $dictionary[100]; - if ($remainder) { - $string .= $conjunction . convert_number_to_words($remainder); - } - break; - default: - $baseUnit = pow(1000, floor(log($number, 1000))); - $numBaseUnits = (int) ($number / $baseUnit); - $remainder = $number % $baseUnit; - $string = convert_number_to_words($numBaseUnits) . ' ' . $dictionary[$baseUnit]; - if ($remainder) { - $string .= $remainder < 100 ? $conjunction : $separator; - $string .= convert_number_to_words($remainder); - } - break; - } - - if (null !== $fraction && is_numeric($fraction)) { - $string .= $decimal; - $words = array(); - foreach (str_split((string) $fraction) as $number) { - $words[] = $dictionary[$number]; - } - $string .= implode(' ', $words); - } - - return strtolower($string); + 1 => 'One', + 2 => 'Two', + 3 => 'Three', + 4 => 'Four', + 5 => 'Five', + 6 => 'Six', + 7 => 'Seven', + 8 => 'Eight', + 9 => 'Nine', + 10 => 'Ten', + 11 => 'Eleven', + 12 => 'Twelve', + 13 => 'Thirteen', + 14 => 'Fourteen', + 15 => 'Fifteen', + 16 => 'Sixteen', + 17 => 'Seventeen', + 18 => 'Eighteen', + 19 => 'Nineteen', + 20 => 'Twenty', + 30 => 'Thirty', + 40 => 'Fourty', + 50 => 'Fifty', + 60 => 'Sixty', + 70 => 'Seventy', + 80 => 'Eighty', + 90 => 'Ninety', + 100 => 'Hundred', + 1000 => 'Thousand', + 1000000 => 'Million', + 1000000000 => 'Billion', + 1000000000000 => 'Trillion', + 1000000000000000 => 'Quadrillion', + 1000000000000000000 => 'Quintillion' + ); + + if (!is_numeric($number)) + { + return false; + } + + if (($number >= 0 && (int) $number < 0) || (int) $number < 0 - PHP_INT_MAX) + { + // overflow + trigger_error( + 'convert_number_to_words only accepts numbers between -' . PHP_INT_MAX . ' and ' . PHP_INT_MAX, + E_USER_WARNING + ); + return false; + } + + if ($number < 0) + { + return $negative . convert_number_to_words(abs($number)); + } + + $string = $fraction = null; + + if (strpos($number, '.') !== false) + { + list($number, $fraction) = explode('.', $number); + } + + switch (true) + { + case $number < 21: + $string = $dictionary[$number]; + break; + case $number < 100: + $tens = ((int) ($number / 10)) * 10; + $units = $number % 10; + $string = $dictionary[$tens]; + if ($units) + { + $string .= $hyphen . $dictionary[$units]; + } + break; + case $number < 1000: + $hundreds = $number / 100; + $remainder = $number % 100; + $string = $dictionary[$hundreds] . ' ' . $dictionary[100]; + if ($remainder) + { + $string .= $conjunction . convert_number_to_words($remainder); + } + break; + default: + $baseUnit = pow(1000, floor(log($number, 1000))); + $numBaseUnits = (int) ($number / $baseUnit); + $remainder = $number % $baseUnit; + $string = convert_number_to_words($numBaseUnits) . ' ' . $dictionary[$baseUnit]; + if ($remainder) + { + $string .= $remainder < 100 ? $conjunction : $separator; + $string .= convert_number_to_words($remainder); + } + break; + } + + if (null !== $fraction && is_numeric($fraction)) + { + $string .= $decimal; + $words = array(); + foreach (str_split((string) $fraction) as $number) + { + $words[] = $dictionary[$number]; + } + + $string .= implode(' ', $words); + } + + return strtolower($string); } /** * Function for displaying what called function, useful for debugging */ -function _xls_whereCalled( $level = 1 ) { +// @codingStandardsIgnoreStart +function _xls_whereCalled($level = 1) +// @codingStandardsIgnoreEnd +{ $trace = debug_backtrace(); $file = isset($trace[$level]['file']) ? $trace[$level]['file'] : "file?"; $line = isset($trace[$level]['line']) ? $trace[$level]['line'] : "line?"; $object = isset($trace[$level]['object']) ? $trace[$level]['object'] : "object?"; - if (is_object($object)) { $object = get_class($object); } + if (is_object($object)) + { + $object = get_class($object); + } return "Where called: class $object was called on line $line of $file"; - } -function _dbx($sql) { - //Run SQL query directly +function _dbx($sql) +{ + // Run SQL query directly return Yii::app()->db->createCommand($sql)->execute(); } + function _xt($strToTranslate) { - echo Yii::t('global',$strToTranslate); + echo Yii::t('global', $strToTranslate); Yii::log("Called outdated _xt() function for string ".$strToTranslate, CLogger::LEVEL_WARNING, 'application.'.__CLASS__.".".__FUNCTION__); } +// @codingStandardsIgnoreStart function _xls_convert_date_to_js($strFormat) +// @codingStandardsIgnoreEnd { - - $strFormat = str_replace("y","yy",$strFormat); - $strFormat = str_replace("Y","yyyy",$strFormat); - $strFormat = str_replace("d","dd",$strFormat); - $strFormat = str_replace("m","mm",$strFormat); + $strFormat = str_replace("y", "yy", $strFormat); + $strFormat = str_replace("Y", "yyyy", $strFormat); + $strFormat = str_replace("d", "dd", $strFormat); + $strFormat = str_replace("m", "mm", $strFormat); return $strFormat; - } -function recurse_copy($src,$dst) { +// @codingStandardsIgnoreStart +function recurse_copy($src, $dst) +// @codingStandardsIgnoreEnd +{ $dir = opendir($src); @mkdir($dst); - while(false !== ( $file = readdir($dir)) ) { - if (( $file != '.' ) && ( $file != '..' )) { - if ( is_dir($src . '/' . $file) ) { - recurse_copy($src . '/' . $file,$dst . '/' . $file); + while(false !== ( $file = readdir($dir))) + { + if (( $file != '.' ) && ( $file != '..' )) + { + if (is_dir($src . '/' . $file)) + { + recurse_copy($src . '/' . $file, $dst . '/' . $file); } else { - copy($src . '/' . $file,$dst . '/' . $file); + copy($src . '/' . $file, $dst . '/' . $file); } } } + closedir($dir); } -function rrmdir($dir) { - if (is_dir($dir)) { +function rrmdir($dir) +{ + if (is_dir($dir)) + { $files = scandir($dir); foreach ($files as $file) - if ($file != "." && $file != "..") rrmdir("$dir/$file"); + { + if ($file != "." && $file != "..") + { + rrmdir("$dir/$file"); + } + } + rmdir($dir); } - else if (file_exists($dir)) unlink($dir); + elseif (file_exists($dir)) + { + unlink($dir); + } } // Function to Copy folders and files -function rcopy($src, $dst) { - if (file_exists ( $dst )) - rrmdir ( $dst ); - if (is_dir ( $src )) { - mkdir ( $dst ); - $files = scandir ( $src ); - foreach ( $files as $file ) +function rcopy($src, $dst) +{ + if (file_exists($dst)) + { + rrmdir($dst); + } + + if (is_dir($src)) + { + mkdir($dst); + $files = scandir($src); + foreach ($files as $file) + { if ($file != "." && $file != "..") - rcopy ( "$src/$file", "$dst/$file" ); - } else if (file_exists ( $src )) - copy ( $src, $dst ); + { + rcopy("$src/$file", "$dst/$file"); + } + } + } elseif (file_exists($src)) { + copy($src, $dst); + } } +// @codingStandardsIgnoreStart function RemoveEmptySubFolders($path) +// @codingStandardsIgnoreEnd { - $empty=true; + $empty = true; foreach (glob($path.DIRECTORY_SEPARATOR."*") as $file) { $empty &= is_dir($file) && RemoveEmptySubFolders($file); } + return $empty && @rmdir($path); } -function _xls_custom_css_folder($local=false) +// @codingStandardsIgnoreStart +function _xls_custom_css_folder($local = false) +// @codingStandardsIgnoreEnd { - if(Yii::app()->params['LIGHTSPEED_MT']=="1") + if(Yii::app()->params['LIGHTSPEED_MT'] == "1") + { return "http://lightspeedwebstore.s3.amazonaws.com/". Yii::app()->params['LIGHTSPEED_HOSTING_LIGHTSPEED_URL']."/themes/"; - else - { + } else { $strCustomFolder = Yii::app()->theme->info->useCustomFolderForCustomcss ? '/custom' : ''; return ($local ? YiiBase::getPathOfAlias('custom') : Yii::app()->baseUrl . $strCustomFolder) . "/themes/"; } - } +// @codingStandardsIgnoreStart function _upload_default_header_to_s3() +// @codingStandardsIgnoreEnd { Gallery::LoadGallery(1); $d = dir(YiiBase::getPathOfAlias('webroot')."/images/header"); - while (false!== ($filename = $d->read())) + while (false !== ($filename = $d->read())) { if ($filename == "defaultheader.png") { @@ -2387,33 +3004,33 @@ function _upload_default_header_to_s3() $model->description = ''; $model->thumb_ext = 'png'; $model->save(); - $arrImages["/images/header/".$filename] = - CHtml::image(Yii::app()->request->baseUrl."/images/header/".$filename); + $arrImages["/images/header/".$filename] = CHtml::image(Yii::app()->request->baseUrl."/images/header/".$filename); $src = YiiBase::getPathOfAlias('webroot')."/images/header/".$filename; $fileinfo = mb_pathinfo($filename); - $imageFile = new CUploadedFile($filename, + $imageFile = new CUploadedFile( + $filename, $src, "image/".$fileinfo['extension'], getimagesize($src), null ); - if(Yii::app()->params['LIGHTSPEED_MT']=='1') + if(Yii::app()->params['LIGHTSPEED_MT'] == '1') + { $model->setS3Image($imageFile); - _xls_set_conf('HEADER_IMAGE', + } + + _xls_set_conf( + 'HEADER_IMAGE', "//lightspeedwebstore.s3.amazonaws.com/". _xls_get_conf('LIGHTSPEED_HOSTING_LIGHTSPEED_URL'). "/gallery/1/".$model->id.".png" ); - } } - - - } /** @@ -2423,7 +3040,8 @@ function _upload_default_header_to_s3() * * @return string Indented version of the original JSON string. */ -function prettyjson($json) { +function prettyjson($json) +{ $result = ''; $pos = 0; @@ -2433,21 +3051,23 @@ function prettyjson($json) { $prevChar = ''; $outOfQuotes = true; - for ($i=0; $i<=$strLen; $i++) { - + for ($i = 0; $i <= $strLen; $i++) + { // Grab the next character in the string. $char = substr($json, $i, 1); // Are we inside a quoted string? - if ($char == '"' && $prevChar != '\\') { + if ($char == '"' && $prevChar != '\\') + { $outOfQuotes = !$outOfQuotes; // If this character is the end of an element, // output a new line and indent the next line. - } else if(($char == '}' || $char == ']') && $outOfQuotes) { + } elseif(($char == '}' || $char == ']') && $outOfQuotes) { $result .= $newLine; $pos --; - for ($j=0; $j<$pos; $j++) { + for ($j = 0; $j < $pos; $j++) + { $result .= $indentStr; } } @@ -2457,13 +3077,16 @@ function prettyjson($json) { // If the last character was the beginning of an element, // output a new line and indent the next line. - if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) { + if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) + { $result .= $newLine; - if ($char == '{' || $char == '[') { + if ($char == '{' || $char == '[') + { $pos ++; } - for ($j = 0; $j < $pos; $j++) { + for ($j = 0; $j < $pos; $j++) + { $result .= $indentStr; } } @@ -2476,7 +3099,6 @@ function prettyjson($json) { function _runMigrationTool($steps = null) { - $commandPath = Yii::app()->getBasePath() . DIRECTORY_SEPARATOR . 'commands'; $runner = new CConsoleCommandRunner(); $runner->addCommands($commandPath); @@ -2485,13 +3107,15 @@ function _runMigrationTool($steps = null) $commandPath = Yii::app()->getBasePath() . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'SingleMigrateCommand'; $runner->addCommands($commandPath); if(is_null($steps)) - $strCommand = 'migrate'; - elseif($steps == 'set') - $strCommand = 'setmigrate'; - elseif($steps == 'upgrade') - $strCommand = 'upgrademigrate'; - else - $strCommand = 'singlemigrate'; + { + $strCommand = 'migrate'; + } elseif($steps == 'set') { + $strCommand = 'setmigrate'; + } elseif($steps == 'upgrade') { + $strCommand = 'upgrademigrate'; + } else { + $strCommand = 'singlemigrate'; + } Yii::log("Migrating with $strCommand", 'error', 'application.'.__CLASS__.".".__FUNCTION__); $args = array('yiic', $strCommand, '--interactive=0','--migrationTable=xlsws_migrations'); @@ -2499,7 +3123,6 @@ function _runMigrationTool($steps = null) ob_start(); $runner->run($args); return htmlentities(ob_get_clean(), null, Yii::app()->charset); - } diff --git a/core/protected/components/zip.php b/core/protected/components/zip.php index 2054b53d..68660def 100644 --- a/core/protected/components/zip.php +++ b/core/protected/components/zip.php @@ -1,4 +1,6 @@ user->setFlash( 'error', - Yii::t('global','This email address already exists but that is not the correct password so we cannot log you in.') + Yii::t('global', 'This email address already exists but that is not the correct password so we cannot log you in.') ); Yii::log( $model->contactEmail." login from checkout with invalid password", @@ -694,7 +694,7 @@ public function actionCheckout() ); $this->refresh(); return; - break; + case UserIdentity::ERROR_USERNAME_INVALID: $objCustomer = Customer::CreateFromCheckoutForm($model); $identity = new UserIdentity($model->contactEmail, $model->createPassword); @@ -711,16 +711,17 @@ public function actionCheckout() Yii::app()->user->setFlash( 'error', - Yii::t('global','Error logging in after creating account. Cannot continue.') + Yii::t('global', 'Error logging in after creating account. Cannot continue.') ); $this->refresh(); return; } - break; + case UserIdentity::ERROR_NONE: break; + default: Yii::log( "Error: Unhandled errorCode " . $identity->errorCode, diff --git a/core/protected/controllers/InstallController.php b/core/protected/controllers/InstallController.php index 05b22916..51d5a0b1 100644 --- a/core/protected/controllers/InstallController.php +++ b/core/protected/controllers/InstallController.php @@ -1134,7 +1134,6 @@ protected function actionUpdateConfiguration() $objConfig->save(); //What we're gonna do right here is go back.... way back... - _xls_set_conf('DATABASE_SCHEMA_VERSION',447); return array('result'=>"success",'makeline'=>50,'tag'=>'Migrating Database','total'=>50); } diff --git a/core/protected/controllers/LegacysoapController.php b/core/protected/controllers/LegacysoapController.php index 7cbdadcf..7d0f37f7 100644 --- a/core/protected/controllers/LegacysoapController.php +++ b/core/protected/controllers/LegacysoapController.php @@ -911,7 +911,7 @@ public function remove_product_images($passkey , $intRowid){ return self::OK; try { - $objProduct->DeleteImages(); + $objProduct->deleteImages(); } catch(Exception $e) { Yii::log('Error deleting product images for ' . $intRowid . @@ -1635,15 +1635,26 @@ public function add_quote_item($passkey if (empty($strDescription)) $strDescription=$objProduct->title; - if(_xls_get_conf('TAX_INCLUSIVE_PRICING') == '1') - list($fltTaxedPrice, $arrTaxes) = - Tax::CalculatePricesWithTax($fltSell, $objDocument->fk_tax_code_id, $objProduct->tax_status_id); - else $fltTaxedPrice = $fltSell; + if (_xls_get_conf('TAX_INCLUSIVE_PRICING') == '1') + { + $arr = Tax::calculatePricesWithTax($fltSell, $objDocument->fk_tax_code_id, $objProduct->tax_status_id); + + $fltTaxedPrice = $arr['fltSellTotalWithTax']; + } + else + { + $fltTaxedPrice = $fltSell; + } - $retVal = $objDocument->AddSoapProduct($objDocument->id, + $retVal = $objDocument->AddSoapProduct( + $objDocument->id, $objProduct, - $fltQty, $strDescription, - $fltTaxedPrice, $fltDiscount, CartType::quote); + $fltQty, + $strDescription, + $fltTaxedPrice, + $fltDiscount, + CartType::quote + ); if (!$retVal) return self::UNKNOWN_ERROR; diff --git a/core/protected/controllers/MyaccountController.php b/core/protected/controllers/MyaccountController.php index 8118fbda..bdeb32c1 100644 --- a/core/protected/controllers/MyaccountController.php +++ b/core/protected/controllers/MyaccountController.php @@ -49,77 +49,87 @@ public function actionEdit() { //For current customers $model = Customer::GetCurrent(); - } // collect user input data - if(isset($_POST['Customer'])) + if (isset($_POST['Customer'])) { if (is_null($model->id)) { $model->scenario = Customer::SCENARIO_INSERT; } - else $model->scenario = Customer::SCENARIO_UPDATE; + else + { + $model->scenario = Customer::SCENARIO_UPDATE; + } $strPassword = $_POST['Customer']['password']; + if (empty($strPassword) && isset($_POST['Customer']['password'])) { unset($_POST['Customer']['password']); if (empty($strPassword) && isset($_POST['Customer']['password_repeat'])) + { unset($_POST['Customer']['password_repeat']); + } + } + elseif ($model->scenario == Customer::SCENARIO_UPDATE) + { + $model->scenario = Customer::SCENARIO_UPDATEPASSWORD; } - elseif ($model->scenario == Customer::SCENARIO_UPDATE) $model->scenario = Customer::SCENARIO_UPDATEPASSWORD; - $model->attributes=$_POST['Customer']; + $model->attributes = $_POST['Customer']; - if($model->validate()) + if ($model->validate()) { //If we haven't created a new password, retain the old one -- need repeat to pass validation - if ($model->scenario== Customer::SCENARIO_INSERT || $model->scenario== Customer::SCENARIO_UPDATEPASSWORD) + if ($model->scenario == Customer::SCENARIO_INSERT || $model->scenario == Customer::SCENARIO_UPDATEPASSWORD) { - //$model->password = _xls_encrypt($strPassword); $model->password = $strPassword; $model->password_repeat = $model->password; } - if ($model->scenario== Customer::SCENARIO_INSERT && _xls_get_conf('MODERATE_REGISTRATION')==1) + if ($model->scenario == Customer::SCENARIO_INSERT && _xls_get_conf('MODERATE_REGISTRATION') == 1) { $model->allow_login = Customer::UNAPPROVED_USER; $model->record_type = Customer::REGISTERED; } - elseif ($model->scenario== Customer::SCENARIO_INSERT) + elseif ($model->scenario == Customer::SCENARIO_INSERT) { $model->allow_login = Customer::NORMAL_USER; $model->record_type = Customer::REGISTERED; } + if (!$model->save()) { //Put plain text passwords back for form refresh $model->password = $strPassword; $model->password_repeat = $strPassword; - Yii::log("Error creating new user ".print_r($model->getErrors(),true), 'error', 'application.'.__CLASS__.".".__FUNCTION__); + Yii::log("Error creating new user ".print_r($model->getErrors(), true), 'error', 'application.'.__CLASS__.".".__FUNCTION__); } else { - if (Yii::app()->user->isGuest) - $this->createAndLogin($model,$strPassword); + { + $this->createAndLogin($model, $strPassword); + } else - $this->triggerEmailCampaign($model,'onUpdateCustomer'); + { + $this->triggerEmailCampaign($model, 'onUpdateCustomer'); + } $this->redirect($this->createUrl("/myaccount")); } - } } $this->breadcrumbs = array( - Yii::t('global','My Account')=>$this->createUrl("/myaccount"), - Yii::t('global','Edit Account')=>$this->createUrl("myaccount/edit"), + Yii::t('global', 'My Account') => $this->createUrl("/myaccount"), + Yii::t('global', 'Edit Account') => $this->createUrl("myaccount/edit"), ); $model->password = null; //don't bother sending password to form - $this->render('edit',array('model'=>$model)); + $this->render('edit', array('model' => $model)); } /** @@ -281,7 +291,7 @@ public function actionCreate() */ protected function createAndLogin($model,$strPassword) { - if(Yii::app()->params['MODERATE_REGISTRATION']==1) + if (Yii::app()->params['MODERATE_REGISTRATION'] == 1) { $this->triggerEmailCampaign($model,'onAddCustomer'); @@ -292,34 +302,39 @@ protected function createAndLogin($model,$strPassword) } //We've successfully created the account, so just log in - $loginModel=new LoginForm; - $loginModel->email=$model->email; - $loginModel->password=$strPassword; + $loginModel = new LoginForm; + $loginModel->email = $model->email; + $loginModel->password = $strPassword; // validate user input and redirect to the previous page if valid - if($loginModel->validate() && $loginModel->login()) + if ($loginModel->validate() && $loginModel->login()) { Yii::app()->user->setFlash('success', Yii::t('customer','Your account has been created and you have been logged in automatically.')); } else { - Yii::log("Error logging in our newly created user ".print_r($loginModel->getErrors(),true), - 'error', 'application.'.__CLASS__.".".__FUNCTION__); - Yii::app()->user->setFlash('error', - Yii::t('customer','Your account has been created but we had an error logging you in.')); + Yii::log( + "Error logging in our newly created user " . print_r($loginModel->getErrors(), true), + 'error', + 'application.'.__CLASS__.".".__FUNCTION__ + ); + + Yii::app()->user->setFlash( + 'error', + Yii::t('customer','Your account has been created but we had an error logging you in.') + ); } $this->triggerEmailCampaign($model,'onAddCustomer'); //Common SSL mode means we need to pass back to the original URL and log in again automatically - if(Yii::app()->isCommonSSL) + if (Yii::app()->isCommonSSL) { $strIdentity = Yii::app()->user->id.",".Yii::app()->shoppingcart->id.",site,index"; Yii::log("Log in ".$strIdentity, 'info', 'application.'.__CLASS__.".".__FUNCTION__); $redirString = _xls_encrypt($strIdentity); - $url = Yii::app()->controller->createAbsoluteUrl( - 'commonssl/login',array('link'=>$redirString)); + $url = Yii::app()->controller->createAbsoluteUrl('commonssl/login', array('link'=>$redirString)); $url = str_replace( "https://".Yii::app()->params['LIGHTSPEED_HOSTING_LIGHTSPEED_URL'], diff --git a/core/protected/controllers/SoapController.php b/core/protected/controllers/SoapController.php index 4fe95ba6..15397fef 100644 --- a/core/protected/controllers/SoapController.php +++ b/core/protected/controllers/SoapController.php @@ -594,7 +594,7 @@ public function remove_product_images($passkey , $intRowid) return self::OK; try { - $objProduct->DeleteImages(); + $objProduct->deleteImages(); } catch(Exception $e) { $strMsg = "Error deleting product image for $intRowid"; @@ -1534,7 +1534,9 @@ protected function json_encode_orders($obj, $attributeNames) foreach ($arrItems as $itemKey => $objItem) { - list($taxCharged,$taxesIndividual,$taxRates) = Tax::CalculatePricesWithTax($objItem->sell_total,$order->tax_code_id,$objItem->product->tax_status_id); + $arr = Tax::calculatePricesWithTax($objItem->sell_total, $order->tax_code_id, $objItem->product->tax_status_id); + $taxRates = $arr['arrTaxRates']; + $arrTaxRatesForItem = array(); foreach ($taxRates as $key => $value) { if ($value > 0) { @@ -1658,4 +1660,4 @@ public function assign_lightspeed_id($passkey, $id, $lightspeed_id) Customer::model()->updateByPk($id,array('lightspeed_id'=>$lightspeed_id)); return self::OK; } -} \ No newline at end of file +} diff --git a/core/protected/extensions/umber/assets/customized/_base.scss b/core/protected/extensions/umber/assets/customized/_base.scss deleted file mode 100755 index 43b88324..00000000 --- a/core/protected/extensions/umber/assets/customized/_base.scss +++ /dev/null @@ -1,224 +0,0 @@ -$accent-background-color: #3287cc !default; -$accent-color: white !default; - -$overlay-background-color: #eee !default; -$overlay-color: #555 !default; - -$heading-font-weight: bold !default; -$heading-font-family: 'Open Sans', 'Helvetica Neue', Helvetica, sans-serif !default; - -$confirmation-color: green !default; - -// Font faces -$body-font-family: 'Open Sans', 'Helvetica Neue', Helvetica, sans-serif !default; - - -body.overlay, .editcartmodal.webstore-modal.show { - background-color: $overlay-background-color; -} - - -.webstore-overlay { - font-family: $body-font-family; - - h1 { - font-weight: $heading-font-weight; - font-family: $heading-font-family; - } - - section footer p { - $overlay-color-adjusted: $overlay-color; - @if(lightness($overlay-background-color) > 50) { - $overlay-color-adjusted: lighten($overlay-color, 25%); - } @else { - $overlay-color-adjusted: darken($overlay-color, 25%); - } - - color: $overlay-color-adjusted; - strong { color: $overlay-color-adjusted; } - a { color: $overlay-color-adjusted; } - } - - a { - color: $accent-background-color; - &:hover { border-bottom-color: $accent-background-color; } - - &.hasborder { - border-bottom-color: lighten($accent-background-color, 25%); - &:hover { border-bottom-color: $accent-background-color; } - } - } - - @if(lightness($overlay-background-color) < 20) { - .section-inner { border-color: #fff; } - } - - header.overlay { - #addcart .exit, h1 a { color: $overlay-color; } - #addcart .exit:hover { border-bottom-color: $overlay-color; } - } - - button, .button { - background-color: $calltoaction-color; - color: $accent-color; - - &:hover { background-color: darken($accent-background-color,10%); } - - &.inset:hover { - border-color: $accent-background-color; - background: $accent-background-color; - color: $accent-color; - } - - &.continue, &.share { - &:hover { - background: none; - border-color: $accent-background-color; - color: $accent-background-color; - &:before { color: $accent-background-color; } - } - } - } - - .choices { - button, .button { - &:hover { - background: $accent-background-color; - border-color: $accent-background-color; - color: $accent-color; - } - } - } - - .field-container select.modal-accent-color { color: $accent-background-color; } - - .thankyou a.print:hover, .thankyou a.print:active { - color: $accent-background-color; - border-color: $accent-background-color; - } - - .address-blocks { - p .controls { - a:hover { - border-color: $accent-background-color; - } - } - button:hover { - background-color: $accent-background-color; - border-color: $accent-background-color; - color: lighten($accent-background-color, 100%); - } - } - - .wishlists { - button:hover { - background-color: $accent-background-color; - border-color: $accent-background-color; - color: lighten($accent-background-color, 100%); - } - .wishlist-block { - span.title { - color: $accent-background-color; - } - p:hover { - background-color: $accent-background-color; - border-color: $accent-background-color; - span.title { - color: lighten($accent-background-color, 100%); - } - } - } - } - - .order-history { - table.lines td.date { - color: $accent-background-color; - } - } -} - - - -.wishlist-lines { - .save, .add-to-cart { - background: $accent-background-color; - border-color: $accent-background-color; - - &:hover { - background: darken($accent-background-color,10%); - border-color: darken($accent-background-color,10%) - } - } - a.edit:hover { - border-color: $accent-background-color; - color: $accent-background-color; - } -} - -.wishlist-share a.service { - color: $accent-background-color; - &:hover { color: darken($accent-background-color,10%); } -} - -.wishlist-buttons { - button { - background: none; - color: #888; - - &:hover { - border-color: $accent-background-color; - color: $accent-background-color; - background: none; - } - } -} - -//MO - Prevent text selection -button, .button, .no-selection { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.webstore-modal-overlay, -//MO added second line to include add to cart. -.webstore-modal-overlay .cart-summary footer{ - button, .button, input[type="button"] { - background-color: $accent-background-color; - color: $accent-color; - - &:hover { background-color: darken($accent-background-color,10%); } - - &.inset:hover { - border-color: $accent-background-color; - background: $accent-background-color; - color: $accent-color; - } - - &.continue, &.share, &.webstore-change-item { - &:hover { - background: none; - border-color: $accent-background-color; - color: $accent-background-color; - &:before { color: $accent-background-color; } - } - } - - //added by MO to target the exit button in the add to cart. - #addcart .continue-shopping.exit { - background-color: #ccc; - color: #888; - &:hover { - background-color: #999; - color: #fff; - } - } - } -} - - - -.webstore-modal-overlay .shipping-estimate-line th > a:first-child{ - font-weight: bold; -} \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/customized/brooklyn2014.scss b/core/protected/extensions/umber/assets/customized/brooklyn2014.scss deleted file mode 100644 index 28a67e8c..00000000 --- a/core/protected/extensions/umber/assets/customized/brooklyn2014.scss +++ /dev/null @@ -1,4 +0,0 @@ -$accent-background-color: #3287CC; -$calltoaction-color: #3287CC; - -@import "base"; diff --git a/core/protected/extensions/umber/assets/docs.scss b/core/protected/extensions/umber/assets/docs.scss deleted file mode 100755 index 65c22f8f..00000000 --- a/core/protected/extensions/umber/assets/docs.scss +++ /dev/null @@ -1,379 +0,0 @@ -@import 'lib/normalize'; - -@charset "utf-8"; - -$break-mobile: 0px; // This is used in limited situations, generally styles layer-up, not down. -$break-small: 560px; -$break-medium: 720px; -$break-large: 1025px; - -$break-short: 500px; - -@import 'mixins/html5-input-types'; - -@mixin media($media) { - @if $media == 'mobile' { - @media (max-width: $break-mobile) { @content; } - } - @else if $media == 'small' { - @media (min-width: $break-small) { @content; } - } - @else if $media == 'medium' { - @media (min-width: $break-medium) { @content; } - } - @else if $media == 'large' { - @media (min-width: $break-large) { @content; } - } - @else if $media == 'short' { - @media (max-height: $break-short) { @content; } - } - @else { - @content; - } -} - -* { - @include box-sizing(border-box); -} - -// Colors -$font-color: #000; -$highlight: #ffc; - -$grey-medium: #666; - -$blue: #3d89d1; -$green: #95BE64; - -// Navigation - - -$header-bg-color: $blue; - -// Link colors -$link-color: $blue; -$link-hover-color: darken($blue,10%); -$link-active-color: darken($blue,20%); -//$link-focus-color: false; -//$link-visited-color: false; - -a { - color: $link-color; - &:active { color: $link-active-color; } - a:hover { color: $link-hover-color; } -} - -// Font Sets -$font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, Verdana, Arial, sans-serif; -$font-family-enhanced: 'Open Sans', 'Helvetica Neue', Helvetica, Verdana, Arial, sans-serif; -$font-family-helvetica: 'Helvetica Neue', Helvetica, Verdana, Arial, sans-serif; - -body { - font-family: $font-family; - color: #444; - //MO boostrap override - font-size:16px; -} - -#{headings()} { - font-family: $font-family-enhanced; - font-weight: 600; - margin: 0 0 .25em; - - small { - color: $grey-medium; - font-weight: normal; - } - - a { - text-decoration: none; - border-bottom: 2px solid lighten($blue, 40%); - padding: 0; - color: $blue; - - &:hover { - border-bottom: 2px solid $blue; - } - } -} - -h1 { - font-family: $font-family-helvetica; - font-size: 6em; - font-weight: 100; - margin: 1em 0 .25em; - color: #999; -} -h2 { - font-size: 1.5em; - font-weight: 600; - margin: 1.5em 0 .25em; - color: #666; -} -h3 { - font-size: 1.25em; -} -h4 { - font-size: 1.125em; -} - -ol, ul { - -} -li { - font: .9em/1.6 $font-family; - -} - -p { - font: .9em/1.6 $font-family; - margin: 0 0 1em; - - &.large, &.medium { - font-family: $font-family-enhanced; - line-height: 1.5; - font-size: 1.1em; - } - - &.large { - font-size: 1.5em; - margin-bottom: .5em; - } -} - - -ol.products { - width: 100%; - margin: 0; - padding: 0; - border: 1px solid #ccc; - @include clearfix(); - - li { - width: 50%; - display: inline-block; - float: left; - padding: 1.25rem 1rem 1rem; - - } - - :first-child > li { border-right: 1px solid #ccc; } - :last-child > li { - margin-left: -1px; - border-left: 1px solid #ccc; - } - - a { - color: #888; - - &:hover li { background-color: #f8f8f8; } - } - - h2 { - color: $blue; - margin: 0 0 .125em; - font-weight: 400; - font-size: 2.5rem; - line-height: 1; - } - p { - margin: 0; - - } -} - - - -body { - margin-top: 68px; - - & > header { - h1 { - border-top: none; - margin: 0; - font: bold 1.25rem $font-family-enhanced; - - padding: 1em 5%; - color: #888; - font-weight: 600; - background-color: rgba(255,255,255,.9); - border-bottom: 1px solid #eee; - position: fixed; - top: 0; - left: 0; - width: 100%; - } - } -} - -#page { - margin: 5em 5%; -} - -img { - &.diagram { - border: 1px solid #ccc; - padding: 20px; - margin-bottom: 1em - } -} - -ol.images, ol.colors { - padding: 0; - list-style: none; - - display: -webkit-box; - display: -moz-box; - display: -ms-flexbox; - display: -webkit-flex; - display: flex; - - -webkit-flex-flow: row wrap; - flex-flow: row wrap; - - li { - margin: 0 1em 1em 0; - } -} - -ol.colors { - & > li { - width: 11em; - overflow: hidden; - - padding: 10px 10px 0 10px; - border: 1px solid #ccc; - - .swatch { - display: block; - width: 100%; - height: 150px; - margin: 0 0 .25em; - padding: 100px 0 0 0; - text-align: center; - font: 2em $font-family-enhanced; - text-transform: uppercase; - } - - h3 { - font-weight: 600; - font-size: 1.25em; - } - } - - p { - font-size: .7em; - } - - ul { - list-style: none; - padding: 0; - - li { - float: left; - width: 5em; - - } - } -} - - -.note, .pro, .future, .deprecated, .todo { - &:before { - text-transform: uppercase; - font-weight: 300; - font-size: .95em; - padding: 2px 4px; - margin: 0 5px 0 -2px; - } -} - -.deprecated { - color: #999; - background-color: #eee; - padding: 5px; - margin-top: -5px; - - &:before { - content: "Deprecated"; - font-weight: 300; - color: #999; - border: 1px dotted #999; - } -} -.future { - color: #777; - - &:before { - content: "Future"; - font-weight: 300; - background-color: #999; - color: #fff; - } -} -.pro { - color: #777; - - &:before { - content: "Pro"; - background-color: #84B745; - color: #fff; - } -} -.todo { - &:before { - font-weight: 600; - content: 'To Do'; - background-color: #ffc; - border: 1px dotted #ccc; - color: #666; - } -} - -.note { - // background-color: #ffc; - color: #777; - - &:before { - content: "Note"; - background-color: #ffc; - color: #999; - border: 1px dotted #ccc; - } -} - - -dl { - overflow: hidden; - border-bottom: 1px solid #eee; - - dd, dt { - border-top: 1px solid #eee; - - margin: 0; - padding: 10px 0; - font: normal .8em $font-family; - } - - dt { - font: 1.25em $font-family-enhanced; - width: 150px; - float: left; - margin: 0; - font-weight: bold; - } - - dd { - margin-left: 150px; - min-height: 5em; - - *:last-child { - margin-bottom: 0; - } - - p { - margin: 0 0 .5em; - } - } - -} diff --git a/core/protected/extensions/umber/assets/lib/_clearfix-hack b/core/protected/extensions/umber/assets/lib/_clearfix-hack deleted file mode 100644 index 47b5b22b..00000000 --- a/core/protected/extensions/umber/assets/lib/_clearfix-hack +++ /dev/null @@ -1,26 +0,0 @@ -/** - * For modern browsers - * 1. The space content is one way to avoid an Opera bug when the - * contenteditable attribute is included anywhere else in the document. - * Otherwise it causes space to appear at the top and bottom of elements - * that are clearfixed. - * 2. The use of `table` rather than `block` is only necessary if using - * `:before` to contain the top-margins of child elements. - */ -.cf:before, -.cf:after { - content: " "; /* 1 */ - display: table; /* 2 */ -} - -.cf:after { - clear: both; -} - -/** - * For IE 6/7 only - * Include this rule to trigger hasLayout and contain floats. - */ -.cf { - *zoom: 1; -} \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/lib/_normalize.scss b/core/protected/extensions/umber/assets/lib/_normalize.scss deleted file mode 100755 index e93e9aca..00000000 --- a/core/protected/extensions/umber/assets/lib/_normalize.scss +++ /dev/null @@ -1,408 +0,0 @@ -.webstore-modal{ - /*! normalize.css v2.1.3 | MIT License | git.io/normalize */ - - /* ========================================================================== - HTML5 display definitions - ========================================================================== */ - - /** - * Correct `block` display not defined in IE 8/9. - */ - - article, - aside, - details, - figcaption, - figure, - footer, - header, - hgroup, - main, - nav, - section, - summary { - display: block; - } - - /** - * Correct `inline-block` display not defined in IE 8/9. - */ - - audio, - canvas, - video { - display: inline-block; - } - - /** - * Prevent modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ - - audio:not([controls]) { - display: none; - height: 0; - } - - /** - * Address `[hidden]` styling not present in IE 8/9. - * Hide the `template` element in IE, Safari, and Firefox < 22. - */ - - [hidden], - template { - display: none; - } - - /* ========================================================================== - Base - ========================================================================== */ - - /** - * 1. Set default font family to sans-serif. - * 2. Prevent iOS text size adjust after orientation change, without disabling - * user zoom. - */ - - html { - font-family: sans-serif; /* 1 */ - -ms-text-size-adjust: 100%; /* 2 */ - -webkit-text-size-adjust: 100%; /* 2 */ - } - - /** - * Remove default margin. - */ - - body { - margin: 0; - } - - /* ========================================================================== - Links - ========================================================================== */ - - /** - * Remove the gray background color from active links in IE 10. - */ - - a { - background: transparent; - } - - /** - * Address `outline` inconsistency between Chrome and other browsers. - */ - - a:focus { - outline: thin dotted; - } - - /** - * Improve readability when focused and also mouse hovered in all browsers. - */ - - a:active, - a:hover { - outline: 0; - } - - /* ========================================================================== - Typography - ========================================================================== */ - - /** - * Address variable `h1` font-size and margin within `section` and `article` - * contexts in Firefox 4+, Safari 5, and Chrome. - */ - - h1 { - font-size: 2em; - margin: 0.67em 0; - } - - /** - * Address styling not present in IE 8/9, Safari 5, and Chrome. - */ - - abbr[title] { - border-bottom: 1px dotted; - } - - /** - * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. - */ - - b, - strong { - font-weight: bold; - } - - /** - * Address styling not present in Safari 5 and Chrome. - */ - - dfn { - font-style: italic; - } - - /** - * Address differences between Firefox and other browsers. - */ - - hr { - -moz-box-sizing: content-box; - box-sizing: content-box; - height: 0; - } - - /** - * Address styling not present in IE 8/9. - */ - - mark { - background: #ff0; - color: #000; - } - - /** - * Correct font family set oddly in Safari 5 and Chrome. - */ - - code, - kbd, - pre, - samp { - font-family: monospace, serif; - font-size: 1em; - } - - /** - * Improve readability of pre-formatted text in all browsers. - */ - - pre { - white-space: pre-wrap; - } - - /** - * Set consistent quote types. - */ - - q { - quotes: "\201C" "\201D" "\2018" "\2019"; - } - - /** - * Address inconsistent and variable font size in all browsers. - */ - - small { - font-size: 80%; - } - - /** - * Prevent `sub` and `sup` affecting `line-height` in all browsers. - */ - - sub, - sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; - } - - sup { - top: -0.5em; - } - - sub { - bottom: -0.25em; - } - - /* ========================================================================== - Embedded content - ========================================================================== */ - - /** - * Remove border when inside `a` element in IE 8/9. - */ - - img { - border: 0; - } - - /** - * Correct overflow displayed oddly in IE 9. - */ - - svg:not(:root) { - overflow: hidden; - } - - /* ========================================================================== - Figures - ========================================================================== */ - - /** - * Address margin not present in IE 8/9 and Safari 5. - */ - - figure { - margin: 0; - } - - /* ========================================================================== - Forms - ========================================================================== */ - - /** - * Define consistent border, margin, and padding. - */ - - fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; - } - - /** - * 1. Correct `color` not being inherited in IE 8/9. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. - */ - - legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ - } - - /** - * 1. Correct font family not being inherited in all browsers. - * 2. Correct font size not being inherited in all browsers. - * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. - */ - - button, - input, - //select, - textarea { - font-family: inherit; /* 1 */ - font-size: 100%; /* 2 */ - margin: 0; /* 3 */ - } - - /** - * Address Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ - - button, - input { - line-height: normal; - } - - /** - * Address inconsistent `text-transform` inheritance for `button` and `select`. - * All other form control elements do not inherit `text-transform` values. - * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. - * Correct `select` style inheritance in Firefox 4+ and Opera. - */ - - button, - select { - text-transform: none; - } - - /** - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Correct inability to style clickable `input` types in iOS. - * 3. Improve usability and consistency of cursor style between image-type - * `input` and others. - */ - - button, - html input[type="button"], /* 1 */ - input[type="reset"], - input[type="submit"] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ - } - - /** - * Re-set default cursor for disabled elements. - */ - - button[disabled], - html input[disabled] { - cursor: default; - } - - /** - * 1. Address box sizing set to `content-box` in IE 8/9/10. - * 2. Remove excess padding in IE 8/9/10. - */ - - input[type="checkbox"], - input[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ - } - - /** - * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. - * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome - * (include `-moz` to future-proof). - */ - - input[type="search"] { - -webkit-appearance: textfield; /* 1 */ - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; /* 2 */ - box-sizing: content-box; - } - - /** - * Remove inner padding and search cancel button in Safari 5 and Chrome - * on OS X. - */ - - input[type="search"]::-webkit-search-cancel-button, - input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; - } - - /** - * Remove inner padding and border in Firefox 4+. - */ - - button::-moz-focus-inner, - input::-moz-focus-inner { - border: 0; - padding: 0; - } - - /** - * 1. Remove default vertical scrollbar in IE 8/9. - * 2. Improve readability and alignment in all browsers. - */ - - textarea { - overflow: auto; /* 1 */ - vertical-align: top; /* 2 */ - } - - /* ========================================================================== - Tables - ========================================================================== */ - - /** - * Remove most spacing between table cells. - */ - - table { - border-collapse: collapse; - border-spacing: 0; - } -} \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/mixins/_animations.scss b/core/protected/extensions/umber/assets/mixins/_animations.scss deleted file mode 100644 index 8d863a0e..00000000 --- a/core/protected/extensions/umber/assets/mixins/_animations.scss +++ /dev/null @@ -1,35 +0,0 @@ -//MO -//This mixin file can be removed when we update compass to latest version -//which would require first to update sass scss currently 3.2.12 to version like 3.4.2 or later. - -@mixin animation-duration($val) { - -webkit-animation-duration:$val; - -moz-animation-duration:$val; - -ms-animation-duration:$val; - -o-animation-duration:$val; - animation-duration:$val; -} - -@mixin animation-fill-mode($val) { - -webkit-animation-fill-mode:$val; - -moz-animation-fill-mode:$val; - -ms-animation-fill-mode:$val; - -o-animation-fill-mode:$val; - animation-fill-mode:$val; -} - -@mixin animation-iteration-count($val) { - -webkit-animation-iteration-count:$val; - -moz-animation-iteration-count:$val; - -ms-animation-iteration-count:$val; - -o-animation-iteration-count:$val; - animation-iteration-count:$val; -} - -@mixin animation-name($val) { - -webkit-animation-name:$val; - -moz-animation-name:$val; - -ms-animation-name:$val; - -o-animation-name:$val; - animation-name:$val; -} \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/mixins/_arrows.scss b/core/protected/extensions/umber/assets/mixins/_arrows.scss deleted file mode 100644 index 1b36cb57..00000000 --- a/core/protected/extensions/umber/assets/mixins/_arrows.scss +++ /dev/null @@ -1,78 +0,0 @@ - -// CSS Arrows -@mixin arrow($box-edge : bottom, - $edge-side : center, - $arrow-size : 10px, - $edge-side-offset : 0, - $fill-color : black, - $border-color : none, - $border-style : border) { - - // initiate internal variables - $box-edge-inverse: bottom; - $edge-side-pos: $edge-side; - $edge-side-pos-value: 0; - - // establish inverse variables - @if $box-edge == top { $box-edge-inverse: bottom; } - @else if $box-edge == right { $box-edge-inverse: left; } - @else if $box-edge == bottom { $box-edge-inverse: top; } - @else if $box-edge == left { $box-edge-inverse: right; } - - // calculate remaining internal variables - @if ($box-edge == 'top' or - $box-edge == 'bottom') { - @if $edge-side == center { - $edge-side-pos: left; - $edge-side-pos-value: 50%; - $edge-side-offset: (-$arrow-size); - } - } - @if ($box-edge == 'left' or - $box-edge == 'right') { - @if $edge-side == center { - $edge-side-pos: top; - $edge-side-pos-value: 50%; - $edge-side-offset: (-$arrow-size); - } - } - - &:after, &:before { - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border: solid rgba(#fff, 0); - } - - &:after { - border-color: rgba(#fff, 0); - border-width: $arrow-size - 1; - #{$box-edge}: (-$arrow-size) - $arrow-size + 2; - border-#{$box-edge-inverse}-color: $fill-color; - #{$edge-side-pos}: $edge-side-pos-value; - margin-#{$edge-side-pos}: $edge-side-offset + 1; - } - - @if $border-style == flag { - @include border-radius(2px); - &:before { - border-color: rgba(#fff, 0); - border-width: $arrow-size - 1; - #{$box-edge}: (-$arrow-size) - $arrow-size + 2; - border-#{$box-edge-inverse}-color: $border-color; - #{$edge-side-pos}: $edge-side-pos-value; - margin-#{$edge-side-pos}: $edge-side-offset + 2; - } - } @else { - &:before { - border-color: rgba(#fff, 0); - border-width: $arrow-size; - #{$box-edge}: (-$arrow-size) - $arrow-size; - border-#{$box-edge-inverse}-color: $border-color; - #{$edge-side-pos}: $edge-side-pos-value; - margin-#{$edge-side-pos}: $edge-side-offset; - } - } -} diff --git a/core/protected/extensions/umber/assets/mixins/_borders.scss b/core/protected/extensions/umber/assets/mixins/_borders.scss deleted file mode 100644 index 7c4b659f..00000000 --- a/core/protected/extensions/umber/assets/mixins/_borders.scss +++ /dev/null @@ -1,6 +0,0 @@ -@mixin border-radius($radius) { - -webkit-border-radius: $radius; - -moz-border-radius: $radius; - -ms-border-radius: $radius; - border-radius: $radius; -} \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/mixins/_flexbox.scss b/core/protected/extensions/umber/assets/mixins/_flexbox.scss deleted file mode 100644 index 2d874566..00000000 --- a/core/protected/extensions/umber/assets/mixins/_flexbox.scss +++ /dev/null @@ -1,47 +0,0 @@ -@mixin flexbox() { - display: -moz-box; - display: -ms-flexbox; - display: -webkit-flex; - display: flex; -} - -@mixin flex($values) { - -webkit-box-flex: $values; - -moz-box-flex: $values; - -webkit-flex: $values; - -ms-flex: $values; - flex: $values; -} - -@mixin order($val) { - -webkit-box-ordinal-group: $val; - -moz-box-ordinal-group: $val; - -ms-flex-order: $val; - -webkit-order: $val; - order: $val; -} - -@mixin direction($val) { - -webkit-flex-direction: $val; - flex-direction: $val; -} - -@mixin flow($val) { - -webkit-flex-flow: $val; - flex-flow: $val; -} - -@mixin wrap($val) { - -webkit-flex-wrap: $val; - flex-wrap: $val; -} - -@mixin justify-content($val) { - -webkit-justify-content: $val; - justify-content: $val; -} - -@mixin align-self($val) { - -webkit-align-self: $val; - align-self: $val; -} diff --git a/core/protected/extensions/umber/assets/mixins/_html5-input-types.scss b/core/protected/extensions/umber/assets/mixins/_html5-input-types.scss deleted file mode 100755 index d4bb9f4c..00000000 --- a/core/protected/extensions/umber/assets/mixins/_html5-input-types.scss +++ /dev/null @@ -1,87 +0,0 @@ -//************************************************************************// -// Generate a variable ($all-text-inputs) with a list of all html5 -// input types that have a text-based input, excluding textarea. -// http://diveintohtml5.org/forms.html -//************************************************************************// -$inputs-list: 'input[type="email"]', - 'input[type="number"]', - 'input[type="password"]', - 'input[type="search"]', - 'input[type="tel"]', - 'input[type="text"]', - 'input[type="url"]', - - // Webkit & Gecko may change the display of these in the future - 'input[type="color"]', - 'input[type="date"]', - 'input[type="datetime"]', - 'input[type="datetime-local"]', - 'input[type="month"]', - 'input[type="time"]', - 'input[type="week"]'; - -$unquoted-inputs-list: (); - -@each $input-type in $inputs-list { - $unquoted-inputs-list: append($unquoted-inputs-list, unquote($input-type), comma); -} - -$all-text-inputs: $unquoted-inputs-list; - -// You must use interpolation on the variable: -// #{$all-text-inputs} -//************************************************************************// -// #{$all-text-inputs}, textarea { -// border: 1px solid red; -// } - -// :hover and :focus pseudo elements -// Added by Ricardo Zea -// http://ricardozea.net -// @ricardozea -// Tracking: http://stackoverflow.com/questions/13180807/sass-create-mixin-for-input-fields - -$inputs-list-hf:'input[type="email"]:hover', - 'input[type="number"]:hover', - 'input[type="password"]:hover', - 'input[type="search"]:hover', - 'input[type="tel"]:hover', - 'input[type="text"]:hover', - 'input[type="url"]:hover', - 'input[type="color"]:hover', - 'input[type="date"]:hover', - 'input[type="datetime"]:hover', - 'input[type="datetime-local"]:hover', - 'input[type="month"]:hover', - 'input[type="time"]:hover', - 'input[type="week"]:hover', - - 'input[type="email"]:focus', - 'input[type="number"]:focus', - 'input[type="password"]:focus', - 'input[type="search"]:focus', - 'input[type="tel"]:focus', - 'input[type="text"]:focus', - 'input[type="url"]:focus', - 'input[type="color"]:focus', - 'input[type="date"]:focus', - 'input[type="datetime"]:focus', - 'input[type="datetime-local"]:focus', - 'input[type="month"]:focus', - 'input[type="time"]:focus', - 'input[type="week"]:focus'; - -$unquoted-inputs-list-hf: (); - -@each $input-type-hf in $inputs-list-hf { - $unquoted-inputs-list-hf: append($unquoted-inputs-list-hf, unquote($input-type-hf), comma); -} - -$all-text-inputs-hf: $unquoted-inputs-list-hf; - -// You must use interpolation on the variable: -// #{$all-text-inputs-hf} -//************************************************************************// -// #{$all-text-inputs-hf}, textarea { -// border: 1px solid red; -// } \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/mixins/_keyframes.scss b/core/protected/extensions/umber/assets/mixins/_keyframes.scss deleted file mode 100755 index 76f23d3f..00000000 --- a/core/protected/extensions/umber/assets/mixins/_keyframes.scss +++ /dev/null @@ -1,15 +0,0 @@ -// keyframes mixin -@mixin keyframes($name) { - @-webkit-keyframes #{$name} { - @content; - } - @-moz-keyframes #{$name} { - @content; - } - @-ms-keyframes #{$name} { - @content; - } - @keyframes #{$name} { - @content; - } -} \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/mixins/_placeholders.scss b/core/protected/extensions/umber/assets/mixins/_placeholders.scss deleted file mode 100644 index 777069f4..00000000 --- a/core/protected/extensions/umber/assets/mixins/_placeholders.scss +++ /dev/null @@ -1,6 +0,0 @@ -@mixin placeholder-styles() { - &::-webkit-input-placeholder { @content; } - &:-moz-placeholder { @content; } - &::-moz-placeholder { @content; } - &::-ms-input-placeholder { @content; } -} diff --git a/core/protected/extensions/umber/assets/mixins/_transitions.scss b/core/protected/extensions/umber/assets/mixins/_transitions.scss deleted file mode 100644 index 6f3b39f5..00000000 --- a/core/protected/extensions/umber/assets/mixins/_transitions.scss +++ /dev/null @@ -1,13 +0,0 @@ -@mixin transition-property($val) { - -webkit-transition-property: $val; - -moz-transition-property: $val; - -o-transition-property: $val; - transition-property: $val; -} - -@mixin transition-duration($val) { - -webkit-transition-duration: $val; - -moz-transition-duration: $val; - -o-transition-duration: $val; - transition-duration: $val; -} diff --git a/core/protected/extensions/umber/assets/modal/.DS_Store b/core/protected/extensions/umber/assets/modal/.DS_Store deleted file mode 100644 index d6c294b9217e05e72b5ac59532c5990962148da1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12292 zcmeI0&u-H|5XNUs4p9pT1S*A-kDQP=B5{bSBEh*QP9bs964k^}(m!zXWAF;R01wa` z@4@^Q>DX3oR5o z=tb5tmkmB+nQmQe4MxBS7y%<-1dPDHKmgBdmSN(#@6X!N2pEC?k^t`yIV$Za*xFmY zb>N^|0N4SVwctDU0jkM^9R*u^t5W#%y9XDfE^INJm*afS%V9^s*4}!#I4>6$dUj!l z;*|d}AB^EM*~|U@u@R{7UNG>z4kZzBiaau|R)gc&QN6M9NeI?xy8o52^x+HF{4( zoxN>o?nN3;A)(ZKe?%K)=GB2d5{z@U#ZSL_SI{_SGHJDSXjOavYUt?58`X6~^TY{LGPEa&(l_tBBK+&ipnYw~!S+ zWObIz5Hrlh-nt{>e48Pzsm`1pS`A;_kzF7%u7Pvp${CUHMrI9fcQsG07miwgM)5q_ zhmNbIf2CoaG-ls3sQ#?3G1OPce~p#KF&bm6nFa3#v)&BiNVtxgeiFHJjI*cF7;_!n zDzA{uT&`2Sa{f28%zuSQIS-PviZi`aRVjr;oE)QuiWzRgoLefdl=3I;G0$5WUL!_w zE!8Gt&7gI|Nc#xAwzXr7S1%`ek*|@Ly=c69qIRDn4P02+VFGu2Zin3ezro|%-UICL zU|VWNAVI(lj!%w{a5C(zw=T=jlB0e=W#M(Tw<^Jbm#}>hY}k%#TOQg*!PefY6dIMn zsub2s|LTi?+kXxA{Ezl?`p?6j|D2pwjDQg^0!F|H7y%<-1dM *:first-child { - float: left; - } - > *:last-child { - float: right; - } - } - } - } - - h1 { - - font-weight: 600; - //MO conflicting with Edit cart Is this needed anywhere else? - font: 1rem $webstore-modal-header-font-family; - font-weight: $webstore-modal-header-font-weight; - margin: .25rem 0; - - .cancel { - position: absolute; - right: 20px; - top: 16px; - font-size: .75rem; - color: #777; - text-transform: none; - border-bottom: 1px solid #ccc; - } - small { - float: right; - color: #aaa; - - } - } - - h2 { - font-size: 1.5rem; - margin: .5em 0 1em; - color: #555; - } - h4 { - text-transform: uppercase; - margin: 0 0 .75em; - font-weight: 400; - color: #888; - font-size: 1rem; - } - - header { - background-color: #eee; - border-bottom: 1px solid #ccc; - } - - .invisible { visibility: hidden; } - - footer.submit { - padding: 0; - background-color: #eee; - color: #999; - overflow: hidden; - - input[type="submit"] { - @include transition-property(background-color); - @include transition-duration(.3s); - - font: 1.25rem $webstore-modal-header-font-family; - font-weight: $webstore-modal-header-font-weight; - - padding: $modal-padding; - background: $calltoaction-color; - width: 100%; - border: none; - color: #fff; - float: left; - - &:hover { - background-color: darken($calltoaction-color,10%); - } - } - } - - .hint, .info { - p { - margin: 0; - padding: 12px $modal-padding 11px; - color: #666; - font-size:.875rem; - } - } - - .hint p { margin-right: 80px; } - - input[type="text"], input[type="email"], input[type="password"], input[type="tel"] { - &.split-2 { - width: 50%; - float: left; - border-right: $input-border; - &:last-child { - border-right: none; - } - } - &.split-3 { - width: 33%; - float: left; - border-right: $input-border; - &:last-child { - border-right: none; - width: 34%; - } - } - - &:focus { - box-shadow: inset 1px 1px 3px #ccc; - background-color: #f8f8f8; - outline: none; - } - } - label { - &.transient { - display: none; - color: #666; - position: absolute; - top: 3px; - left: $modal-padding; - font-size: .5rem; - text-transform: uppercase; - font-weight: bold; - } - &.text { - @include transition-property(background-color, color); - @include transition-duration(.3s); - display: block; - padding: $modal-padding; - font-size: .85rem; - color: #888; - cursor: pointer; - @include transition-property(color); - @include transition-duration(.3s); - background-color: #fff; - } - &.checkbox { - @include transition-property(background-color, color); - @include transition-duration(.3s); - - display: block; - padding: $modal-padding; - font-size: .85rem; - color: #888; - cursor: pointer; - @include transition-property(color); - @include transition-duration(.3s); - background-color: #fff; - - &:hover { - color: #555; - } - - input { - font-size: 2em; - //MO - margin-right: 2px; - } - } - } - - .minor { - @include transition-property(background-color, color, border-color); - @include transition-duration(.3s); - text-decoration: none; - width: auto; - @include border-radius(0); - background: none; - color: #aaa; - padding: 7px 6px; - text-align: right; - font-size: .75rem; - line-height: 1; - position: absolute; - right: 18px; - top: 18px; - - strong { - font-weight: normal; - color: $calltoaction-color; - text-decoration: underline; - } - - &:hover { - color: #888; - strong { color: darken($calltoaction-color,10%); } - } - } - - label { - margin: 0 0 2px; - display: block; - color: #666; - } - - input { - padding: 8px; - background-color:transparent; - @include border-radius(0); - } -} - -.webstore-modal-narrow { - @include media(small) { - &:before { - content: ''; - display: inline-block; - height: 100%; - vertical-align: middle; - margin-right: -0.25em; /* Adjusts for spacing */ - } - } - section { - max-width: $modal-width-narrow; - } -} - -//webstore Montreal override -.webstore-modal.show { - visibility: visible; - text-align: center; - -webkit-font-smoothing: initial; - font-smoothing: initial; - display: inline-block; - -} -//MO -.estimator-zip-error{ - float:left; - color: #a44039; - margin: 0; - font-size: 0.75rem; - padding: 3px 0 6px; - text-align: left; - p{ - margin: 0; - } -} - diff --git a/core/protected/extensions/umber/assets/modal/_browsers_unistyle.scss b/core/protected/extensions/umber/assets/modal/_browsers_unistyle.scss deleted file mode 100644 index b4e28ceb..00000000 --- a/core/protected/extensions/umber/assets/modal/_browsers_unistyle.scss +++ /dev/null @@ -1,16 +0,0 @@ -::-webkit-input-placeholder { color: #aaa !important; } -:-moz-placeholder { /* Firefox 18- */ color: #aaa !important; } -::-moz-placeholder { /* Firefox 19+ */ color: #aaa !important ; } -:-ms-input-placeholder { color: #aaa !important; } - -.quantity input, input.cc-exp , input.creditcard-number ,.editcartmodal input.promo-code-value, #MultiCheckoutForm_orderNotes{ - &:focus{ - /* -webkit-focus-ring-color = '#5B9DD9' */ - outline: #5B9DD9 auto 5px!important; - } -} - -//remove "clear field" X buttons IE -::-ms-clear { - display: none; -} \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/modal/_cart.scss b/core/protected/extensions/umber/assets/modal/_cart.scss deleted file mode 100755 index df98e859..00000000 --- a/core/protected/extensions/umber/assets/modal/_cart.scss +++ /dev/null @@ -1,481 +0,0 @@ -.webstore-overlay-cart { - - display:block; - overflow-y:scroll; - - .webstore-estimator-form,.shipping-postal-entry { - background: none; - display:none; - } - .shipping-postal-entry { - margin-top: 16px; - } - - .shipping-city-state-link{ - font-size:11px; - } - .lines-container, .totals, .submit { - - @media(width:640px) { - margin: 0; - } - } - - @media(min-width:640px) { - // Push delete buttons into margin - .lines { margin-right: -15px; } - } - - header { - position: relative; - - a.button.edit, a.button.edit:focus { - @media(min-width:640px) { display: none; } - top: 9px; - right: 8px; - font-weight: bold; - border-color: #ccc; - text-decoration: none; - background: none; - font-size: .8375rem; - color: #aaa; - - &:hover { - border-color: $calltoaction-color; - color: $calltoaction-color; - background: none; - } - } - } - .cart-footer { - clear: both; - @extend %clearfix; - - .pricechange { - display: none; - font-size: 0.75rem; - float: right; - width: 18rem; - color: #666; - background-color: #ffc; - padding: 12px; - margin-right: 15px; - border-bottom: 1px solid #ccc; - - @media(max-width: 640px) - { - width: 100%; - float: none; - } - } - } - - table { - border-collapse: collapse; - - td, th { - text-align: left; - vertical-align: middle; - padding: 0; - } - - &.lines { - a { color: #555; } - - tr td:first-child, tr th:first-child { - padding-left: 8px; - @media(min-width:640px) { - padding-left: 0; - } - } - tr:last-child { - td { - border-bottom: 1px solid #ccc; - &:last-child { border-bottom-color: #fff; } - } - } - - td { border-bottom: 1px solid #eee; } - } - - a { - font-weight: bold; - border-bottom: 1px solid #bbb; - } - - td.image { - width: 0; - @media(min-width:640px) { width: 62px; } - img { - display: none; - vertical-align: middle; - width: 56px; - margin-right: -62px; - padding: 6px 6px 6px 0; - - @media(min-width:640px) { display: block; } - } - } - - td.description { - height: 62px; - padding-right:5px; - - strong, img { float: left; } - strong { - line-height: 1.4; - - @media(min-width:640px) { - font-size: 1.125rem; - } - } - img { - display: none; - vertical-align: middle; - width: 56px; - padding: 6px 6px 6px 0; - - @media(min-width:640px) { display: block; } - } - } - - .price { - text-align: right; - - strike { - font-size: .75rem; - color: #ccc; - text-align: -1000em; - overflow: hidden; - display: block; - line-height: 1; - height: 12px; - margin-top: -12px; - - &:after { - color: #888; - content: attr(data-text); - } - } - } - - .quantity { - text-align: center; - width: 3rem; - @media(min-width:640px) { width: 7rem; } - } - - .subtotal { - width: 5rem; - padding-right: 12px; - padding-left: 5px; - } - - @include media(mobile) { - &.edit { - td.quantity, th.quantity { display: none; } - td.remove, th.remove { - display: table-cell; - width: 40px; - - a { - color: #fff; - border-color: $red; - background-color: $red; - - &:hover { - border-color: darken($red,10%); - background-color: darken($red,10%); - } - } - } - th.remove { border-bottom: 1px solid #ccc; } - //MO removing this is breaking the cart when edited on mobile and then screen is resized - //tr:last-child td:last-child { border-bottom: 1px solid #ccc; } - } - } - - .price, .remove { - display: none; - } - @media(min-width:640px) { - .price, .remove { display: table-cell; } - .price { width: 6rem; } - } - } - - tr { - opacity: 1; - @include transition-property(opacity); - @include transition-duration(.5s); - - - &.delete { - opacity: 0; - } - } - - table.lines thead { - th,a { - border-bottom: 1px solid #ccc; - text-transform: uppercase; - color: #999; - font-size: .875rem; - padding-bottom: 3px; - font-weight: bold; - } - } - - .subtotal, #PromoCodeStr { text-align: right; } - - table.lines { - th.remove, td.remove { - width: 30px; - border-bottom-color: #fff; - - a { - text-decoration: none; - display: block; - border: 2px solid #eee; - color: #ccc; - background-color: #fff; - @include border-radius(20px); - height: 28px; - width: 28px; - line-height: 22px; - padding-left: 5px; - font-size: 25px; - font-weight: bold; - margin: 0; - - @include transition-property(border-color, background-color,color); - @include transition-duration(.3s); - - &:hover { - color: #fff; - border-color: $red; - background-color: $red; - } - } - } - - } - - input[type="number"] { - width: 3rem; - //webstore montreal override - height:2rem; - text-align: center; - padding: 2px 4px; - - &::-webkit-inner-spin-button, &::-webkit-outer-spin-button { - -webkit-appearance: none; - margin: 0; - } - //MO remove spinner in mozilla number inputs - -moz-appearance:textfield; - - } - - .submit button{ - &.continue { - border-bottom: 1px solid #ddd; - } - } - .cart-footer button, .cart-footer .button { - @include media(small) { - width: auto; - } - - &.checkout, &.continue { float: right; } - &.checkout { - margin: 0 0 0 1em; - @media(min-width:640px) { - width: 18rem; - } - } - - &.continue { - display:none; - color: #999; - background: none; - @include media(small) { - display: block; - } - - @media(min-width:640px) { - margin: 20px; - padding: 0 0 2px; - } - - @include transition-property(border, background-color,color); - @include transition-duration(.3s); - - &:hover { - color: $calltoaction-color; - border-color: lighten($calltoaction-color, 20%); - } - } - } - - .submit { - padding: 0; - clear: both; - overflow: hidden; - - @media(min-width:640px) { margin: 0 15px 0 0; } - } - - .webstore-estimator { - &.recalculate { - td { - visibility: hidden; - color: #f8f8f8; - - &:after { visibility: visible; } - } - td.csspinner:after { - top: 27px; - left: 45px; - } - } - - form { - margin-top: 6px; - display: block; - } - input, button { - float: left; - - &:focus { - outline: none; - box-shadow: inset 1px 1px 2px rgba(0,0,0,.1); - border: 1px solid #bbb; - } - } - input { - border: $input-border; - padding: 9px 8px; - &:focus{ - padding: 9px 8px; - } - } - - select.webstore-estimator-country-form { - margin: 8px 0 0; - } - - button { - padding-left: 8px; - padding-right: 8px; - } - - a.webstore-estimator-country { - float: right; - color: #999; - text-decoration: none; - border-bottom: 1px dotted #ccc; - font-size: .75rem; - display: inline-block; - padding: 2px 0 0; - font-weight: normal; - } - } - - .webstore-promo-line { - small { text-transform: uppercase; } - } - - .totals { - min-height: 135px; - background-color: #f8f8f8; - width: auto; - margin: 0 15px 0 0; - width: 100%; - - @media(min-width:640px) { - float: right; - width: 18rem; - } - - tr:first-child { - th, td { - padding-top: 8px; - } - } - - small a { - color: #999; - border-bottom: 1px dotted #ccc; - text-decoration: none; - } - - td, th { - color: #888; - padding: 4px 8px; - - @media(min-width:640px){ - padding: 4px 12px; - } - } - th { - text-align: left; - } - td { - @include transition(color 1s) - } - - .active a { - text-decoration: none; - color: #888; - } - - .total { - font-weight: bold; - - td, th { - padding: 4px 8px 16px; - color: #444; - font-size: 1.25rem; - - @media(min-width:640px) { - padding-right: 12px; - padding-left: 12px; - } - } - } - } -} - - -//MO -.hide-me { - display: none; visibility: hidden; -} - -.editcartmodal{ - .promo input{ - min-width: 16rem; - } -} - -@media (max-width: 640px){ - .webstore-overlay-cart table.edit{ - th.remove, tr:last-child td:last-child { - border-bottom: 1px solid #ccc; - } - td.remove a { - color: #fff; - border-color: #a44039; - background-color: #a44039; - } - } -} -//MO override against bootstrap background -.editcartmodal { - @include media(medium) { - &:before { - height:0; - } - } -} diff --git a/core/protected/extensions/umber/assets/modal/_cartadd.scss b/core/protected/extensions/umber/assets/modal/_cartadd.scss deleted file mode 100755 index af26ddad..00000000 --- a/core/protected/extensions/umber/assets/modal/_cartadd.scss +++ /dev/null @@ -1,440 +0,0 @@ -$cart-confirmation-image-width: 140px; -.webstore-modal-cart-confirm { - img { - width: $cart-confirmation-image-width; - } - - //D--.webstore-estimator-form P--shipping-postal-entry - .webstore-estimator-form,.shipping-postal-entry { - background: none; - display:none; - - } - table a, table a:hover { - font-weight: bold; - } - table a{ - border-bottom: 1px solid #bbb; - } - - .totals { - small a { - color: #999; - border-bottom: 1px dotted #ccc; - text-decoration: none; - - // - font-size:0.9167em; - } - - td{ - color: #888; - } - th{ - text-align: left; - } - - .active a { - text-decoration: none; - color: #888; - } - } -} - -aside.related-products { - overflow: hidden; - padding: 20px; - - @include media(small) { - border-top: 1px solid #ccc; - padding: 20px 30px; - } - - a { text-decoration: none; } - - h4 { - margin-bottom: .5em; - } - - ul { - margin: 0; - padding: 0; - overflow: hidden; - list-style: none; - - a:last-child li { - margin-right: 0; - margin-bottom: 0; - } - } - li { - @include clearfix(); - border: 1px solid #ddd; - padding: 10px; - margin-bottom: 10px; - position: relative; - - @include media(medium) { - float: left; - width: 210px; - margin-right: 15px; - } - - - } - - img { - width: 80px; - margin: 0 12px 0 0; - float: left; - } - - h3, p { - font-size: 1rem; - @include media(medium) { font-size: .8rem; } - margin: 0; - } - h3 { - color: #666; - max-height: 4.5em; - overflow: hidden; - } - p.price { - color: #888; - position: absolute; - bottom: 8px; - left: 102px; - } -} - -.cart-summary { - background-color: #eee; - border-left: 1px solid #ccc; - - table { - color: #888; - margin: 0 0 .5rem; - } - td { - line-height: 2; - } - tfoot td { - font-weight: bold; - color: #444; - } - - .webstore-promo-form { - position: relative; - //MO - line-height:normal; - - input { - border: none; - background-color: #eee; - border-top: $input-border; - font-size: .9375rem; - padding: 12px 20px 13px; - width: 100%; - //MO - min-height: 46px; - margin-bottom: 0; - &:focus{ - //MO - border:0; - width:100%; - padding:12px 20px 13px; - } - } - button { - @include transition-property(opacity); - @include transition-duration(.5s); - - opacity: 0; - position: absolute; - top: auto; - right:20px; - background: none; - //MO - bottom: 9.5px; - height:27px; - } - - &:hover button { - opacity: 1; - } - } - - .webstore-promo-line { - small { - text-transform: uppercase; - float: none; - font-weight: bold; - padding: 6px 0; - } - } - - small { - font-size: .75rem; - float: right; - font-weight: normal; - color: #999; - - a { - color: #999; - border-bottom: 1px dotted #ccc; - - //MO - text-decoration: none; - } - } - - footer { - button, .button, .button:focus{ - width: 100%; - - @include media(medium) { - width: 50%; - } - - float: left; - height: 60px; - font-size: 1rem; - - &.exit { - background-color: #ccc; - color: #888; - - &:hover { - background-color: #999; - color: #fff; - } - } - - &.continue-shopping{ - display: none; - @include media(small) { - display: block; - } - } - - } - } - - button.checkout, .button.checkout, - .button.checkout:focus{ - float: right; - } - - .pricechange { - display: none; - font-size: 0.75rem; - color: #666; - background-color: #ffc; - padding: 12px; - border-bottom: 1px solid #ccc; - } -} -.item-confirm { - header { - background: none; - border-bottom: none; - - padding: 15px 30px; - - @include media(medium) { - padding: 24px 30px; - } - - h1 { - text-transform: none; - color: #589141; - font-size: 1.3rem; - - &::before { - font-family: 'Lucida Grande'; - content: '\2713'; - padding-right: 8px; - } - } - } - - &.column .content { - padding: 0px 30px 15px; - //MO added clearfix to fix change button coming out of its parent div. - @include clearfix(); - } - - .webstore-change-item { - padding: 4px 6px; - font-size: .75rem; - text-decoration: none; - margin: .75em 0 0 0; - display: inline-block; - color: #aaa; - border: 2px solid #ccc; - font-weight: bold; - text-transform: uppercase; - @include transition-property(border-color,background-color,color); - @include transition-duration(.5s); - - &:hover { - border-color: $calltoaction-color; - color: $calltoaction-color; - } - } - - img { //MO - float: left; - margin-bottom: 20px; - position: absolute; - } - - .product-data {//MO - padding-left: 100px; - margin-left: 20px; - } - - h3 { - margin-top: 0; - font-size: 1.125rem; - margin-bottom: .25em; - } - - p { - margin-bottom: .125rem; - margin-top: 0; - color: #888; - } -} - -//webstore montreal ovewrites -@media (min-width: 720px) { - /* line 173, /app/source/stylesheets/webstore/_cartadd.scss */ - .item-confirm header { - padding: 5px 30px; } } - -.webstore-modal-cart-confirm h1{ - color: #777; - font-weight: 600; - text-transform: uppercase; - font: 1rem "Open Sans", "Helvetica Neue", Helvetica, sans-serif; - font-weight: normal; - margin: .25rem 0; -} - -/* override fonts */ -.webstore-modal .item-confirm .content h3, -.webstore-modal .item-confirm header h1, -.webstore-modal .cart-summary header h1, -.webstore-modal .cart-summary footer .button, -.webstore-modal .cart-summary footer button, -.webstore-modal aside.related-products h4, -.webstore-modal aside.related-products h3 { font-family: 'Open Sans','Helvetica Neue',Helvetica,sans-serif; } - -/* left side tweaks */ -.webstore-modal .item-confirm header h1 { margin: 12px 0; } -.webstore-modal .item-confirm .content { text-transform: none; } -.webstore-modal .item-confirm .content p { font-size: 15px; } -.webstore-modal .item-confirm .content h3 { font-weight: bold; line-height: 24px; margin-bottom: 10px; word-wrap: break-word; overflow-x: auto; overflow-y: -moz-hidden-unscrollable;} -.webstore-modal .item-confirm .content .sku { text-transform: uppercase; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } -.webstore-modal .item-confirm button.webstore-change-item { background-color: #ffffff; width: auto; } //MO -.webstore-modal .item-confirm button.webstore-change-item:hover { background-color: #ffffff; } -.webstore-modal .item-confirm img { max-width: 100px; max-height: 140px; width: auto; margin-bottom: 55px; } -.webstore-modal .item-confirm.column .content { padding: 0 20px 15px 25px; } - - -/* right side tweaks */ -.webstore-modal .cart-summary header { font-family: 'Open Sans','Helvetica Neue',Helvetica,sans-serif; } -.webstore-modal .cart-summary .webstore-promo-form button.inset { max-height: 30px; min-width: 50px; } -.webstore-modal input[type="text"] { min-height: 41px; margin-bottom: 0; } -.webstore-modal form { background-color: #EEE; margin-bottom: 0; } -.webstore-modal button, .cart-summary footer .button { margin-bottom: 0; } -.webstore-modal .cart-summary table td, -.webstore-modal .cart-summary footer .button, -.webstore-modal .cart-summary footer button { text-transform: none; } -.webstore-modal .cart-summary footer a{ - color: #FFF; - text-shadow: none; -} -.webstore-modal .cart-summary footer .button:hover { - background: $link-hover-color; - border: none; -} -.webstore-modal h1 small { - line-height: normal; -} - - -/* related products */ -.webstore-modal aside.related-products h3 { line-height: 18px; text-transform: none; font-weight: bold; } -.webstore-modal aside.related-products img { max-height: 80px; width: auto; } -.webstore-modal aside.related-products p.price { position: static; } - -@media (max-width: 640px) { - .webstore-modal .promo input[type="text"]:focus { max-width: 100%; } -} - -@media (max-width: 740px) { - .webstore-modal .item-confirm img { margin-bottom: 154px; } -} - -@media (max-width: 719px) { - .webstore-modal .item-confirm header { padding: 5px 30px; } - .webstore-modal aside.related-products h3 { line-height: 24px; } -} - -@media (max-width: 670px) and (min-width: 560px) { - .webstore-modal .item-confirm header h1 { font-size: 1rem; } -} - -@media (max-width: 559px) { - .webstore-modal .item-confirm.column .content { padding: 0 0 15px 10px; } - .webstore-modal .item-confirm img { margin-bottom: 76px; } - .webstore-modal .product-data .webstore-change-item { margin-bottom: 18px; } -} - -@media (max-width: 360px) { - .webstore-modal .item-confirm header h1 { font-size: 1rem; } -} - -form.webstore-promo-form.promo{ - width:100%; -} - -//Note that webstore-shipping-options was updated to shipping-options. The -//* webstore prefix was dropped. TODO Update CSS upstream. -// -// Default to the initial screen. -.shipping-estimate-line, -.tax-estimate-line, -.shipping-country-link, -.shipping-country-picker, -.shipping-options { - display: none; -} - -.webstore-shipping-choices li.webstore-shipping-choices-notice { - border-top: none; - border-bottom: 1px solid #ddd; - background-color: #ffc; -} - -.webstore-shipping-choices li.webstore-shipping-choices-notice.grey{ - background-color: #eee; -} - - -.webstore-modal-overlay button .continue-shopping.exit, .webstore-modal-overlay .cart-summary footer button.exit{ - background-color: #ccc; - color: #888; - &:hover{ - background-color: #999; - color: #fff; - } - -} - - -.estimate-shipping-and-taxes-link:hover{ - border-bottom-color: $calltoaction-color; -} diff --git a/core/protected/extensions/umber/assets/modal/_checkout.scss b/core/protected/extensions/umber/assets/modal/_checkout.scss deleted file mode 100755 index 6d3e1552..00000000 --- a/core/protected/extensions/umber/assets/modal/_checkout.scss +++ /dev/null @@ -1,218 +0,0 @@ -.webstore-checkout { - - //MO - input[type] { margin-bottom: 0;} - *, *:before, *:after { - -moz-box-sizing: border-box; -webkit-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box;} - - ol { - list-style: none; - margin: 0; - padding: 0; - } - - p { - font-size: .8375rem; - color: #777; - line-height: 1.5; - } - - label.checkbox { - text-align: center; - width: 100%; - display: block; - font-size: .875rem; - - input { - font-size: 1rem; - margin: 0 .25rem 0 0; - width: auto; - display: inline-block; - } - - //MO alignment of store pickup checkbox - input.instore-toggle { - margin: 0.2rem 0.5rem 0 0; - } - } - - footer.submit { - @extend %clearfix; - margin-bottom: 15px; - } - //MO - input[type="submit"]:focus{ - &#Payment{ - height:64px; - line-height: normal; - font-size: 1.125rem; - padding: 20px 0; - } - } - - input[type="submit"], button, .button { - width: 100%; - font-size: 1.125rem; - padding: 20px 0; - border: none; - &#login-button, &#login-button:focus, - &#guest-button, &#guest-button:focus{ - height: 64px; - font-size: 1.125rem; - } - @include transition-property(border,background); - @include transition-duration(.5s); - - &.small { - width: auto; - font-size: .8375rem; - padding: 9px; //MO - } - } - - .notice { - padding: 15px 30px; - margin: 0 -30px 1em; - - background-color: #ffc; - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - - p { margin: 0; } - strong { color: #333; } - } - - - .choices { - overflow: hidden; - - button, .button { - width: 100%; - font-size: .9375rem; - float: left; - background: #eee; - border: 1px solid #ccc; - color: #777; - margin-top: 6px; - padding: 12px 0; - //override light.css - height: 46px; - - @include media(verysmall) { - width: 50%; - &:last-child { - border-left: none; - } - } - - &:hover { - font-weight: bold; - border-color: $calltoaction-color; - background: $calltoaction-color; - color: #fff; - } - } - } -} - -//TODO:MO have path similar to design? -@import 'address_blocks'; -@import 'checkout_sidebar'; -@import 'checkout_forms'; -@import 'checkout_begin'; -@import 'checkout_shipping'; -@import 'checkout_payment'; -@import 'checkout_confirm'; -@import 'checkout_thankyou'; - - -select[name="city_state"] { max-width: 12em; } - - -.webstore-checkout footer.submit-small { - height: 65px; - - input[type="submit"], .button { - font-size: .9375rem; - padding: 15px 0; - } - - //MO - p { margin: 1rem 0; } -} - -p.tip { - margin: .25em 0 1.25em; - font-size: .8375rem; - color: #aaa; -} - -.or-block { - border-top: 1px solid #ccc; - margin-top: 1rem; - height: .5rem; - - &:before { - text-align: center; - content: 'OR'; - color: #888; - display: block; - background-color: #fff; - margin: -.5rem auto 0; - font-size: .875rem; - width: 2.5rem; - height: 1rem; - line-height: 1; - } -} - -.modal-conditional-block { - overflow: hidden; - height: 0; - opacity: 0; - @include transition(opacity .6s); - - &.active { - height: auto; - opacity: 1; - overflow: visible; - } - -} - - -.note { - background-color: #ffc; - border-top: 1px solid #ccc; - border-bottom: 1px solid #ccc; - padding: 15px 30px; - margin: 0 -30px .5em; - - h5 { - text-transform: uppercase; - margin: 0 0 .25em; - } - p { - margin: 0; - } -} - -.button-paragraph { - margin-left: 1em; - - button { - display: inline-block; - float: none; - margin: 0 .5em; - } -} - -#checkout section > header { - @include media(medium) { - padding: 0; - a.exit{ - margin-right: 0!important; - } - } -} - diff --git a/core/protected/extensions/umber/assets/modal/_checkout_begin.scss b/core/protected/extensions/umber/assets/modal/_checkout_begin.scss deleted file mode 100644 index 46b5891d..00000000 --- a/core/protected/extensions/umber/assets/modal/_checkout_begin.scss +++ /dev/null @@ -1,70 +0,0 @@ -@include media(medium) { - #start { - & > footer p { - margin-right: -60px; - margin-left: -60px; - } - } -} - - -#start { - //MO to avoid text overlapping - //and too narrow inputs on login page. - .section-inner{ - padding: 15px 10px 20px; - @include media(verysmall){ - padding: 15px 20px 20px; - } - } - - footer.submit { - text-align: center; - height: 91px; - - p { - color: #999; - font-size: .9375rem; - margin: 0 0; - } - a.alternate { - text-align: center; - background: #fff; - color: #999; - margin: 12px auto 0; - display: inline-block; - border-bottom: 1px dotted #ccc; - } - - opacity: 1; - - & > div { - @include transition(opacity .5s); - - } - - .invisible { - overflow: hidden; - height: 0; - visibility: none; - opacity: 0; - } - - } - - li.password-block { - margin-top: -1px; - input { border-bottom: none; } - - .reset { - .inset { right: 0; } - p { margin-right: 5em; } - } - } - - //MO - .form-error{ - border-bottom: none; - margin-bottom: 0; - } -} diff --git a/core/protected/extensions/umber/assets/modal/_checkout_confirm.scss b/core/protected/extensions/umber/assets/modal/_checkout_confirm.scss deleted file mode 100644 index f5396a7c..00000000 --- a/core/protected/extensions/umber/assets/modal/_checkout_confirm.scss +++ /dev/null @@ -1,408 +0,0 @@ -#confirm { - .section-inner{ width:100%; } //MO fix for IE10 order summary. - - .section-content { - width: inherit; //MO fix for IE10 order summary. - border-right: none; - } - - h4 { - text-transform: uppercase; - color: #666; - margin: 1em 0 .5em; - font-size: .875rem; - } - - .final-confirmation { - border-bottom: 1px solid #ddd; - padding-bottom: 30px; - - label { - margin-top: .5em; - text-align: left; - padding-left: 25px; - input { - margin-top: 3px; - margin-left: -25px; - float: left; - } - - &:hover { cursor: pointer; } - } - - .terms { - line-height: 1.4; - font-size: .75rem; - margin: 0; - margin-left: 25px; - } - - .button.paypal { - font-size: 0.875rem; - width: 11rem; - background-color: #f8f8f8; - overflow: hidden; - border: 1px solid #ccc; - color: #666; - &:hover { - background-color: darken(#f8f8f8, 10%); - } - span { - background: url("images/altpayments/logo-paypal.png") no-repeat scroll center center; - background-size: 100% auto; - position: relative; - display: inline-block; - height: 25px; - margin-left: 5px; - top: -2px; - vertical-align: middle; - width: 75px; - } - - } - @include media(small) { - .button.paypal { - width: 37%; - margin-right: 11%; - float: right; - font-size: 1.25rem; - span { - margin-left: 10px; - width: 101px; - } - } - } - } - - .comments { - margin: 1.25rem 0 1.25rem 25px; - - a, textarea { font-size: .875rem; } - - a:before { - @extend %icon-prereqs; - @extend %icon-chat-bubble; - - float: left; - margin-top: 4px; - margin-right: 5px; - border-bottom: none; - } - - textarea { - display: none; - width: 16rem; - padding: 10px; - border: $input-border; - } - } - - - %twocolumn { - @extend %clearfix; - - .column { - width: 96%; - float: left; - margin-left: 2%; - - @include media(verysmall) { - width: 48%; - } - - @include media(small) { - margin-left: 0; - &:first-child { - margin-right: 4%; - } - } - } - } - - .order-details { - @extend %twocolumn; - margin: .5rem 0; - - h2 { - margin: 0; - } - } - - .shipping { - p{ - a { display: block; } - } - } - - .payment { - p { - font-size: 0.75rem; - margin: 0 0 1.25em; - border: 1px solid #ddd; - padding: 15px 5px 15px 75px; - - a { - display: block; - margin-top: 5px; - } - - } - - //MO - p.sim { - padding: 7px 5px 8px 15px; - - .instructions { - font-size: 0.6rem; - } - } - - .payment-note { - margin-bottom: 10px; - display: inline-block; - font-size: 0.75rem; - } - - .card-tiny { - display: inline-block; - padding: 8px 4px; - margin-left: -60px; - width: 45px; - border: 1px solid #ccc; - float: left; - } - .card-only { - display: inline-block; - margin-left: -60px; - width: 45px; - float: left; - } - } - - .lines { - tbody { - border-bottom: 1px solid #ddd; - } - - td { - border-top: 1px solid #ddd; - line-height: 40px; - } - - //MO override bootstrap - td.controls { - vertical-align: middle; - } - - .quantity { - font-weight: bold; - text-align: center; - padding: 0; - line-height: 4rem; - min-width: 1.75rem; - - input { - display: none; - width: 2.60rem; - padding: 3px 3px; - text-align: center; - font-weight: bold; - - &::-webkit-inner-spin-button, &::-webkit-outer-spin-button { - -webkit-appearance: none; - margin: 0; - } - //MO remove spinner from number inputs mozilla - -moz-appearance:textfield; - } - } - - .image { - display: none; - white-space: nowrap; - width: 65px; - vertical-align: middle; //MO bootstrap override - @include media(small) { - display: table-cell; - } - - &:before { - display: inline-block; - padding: 0 .5em 0 0; - height: 40px; - font-weight: normal; - font-size: 1.25rem; - content: '\d7'; - float: left; - } - - img { - float: left; - max-height: 40px; - max-width: 40px; - } - } - - .description { - line-height: 1.3; - font-size: .875rem; - padding-right: .5em; - padding-left: .5em; - font-weight: bold; - //override base.css l.25 - vertical-align: middle; - - .price { - font-weight: normal; - font-size: .8375em; - color: #888; - } - a > strong{ - margin-right: 15px; - } - } - - .subtotal { - text-align: right; - font-weight: bold; - } - - .controls { - padding: 0 1em; - text-transform: uppercase; - font-size: .75rem; - width: 2.5rem; - - a { float: right; } - - a.edit { - line-height: 1; - padding: 6px 4px 5px; - border: 1px solid #ccc; - color: #aaa; - - &:hover { - color: $blue; - border-color: $blue; - } - } - a.remove { - @extend %remove-icon; - display: none; - } - } - - - tr.active { - .quantity { - strong { display: none; } - input { display: inline-block; } - } - .controls { - a.edit { display: none; } - a.remove { display: block; } - } - } - } - - .lines-footer { @extend %clearfix; } - - .totals { - margin-top: .5rem; - float: right; - width: 100%; - @media(min-width:640px) { - float: right; - width: 16rem; - } - - td, th { - color: #666; - line-height: 1.75rem; - font-size: 1rem; - } - - small { - font-size: .75rem; - color: #999; - font-weight: normal; - } - - th{ - text-align:left; - } - - td { - text-align: right; - border-top: none; - line-height: 1; - } - - .total { - td, th { - color: #333; - font-size: 1.25rem; - line-height: 1.5em; - - } - td { font-weight: bold;} - - } - } -} - - -//MO -#place-order{ - width: 48%; - float: right; - margin-left: 4%; - margin-bottom: 25px; - text-shadow: 0 0; - &:focus{ - font-size: 1.125rem; - } -} -#checkout .quantity input{ - height:30px; - font-size:16px; -} -#checkout .address-block button a{ - color: white; - text-decoration: none; - //MO override base.css line 183. - &:focus{ - outline:none; - } - -} -.webstore-overlay table.lines a { - color: #555; - text-decoration: none; -} -#confirm .promo input[type="text"] { - height: 41px; -} - -.thankyou input[type="password"]{ - height:40px; -} -.thankyou h2 { - font-weight: normal; - font-size: 1.5rem; - color: #589141; - margin: -.25em 0 .25em; -} - -.webstore-overlay #confirm form.promo{ - p{ - line-height: 1.3; - font-size: 0.6875rem; - } -} -p.webstore-label.confirmation span { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - display: block; -} diff --git a/core/protected/extensions/umber/assets/modal/_checkout_forms.scss b/core/protected/extensions/umber/assets/modal/_checkout_forms.scss deleted file mode 100644 index f51d00c5..00000000 --- a/core/protected/extensions/umber/assets/modal/_checkout_forms.scss +++ /dev/null @@ -1,174 +0,0 @@ -.field-containers-small { - @extend %clearfix; - - .field-container { - input, select { - height: 2.75rem; - font-size: .875rem; - padding: .25em 8px; - } - select { - font-size: .875rem; - color: #444; - } - p.hint { - color: #999; - top: 0px; - right: 10px; - font-size: .8375rem; - line-height: 1rem; - } - } -} - - -.fieldgroup { - @extend %clearfix; - - border: 1px solid #ddd; - border-top: none; - overflow: hidden; - - //MO - &.city-fieldgroup ol li:nth-child(1){ - width: 25%; - @include media(verysmall){ - width: 20%; - } - input{ - width:100%; - &:focus{ - width: 100%!important; - } - } - } - &.city-fieldgroup ol li:nth-child(2){ - width: 50%; - @include media(verysmall){ - width: 65%; - } - input{ - width: 100%; - &:focus{ - width: 100%!important; - } - } - } - &.city-fieldgroup ol li:nth-child(3){ - width: 25%; - @include media(verysmall){ - width: 15%; - } - input{ - width: 100%; - &:focus{ - width: 100%!important; - } - } - } - .field-container { - float: left; - border-right: 1px solid #ddd; - - input, select { - width: auto; - border: none; - margin: 0; - } - } - - .field-container:last-child { - border-right: none; - } - -} - -.field-container.field-container-select { - select { - padding-right: 1.75rem; - - &:hover, &:focus { - background: none; - cursor: pointer; - } - } - - &:after { - font-family: FontAwesome; - display: inline-block; - content: "\f0d7"; - font-size: 21px; - color: #bbb; - position: absolute; - right: .5rem; - top: 0; - pointer-events:none; - line-height: 2.75rem; - } - - &.field-container-select-no-handle { - select { padding-right: 0; } - &:after { - content: ' '; - } - } -} - -.fieldgroup .field-container.country { - float: right; - select { max-width: 7rem; } -} - - //TODO:MO temporary until no-handle style is fully implemented on country inputs. -.country-container{ - border: 1px solid #ddd; - border-top: none; -} - -.field-container select.modal-accent-color { color: $blue; } - -ol.field-container-gap { - margin-bottom: 1rem; -} - -.field-container-split { - width: 50%; - float: left; -} -.field-container-split-latter { -// MO removed this, company input is misaligned with -// names input with this -// margin-left: -1px; -} -.field-container-toggle { - font-size: .8125rem; - - a { - display: inline-block; - padding: 9px 9px 3px; - } -} - -.company-container { - clear: both; -} - -.field-container-select { - height: 2.75rem; - line-height: 2.75rem; - - select { font-size: .875rem; } -} - -.field-container-narrowed { - width: 75%; - float: left; -} - -.webstore-modal-overlay .address-form .fieldgroup .field-container input:focus, -.webstore-modal-overlay .address-form .fieldgroup .field-container input:focus:required:invalid:focus{ - width: auto; - border: none; - margin: 0; -} - diff --git a/core/protected/extensions/umber/assets/modal/_checkout_payment.scss b/core/protected/extensions/umber/assets/modal/_checkout_payment.scss deleted file mode 100644 index ce717c51..00000000 --- a/core/protected/extensions/umber/assets/modal/_checkout_payment.scss +++ /dev/null @@ -1,405 +0,0 @@ -.cvc-container { - position: relative; -} -.cvc-hint { - position: absolute; - top: -50%; - left: 100%; - width: 180px; - - display: none; - - margin-left: 5px; - - box-shadow: 0 2px 4px rgba(0,0,0,.1); - border: 1px solid #ccc; - background-color: #fff; - padding: 10px 15px 0 15px; - - p { - margin: 0 0 .75em; - font-size: .6875rem; - } - - img { - width: 100px; - margin-bottom: -5px; - } -} - -#payment { - .outofbandpayment { - padding-top: 5px; - padding-bottom: 45px; - margin-bottom: -8px; - position: relative; - - .buttons { - @extend %clearfix; - - @include flexbox(); - @include justify-content(center); - } - - button { - display: inline-block; - text-align: center; - font-size: .875rem; - padding: 10px; - @include border-radius(2px); - width: 140px; - margin-top: 0; - - &.paypal { - width: 11rem; - background-color: #f8f8f8; - overflow: hidden; - border: 1px solid #CCC; - color: #666; - &:hover { - background-color: darken(#f8f8f8, 10%); - } - span{ - background: url("images/altpayments/logo-paypal.png") no-repeat scroll center center; - background-size: 100% auto; - position: relative; - display: inline-block; - height: 25px; - margin-left: 5px; - top: -2px; - vertical-align: middle; - width: 75px; - } - } - } - //MO - .or-block { - position: absolute; - left: 0; - right: 0; - bottom: 0; - } - - .spacer { - margin: 12px 0; - } - } - - h4 { - margin: 0 0 .5em; - } - - .address-form { - @extend %clearfix; - margin-bottom: 15px; - - //MO - h4 { margin-top: 20px; } - } - - //MO - .address-form.invisible { - display: none; - visibility: visible; // override bootstrap - .fieldgroup .field-container input, .fieldgroup .field-container select { - height: 2.375rem; - font-size: .75rem; - } - } - - .payment-methods { - input[type=radio] { - vertical-align: baseline; - margin: 4px 5px 0.5em 0; - width: 13px; - height: 13px; - - &:checked + label { - color: #333; - } - } - - label { - color: #777; - font-size: 0.875rem; - padding-left: 10px; - margin-bottom: 0.5rem; - } - - //MO payment-simple page cc label - .sim-cc { - font-size: 19px; - font-weight: bold; - margin-left: 10px; - } - - //MO payment-simple page cc radio - input.sim-cc-radio { - margin-top: 8px; - } - } - - .checkset { - input[type=radio], input[type=checkbox] { - display: none; - - &:checked + label.checklabel { - color: #333; - - &:before { - border-color: #ccc; - @extend %icon-check-mark; - } - } - } - } - - label.checklabel { - display: block; - margin: 0 0 .5em; - color: #999; - @include transition(all .4s); - - &:before { - @extend %icon-prereqs; - margin: 0 8px -4px 0; - @include border-radius(16px); - content: ""; - display: inline-block; - width: 20px; - - height: 20px; - border: 2px solid #ccc; - font-size: 24px; - color: #444; - text-align: center; - line-height: 15px; - text-indent: -2px; - float: left; - } - - &:hover { - color: #444; - &:before { border-color: #999; } - } - - &.error { color: #999; } - } - - .alt-payment-methods { - padding: 15px 30px 10px; - border: 1px solid #ccc; - - h4 { - text-transform: uppercase; - color: #444; - font-size: .8125rem; - margin: 0 0 1em; - } - - .subform { - input { - width: 12em; - min-height: 35px; - padding: 6px 7px; - display: none; - } - } - } - - //MO - .alt-payment-methods.borderclose { - border-top: 0; - } - - } - - .address-blocks { - - - p { - font-size: .6875rem; - padding: 10px; - - &:before { - display: none; - } - } - } - - .creditcard { - @extend %clearfix; - - border: 1px solid #ccc; - border-bottom: none; - padding: 30px 15px 0; - margin: 0; - - @include media(verysmall){ - padding: 30px 30px 0; - } - - &.creditcard-nosubmit { - border-bottom: 1px solid #ccc; - margin-bottom: 15px; - } - - h3 { - margin: 0 0 .25em; - } - - p.large { - margin: 0; - font-size: 1rem; - } - - input.creditcard-number { - padding-left: 10px; - padding-right: 10px; - font-size: 1.325rem; - - &::-webkit-input-placeholder { - font-size: 1.2rem; - line-height: 1.5; - font-family: $default-font-family; - } - &:-moz-placeholder { - font-size: 1.2rem; - line-height: 1.5; - font-family: $default-font-family; - } - &:-ms-input-placeholder { - font-size: 1.2rem; - line-height: 1.5; - font-family: $default-font-family; - } - } - - .card-details { - input, input#MultiCheckoutForm_cardExpiry:focus, - input#MultiCheckoutForm_cardNumber:focus, input#MultiCheckoutForm_cardCVV:focus { - background-color: #fff; - } - input#MultiCheckoutForm_cardNumber:focus{ - font-size: 1.325rem; - } - @include media(verysmall){ - background-color: #f8f8f8; - border: 1px solid #ddd; - padding: 20px 20px 15px; - $height: 204px; - height: $height; - max-width:($height*1.76) - } - margin-top: 20px; - @include border-radius(10px); - - ol.field-container-gap { - margin-bottom: 1rem; - } - - input:focus { - background-color: #fff; - outline-color: rgb(91, 157, 217); - outline-offset: -2px; - outline-style: auto; - outline-width: 5px; - } - - p.cardholder { - margin: .65em 0 0; - text-transform: uppercase; - font-size: 1.125rem; - color: #999; - - a { - font-family: $default-font-family; - font-size: .8375rem; - text-transform: none; - border-bottom: 1px dotted #999; - } - } - .cardholder-field { - margin-top: 1em; - - input { - height: 2.75rem; - font-size: .9375rem; - padding: 0 10px; - } - } - - } - .cart-details-secondary { - - li { - float: left; - - &:first-child { margin-right: 1rem; } - } - - .card-logo { - float: right; - height: 44px; - - - img, div { - display: none; - max-height: 44px; - position: relative; - top: 50%; - @include transform(translateY(-50%)); - - &.active { - display: block; - } - } - } - } - } - - .shippingasbilling { - display: inline-block; - font-size: .8375rem; - color: #999; - font-weight: bold; - width: 100%; - margin: 15px 0 20px; - padding: 20px 15px 15px 0; - @include media(verysmall){ - padding: 20px 10px 15px; - } - - //MO - div.text{ - font-size: .8rem; - font-weight: normal; - margin-top: 0.40em; - } - - :checked + .text { - color: #444; - } - - .address-abbr { - color: #999; - font-weight: normal; - font-size: .75rem; - margin: .125em 0 .75em 30px; - } - - input { - float: left; - line-height: 2rem; - margin: .45em .5em 1em 0; - font-size: 1.25rem; - } - } - -//temporary fix, confirm exact styling with Kevin and Luke -input#MultiCheckoutForm_cardNumber { - &:focus{ - padding-left: 10px; - padding-right: 10px; - } -} diff --git a/core/protected/extensions/umber/assets/modal/_checkout_shipping.scss b/core/protected/extensions/umber/assets/modal/_checkout_shipping.scss deleted file mode 100644 index 99174cbd..00000000 --- a/core/protected/extensions/umber/assets/modal/_checkout_shipping.scss +++ /dev/null @@ -1,108 +0,0 @@ -#shipping { - p.introduction { - margin: -.5rem 0 1.5rem; - font-size: .9375rem; - } - - table.shipping-options { - margin: 0; - border: 1px solid #ccc; - display: table; - - td, th { - font-size: .875rem; - padding: .75em; - } - - thead { - th { - color: #666; - font-weight: normal; - font-size: .8375rem; - background-color: #eee; - border-bottom: 1px solid #ccc; - } - } - - tbody { - td, th { - color: #999; - border-bottom: 1px solid #eee; - padding: 1em .75em; - } - th { - color: #555; - font-size: .9375rem; - - input { font-size: 1rem; } - } - - } - - label { - input { margin-right: 8px; } - &:hover { cursor: pointer; } - } - - } - - label.checkbox { - text-align: left; - font-size: 1rem; - margin-bottom: 1rem; - - input.residential-toggle { - margin: 0.2rem 0.5rem 0 0; - } - } -} - -.shipping-instore { - label.checkbox { - text-align: left; - font-weight: bold; - font-size: 1rem; - - &:hover { cursor: pointer; } - - p { - font-weight: normal; - font-size: .8375rem; - margin: .125em 0 .75em 24px; - } - } - - .shipping-instore-details { - @include clearfix(); - margin: .25em 0 0 24px; - - p.contact-info { - float: left; - width: 100%; - margin: 0 0 1.5em; - @include media(verysmall) { - width: 50%; - } - } - } - - h4 { - margin: 0 0 .25em; - font-size: .8375rem; - color: #333; - text-transform: uppercase; - } -} - - -//MO -.overlay #checkout label { - color: #555; font-size: 15px; -} - -#MultiCheckoutForm_shippingFirstName, #MultiCheckoutForm_pickupFirstName{ - border-right: none; -} -#MultiCheckoutForm_shippingAddress1:focus{ - border-bottom: none; -} \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/modal/_checkout_sidebar.scss b/core/protected/extensions/umber/assets/modal/_checkout_sidebar.scss deleted file mode 100644 index 4abd2504..00000000 --- a/core/protected/extensions/umber/assets/modal/_checkout_sidebar.scss +++ /dev/null @@ -1,136 +0,0 @@ -.webstore-sidebar-summary { - - @include flexbox(); - @include flow(column); - @include justify-content(space-between); - - h2, h3 { - color: #666; - text-transform: uppercase; - } - - h2 { - margin: 0 0 .25em; - font-size: 1rem; - } - h3 { - font-size: .875rem; - margin: 0 0 .5em; - } - - a { - text-decoration: none; - border-bottom: 1px dotted #ccc; - padding-bottom: 1px; - - &:hover { - border-bottom: 1px solid $blue; - } - } - - - table { - margin: 0; - color: #888; - - td, th { - font-size: .8375rem; - padding: .5em 0; - } - td { text-align: right; } - - tbody { - th { - font-weight: normal; - //MO - text-align: left; - } - - td, th { - border-bottom: 1px solid #eee; - } - } - - tfoot { - td, th { - color: #333; - font-weight: bold; - text-transform: uppercase; - } - //MO - th { - text-align: left; - } - } - } - - .summary { - max-width: 100%; //MO fix for IE10 order summary. - padding: 30px 15px 15px; - } - - .pricechange { - width: 239px; - font-size: 0.8375rem; - color: #666; - background-color: #ffc; - padding: 15px; - margin: -30px 0px 10px -15px; - border-bottom: 1px solid #ccc; - - @media(max-width: 640px) - { - width: 100%; - margin-left: 0px; - } - } - - .promo { - margin-top: 2rem; - min-width: 100%; - - input { border-color: #eee; - // MO override bootstrap - height:41px; - } - - p.description { display: none; } - } - - .contact { - padding: 15px 15px 20px; - - p { - font-size: .8375rem; - margin: 0; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - h3 { - text-transform: none; - margin: 0 0 .125em; - } - } - - .account { - margin: 0 0 0; - background-color: #f8f8f8; - border-top: 1px solid #eee; - padding: 15px; - - @include align-self(flex-end); - - p { - margin: 0 0 .75em; - font-size: .875rem; - line-height: 1.4; - - &.hint { - margin: 0; - font-size: .8375em; - color: #aaa; - } - } - } -} diff --git a/core/protected/extensions/umber/assets/modal/_checkout_thankyou.scss b/core/protected/extensions/umber/assets/modal/_checkout_thankyou.scss deleted file mode 100644 index f74e8d0d..00000000 --- a/core/protected/extensions/umber/assets/modal/_checkout_thankyou.scss +++ /dev/null @@ -1,199 +0,0 @@ -#thankyou { - .section-content { - width: inherit; //MO fix for IE10 order summary. - border-right: none; - } - - -} -$check-width: 3.25rem; - -.thankyou { - padding-bottom: 2rem; - margin-bottom: 1.5rem; - border-bottom: 1px solid #ccc; - - h1 { - font-size: 1.75rem; - margin: .25em 0 .75em; - @include media(small){ - font-size: 2.25rem; - } - } - - - h2, h3, p, .create-account ol { - margin-left: 0; - } - - @include media(small){ - h2, h3, p, .create-account ol{ - margin-left: $check-width; - } - } - - - h2 { - font-weight: normal; - font-size: 1.3rem; - color: $confirmation-color; - margin: -.25em 0 .25em; - @include media(small){ - font-size: 1.5rem; - } - - &:before { - margin-top: .35rem; - padding-left: .25rem; - margin-right: -.6rem; - float: left; - width: $check-width; - font-size: 1.85rem; - @include media(small){ - margin-top: -.125rem; - padding-left: .25rem; - margin-right: -.25rem; - font-size: 2.5rem; - } - - - - @extend %icon-prereqs; - @extend %icon-check-mark; - } - } - - h3 { - margin-bottom: .125em; - font-size: 1rem; - color: #444; - font-weight: normal; - } - p { - color: #999; - font-size: .8375rem; - margin-top: 0; - margin-bottom: .5em; - - &.large { - font-size: 1.125rem; - color: #444; - margin-bottom: .25rem; - - - } - - - } - - a.print { - font-size: .8125rem; - margin-bottom: 1em; - margin-top: .5em; - border: 1px solid #ddd; - color: #888; - padding: 10px 12px; - display: inline-block; - - &:before { - @extend %icon-prereqs; - @extend %icon-print; - - float: left; - margin-top: 1px; - font-size: 18px; - margin-right: 6px; - } - - &:hover, &:active { - color: $calltoaction-color; - border-color: $calltoaction-color; - } - } - -} -.create-account { - @extend %clearfix; - - li { - &:last-child{ - clear: both; - margin-top: 0.75em; - @include media(small){ - clear: none; - margin-top: 0; - } - } - @include media(verysmall){ - float: left; - margin-right: .5rem; - } - } - input { - border: $input-border; - padding: 10px; - font-size: .8375rem; - width: 12em; - //MO to override style.css l.24. - &:focus{ - padding: 10px; - font-size: .8375rem; - } - } - button { - font-size: .8375rem; - padding: 11px 10px; - color: #666; - background-color: #eee; - // border: 1px solid #ccc; - - &:hover { - color: #fff; - } - } - .hint { - margin: .5em 0 0; - font-size: .675rem; - color: #999; - } -} -.create-account-confirm { - margin-left: $check-width; - font-size: 1rem; - padding: 12px; - color: #999; - border: 1px solid #ccc; - max-width: 24rem; - - h3, p { margin: 0; } - h3 { font-weight:bold; } -} - -.receipt { - h2 { - font-size: 1.3rem; - margin: 0 0 -.5em; - @include media(small) { - font-size: 1.5rem; - } - - .order-id { - border: 1px solid #ddd; - float: right; - padding: 6px 10px; - margin-bottom: -1rem; - font-size: 1rem; - text-transform: uppercase; - color: #bbb; - font-weight: normal; - line-height: normal; //MO override bootstrap - - strong { color: #555; } - } - } -} - -//MO override -.create-account p.form-error { - width: 20rem; -} diff --git a/core/protected/extensions/umber/assets/modal/_config.scss b/core/protected/extensions/umber/assets/modal/_config.scss deleted file mode 100755 index 77dc4fa3..00000000 --- a/core/protected/extensions/umber/assets/modal/_config.scss +++ /dev/null @@ -1,154 +0,0 @@ -@charset "utf-8"; - -$break-mobile: 0px; // This is used in limited situations, generally styles layer-up, not down. -$break-narrow-modal: 360px; -$break-verysmall: 450px; -$break-small: 640px; -$break-medium: 720px; -$break-cart-width: 840px; -$break-large: 1025px; -$break-verylarge: 1240px; - - -@import 'compass'; -@import '../mixins/html5-input-types'; - - -@mixin media($media) { - @if $media == 'mobile' { - @media (max-width: $break-small) { @content; } - } - @if $media == 'narrow-modal' { - @media (min-width: $break-narrow-modal) { @content; } - } - @else if $media == 'verysmall' { - @media (min-width: $break-verysmall) { @content; } - } - @else if $media == 'small' { - @media (min-width: $break-small) { @content; } - } - @else if $media == 'medium' { - @media (min-width: $break-medium) { @content; } - } - @else if $media == 'cartwidth' { - @media (min-width: $break-cart-width) { @content; } - } - @else if $media == 'large' { - @media (min-width: $break-large) { @content; } - } - @else if $media == 'short' { - @media (max-height: $break-short) { @content; } - } - @else { - @content; - } -} - -.webstore-modal * { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - padding-bottom: 0; -} - -// Colors -$font-color: #000; - -$blue: #3287CC; -$blue-steel: #435261; - -$purple: #897897; -$green: #589141; -$green-pale: #DBEBD6; -$pink: #CC89A6; -$red: #A44039; -$orange: #E27E38; -$yellow: #F6B444; - -$light-grey-border: #ccc; -$light-grey-text: #aaa; - -// Input borders -$input-border:1px solid $light-grey-border; - -// Link colors -$link-color: $blue; -$link-hover-color: darken($blue,10%); -$link-active-color: darken($blue,20%); - - - -.webstore-modal-overlay{ - a { - color: $link-color; - text-decoration: none; - - &:active { color: $link-active-color; } - &:hover { - color: $link-hover-color; - //MO boostrap override - text-decoration: none; - } - - &.hasborder { - padding-bottom: 1px; - border-bottom: $input-border !important; - - &:hover, &:active { - border-bottom-color: $blue; - } - } - } - -} - -$modal-padding: 20px; - -$modal-width: 720px; -$modal-width-narrow: 480px; - -$error-color: #B4282E; -$success-color: #ffffcc; - -$calltoaction-color: $blue; -$confirmation-color: $green !default; - -$default-font-family: 'Open Sans', 'Helvetica Neue', Helvetica, sans-serif;; - -$webstore-modal-font: $default-font-family; -$webstore-modal-header-font-weight: normal; -$webstore-modal-header-font-family: $default-font-family; - - -%clearfix { - &:after { - content: ""; - display: table; - clear: both; - } -} - -%remove-icon { - text-decoration: none; - display: block; - border: 2px solid #eee; - color: #ccc; - background-color: #fff; - @include border-radius(20px); - height: 28px; - width: 28px; - line-height: 22px; - padding-left: 5px; - font-size: 25px; - font-weight: bold; - margin: 0; - - @include transition-property(border-color, background-color,color); - @include transition-duration(.3s); - - &:hover { - color: #fff; - border-color: $red; - background-color: $red; - } -} diff --git a/core/protected/extensions/umber/assets/modal/_estimator.scss b/core/protected/extensions/umber/assets/modal/_estimator.scss deleted file mode 100644 index fe1c5065..00000000 --- a/core/protected/extensions/umber/assets/modal/_estimator.scss +++ /dev/null @@ -1,308 +0,0 @@ -.webstore-estimator { - &.recalculate { - td { - visibility: hidden; - color: #f8f8f8; - - &:after { visibility: visible; } - } - td.csspinner:after { - top: 27px; - left: 45px; - } - } - - form { - margin-top: 6px; - display: block; - } - input, button { - float: left; - - &:focus { - outline: none; - box-shadow: inset 1px 1px 2px rgba(0,0,0,.1); - border: 1px solid #bbb; - } - } - input { - border: $input-border; - padding: 9px 8px; - &:focus{ - padding: 9px 8px; - } - } - - select.webstore-estimator-country-form, select#webstore-estimator-country-form { - -webkit-appearance: menulist; - -moz-appearance: menulist; - appearance: menulist; - margin: 8px 0 0; - border: solid 1px #ccc; - } - - button { - padding-left: 8px; - padding-right: 8px; - } - - a.webstore-estimator-country { - float: right; - color: #888; - text-decoration: none; - border-bottom: 1px dotted #ccc; - font-size: .75rem; - display: inline-block; - padding: 10px 1px 0; - font-weight: normal; - line-height: normal; - &:active, &:hover { - color: #888; - font-weight: normal; - } - } -} - -.webstore-shipping-choices{ - background-color: rgba(0,0,0,.7); - height: 100%; - position: absolute; - top: 0; - right: 0; - left: 0; - z-index: 20; - - - @include media(small) { - position: relative; - background: none; - top: auto; - right: auto; - left: auto; - height: auto; - } - - form { - z-index:10; - position: absolute; - left: 0; - top: 0; - right: 0; - background-color: #fff; - margin: 0; - padding: 0 0 67px; - box-shadow: 1px 1px 3px rgba(0,0,0,.1); - - ol{ - min-height: 120px; - } - - @include media(small) { - left: -265px; - top: -24px; - width: 250px; - padding: 0 0 39px; - - &:after, &:before { - left: 249px; - top: 75px; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - } - - &:after { - border-color: rgba(255, 255, 255, 0); - border-left-color: #ffffff; - border-width: 10px; - margin-top: -10px; - } - &:before { - border-color: rgba(204, 204, 204, 0); - border-left-color: #bbb; - border-width: 11px; - margin-top: -11px; - } - } - } - - ol { - margin: 0; - padding: 0 0 4px; - list-style: none; - border: 1px solid #ccc; - border-bottom: none; - - li:last-child label { border-bottom: none; } - } - - li { - display: inline; - //MO - margin-bottom: 0; - - &.webstore-shipping-choices-more, - &.webstore-shipping-choices-notice { - display: block; - padding: 8px 10px; - color: #555; - background-color: #eee; - border-top: 1px solid #ccc; - font-size: .75rem; - margin-bottom: 0; - } - &.webstore-shipping-choices-notice { - border-top: none; - border-bottom: 1px solid #ddd; - background-color: #ffc; - } - - small{ - font-weight: normal; - color: #999; - } - } - - button, input[type="button"] { - width: 100%; - position: absolute; - bottom: 0; - left: 0; - right: 0; - - @include media(small) { - font-size: .875rem; - padding: 10px; - } - } - - //MO - .radio input[type="radio"]{ - float: left; - margin-left: -18px; - margin-top: 2px; - } - - label { - padding: 8px 48px 8px 24px; - color: #666; - margin: 0; - font-weight: bold; - display: block; - - small { - float: right; - font-weight: normal; - color: #999; - font-size: .9375rem; - margin-right: -42px; - @include media(small) { font-size: .75rem; } - } - - &:hover{ - background-color: #eee; - cursor: pointer; - } - } - - input{ - margin-right: 3px; - } -} - -.shipping-postal-entry{ - position: relative; - display: block; - height: 47px; - width: 100%; - overflow: hidden; - - button.inset{ - right: 8px; - top: 7px; - } - - input, input:focus{ - font-size: .875rem; - width: 100%; - outline: none; - box-shadow: inset 1px 1px 2px rgba(0,0,0,.1); - border: 1px solid #bbb!important; - } -} - -.webstore-modal-cart-confirm .shipping-postal-entry input, .shipping-postal-entry input:focus { - padding: 10px; -} - - -@media (min-width: 560px){ - .webstore-shipping-choices{ - input[type="button"] { - font-size: .875rem; - padding: 10px; - } - - form { - left: -265px; - top: -24px; - width: 250px; - padding: 0 0 39px; - } - } - - input.close-shipping-options.close-shipping-choices:focus{ - padding: 10px!important; - font-size: 0.875rem!important; - } - .close-shipping-options, .close-shipping-options:focus{ - max-height: 39px; - font-size: 0.875rem; - } -} - -@media (max-width: 560px){ - .webstore-shipping-choices label{ - font-size: 16px; - } - .webstore-shipping-choices li small{ - font-size: .9375rem; - } -} - - -.webstore-modal-cart-confirm{ - .shipping-postal-entry button.inset{ - left: calc(100% - 80px); - top:-34px; - position: relative; - } - a.webstore-estimator-country { - margin-bottom: 10px; - } - .shipping-postal-entry button.inset-spinner{ - left: calc(100% - 37px); - } -} - -.editcartmodal{ - .shipping-postal-entry button.inset{ - left: calc(100% - 85px); - top:-34px; - position: relative; - } - a.webstore-estimator-country { - margin-bottom: 10px; - padding-top: 5px; - } - .shipping-postal-entry button.inset-spinner{ - left: calc(100% - 42px); - } -} - - - - diff --git a/core/protected/extensions/umber/assets/modal/_icons.scss b/core/protected/extensions/umber/assets/modal/_icons.scss deleted file mode 100644 index 38753b4c..00000000 --- a/core/protected/extensions/umber/assets/modal/_icons.scss +++ /dev/null @@ -1,29 +0,0 @@ -//TODO: MO FONTS -@font-face { - font-family: "ls-webstore"; - src:url("fonts/ls-webstore.eot"); - src:url("fonts/ls-webstore.eot?#iefix") format("embedded-opentype"), - url("fonts/ls-webstore.woff") format("woff"), - url("fonts/ls-webstore.ttf") format("truetype"), - url("fonts/ls-webstore.svg#ls-webstore") format("svg"); - font-weight: normal; - font-style: normal; - -} - -%icon-prereqs { - font-family: "ls-webstore" !important; - font-style: normal !important; - font-weight: normal !important; - font-variant: normal !important; - text-transform: none !important; - speak: none; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -%icon-pencil { content: "\e000"; } -%icon-check-mark { content: "\e001"; } -%icon-chat-bubble { content: "\e002"; } -%icon-print { content: "\e003"; } diff --git a/core/protected/extensions/umber/assets/modal/_lines.scss b/core/protected/extensions/umber/assets/modal/_lines.scss deleted file mode 100644 index 3cf05037..00000000 --- a/core/protected/extensions/umber/assets/modal/_lines.scss +++ /dev/null @@ -1,143 +0,0 @@ -.webstore-lines { - tbody { - border-bottom: 1px solid #ddd; - } - - td { - border-top: 1px solid #ddd; - line-height: 40px; - } - - .quantity { - font-weight: bold; - text-align: center; - padding: 0; - line-height: 4rem; - min-width: 1.75rem; - - input { - display: none; - width: 1.75rem; - padding: 3px 3px; - text-align: center; - font-weight: bold; - - &::-webkit-inner-spin-button, &::-webkit-outer-spin-button { - -webkit-appearance: none; - margin: 0; - } - -moz-appearance:textfield; - } - } - - .image { - white-space: nowrap; - width: 65px; - - &:before { - display: inline-block; - padding: 0 .5em 0 0; - height: 40px; - font-weight: normal; - font-size: 1.25rem; - content: '\d7'; - float: left; - } - - img { - float: left; - max-height: 40px; - max-width: 40px; - } - } - - .description { - line-height: 1.3; - font-size: .875rem; - padding-right: .5em; - padding-left: .5em; - font-weight: bold; - - .price { - font-weight: normal; - font-size: .8375em; - color: #888; - } - } - - .subtotal { - text-align: right; - font-weight: bold; - } - - .controls { - padding-left: 1em; - text-transform: uppercase; - font-size: .75rem; - width: 2.5rem; - - a { float: right; } - } - a.edit { - line-height: 1; - padding: 6px 4px 5px; - border: 1px solid #ccc; - color: #aaa; - - &:hover { - color: $blue; - border-color: $blue; - } - } - a.remove { - @extend %remove-icon; - display: none; - } - - - tr.active { - .quantity { - strong { display: none; } - input { display: inline-block; } - } - .controls { - a.edit { display: none; } - a.remove { display: block; } - } - } -} - -.lines-footer { @extend %clearfix; } - -.webstore-lines-totals { - margin-top: .5rem; - float: right; - max-width: 16rem; - - td, th { - color: #666; - line-height: 1.75rem; - font-size: 1rem; - } - small { - font-size: .75rem; - color: #999; - font-weight: normal; - } - td { - text-align: right; - border-top: none; - line-height: 1; - } - - .total { - td, th { - color: #333; - font-size: 1.25rem; - line-height: 1.5em; - - } - td { font-weight: bold;} - - } -} \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/modal/_modal_overlay_shared.scss b/core/protected/extensions/umber/assets/modal/_modal_overlay_shared.scss deleted file mode 100755 index 28bbf7c3..00000000 --- a/core/protected/extensions/umber/assets/modal/_modal_overlay_shared.scss +++ /dev/null @@ -1,439 +0,0 @@ -// Shared styles used by modals and overlays -.webstore-modal-overlay { - button, textarea { - @include border-radius(0); - //MO - text-transform:none; - } - - //webstore Montreal override see .webstore-modal * in _basic_modal.scss - * { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; - } - - input[type="submit"] { - outline: none; - } - - button, .button, input[type="button"], .button:focus, input[type="button"]:focus { - @include transition-property(background-color,color); - @include transition-duration(.3s); - - font-size: 1.25rem; - font-weight: $webstore-modal-header-font-weight; - - padding: $modal-padding 0; - background: $calltoaction-color; - width: 100%; - border: none; - color: #fff; - float: left; - @include border-radius(0); - text-decoration: none; - text-align: center; - - &:hover { - background-color: darken($calltoaction-color,10%); - } - &:focus { - outline: none; - } - - &.inline { - font-family: $webstore-modal-font; - float: none; - width: auto; - padding: 11px 14px; - margin-left: -1px; - font-size: .9375rem; - } - - &.inset { - @include transition-property(background-color, color, border-color); - @include transition-duration(.3s); - - background: none; - border: 1px solid rgba(0,0,0,.1); - @include border-radius(0); - text-transform: uppercase; - color: #bbb; - padding: 7px 6px; - width: auto; - font-size: .7rem; - font-weight: 600; - line-height: 1; - position: absolute; - right: 18px; - top: 21px; - - &:hover { - border-color: $calltoaction-color; - color: #fff; - background: $calltoaction-color; - } - } - } - - table { - width: 100%; - - th, td { - font-size: 1rem; - } - .money { - text-align: right; - } - } - - .field-container { - position: relative; - - &:before, &:after { - content: " "; /* 1 */ - display: table; /* 2 */ - } - &:after { clear: both; } - - p.hint { - line-height: 2rem; - color: #888; - font-size: 1rem; - position: absolute; - right: 20px; - top: 20px; - z-index: 1; - pointer-events:none; - - @include transition-property(opacity); - @include transition-duration(.2s); - - strong { - padding: 3px; - text-transform: uppercase; - color: #bbb; - font-size: .875rem; - font-weight: normal; - } - - &.show { - opacity: 0; - } - } - - label.placeheld { - opacity: 0; - z-index: 1; - position: absolute; - visibility: hidden; - top: 24px; - left: 20px; - transition: all 0.1s linear; - color: #aaa; - font-size: .875rem; - - &.show, &.locked { - visibility: visible; - top: 12px; - opacity:1; - } - } - - input { height: 4.25rem; } - - input{ - transition: all 0.1s linear; - - padding: .75em 20px; - box-shadow: none; - font-size: 1.25rem; - width: 100%; - //MO - @include border-radius(0); - border: 1px solid #ddd; - - &.show { - padding: 1.25em 20px .25em; - } - - &:focus { - background-color: #f8f8f8; - outline: none; - box-shadow: inset 0 1px 1px rgba(0,0,0,.1); - } - } - - select { - transition: all 0.1s linear; - border: none; - margin: 0; - font: 1.5rem $default-font-family; - @include border-radius(0); - padding: .9375em 20px; - box-shadow: none; - width: 100%; - background: none; - color: #bbb; - -webkit-appearance: none; - -moz-appearance:none; - -ms-appearance:none; - appearance:none; - - &.show { - color: #333; - padding: 1.25em 20px .5em; - } - - - &:focus { - background-color: #f8f8f8; - outline: none; - } - } - - &.field-container-nobottomborder { - input, input:focus { - border-bottom: none !important; - } - } - &.field-container-notopborder { - input { - border-top: none; - } - } - } - - - - .flippable { - height: 68px; - margin: 0 auto; - @include perspective(600px); - - .side { - top: 0; - right: 0; - left: 0; - overflow: hidden; - height: inherit; - position: absolute; - - @include transform(rotateX(-180deg)); - @include transform-style(preserve-3d); - @include backface-visibility(hidden); - /* -- transition is the magic sauce for animation -- */ - @include transition(all 0.4s ease-in-out); - - p { - //MO bootstrap override - margin: 13px 0; - } - - } - - .front { - z-index: 900; - @include transform(rotateX(0deg) rotateY(0deg)); - @include transform-style(preserve-3d); - @include backface-visibility(hidden); - /* -- transition is the magic sauce for animation -- */ - @include transition(all .4s ease-in-out); - } - .back { - z-index: 800; - @include transform(rotateX(-180deg)); - @include transform-style(preserve-3d); - @include backface-visibility(hidden); - /* -- transition is the magic sauce for animation -- */ - @include transition(all .4s ease-in-out); - } - - &.flip { - .front { - z-index: 900; - @include transform(rotateX(180deg)); - } - .back { - z-index: 1000; - @include transform(rotateX(0deg) rotateY(0deg)); - } - } - } - - .form-error { - border-top: 3px solid $error-color; - padding: 12px 15px; - background-color: #FFF2F2; - border-bottom: 1px solid #ddd; - margin: -.5em 0 1em; - - p { - - color: $error-color; - font-size: .8125rem; - line-height: 1.5; - } - } - - .success .form-error{ - border-top: 1px solid #ddd; - border-right: 1px solid #ddd; - border-left: 1px solid #ddd; - padding: 12px 20px; - background-color: $success-color; - border-bottom: 1px solid #ddd; - margin: -0.5em 0 1em; - - p { - margin: 0; - color: #666; - font-size: .85rem; - } - } - - form.error { - input { - &::-webkit-input-placeholder { - color: #aaa; - @include transition-property(color); - @include transition-duration(1s); - } - &:-moz-placeholder { - color: #aaa; - @include transition-property(color); - @include transition-duration(1s); - } - &::-moz-placeholder { - color: #aaa; - @include transition-property(color); - @include transition-duration(1s); - } - &:-ms-input-placeholder { - color: #aaa; - @include transition-property(color); - @include transition-duration(1s); - } - - &.error, &:invalid, { - box-shadow: none; - color: #B4282E; - - &::-webkit-input-placeholder { color: #B4282E; } - &:-moz-placeholder { color: #B4282E; } - &::-moz-placeholder { color: #B4282E; } - &:-ms-input-placeholder { color: #B4282E; } - &:focus { color: inherit; } - } - } - - .field-container { - .required { - position: absolute; - top: 26px; - right: 20px; - - font-weight: bold; - text-transform: uppercase; - color: $error-color; - font-size: .75rem; - } - &.password .required { - right: 160px; - } - } - .field-container-password .required { - right: 160px; - } - } - -} - -#confirm h4 { - margin: .5em 0 .25em; -} - - -.steps { - display: none; - @include clearfix(); - background-color: #f8f8f8; - border-bottom: 1px solid #ddd; - margin: -15px -30px 15px; - padding: 0; - @include media(verysmall) { - display: block; - } - - - li { - position: relative; - width: 33.3%; - height: 40px; - - float: left; - - color: #777; - font-size: .8375rem; - font-weight: bold; - line-height: 40px; - text-transform: uppercase; - - text-align: center; - border-right: 1px solid #ddd; - - &:last-child { border-right: none; } - - &.completed { - color: #aaa; - - //MO .webstore-label previously .label refractored to avoid boostrap conflict. - .webstore-label { - position: relative; - width: 28px; - display: inline-block; - height: 18px; - - &:before { - - @extend %icon-prereqs; - @extend %icon-check-mark; - - position: absolute; - top: 2px; - left: 0; - height: 20px; - width: 20px; - - display: inline-block; - color: #ccc; - line-height: 18px; - @include border-radius(20px); - border: 2px solid #ccc; - text-align: center; - } - } - } - &.current { - background-color: #eee; - color: #000; - } - } -} - -//MO temporary fix -p.hint{ - margin:13.4px 0; -} -.controls a{ - font-size: .75rem; -// TODO:remove this; - max-width: 43px; -} - -//confirmation quantity on focus -.webstore-overlay input, .webstore-overlay input:focus { - border: solid 1px #ddd; - background-color: initial; -} \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/modal/_overlay.scss b/core/protected/extensions/umber/assets/modal/_overlay.scss deleted file mode 100755 index 8dc51039..00000000 --- a/core/protected/extensions/umber/assets/modal/_overlay.scss +++ /dev/null @@ -1,325 +0,0 @@ -body.overlay { - background-color: #eee; -} - -.editcartmodal{ - @include media(medium) { - &:before { - content: ''; - display: inline-block; - //breaking on certain browser widths - height: 5%; - vertical-align: middle; - margin-right: -0.25em; /* Adjusts for spacing */ - } - } - } -.webstore-modal-cart-confirm{ - @include media(medium) { - &:before { - content: ''; - display: inline-block; - //breaking on certain browser widths - height: 85%; - vertical-align: middle; - margin-right: -0.25em; /* Adjusts for spacing */ - } - } -} -.webstore-overlay { - height: 100%; - position: absolute; - padding: 0; - z-index: 2; - - top: 0; - bottom: 0; - left: 0; - right: 0; - font-family: $webstore-modal-font; - - .field-container { - input { - border: 1px solid #ddd; - } - } - - .section-inner { - background-color: #fff; - padding: 15px 20px 20px; - border-top: 1px solid #ccc; - border-bottom: 1px solid #ccc; - - @media(min-width:640px) { - padding: 15px 30px 30px; - border: 1px solid #ccc; - } - } - - .section-inner.jumper { - text-align: center; - margin-top: 50px; - } - - section { - box-shadow: none; - display: inline-block; - vertical-align: middle; - width: 100%; - max-width: 840px; - margin: 0 auto; - text-align: left; - - & > header { - padding: 0 10px; - overflow: hidden; - position: relative; - - @include media(small) { - padding: 0 30px; - border-bottom: none; - button.exit, a.exit{ - margin-right: 30px; - } - } - - @include media(cartwidth) { - padding: 0; - button.exit, a.exit{ - margin-right: 0; - } - } - - h1, .exit { - margin: .75rem 0; - display: inline-block; - float: left; - line-height: 1.5rem; - } - - h1 { - font-size: 1.125rem; - width: 50%; - font-weight: bold; - - a { - text-decoration: none; - color: #555; - } - - img + span { display: none; } - - img { - max-height: 80px; - max-width: 100%; - } - } - - .exit { - color: #777; - //MO - padding: 0; - background:none; - border-bottom: 1px dotted #ccc; - text-align: right; - font-size: .8375rem; - text-decoration: none; - display: none; - position: absolute; - right: 0; - bottom: 0; - - &:hover { border-bottom: 1px solid #777; } - - @media(min-width:640px) { - display: block; - width: auto; - } - } - - .logo-placement{ - outline: none; - img{ - outline: none; - } - } - } - - footer { - padding: 0; - - &.submit input{ - float: none; - } - - img { margin: 0 3px 0 0; } - - &.submit input{ float:none; } - p { - margin: 3rem 0 1rem; - text-align: center; - font-size: 12px; - line-height: 16px; - color: #999; - } - strong { - color: #777; - font-size: 13px; - } - a { color: #999; } - } - } - - h1 { - font-size: 1.35rem; - margin: 0 0 .75em; - //MO - font-weight: bold; - - @include media(small) { - margin: .5em 0 .75em; - font-size: 1.75rem; - } - } - - &.show { background-color: #fff; } - - header.webstore-brand { - border-bottom: 1px solid #ccc; - background: #eee; - padding: 10px; - - @include media(small) { padding: 10px 30px; } - - h3 { - font: normal 1rem $webstore-modal-header-font-family; - font-weight: $webstore-modal-header-font-weight; - text-transform: uppercase; - color: #666; - text-align: left; - margin: 0 auto; - max-width: 1000px; - - } - } - - header { - padding: none; - background: none; - padding: 0 8px; - border: none; - - @include media(small) { - padding-right: 30px; - padding-left: 30px; - } - - h1 { - font: normal 2.25rem $webstore-modal-header-font-family; - font-weight: $webstore-modal-header-font-weight; - margin: .5em 0 .35em; - text-transform: none; - color: #555; - } - } - - .field-container { - label.placeheld { - font-size: .8375rem; - } - input { - height: 4.25rem; - &.show { - } - - } - } - - footer button.continue, footer button.continue:focus{ - display: block; - background: none; - border: 1px solid #999; - color: #999; - font-size: 1.125rem; - margin-botom:0; - @include transition-property(border); - @include transition-duration(0.3s); - margin-top: 25px; - margin-bottom: 30px; - } - section>footer{ - padding: 15px 20px 20px!important; - } - @include media(small){ - footer button.continue{ - display:none; - } - - } -} - -.webstore-overlay-narrow { - section { max-width: 480px; } -} -.webstore-overlay-aside { - $section-sidebar-width: 240px; - $section-content-width: 480px; - - @include media(small) { - section { max-width: $section-sidebar-width + $section-content-width; } - } - - .section-inner { - padding: 0; - margin-bottom: 30px; - @include clearfix(); - - @include media(small) { - - @include flexbox(); - @include direction(row); - - .section-content, .section-sidebar { - -webkit-flex: 1 1 auto; - flex: 1 1 auto; - } - } - - .section-content { - @extend %clearfix; - padding: 15px; - - @include media(small) { - width: $section-content-width; - padding-left: 30px; - padding-right: 30px; - &.full { - width: auto; - } - } - - } - .section-sidebar { - background: #f8f8f8; - - @include media(small) { - border-top: none; - background: none; - width: $section-sidebar-width - 1px; - padding: 0; - margin-left: -1px; - border-left: 1px solid #ccc; - } - } - } -} - -@media(max-width: 640px){ - .mobile-hide{ - display:none; - } -} - - - - diff --git a/core/protected/extensions/umber/assets/modal/_override_legacy.scss b/core/protected/extensions/umber/assets/modal/_override_legacy.scss deleted file mode 100644 index 7ec36f9a..00000000 --- a/core/protected/extensions/umber/assets/modal/_override_legacy.scss +++ /dev/null @@ -1,196 +0,0 @@ -body{ - color: rgb(0, 0, 0); -} - -//override light.css, style.css, base.css -//bootstrap.css -a, a:hover, a:focus, a:visited, a * { - outline: none; -} - -.webstore-overlay{ - line-height:normal; - body{ - line-height:normal; - } - //override: base.css l.119 - p { - margin-bottom:0px; - } - .button, button, input[type="submit"], input[type="reset"], input[type="button"]{ - text-shadow:none; - } - - h3 { - display: block; - -webkit-margin-before: 1em; - -webkit-margin-after: 1em; - -webkit-margin-start: 0px; - -webkit-margin-end: 0px; - -moz-margin-before: 1em; - -moz-margin-after: 1em; - -moz-margin-start: 0px; - -moz-margin-end: 0px; - margin-before: 1em; - margin-after: 1em; - margin-start: 0px; - margin-end: 0px; - font-weight: bold; - line-height: normal; - font-size: 19px; - } - h1, h2, h3, h4, h5, h6{ - font-family: "Open Sans", "Helvetica Neue", Helvetica, sans-serif; - font-weight: bold; - } - button, input, select, textarea { - vertical-align: baseline; - } - h1 { - line-height: inherit; - } - li { - margin-bottom:0; - } - .button, - button, - input[type="submit"], - input[type="reset"], - input[type="button"] { - font-family:inherit; - text-transform: none; - margin-bottom: 0; - } - - //override bootstrap:1518 - input:focus:required:invalid:focus, textarea:focus:required:invalid:focus, select:focus:required:invalid:focus{ - border-color:#ddd; - -webkit-box-shadow:none; - -moz-box-shadow:none; - box-shadow:none; - } - //override bootstrap:1511 - input:focus:required:invalid, textarea:focus:required:invalid, select:focus:required:invalid{ - color:#000000; - border-color:#ddd; - } - - input:focus { - outline: -webkit-focus-ring-color auto 5px; - } - - select, input[type="text"], input[type="password"], input[type="email"],input[type="text"]:focus, - input[type="password"]:focus, input[type="email"]:focus { - width: 100%; - background-color: transparent; - line-height: normal; - max-width: none; - } - - select, textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], - input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], - input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], - .uneditable-input{ - @include border-radius(0); - line-height:normal; - } - - @media only screen and (max-width: 960px){ - select, input[type="text"], input[type="password"], input[type="email"], input[type="text"]:focus, input[type="password"]:focus, input[type="email"]:focus { - max-width: none; - } - } - - input[type=submit] { - margin-top: 0; - } - - //override light l.154, l.141 height auto height 30px - .submit-small{ - .button:focus, input[type="button"]:focus { - //MO - min-height:50px; - } - } - - //override base.css l.350 - form{ - margin-bottom: 0; - } - - section footer.submit p { - display: block; - -webkit-margin-before: 1em; - -webkit-margin-after: 1em; - -webkit-margin-start: 0px; - -webkit-margin-end: 0px; - } -} - -.overlay{ - #checkout input[type="text"], #checkout input[type="password"], - #checkout input[type="email"], #checkout input[type="select"], - #checkout input[type="text"]:focus, #checkout input[type="password"]:focus, - #checkout input[type="email"]:focus, #checkout input[type="select"]:focus { -// border: 1px solid #ddd; - } - #checkout label{ - text-transform: none; - } -} - - -.webstore-modal{ - select{ - font-size: 11px; - height: 18px; - line-height: normal; - } - - //override style.css l.27 and bootstrap. - input[type="radio"] { - width: initial; - height: initial; - } - - //bootstrap override - .radio input[type="radio"], .checkbox input[type="checkbox"] { - margin-left:0; - } - - .webstore-checkout .choices .button:focus { - height:46px; - } - - button, input, select, textarea{ - vertical-align:baseline; - } - - //override light.css - input[type=button], input[type=submit], button, label{ - text-transform:none; - } - - //override style.css - select, input[type="text"], input[type="password"], input[type="email"] { - max-width: none; - } - - //override base.css - - //l.119 - p{ margin-bottom: 0; } - - //l.265 - .button, button, input[type="submit"], input[type="reset"], input[type="button"] { - margin-bottom: initial; - } - //l.350 - form{ - margin-bottom: initial; - } - - /* JPickard - added this because in base.css: #shoppingcart {text-transform: uppercase} */ - text-transform: none; -} - diff --git a/core/protected/extensions/umber/assets/modal/_overview.scss b/core/protected/extensions/umber/assets/modal/_overview.scss deleted file mode 100644 index 165577c4..00000000 --- a/core/protected/extensions/umber/assets/modal/_overview.scss +++ /dev/null @@ -1,177 +0,0 @@ -.address-blocks { - @include transition(opacity .5s); - height: auto; - opacity: 1; - &.flipped { - height: 0; - opacity: 0; - overflow: hidden; - } -} - -.address-new { - position: relative; - footer { - max-width: 200px; - .button { - padding: 10px 0; - } - } - .select-options { - font-size: .9rem; - color: #888; - label.checkbox { - padding-bottom: 5px; - display: block; - padding-right: 10px; - @include media(medium) { - display: inline-block; - padding-bottom: 0; - } - &:last-child { - padding-right: 0; - } - } - } - .address-form { - max-width: 420px; - .submit-small .button { - font-size: .9rem; - } - ol { - padding-left: 0; - li { - list-style: none; - } - } - } - @include transition(opacity .5s); - height: 0; - opacity: 0; - overflow: hidden; - &.flipped { - height: auto; - opacity: 1; - } -} -.account-address { - .address-block { - width: 100%; - margin-right: 0; - margin-bottom: 30px; - display: inline-block; - vertical-align: top; - p:before { - display: none; - } - @include media(medium) { - width: 47%; - margin-right: 4%; - &:last-child { - margin-right: 0; - } - } - } -} - -.order-history { - table { - border-collapse: collapse; - color: #444; - - th, td { - text-align: left; - } - tr { - @include transition(color .1s, border .1s, background .1s); - &:hover { - cursor: pointer; - background-color: #f8f8f8; - } - } - - &.lines { - a { color: #555; } - td { - padding: 10px 0; - font-size: 0.875rem; - &.date { - color: $blue; - font-weight: bold; - } - &.num { - font-weight: bold; - } - } - tr td:first-child, tr th:first-child { - padding-left: 8px; - @include media(small) { - padding-left: 10px; - } - } - tr td:last-child, tr th:last-child { - padding-right: 8px; - @include media(small) { - padding-right: 10px; - } - } - tbody { - border-top: 1px solid #eee; - } - td { border-bottom: 1px solid #eee; } - } - - - } - .subtotal { - text-align: right; - } - -} - -//MO added the .add .small class to support links with button like look-n-feel -button.small, .add .small { - float: none; - padding: 9px 12px; - margin-bottom: 30px; - width: auto; - display: inline-block; - vertical-align: top; - font-size: .8rem; -} - -.modify { - font-size: .8rem; - padding-left: 0; - list-style: none; - li { - display: inline; - margin-right: 20px; - &:last-child { - margin-right: 0; - } - } - a { - text-decoration: none; - border-bottom: 1px solid #fff; - padding-bottom: 1px; - - &:hover { - border-bottom-color: $blue; - } - } -} - -.customer p { - font-size: 1.1em; - strong { - font-size: 1.2em; - } -} - -.customerorder p { - font-size: .75em; - strong { - font-size: 1.2em; - } -} diff --git a/core/protected/extensions/umber/assets/modal/_print.scss b/core/protected/extensions/umber/assets/modal/_print.scss deleted file mode 100644 index 7d656c3f..00000000 --- a/core/protected/extensions/umber/assets/modal/_print.scss +++ /dev/null @@ -1,31 +0,0 @@ -@media print { - - body.overlay { - background: none; - } - .webstore-overlay { - section { - border: none; - width: 100%; - max-width: 100%; - - header { - padding: 0 15px; - - .exit { display: none; } - } - footer { display: none; } - } - .section-inner { - border: none; - - .section-content { - padding: 0 15px; - } - - } - } - - .controls { display: none; } - .thankyou { display: none; } -} diff --git a/core/protected/extensions/umber/assets/modal/_promo.scss b/core/protected/extensions/umber/assets/modal/_promo.scss deleted file mode 100644 index 8dde2168..00000000 --- a/core/protected/extensions/umber/assets/modal/_promo.scss +++ /dev/null @@ -1,109 +0,0 @@ -.promo { - min-width: 16rem; - position: relative; - - @media(min-width:640px) { - float: left; - margin: 2rem 0 0; - } - - input, input[type="text"],input:focus,input[type="text"]:focus { - font-size: .875rem; - width: 100%; - padding: 10px; - border: none; - border-bottom: 1px solid #ddd; - box-shadow: none; - padding-right: 64px; - - @media (min-width: 640px) { - border: 1px solid #ddd; - } - } - - button.inset { - right: 8px; - top: 7px; - opacity: 1; - @include transition(opacity .3s); - - @include media(small) { - opacity: 0; - } - - &:hover, &:active { - color: #fff; - border-color: $blue; - background-color: $calltoaction-color; - } - } - - .form-error { - clear: both; - padding: 10px 10px; - border-top: none; - border-bottom: 3px solid $red; - margin-bottom: 0; - width: 100%; - - p { - font-weight: bold; - color: $red; - padding: 0; - line-height: 1.3; - } - } - - .description { - display: none; - - padding: 0; - margin: .25em 0 0; - - color: #aaa; - font-size: .75rem; - @media(min-width:640px) { display: block; } - - } - - &:hover button { opacity: 1; } -} - -//MO -//add to cart view promo code -#addcart { - .promo{ - input[type="text"]{ - border-top: $input-border; - width:100%; - padding-right:90px; - padding-left:20px; - height:46px; - &:focus{ - box-shadow: inset 1px 1px 3px #ccc; - background-color: #f8f8f8; - outline: none; - } - } - button.inset { - right:20px; - top:9.5px; - } - } -} - -#confirm, .editcartmodal{ - .promo{ - //MO not working for order_summary - width:100%; - @media (min-width: 640px) { - width: 256px; - } - } - -} - -#Checkout_promoCode,#EditCart_promoCode{ - background-color:#fff; -} - diff --git a/core/protected/extensions/umber/assets/modal/_spinner.scss b/core/protected/extensions/umber/assets/modal/_spinner.scss deleted file mode 100755 index 129eaabe..00000000 --- a/core/protected/extensions/umber/assets/modal/_spinner.scss +++ /dev/null @@ -1,104 +0,0 @@ -/* -(cs)spinner.css - http://jh3y.github.io/-cs-spinner -Licensed under the MIT license - -Jhey Tompkins (c) 2014. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -//(cs)spinner base variables -$height: 40px; -$width: 40px; -$border-width: 4px; -//TODO:MO conflicting with $overlay-color: #555 !default; and altering colors in cart checkout. -//$overlay-color: #999; -$base-color: #555; - -/* (cs)spinner base styling */ -.csspinner { - position: relative; -} -// .csspinner:before { -// content: ""; -// z-index: 1; -// position: absolute; -// top: 0; -// left: 0; -// display: block; -// height: 100%; -// width: 100%; -// } -.csspinner:after { - z-index: 2; - content: ""; - height: $height; - width: $width; - position: absolute; - top: 50%; - left: 50%; - margin: (-$width / 2) 0 0 (-$width / 2); - @include border-radius(100%); - border-top: $border-width solid $base-color; - - @include transition(all .75s ease 0s); - -webkit-animation: standard .75s infinite linear; - -moz-animation: standard .75s infinite linear; - -o-animation: standard .75s infinite linear; - animation: standard .75s infinite linear; -} -.csspinner.no-overlay:before { - content: none; - display: none; -} - -/* (cs)spinner traditional spinner. -Makes use of standard animation spin and minimally extends core.*/ -$traditional-color-one: #aaa; -$traditional-color-two: #bbb; -$traditional-color-three: #ccc; - -.csspinner:after { - border-right: $border-width solid $traditional-color-one; - border-top: $border-width solid $traditional-color-one; - border-left: $border-width solid $traditional-color-two; - border-bottom: $border-width solid $traditional-color-three; -} - -/* (cs)spinner standard rotation animation used for duo, double-up etc. */ -@-o-keyframes standard { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} -@-webkit-keyframes standard { - from { - -webkit-transform: rotate(0deg); - } - to { - -webkit-transform: rotate(360deg); - } -} -@-moz-keyframes standard { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} -@keyframes standard { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/core/protected/extensions/umber/assets/modal/_tooltip b/core/protected/extensions/umber/assets/modal/_tooltip deleted file mode 100644 index bc33d847..00000000 --- a/core/protected/extensions/umber/assets/modal/_tooltip +++ /dev/null @@ -1,34 +0,0 @@ -// TODO: add error message in tooltip when item quantity is not available. -.alert-tooltip { - position: absolute; - width: 200px; - background: rgb(255, 255, 204); - border: 1px solid rgb(102, 102, 102); - color: rgb(102, 102, 102); - font-size: 12px; - line-height: 1.3; - padding:5px 2px 0; - z-index: 10; -} -.alert-tooltip:after { - content: ""; - position: absolute; - width: 0; - height: 0; - border-width: 10px; - border-style: solid; - border-color: #FFFFCC transparent transparent transparent ; - top: 100%; - left: 50%; -} -.alert-tooltip:before { - content: ""; - position: absolute; - width: 0; - height: 0; - border-width: 12px; - border-style: solid; - border-color: rgb(102, 102, 102) transparent transparent transparent ; - top: 100%; - left: 49%; -} \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/modal/_wishlist.scss b/core/protected/extensions/umber/assets/modal/_wishlist.scss deleted file mode 100755 index b77448b0..00000000 --- a/core/protected/extensions/umber/assets/modal/_wishlist.scss +++ /dev/null @@ -1,228 +0,0 @@ -.webstore-modal-wishlist { - .search-results { - display: none; - } - - .list { - ul { - list-style: none; - padding: 0; - margin: 0; - - &:last-child { - border-bottom: none; - } - } - li { - border-bottom: 1px solid #ccc; - padding: $modal-padding*.75 $modal-padding; - background-color: #fff; - @include transition(background-color .3s,color .3s); - } - - a { - text-decoration: none; - &:hover { - li { - background-color: #f8f8f8; - } - h3 { - color: darken($calltoaction-color,10%); - } - } - } - h3 { - @include transition-property(color); - @include transition-duration(.3s); - - color: $calltoaction-color; - margin: 0; - font-weight: bold; - font-size: 1rem; - - small { - color: #999; - background-color: #eee; - padding: 2px 4px; - - margin: -3px 0 0 3px; - display: inline-block; - } - } - p { - line-height: 1.5; - font-size: .875rem; - color: #999; - margin: 0; - } - } -} - - -.wishlist-block { - p { - @include transition(color .1s, border .1s, background .1s); - position: relative; - margin: 0; - padding: 10px 2px 10px 10px; - border: 1px solid #ddd; - color: #999; - font-size: .75rem; - min-height: 80px; - line-height: 1.5; - span.title { - color: $blue; - font-weight: bold; - font-size: 1rem; - } - span.date { - display: block; - color: #aaa; - font-size: .7rem; - } - a { - font-weight: bold; - font-size: 1rem; - } - - &:hover { - color: #FFF; - cursor: pointer; - span { - color: #FFF; - } - p { - color: #FFF; - a { - color: #FFF; - } - } - border-color: $blue; - background-color: $blue; - } - - &.private, &.public, &.personal { - &:after { - font-size: .75rem; - color: #888; - border: 1px solid #ccc; - background-color: #eee; - position: absolute; - top: 10px; - padding: 3px 6px 2px; - right: -10px; - text-transform: uppercase; - - } - } - &.private { - &:after { - content: "Private"; - } - } - &.public { - &:after { - content: "Public"; - } - } - &.personal { - &:after { - content: "Personal"; - } - } - } -} - -.lines-footer { - &.purchased { - @include transition(opacity .3s); - opacity: 0; - overflow: hidden; - height: 0; - clear: both; - &.active { - opacity: 1; - height: auto; - } - .lines { - opacity: .4; - } - } -} - -.field-container { - &.optional:after { - content: 'Optional'; - background: none repeat scroll 0 0 rgba(0, 0, 0, 0); - border: 1px solid rgba(0, 0, 0, 0.1); - @include border-radius(0); - color: #bbb; - font-size: 0.7rem; - font-weight: 600; - line-height: 1; - padding: 7px 6px; - position: absolute; - right: 18px; - text-transform: uppercase; - top: 21px; - transition-duration: 0.3s; - transition-property: background-color, color, border-color; - width: auto; - } - button{ - color: #999; - } -} - - -.webstore-modal .radio-box { - border-bottom: 1px solid #ddd; - li { - label { - float:left; - width: 32.75%; - border-left: 1px solid #DDD; - border-right: 1px solid #DDD; - display: inline-block; - margin-bottom: 0; - @include transition-property(background-color,color); - @include transition-duration(.2s); - - &:first-child { - border-right: 0; - } - &:last-child { - border-left: 0; - } - &.active { - background-color: #e8e8e8; - border-color: #DDD; - } - &:first-child { - border-left: 0; - } - &:last-child { - width: 34.25%; - border-right: 0; - } - &:hover { - box-shadow: inset 0 10px 20px -20px rgba(0, 0, 0, 0.9); - background-color: #DDD; - border-color: #DDD; - } - color: #666; - font-size: 1rem; - font-weight: bold; - span { - font-weight: normal; - color: #888; - font-size: .75rem; - display: block; - } - &:hover { - color: $calltoaction-color; - cursor: pointer; - } - } - } -} diff --git a/core/protected/extensions/umber/assets/modal/_wishlist_view.scss b/core/protected/extensions/umber/assets/modal/_wishlist_view.scss deleted file mode 100644 index 3838ac1e..00000000 --- a/core/protected/extensions/umber/assets/modal/_wishlist_view.scss +++ /dev/null @@ -1,256 +0,0 @@ -.webstore-wishlist-view { - .section-content { position: relative; } - - .wishlist-description { - padding: 0 0 10px; - max-width: 400px; - } - - .wishlist-date { - position: relative; - margin: 0; - padding: 10px; - - color: #666; - font-size: .9375rem; - border: 1px solid #ccc; - - @include media(small) { - position: absolute; - right: 30px; - top: 30px; - } - } - - h1 { - small { - font-size: .75rem; - color: #888; - border: 1px solid #ccc; - background-color: #f8f8f8; - padding: 3px 6px 2px; - margin-left: 10px; - text-transform: uppercase; - } - } -} - -$share-block-height: 70px; - -.wishlist-share { - @extend %clearfix; - margin: 30px 0; - border: 1px solid #ddd; - height: $share-block-height; - - h3 { - line-height: $share-block-height - 2px; - color: #666; - padding: 0 20px; - margin: 0; - display: inline-block; - - float: left; - } - - a { - display: inline-block; - line-height: $share-block-height - 2px; - float: left; - color: #666; - - &.url { - display: none; - width: 50%; - overflow: hidden; - padding: 20px 10px 0; - line-height: 1.2; - font-size: .75rem; - word-wrap: break-word; - color: #888; - - @include media(medium) { - display: inline-block; - } - } - - &.service { - font-size: 0; - line-height: 1; - padding: 0 15px; - text-align: center; - float: right; - color: $blue; - - &:before { - font-family: FontAwesome; - font-size: 1.5rem; - line-height: $share-block-height - 2px; - } - &:hover {color: darken($blue,10%); } - - &.email:before { content: '\f003'; } - &.twitter:before { content: '\f099'; } - &.facebook:before { content: '\f09a'; } - } - } -} - -.wishlist-buttons { - @extend %clearfix; - - button { - border: 1px solid #ccc; - background: #fff; - color: #999; - width: auto; - padding: 20px; - margin-bottom: 20px; - - - &:hover { - color: $blue; - border-color: $blue; - background: #fff; - } - } - .wishlist-settings { - float: right; - display: none; - } -} - -.wishlist-lines { - thead { - th { - border-bottom: 1px solid #ccc; - color: #999; - text-transform: uppercase; - font-size: .875rem; - font-weight: normal; - } - } -} - - -.webstore-wishlist-view { - td.description { - .item-note { - color: #aaa; - display: block; - font-size: .8125rem; - font-weight: normal; - } - textarea { - display: none; - margin-top: 3px; - padding: 5px; - width: 100%; - border: 1px solid #ddd; - } - } - - td.priority { - .label { - color: #888; - text-transform: uppercase; - font-size: .8125rem; - } - select { display: none; } - } - - - - .purchased { - display: none; - } -} - -.wishlist-lines { - .controls { - white-space: nowrap; - a { float: none; } - } - - .edit, .save, .add-to-cart { - padding: 6px 8px 5px; - display: inline-block; - line-height: 1; - font-size: .75rem; - white-space: nowrap; - float: none; - - background-color: $blue; - border: 1px solid $blue; - color: #fff; - - @include transition(background-color .3s, color .3s, border-color .3s); - - &:hover { - border-color: darken($blue,10%); - background-color: darken($blue,10%); - } - } - - .save { display: none; } - .edit { - border-color: #ccc; - color: #999; - background: none; - margin-right: 6px; - - &:hover { - background: none; - border-color: $blue; - color: $blue; - } - } - - .in-cart { - .add-to-cart { - color: #999; - border-color: transparent; - background: transparent; - - } - } - - tr.active { - td.description { - padding-top: 10px; - padding-bottom: 10px; - - textarea { display: block; } - .item-note { display: none; } - } - - td.priority { - // span { display: block; } - .custom-select { display: block; } - } - td.controls { - a.save { display: inline-block; } - a.remove { - display: inline-block; - margin-left: 25px; - margin-top: -1px; - } - a.add-to-cart { display: none; } - a.save, a.remove { float: left; } - } - } -} - - -.webstore-wishlist-owner { - button.wishlist-settings { display: block; } - button.wishlist-purchases { display: none; } - .purchased { display: block; } - .wishlist-lines { - a.edit { display: inline-block; } - } - td.priority { - .label { display: none; } - select { display: block; } - } -} \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/modal/modal.scss b/core/protected/extensions/umber/assets/modal/modal.scss deleted file mode 100755 index 9bea695c..00000000 --- a/core/protected/extensions/umber/assets/modal/modal.scss +++ /dev/null @@ -1,108 +0,0 @@ -@import "../mixins/arrows"; -@import "../mixins/borders"; -@import "../mixins/flexbox"; -@import "../mixins/transitions"; -@import "../mixins/animations"; -@import "../lib/normalize"; -@import "override_legacy"; -@import "browsers_unistyle"; -@import "config"; -@import 'icons'; - -#modal-trigger { - position: absolute; - right: 30px; - top: 20px; - padding: 10px 20px; - color: #fff; - font: .875rem $webstore-modal-font; - z-index: 1; - - background-color: #999; - text-transform: uppercase; - &:hover { cursor: pointer; } -} - -#wrapper { - width: 100%; - height: 100%; - text-align: center; -} - -@import 'basic_modal'; -@import 'modal_overlay_shared'; -@import 'overlay'; -@import 'cart'; -@import 'cartadd'; -@import 'wishlist'; -@import 'promo'; -@import 'tooltip'; -@import 'estimator'; -@import 'animations'; -@import 'spinner'; -@import 'checkout'; -@import 'overview'; -@import 'lines'; -@import 'wishlist_view'; - -@import 'print'; - -main.verification { - padding: 1px $modal-padding; - - p { - font-size: 1.125rem; - line-height: 1.5; - color: #666; - } - strong { - color: $calltoaction-color; - } -} -.webstore-overlay{ - @media (max-width: 640px){ - //MO hack for input zoom bug ios. http://www.ampedupdesigns.com/blog/show?bid=53 - //Do not override without finding an alternate solution. - input[type="text"], input[type="password"], input[type="phone"], input[type="email"], - input[type="tel"], textarea, .field-container-toggle a, .field-container-select select{ - font-size: 16px !important; } - } -} - - -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 300; - src: local('Open Sans Light'), local('OpenSans-Light'), url('//themes.googleusercontent.com/static/fonts/opensans/v6/DXI1ORHCpsQm3Vp6mXoaTXhCUOGz7vYGh680lGh-uXM.woff') format('woff'); -} - -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url('//themes.googleusercontent.com/static/fonts/opensans/v8/cJZKeOuBrn4kERxqtaUH3bO3LdcAZYWl9Si6vvxL-qU.woff') format('woff'); -} - -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 600; - src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url('//themes.googleusercontent.com/static/fonts/opensans/v8/MTP_ySUJH_bn48VBG8sNSqRDOzjiPcYnFooOUGCOsRk.woff') format('woff'); -} - -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url('//themes.googleusercontent.com/static/fonts/opensans/v6/cJZKeOuBrn4kERxqtaUH3T8E0i7KZn-EPnyo3HZu7kw.woff') format('woff'); -} - - -th{ - font-family: "Open Sans", "Helvetica Neue", Helvetica, sans-serif; - font-weight: bold; -} - -//MO temporary -@import '../customized/brooklyn2014'; \ No newline at end of file diff --git a/core/protected/extensions/umber/assets/theme/_config.scss b/core/protected/extensions/umber/assets/theme/_config.scss deleted file mode 100755 index 676cd040..00000000 --- a/core/protected/extensions/umber/assets/theme/_config.scss +++ /dev/null @@ -1,76 +0,0 @@ -@charset "utf-8"; - -$break-mobile: 0px; // This is used in limited situations, generally styles layer-up, not down. -$break-narrow-modal: 360px; -$break-verysmall: 450px; -$break-small: 560px; -$break-medium: 720px; -$break-large: 1025px; -$break-verylarge: 1240px; - -@import 'compass'; -@import '../mixins/html5-input-types'; - -@mixin media($media) { - @if $media == 'mobile' { - @media (max-width: $break-small) { @content; } - } - @if $media == 'narrow-modal' { - @media (min-width: $break-narrow-modal) { @content; } - } - @else if $media == 'verysmall' { - @media (min-width: $break-verysmall) { @content; } - } - @else if $media == 'small' { - @media (min-width: $break-small) { @content; } - } - @else if $media == 'medium' { - @media (min-width: $break-medium) { @content; } - } - @else if $media == 'large' { - @media (min-width: $break-large) { @content; } - } - @else if $media == 'short' { - @media (max-height: $break-short) { @content; } - } - @else { - @content; - } -} - -* { - @include box-sizing(border-box); -} - -// Colors -$font-color: #000; - -$blue: #3287CC; - -// Link colors -$link-color: $blue; -$link-hover-color: darken($blue,10%); -$link-active-color: darken($blue,20%); -//$link-focus-color: false; -//$link-visited-color: false; - -a { - color: $link-color; - &:active { color: $link-active-color; } - a:hover { color: $link-hover-color; } -} - -$modal-padding: 20px; - -$modal-width: 720px; -$modal-width-narrow: 540px; - -$error-color: #B4282E; - -$calltoaction-color: $blue; - -$default-font-family: 'Open Sans', 'Helvetica Neue', Helvetica, sans-serif; - -$fa-font-path: "/fonts" !default; -$fa-css-prefix: fa !default; -$fa-version: "4.1.0" !default; diff --git a/core/protected/extensions/umber/assets/theme/_footer.scss b/core/protected/extensions/umber/assets/theme/_footer.scss deleted file mode 100755 index 9cf6ab24..00000000 --- a/core/protected/extensions/umber/assets/theme/_footer.scss +++ /dev/null @@ -1,153 +0,0 @@ -.footer { - background-color: #eee; - color: #777; - font-size: .875rem; - - h3 { - text-transform: uppercase; - color: #888; - font-size: .875rem; - margin: 0; - font-weight: 600; - margin-bottom: .5rem; - } - p, ol, ul { - margin: 0; - } -} -.footer-section { - @include clearfix(); -} - -.footer-primary { - padding: 30px 0; - - article { - width: 20.6%; - margin: 1% 0 1% 2.6%; - float: left; - word-wrap: break-word; - - p { margin-bottom: 1.25rem;} - &:first-child { - margin-left: 0; - } - &.about { - width: 34%; - } - &.nav { - width: 17%; - } - &.vcard { - table.hours { - th { - text-align: right; - padding-right: .5rem; - } - } - } - &.contact { - .phone { - font-size: 1.9rem; - margin-bottom: 0; - } - .email { - margin-bottom: 0; - } - } - } - &:last-child { - margin-right: 0; - } -} -.footer-secondary { - border-top: 1px solid #ccc; - margin-top: 30px; - padding: 15px 0; - color: #999; - font-size: .75rem; - - p, .paymentmethods { float: left; } - - .paymentmethods { - padding: 0; - float: right; - - li { display: inline-block; } - } -} - -.footer { - .page-collection { - font-size: .75rem; - - ul { - list-style: none; - padding: 0; - } - } - - .newsletter { - form { - position: relative; - max-width: 300px; - } - - input { - box-sizing: border-box; - width: 100%; - border: 1px solid #999; - background: #fff; - padding: 10px 95px 10px 10px; - } - button { - font-size: .75rem; - text-transform: uppercase; - height: 40px; - background-color: #555; - padding: 0 10px; - border: none; - color: #fff; - position: absolute; - top: 1px; - right: 0; - - &:hover { background: #666; } - } - } - - .social { - margin-top: .5rem; - - a { - font-size: 0; - - &:after { - font-size: 1.8rem; - margin-right: 2px; - } - - &.facebook:after { content: '\f082'; } - &.twitter:after { content: '\f081'; } - &.googleplus:after { content: '\f0d4'; } - &.instagram:after { content: '\f16d'; } - &.pinterest:after { content: '\f0d3'; } - &.linkedin:after { content: '\f08c'; } - } - } - - .paymentmethods { - margin-top: -10px; - position: relative; - li { - display: inline-block; - background-color: #333; - width: 45px; - height: 25px; - /* Hide the text. */ - text-indent: 100%; - white-space: nowrap; - overflow: hidden; - } - } -} diff --git a/core/protected/extensions/umber/assets/theme/_header.scss b/core/protected/extensions/umber/assets/theme/_header.scss deleted file mode 100755 index c59895ce..00000000 --- a/core/protected/extensions/umber/assets/theme/_header.scss +++ /dev/null @@ -1,89 +0,0 @@ -header { - @include background-image(linear-gradient(#ffffff, rgba(#ffffff,0))); - width: 100%; - position: fixed; - top: 0; - // left: 0; - // right: 0; - -} - -.header { - background-color: transparent; - -webkit-transition: background-color 400ms linear; - -moz-transition: background-color 400ms linear; - -o-transition: background-color 400ms linear; - -ms-transition: background-color 400ms linear; - transition: background-color 400ms linear; - &.scrolled { - background-color: #FFF; - } - padding: 2rem 0; - @include clearfix(); - .brand, .webstore-features { - display: inline-block; - } - - .brand { - width: 240px; - float: left; - - p { display: none; } - } - .webstore-features { - float: right; - } - - .brand { - img { - max-height: 50px; - } - img + h1 { - display: none; - } - - } - .webstore-features { - .pages, form { - float: right; - } - - .pages { - list-style: none; - padding: 0; - margin: 0; - - li { - display: inline-block; - line-height: 50px; - font-size: .8375rem; - } - a { - display: inline-block; - line-height: 50px; - padding: 0 10px; - } - - } - .language-choices { - display: none; - } - } - - .page-collection { - width: 100%; - @include clearfix(); - - ul { - padding: 0; - display: inline; - } - li { - display: inline; - } - a { - display: inline-block; - padding: 10px; - } - } -} diff --git a/core/protected/extensions/umber/assets/theme/_products.scss b/core/protected/extensions/umber/assets/theme/_products.scss deleted file mode 100755 index 1f92d536..00000000 --- a/core/protected/extensions/umber/assets/theme/_products.scss +++ /dev/null @@ -1,121 +0,0 @@ -.product-browser { - border-top: 1px solid #ccc; - border-bottom: 1px solid #ccc; - - .inner { - display: box; - display: flexbox; - display: -webkit-flex; - display: flex; - - -webkit-flex-flow: row; - flex-flow: row; - - // align-content: flex-start; - // @TODO - background should scale to match full-page width - // @TODO - background should maintain a minimum height - - padding: 0; - - @include media(small) { - article { - -webkit-flex: 3 1 80%; - flex: 3 1 80%; - -webkit-order: 2; - order: 2; - border-right: 1px solid #ccc; - } - - aside { - -webkit-flex: 1 6 20%; - flex: 1 6 20%; - -webkit-order: 1; - order: 1; - - padding-right: 15px; - } - } - } -} - -.product-categories { - ul { - list-style: none; - padding: 0; - } -} -.product-narrowing { - h3 { - margin: 15px 0; - background-color: #eee; - padding: 8px 12px; - text-transform: uppercase; - color: #666; - font-size: .75rem; - } - ul { - margin: 0 15px 30px; - } - li { - margin: 0 0 5px; - } -} - -.product-cards { - // @include clearfix; - list-style: none; - margin: 0 0 -1px; - padding: 0; - - display: box; - display: flexbox; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; -} - -.product-card { - border-bottom: 1px solid #ccc; - border-left: 1px solid #ccc; - padding: 15px; - - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; - -webkit-flex-basis: 0; - -ms-flex-preferred-size: 0; - flex-basis: 0; - - background-color: #fff; - - min-width: 200px; - - - -webkit-transition: width 0.7s ease-out; - transition: width 0.7s ease-out; - - - img { - width: 100%; - } - - h2, p { - margin: 0; - } - h2 { - font-size: .75rem; - } - p { - font-size: .875rem; - } -} diff --git a/core/protected/extensions/umber/assets/theme/_search.scss b/core/protected/extensions/umber/assets/theme/_search.scss deleted file mode 100755 index 48be86a4..00000000 --- a/core/protected/extensions/umber/assets/theme/_search.scss +++ /dev/null @@ -1,13 +0,0 @@ -form.search { - line-height: 50px; - input { - display: inline-block; - font-size: .8375rem; - padding: 6px 8px; - - } - - button { - display: none; - } -} diff --git a/core/protected/extensions/umber/assets/theme/basic.scss b/core/protected/extensions/umber/assets/theme/basic.scss deleted file mode 100755 index 183726d9..00000000 --- a/core/protected/extensions/umber/assets/theme/basic.scss +++ /dev/null @@ -1,59 +0,0 @@ -@import "normalize"; -@import "config"; - -@font-face { - font-family: 'FontAwesome'; - src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); - src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), - url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), - url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), - url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); - //src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts - font-weight: normal; - font-style: normal; -} - -body { - font-family: $default-font-family; -} - -.features { - height: 640px; - background-image: url(/images/backgrounds/trail.jpg); - background-repeat: no-repeat; - background-size: cover; - -} - - -a { - text-decoration: none; - color: $link-color; -} - -.header, .footer, .wrapper { - // flex: 1 100%; - .inner { - max-width: 1024px; - padding: 0 30px; - margin: 0 auto; - - } -} - - -.icon:after { - font-family: 'FontAwesome'; - content: ''; - font-style: normal; - font-weight: normal; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - - -@import 'header'; -@import 'footer'; -@import 'search'; -@import 'products'; diff --git a/core/protected/extensions/umber/assets/wsmodal.js b/core/protected/extensions/umber/assets/wsmodal.js index b6e85537..3496d4fa 100644 --- a/core/protected/extensions/umber/assets/wsmodal.js +++ b/core/protected/extensions/umber/assets/wsmodal.js @@ -1,6 +1,7 @@ 'use strict'; /* globals $:false, History:false */ /* exported showEditCartModal */ + function sleep(millis, callback) { setTimeout(function() { callback(); }, @@ -62,7 +63,7 @@ function hideModal() { * @param {string} [editCartUrl] The URL to add to the browser history. If no * URL is provided, then no URL is added to the history. */ -function showEditCartModalAndPushState(editCartUrl) { +function showEditCartModal(editCartUrl) { // Remove the body's scrollbar when opening a modal $('body').css('overflow', 'hidden'); @@ -76,30 +77,6 @@ function showEditCartModalAndPushState(editCartUrl) { $('#viewport, .btn-navbar, #menubar, #topbar, #footer').addClass('mobile-hide'); } -/** - * Show the edit cart modal. - * @param {boolean} maintainPushState Set this to true to leave the browser - * history state unmodified. Defaults to false. - * @deprecated This is left in for compatibility with Brooklyn2014 3.2.2 - * themes. Use showEditCartModalAndPushState instead. This was deprecated in - * Web Store 3.2.4 because it uses a hard-coded URL instead of going through - * Yii::app()->createUrl. - */ -function showEditCartModal(maintainPushState) { - // This warning is on purpose: we want to store owners to update their - // theme copies. - /* globals console:false */ - console.warn('showEditCartModal is deprecated. Use showEditCartModalAndPushState instead.'); - var editCartUrl = '/editcart'; - - if (maintainPushState === true) { - showEditCartModalAndPushState(); - } else { - showEditCartModalAndPushState(editCartUrl); - } -} - - function showModal() { // Remove the body's scrollbar when opening a modal $('body').css('overflow', 'hidden'); @@ -164,7 +141,7 @@ $(document).on('click', ".webstore-change-item", function() { hideModal(); var editCartUrl = $(this).data('editcarturl'); setTimeout(function(){ - showEditCartModalAndPushState(editCartUrl); + showEditCartModal(editCartUrl); }, 1125); }); @@ -184,7 +161,7 @@ $(function() { // doPushSate=true, and the second time in this callback when the // push state changes. if(State.data.key === 'editcart'){ - showEditCartModalAndPushState(); + showEditCartModal(); } else { hideModal(); diff --git a/core/protected/extensions/wscron/wscron.php b/core/protected/extensions/wscron/wscron.php index a1c7dc90..85497649 100644 --- a/core/protected/extensions/wscron/wscron.php +++ b/core/protected/extensions/wscron/wscron.php @@ -1,42 +1,47 @@ sendQueueEmails(); + // Attemp to send pending emails + $this->_sendQueueEmails(); } /** * Try sending e-mails in the queue. * + * @return void * @throws CDbException */ - public function sendQueueEmails() + private function _sendQueueEmails() { $objMails = EmailQueue::model()->findAll("`sent_attempts` < 20 and `sent_attempts` > 0 and `to` IS NOT NULL LIMIT 10"); foreach ($objMails as $objMail) { - $blnResult = _xls_send_email($objMail->id,true); + $blnResult = _xls_send_email($objMail->id, true); if (!$blnResult) { - EmailQueue::model()->updateByPk($objMail->id,array('sent_attempts'=>($objMail->sent_attempts)+1)); + EmailQueue::model()->updateByPk($objMail->id, array('sent_attempts' => ($objMail->sent_attempts) + 1)); } else { @@ -44,4 +49,4 @@ public function sendQueueEmails() } } } -} \ No newline at end of file +} diff --git a/core/protected/extensions/wslangflags/assets/flags/cze.gif b/core/protected/extensions/wslangflags/assets/flags/cs.gif similarity index 100% rename from core/protected/extensions/wslangflags/assets/flags/cze.gif rename to core/protected/extensions/wslangflags/assets/flags/cs.gif diff --git a/core/protected/extensions/wslangflags/assets/flags/jp.gif b/core/protected/extensions/wslangflags/assets/flags/ja.gif similarity index 100% rename from core/protected/extensions/wslangflags/assets/flags/jp.gif rename to core/protected/extensions/wslangflags/assets/flags/ja.gif diff --git a/core/protected/extensions/wslangflags/assets/flags/swe.gif b/core/protected/extensions/wslangflags/assets/flags/sv.gif similarity index 100% rename from core/protected/extensions/wslangflags/assets/flags/swe.gif rename to core/protected/extensions/wslangflags/assets/flags/sv.gif diff --git a/core/protected/extensions/wspayment/WsPayment.php b/core/protected/extensions/wspayment/WsPayment.php index d3a23830..e5984a56 100644 --- a/core/protected/extensions/wspayment/WsPayment.php +++ b/core/protected/extensions/wspayment/WsPayment.php @@ -64,7 +64,7 @@ public function init() * The name of the payment module that will be displayed in Web Admin payments * @return string */ - public function admin_name() + public function adminName() { if ($this->active) @@ -142,4 +142,4 @@ public function getLogLevel() } -} \ No newline at end of file +} diff --git a/core/protected/extensions/wsshipping/WsShipping.php b/core/protected/extensions/wsshipping/WsShipping.php index 453a5a15..9c40c4eb 100644 --- a/core/protected/extensions/wsshipping/WsShipping.php +++ b/core/protected/extensions/wsshipping/WsShipping.php @@ -54,7 +54,7 @@ public function init() * The name of the payment module that will be displayed in Web Admin payments * @return string */ - public function admin_name() + public function adminName() { if ($this->active) @@ -251,4 +251,4 @@ public function getLogLevel() return CLogger::LEVEL_INFO; } -} \ No newline at end of file +} diff --git a/core/protected/extensions/wsshipping/usps/usps.php b/core/protected/extensions/wsshipping/usps/usps.php index ee4d78a3..ac800696 100644 --- a/core/protected/extensions/wsshipping/usps/usps.php +++ b/core/protected/extensions/wsshipping/usps/usps.php @@ -28,10 +28,10 @@ class usps extends WsShipping //'First-Class Mail Postcards', 'Priority Mail{0}', //'Priority Mail Express{0} Hold For Pickup', - 'Priority Mail Express{0}', + 'Priority Mail Express{0}', 'Standard Post', 'Media Mail', - 'Library Mail'=>'Library Mail', + 'Library Mail' => 'Library Mail', 'Priority Mail Express{0} Flat Rate Envelope', 'First-Class Mail Large Postcards', 'Priority Mail{0} Flat Rate Envelope', @@ -50,13 +50,13 @@ class usps extends WsShipping //'Priority Mail{0} Medium Flat Rate Box Hold For Pickup', //'Priority Mail{0} Small Flat Rate Box Hold For Pickup', //'Priority Mail{0} Flat Rate Envelope Hold For Pickup', - 'Priority Mail{0} Gift Card Flat Rate Envelope', + 'Priority Mail{0} Gift Card Flat Rate Envelope', //'Priority Mail{0} Gift Card Flat Rate Envelope Hold For Pickup', 'Priority Mail{0} Window Flat Rate Envelope', //'Priority Mail{0} Window Flat Rate Envelope Hold For Pickup', - 'Priority Mail{0} Small Flat Rate Envelope', + 'Priority Mail{0} Small Flat Rate Envelope', //'Priority Mail{0} Small Flat Rate Envelope Hold For Pickup', - 'Priority Mail{0} Legal Flat Rate Envelope', + 'Priority Mail{0} Legal Flat Rate Envelope', //'Priority Mail{0} Legal Flat Rate Envelope Hold For Pickup', //'Priority Mail{0} Padded Flat Rate Envelope Hold For Pickup', 'Priority Mail{0} Regional Rate Box A', @@ -110,121 +110,59 @@ class usps extends WsShipping public function run() { - if(!isset($this->config['offerservices'])) return false; - - $weight = $this->objCart->Weight; - if(_xls_get_conf('WEIGHT_UNIT' , 'lb') != 'lb') - $weight = $weight * 2.2; // one KG is 2.2 pounds - - //USPS wants a full country name - $countryObj = Country::LoadByCode($this->CheckoutForm->shippingCountry); - if($countryObj) - $country = $countryObj->country; - else - $country = "US"; - - if (empty($country)) $country = "US"; - - if(empty($this->config['username']) || empty($this->config['originpostcode'])) - return false; - - $this->init_vars( - $this->config['username'], - $this->config['originpostcode'], - $this->CheckoutForm->shippingPostal, - $country, - $this->config['markup']); - $this->addItem(intval($weight) , round(($weight - intval($weight)) *16 , 0) , $this->objCart->total); - - $rates = $this->getRate(); - - if(($rates === FALSE) || (count($rates) == 0 )) { - Yii::log("USPS: Could not get rates. " . print_r($this , true), 'error', 'application.'.__CLASS__.".".__FUNCTION__); + if (!isset($this->config['offerservices'])) + { return false; } - return $this->convertRetToDisplay($rates); - } - - - - - /** - * total - * - * Based on passed address information, calculates the total shipping cost - * - * @param $fields &array - * @param Cart $cart - * @param $country optional - * @param $zipcode optional - * @param $state optional - * @param $city optional - * @param $address2 optional - * @param $address1 optional - * @param $company optional - * @param $lname optional - * @param $fname optional - * - * @return array - */ - public function total($fields, $cart, $country = '', $zipcode = '', $state = '', - $city = '', $address2 = '', $address1 = '', $company = '', $lname = '', $fname = '') { - -// $config = $this->config; -// -// $weight = $cart->Weight; + $weight = $this->objCart->Weight; - if(_xls_get_conf('WEIGHT_UNIT' , 'lb') != 'lb') - $weight = $this->objCart->Weight * 2.2; // one KG is 2.2 pounds + if(_xls_get_conf('WEIGHT_UNIT', 'lb') != 'lb') + { + // one KG is 2.2 pounds + $weight = $weight * 2.2; + } //USPS wants a full country name - $countryObj = Country::LoadByCode($this->CheckoutForm->shippingCountry); - if($countryObj) - $country = $countryObj->country; + $objCountry = Country::Load($this->CheckoutForm->shippingCountry); + if($objCountry instanceof Country) + { + $country = $objCountry->country; + } else + { $country = "US"; + } - if (empty($country)) $country = "US"; - - if(empty($this->config['username']) || empty($this->config['originpostcode'])) + if (empty($this->config['username']) || empty($this->config['originpostcode'])) + { return false; + } $this->init_vars( $this->config['username'], $this->config['originpostcode'], $this->CheckoutForm->shippingPostal, $country, - $this->config['markup']); - $this->addItem(intval($weight) , round(($weight - intval($weight)) *16 , 0) , $this->objCart->total); + $this->config['markup'] + ); + $this->addItem(intval($weight), round(($weight - intval($weight)) * 16, 0), $this->objCart->total); $rates = $this->getRate(); - if(($rates === FALSE) || (count($rates) == 0 )) { - Yii::log("USPS: Could not get rates. " . print_r($this , true), 'error', 'application.'.__CLASS__.".".__FUNCTION__); + if (($rates === FALSE) || (count($rates) == 0 )) + { + Yii::log("USPS: Could not get rates. " . print_r($this, true), 'error', 'application.'.__CLASS__.".".__FUNCTION__); return false; } return $this->convertRetToDisplay($rates); - -// asort($rates); -// $arrServices = array(); -// foreach($rates as $desc=>$returnval) { -// $arrReturn['price']=floatval($returnval); -// $arrReturn['level']=$desc; -// $arrReturn['label'] = $desc; -// -// $arrServices[] = $arrReturn; -// -// } -// -// -// return $arrServices; } + /** * init_vars - * called by total(), sets initial values for calculation + * called by run(), sets initial values for calculation * * @param $usps_account string * @param $usps_zip_origin string @@ -233,7 +171,8 @@ public function total($fields, $cart, $country = '', $zipcode = '', $state = '', * @param $usps_markup string * @return none, populates local scope $this->config */ - function init_vars($usps_account, $usps_zip_origin, $destination, $country, $usps_markup) { + function init_vars($usps_account, $usps_zip_origin, $destination, $country, $usps_markup) + { $config = $this->config; $this->uspsID = $usps_account; @@ -248,36 +187,6 @@ function init_vars($usps_account, $usps_zip_origin, $destination, $country, $usp $this->methods = $this->config['offerservices']; } - /** - * init_admin_vars - * called by total(), sets initial values for calculation - * - * @param $usps_account string - * @param $usps_zip_origin string - * @param $destination string - * @param $country string - * @param $usps_markup string - * @return none, populates local scope $this->config - */ - function init_admin_vars($usps_account, $usps_zip_origin, $destination, $country) { - $this->uspsID = $usps_account; - $this->zipOrigination = $usps_zip_origin; - $this->zipDestination = $destination; - $this->country = $country; - - if ($country == "US") { - $this->pounds = 0; - $this->ounces = 10; - $this->value = 5; - } else { - $this->pounds = 1; - $this->ounces = 0; - $this->value = 20; - } - - $this->markup = 0; - } - /** * addItem * @@ -289,8 +198,8 @@ function init_admin_vars($usps_account, $usps_zip_origin, $destination, $country * @return array */ public function addItem($p, $o, $v) { - $p = (''==$p) ? 0 : $p; - $o = (''==$o) ? 0 : $o; + $p = ('' == $p) ? 0 : $p; + $o = ('' == $o) ? 0 : $o; $this->pounds += $p; $this->ounces += $o; $this->value += $v; @@ -329,28 +238,41 @@ public function cleanMethodName($strName) { * param bool - true will return all values (used by Admin panel) * @return array */ - public function getRate($showall=false) { + public function getRate($showall = false) + { if (($this->ounces + $this->pounds) == 0) - $this->pounds=1; + { + $this->pounds = 1; + } + $config = $this->getConfigValues(get_class($this)); - $request = ($this->isDomestic()) ? $this->buildDomesticRateRequest() : $this->buildInternationalRateRequest() ; + $request = ($this->isDomestic()) ? $this->buildDomesticRateRequest() : $this->buildInternationalRateRequest(); $this->response = $this->sendUSPSRateRequest($request); - if(_xls_get_conf('DEBUG_SHIPPING' , false)) { - _xls_log(get_class($this) . " sending ".print_r($request,true),true); - _xls_log(get_class($this) . " receiving ".$this->response,true); - } + Yii::log( + sprintf("%s sending %s ", __CLASS__, print_r($request, true)), + $this->loglevel, + 'application.'.__CLASS__.'.'.__FUNCTION__ + ); + + Yii::log( + sprintf("%s receiving %s ", __CLASS__, print_r($this->response, true)), + $this->loglevel, + 'application.'.__CLASS__.'.'.__FUNCTION__ + ); // Parse xml for response values $oXML = new SimpleXMLElement($this->response); - if(!$oXML->Package) { + if(!$oXML->Package) + { //What we have is ... failure to communicate Yii::log('Could not get shipping for USPS: '.$oXML->Description, 'error', 'application.'.__CLASS__.".".__FUNCTION__); return false; } - if($oXML->Package->Error) { + if($oXML->Package->Error) + { //What we have is ... failure to communicate Yii::log('Could not get shipping for USPS: '.$oXML->Package->Error->Description, 'error', 'application.'.__CLASS__.".".__FUNCTION__); return false; @@ -358,15 +280,18 @@ public function getRate($showall=false) { $retval = array(); - if($this->isDomestic()) { - foreach($oXML->Package->Postage as $key=>$val) { + if($this->isDomestic()) + { + foreach($oXML->Package->Postage as $key => $val) + { $strKey = $val->MailService; $strRate = $val->Rate; $strKey = $this->cleanMethodName($strKey); $retval[$strKey] = floatval($strRate); } } else { - foreach($oXML->Package->Service as $key=>$val) { + foreach($oXML->Package->Service as $key => $val) + { $strKey = $val->SvcDescription; $strRate = $val->Postage; $strKey = $this->cleanMethodName($strKey); @@ -375,22 +300,30 @@ public function getRate($showall=false) { } return $retval; - - } /** - * isDomestic + * Is shipping address within or outside the US * - * Is shipping address in our outside the US * @return bool */ - private function isDomestic() { + private function isDomestic() + { $c = strtoupper($this->country); - if($c == '' or $c == 'US' or $c == 'USA' or $c == 'AMERICA' or $c == 'US OF A'or $c == 'UNITED STATES') - return true; - return false; + switch ($c) + { + case '': + case 'US': + case 'USA': + case 'AMERICA': + case 'US OF A': + case 'UNITED STATES': + return true; + + default: + return false; + } } /** @@ -399,21 +332,21 @@ private function isDomestic() { * Build XML request for US shipping * @return string */ - private function buildDomesticRateRequest() { - $r ='API=RateV4&XML='; - $r.= ''; - $r.=''; - $r.='ALL'; - $r.=''.substr($this->zipOrigination,0,5).''; - $r.=''.substr($this->zipDestination,0,5).''; - $r.=''.$this->pounds.''; - $r.=''.$this->ounces.''; - $r.=''; - $r.='Regular'; - $r.='true'; - $r.=''; - $r.=''; - + private function buildDomesticRateRequest() + { + $r = 'API=RateV4&XML='; + $r .= ''; + $r .= ''; + $r .= 'ALL'; + $r .= ''.substr($this->zipOrigination, 0, 5).''; + $r .= ''.substr($this->zipDestination, 0, 5).''; + $r .= ''.$this->pounds.''; + $r .= ''.$this->ounces.''; + $r .= ''; + $r .= 'Regular'; + $r .= 'true'; + $r .= ''; + $r .= ''; return $r; } @@ -424,23 +357,24 @@ private function buildDomesticRateRequest() { * Build XML request for US shipping * @return string */ - private function buildInternationalRateRequest() { - $r ='API=IntlRateV2&XML='; - $r.= ''; - $r.=''; - $r.=''.$this->pounds.''; - $r.=''.$this->ounces.''; - $r.='Package'; - $r.=''.$this->value.''; - $r.=''.$this->country.''; - $r.='RECTANGULAR'; - $r.='Regular'; - $r.=''; - $r.=''; - $r.=''; - $r.=''; - $r.=''; - $r.=''; + private function buildInternationalRateRequest() + { + $r = 'API=IntlRateV2&XML='; + $r .= ''; + $r .= ''; + $r .= ''.$this->pounds.''; + $r .= ''.$this->ounces.''; + $r .= 'Package'; + $r .= ''.$this->value.''; + $r .= ''.$this->country.''; + $r .= 'RECTANGULAR'; + $r .= 'Regular'; + $r .= ''; + $r .= ''; + $r .= ''; + $r .= ''; + $r .= ''; + $r .= ''; return $r; } @@ -451,7 +385,8 @@ private function buildInternationalRateRequest() { * cURL string to actually send request * @return string */ - private function sendUSPSRateRequest($req) { + private function sendUSPSRateRequest($req) + { $url = 'http://Production.ShippingAPIs.com/ShippingAPI.dll'; $c = curl_init($url); curl_setopt($c, CURLOPT_POST, true); @@ -463,44 +398,53 @@ private function sendUSPSRateRequest($req) { } - public static function getServiceTypes($class_name,$process_days=true) + public static function getServiceTypes($class_name, $process_days = true) { - if($process_days) + if ($process_days) { $arr = array(); - foreach(self::$service_types as $value) + foreach (self::$service_types as $value) { - if(stripos($value,"{0}") !== false) + if (stripos($value, "{0}") !== false) { - for($x=1; $x<=5; $x++) - $arr[] = Yii::t('usps',$value,array('{0}'=>$x."-Day")); - } else $arr[] = $value; + for ($x = 1; $x <= 5; $x++) + { + $arr[] = Yii::t('usps', $value, array('{0}' => $x."-Day")); + } + } else { + $arr[] = $value; + } } - return array_combine($arr,$arr); + return array_combine($arr, $arr); } else - return array_combine(self::$service_types,self::$service_types); + { + return array_combine(self::$service_types, self::$service_types); + } } public static function expandRestrictions($arrRestrictions) { - $arr = array(); - foreach($arrRestrictions as $key=>$value) + foreach ($arrRestrictions as $key => $value) { - if(stripos($value,"{0}") !== false) + if (stripos($value, "{0}") !== false) { - for($x=1; $x<=5; $x++) - $arr[] = Yii::t('usps',$value,array('{0}'=>" ".$x."-Day")); - } else $arr[] = $value; + for($x = 1; $x <= 5; $x++) + { + $arr[] = Yii::t('usps', $value, array('{0}' => " " . $x . "-Day")); + } + } else { + $arr[] = $value; + } } return $arr; } -} +} \ No newline at end of file diff --git a/core/protected/extensions/wstheme/WsTheme.php b/core/protected/extensions/wstheme/WsTheme.php index e639c774..1bf82d1e 100644 --- a/core/protected/extensions/wstheme/WsTheme.php +++ b/core/protected/extensions/wstheme/WsTheme.php @@ -1,16 +1,15 @@ theme->name; } @@ -133,4 +132,4 @@ public static function getThemeNameOrParentName() return Yii::app()->theme->name; } -} \ No newline at end of file +} diff --git a/core/protected/helpers/ImagesType.php b/core/protected/helpers/ImagesType.php index 13675d9d..728b9e07 100644 --- a/core/protected/helpers/ImagesType.php +++ b/core/protected/helpers/ImagesType.php @@ -82,8 +82,7 @@ public static function ToString($intImageTypeId) { public static function GetSize($intImageTypeId) { - list($intDefWidth, $intDefHeight) = - ImagesType::$SizeArray[$intImageTypeId]; + list($intDefWidth, $intDefHeight) = ImagesType::$SizeArray[$intImageTypeId]; $strCfg = ImagesType::GetConfigKey($intImageTypeId); @@ -96,7 +95,6 @@ public static function GetSize($intImageTypeId) { //If our theme doesn't have the config there, see if we have a 3.0 style config.xml if(empty($intWidth) || empty($intHeight)) { - $fnOptions = YiiBase::getPathOfAlias('webroot')."/themes/".Yii::app()->theme->name."/config.xml"; if (file_exists($fnOptions)) @@ -105,20 +103,22 @@ public static function GetSize($intImageTypeId) { // Parse xml for response values $oXML = new SimpleXMLElement($strXml); - Yii::log("Found config.xml values ".print_r($oXML,true), 'info', 'application.'.__CLASS__.".".__FUNCTION__); if(isset($oXML->defaults->configuration)) { foreach ($oXML->defaults->configuration as $item) { - if((string)$item->key_name==$strCfgWidth) + if((string)$item->key_name == $strCfgWidth) + { $intWidth = (string)$item->key_value; + } - if((string)$item->key_name==$strCfgHeight) + if((string)$item->key_name == $strCfgHeight) + { $intHeight = (string)$item->key_value; + } } } } - } //if all else STILL fails, go old school and get them from the config (And even more so, use defaults) diff --git a/core/protected/migrations/m150304_201446_WS_3110_remove_schema_config_key.php b/core/protected/migrations/m150304_201446_WS_3110_remove_schema_config_key.php new file mode 100644 index 00000000..7c454245 --- /dev/null +++ b/core/protected/migrations/m150304_201446_WS_3110_remove_schema_config_key.php @@ -0,0 +1,35 @@ +delete( + 'xlsws_configuration', + 'key_name = :key', + array('key' => 'DATABASE_SCHEMA_VERSION') + ); + } + + public function down() + { + $now = date('Y-m-d H:i:s'); + + $this->insert( + 'xlsws_configuration', + array( + 'title' => 'Database Schema Version', + 'key_name' => 'DATABASE_SCHEMA_VERSION', + 'key_value' => '447', + 'helper_text' => 'Used for tracking schema changes (pre 3.1.6)', + 'sort_order' => 0, + 'modified' => $now, + 'created' => $now, + 'param' => 301, + 'required' => 0 + ) + ); + + echo "DATABASE_SCHEMA_VERSION config key replaced"; + } +} \ No newline at end of file diff --git a/core/protected/migrations/m150312_160451_WS_3851_delete_abandoned_carts.php b/core/protected/migrations/m150312_160451_WS_3851_delete_abandoned_carts.php new file mode 100644 index 00000000..32c1e517 --- /dev/null +++ b/core/protected/migrations/m150312_160451_WS_3851_delete_abandoned_carts.php @@ -0,0 +1,43 @@ +execute( + 'delete c from + xlsws_cart c left join xlsws_cart_item ci + on c.id = ci.cart_id + where + ci.id is null and + c.id_str is null and + c.customer_id is null and + c.shipaddress_id is null and + c.billaddress_id is null and + c.shipping_id is null and + c.payment_id is null and + c.document_id is null and + c.po is null and + c.cart_type = 1 and + c.status is null and + c.currency is null and + c.printed_notes is null and + c.subtotal is null and + c.total is null and + c.item_count = 0 and + c.downloaded = 0 and + c.lightspeed_user is null and + c.origin is null and + c.gift_registry is null and + c.send_to is null and + c.submitted is null and + c.datetime_cre < now() - interval 1 day' + ); + } + + public function down() + { + echo "m150312_160451_WS_3851_delete_abandoned_carts does not support migration down.\n"; + return false; + } +} diff --git a/core/protected/migrations/m150312_160529_WS_3851_add_index_xlsws_carts_id_str.php b/core/protected/migrations/m150312_160529_WS_3851_add_index_xlsws_carts_id_str.php new file mode 100644 index 00000000..158a1559 --- /dev/null +++ b/core/protected/migrations/m150312_160529_WS_3851_add_index_xlsws_carts_id_str.php @@ -0,0 +1,14 @@ +createIndex('id_str', 'xlsws_cart', 'id_str', FALSE); + } + + public function down() + { + $this->dropIndex('id_str', 'xlsws_cart'); + } +} \ No newline at end of file diff --git a/core/protected/migrations/m150317_151011_log_cleanup.php b/core/protected/migrations/m150317_151011_log_cleanup.php new file mode 100644 index 00000000..65cfdb97 --- /dev/null +++ b/core/protected/migrations/m150317_151011_log_cleanup.php @@ -0,0 +1,21 @@ +execute("DELETE FROM `xlsws_log` WHERE `created` IS NULL"); + } + + public function down() + { + // While you can't technically roll this transaction back, since it + // doesn't change the schema, it makes sense to allow the system to roll + // back through this change to attempt to rollback the next one as well. + return true; + } +} diff --git a/core/protected/models/Cart.php b/core/protected/models/Cart.php index c488a266..69b94c56 100644 --- a/core/protected/models/Cart.php +++ b/core/protected/models/Cart.php @@ -77,17 +77,34 @@ public function searchAdmin() } - /** Create a new cart object and prepopulate some values + /** + * Create and return a cart object with some prepopulated values. + * We pass in and set the customerId to facilitate setting the tax code + * + * @param Customer $objCustomer * @return Cart */ - public static function InitializeCart() { + public static function initialize(Customer $objCustomer = null) + { $objCart = new Cart(); $objCart->cart_type = CartType::cart; + if ($objCustomer instanceof Customer) + { + $objCart->customer_id = $objCustomer->id; + } + $objCart->datetime_cre = new CDbExpression('NOW()');; $objCart->datetime_due = new CDbExpression('now() + INTERVAL '._xls_get_conf('CART_LIFE', 7).' DAY'); $objCart->ResetTaxIncFlag(); $objCart->setTaxCodeByDefaultShippingAddress(); + + return $objCart; + } + + public static function initializeAndSave() + { + $objCart = self::initialize(); if(!$objCart->save()) { Yii::log("Error initializing cart ".print_r($objCart->getErrors(), true), 'error', 'application.'.__CLASS__.".".__FUNCTION__); @@ -122,15 +139,17 @@ public function getDataProvider() * Initialize if needed and return the current Cart * This is used by unit tests to get a cart to work with for testing * Normal use will use the Cart component - * @return + * @return Cart */ - public static function GetCart() { - if(is_null(Yii::app()->user->getState('cartid'))) + public static function GetCart() + { + if (is_null(Yii::app()->user->getState('cartid'))) { - $objCart = Cart::InitializeCart(); - Yii::app()->user->setState('cartid', $objCart->id); + $objCart = Cart::initialize(); return $objCart; - } else { + } + else + { $objCart = Cart::model()->findByPk(Yii::app()->user->getState('cartid')); if ($objCart === null) @@ -138,8 +157,7 @@ public static function GetCart() { //something has happened to the database object Yii::log("Could not find cart ".Yii::app()->user->getState('cartid').", creating new one.", 'error', 'application.'.__CLASS__.".".__FUNCTION__); Yii::app()->user->setState('cartid', null); - $objCart = Cart::InitializeCart(); - Yii::app()->user->setState('cartid', $objCart->id); + $objCart = Cart::initialize(); } return $objCart; @@ -198,7 +216,7 @@ public static function CloneCart($objCart = null){ public function setTaxCodeByDefaultShippingAddress() { - if(is_null($this->customer_id)) + if (is_null($this->customer_id)) { return; } @@ -660,11 +678,13 @@ protected function updateTaxInclusive() { { foreach ($this->cartItems as $objItem) { + $objTaxCode = TaxCode::GetDefault(); + // For quote to cart, we have to remove prices manually if ($objItem->cart_type == CartType::quote && $objItem->tax_in) { $taxes = $objItem->product->CalculateTax( - TaxCode::GetDefault(), + $objTaxCode->id, $objItem->sell ); @@ -717,7 +737,7 @@ protected function updateTaxInclusive() { /** * Update tax values on the cart and cart items for tax exclusive stores. */ - protected function updateTaxExclusive() { + public function updateTaxExclusive() { if (_xls_get_conf('TAX_INCLUSIVE_PRICING', '0') == '1') { return; @@ -809,10 +829,9 @@ protected function updateTaxShipping() { } } - // ToDO: WS-3525 Refactor Tax::CalculatePricesWithTax to return an associative array - $nprice_taxes = Tax::CalculatePricesWithTax($this->shipping->shipping_sell, $this->tax_code_id, $intTaxStatus); + $nprice_taxes = Tax::calculatePricesWithTax($this->shipping->shipping_sell, $this->tax_code_id, $intTaxStatus); - $taxes = $nprice_taxes[1]; + $taxes = $nprice_taxes['arrTaxValues']; if ($this->tax_code_id == $intNoTax) { @@ -821,8 +840,7 @@ protected function updateTaxShipping() { else { - // ToDO: WS-3525 Refactor Tax::CalculatePricesWithTax to return an associative array - $this->shipping->shipping_sell_taxed = $nprice_taxes[0]; + $this->shipping->shipping_sell_taxed = $nprice_taxes['fltSellTotalWithTax']; if (Yii::app()->params['TAX_INCLUSIVE_PRICING'] != '1') { @@ -939,6 +957,23 @@ public function AddProduct($objProduct, } } + // If our Cart isn't saved to the db at this point, save it + if (is_null($this->id)) + { + if (!$this->save()) + { + throw new Exception( + sprintf( + "Unable to save cart before adding this first product: %s\n%s", + $objProduct->code, + print_r($this->getErrors(), true) + ) + ); + } + + Yii::app()->user->setState('cartid', $this->id); + } + if (!$objItem) { $objItem = new CartItem(); @@ -1168,24 +1203,44 @@ public static function LoadCartByLink($strLinkId, $clone = true){ * @param QQClause[] $objOptionalClauses additional optional QQClause objects for this query * @return Cart[] */ - public static function LoadLastCartInProgress($intCustomerId, $intBelowCart = 0) { - // Call Cart::QueryArray to perform the LoadArrayByCustomerId query - try { + public static function LoadLastCartInProgress($intCustomerId, $intBelowCart = 0) + { + // if $intBelowCart is null it means the active cart hasn't been saved to the db yet. + // This most likely means it is empty i.e. no products have been added. + // However, in order for the db query to work as intended, we need to set it to an integer. + if (is_null($intBelowCart)) + { + $intBelowCart = 0; + } - $arrCarts=Cart::model()->findAll(array( - 'condition'=>'customer_id=:id AND cart_type=:type AND item_count > 0 '. - ($intBelowCart>0 ? 'AND id<:currentcart' : 'AND id>:currentcart'), - 'params'=>array(':id'=>$intCustomerId, ':type'=>CartType::cart, ':currentcart'=>$intBelowCart), - 'order'=>'id DESC', - 'limit'=>1, - )); + $strConditionCurrentCart = 'id > :currentcart'; + if ($intBelowCart > 0) + { + $strConditionCurrentCart = 'id < :currentcart'; + } + + $criteria = new CDbCriteria(); + $criteria->condition = + 'customer_id = :id AND '. + 'cart_type = :type AND '. + 'item_count > 0 AND '. + $strConditionCurrentCart; + $criteria->order = 'id DESC'; + $criteria->limit = 1; + $criteria->params = array( + 'id' => $intCustomerId, + 'type' => CartType::cart, + 'currentcart' => $intBelowCart + ); - if(count($arrCarts)>0) { + $arrCarts = Cart::model()->findAll($criteria); - return $arrCarts[0]; - } - else return null; - } catch (Exception $objExc) { + if (count($arrCarts) > 0) + { + return $arrCarts[0]; + } + else + { return null; } } @@ -1356,20 +1411,19 @@ public function getHasPromoCode() } /** - * Called by session management to periodically sweep away old carts, based on config cart life + * Erases all carts and cart items that are older than CART_LIFE days and + * have no customer_id assocaited with them. + * + * Called by legacySoapController when doing a document_flush(), + * document_flush() is called by onsite when the user initiates a + * "Reset Carts and Documents" from the Tools->eCommerce->Documents tab + * + * @return int The number of carts + items deleted by the + * query */ - public static function GarbageCollect() { - //Delete any carts older than our timeout that don't have a customer ID attached (since those can always be restored) - $objCarts = Cart::model()->findAll("cart_type = :type AND customer_id IS NULL AND modified<:date", - array(':type'=>CartType::cart, - ':date'=>date("Y-m-d H:i:s",strtotime("-"._xls_get_conf('CART_LIFE',30)."days")) - )); - foreach ($objCarts as $objCart) - { - foreach ($objCart->cartItems as $item) - $item->delete(); - $objCart->delete(); - } + public static function garbageCollect() + { + return ShoppingCart::eraseExpired(); } diff --git a/core/protected/models/Customer.php b/core/protected/models/Customer.php index 743d6788..383f1966 100644 --- a/core/protected/models/Customer.php +++ b/core/protected/models/Customer.php @@ -27,7 +27,6 @@ class Customer extends BaseCustomer const ADMIN_USER = 2; const EXTERNAL_SHELL_ACCOUNT = -1; //for third party integration - public $email_repeat; public $password_repeat; public $token; //Security token for resetting password @@ -36,7 +35,7 @@ class Customer extends BaseCustomer * Returns the static model of the specified AR class. * @return Customer the static model class */ - public static function model($className=__CLASS__) + public static function model($className = __CLASS__) { return parent::model($className); } @@ -55,41 +54,39 @@ public function rules() // will receive user inputs. return array( array('created, modified', 'required'), - array('newsletter_subscribe', 'numerical', 'integerOnly'=>true), - array('allow_login', 'safe', 'on'=>'update'), //Note this update is Admin Panel, we use a different scenario for front-end update - array('first_name, last_name', 'length', 'max'=>64), - array('company, email, password', 'length', 'max'=>255), - array('currency', 'length', 'max'=>3), - array('preferred_language, mainphonetype', 'length', 'max'=>8), - array('mainphone', 'length','min'=>7, 'max'=>32), + array('newsletter_subscribe', 'numerical', 'integerOnly' => true), + array('allow_login', 'safe', 'on' => 'update'), //Note this update is Admin Panel, we use a different scenario for front-end update + array('first_name,last_name', 'length', 'max' => 64), + array('company,email,password', 'length', 'max' => 255), + array('currency', 'length', 'max' => 3), + array('preferred_language,mainphonetype', 'length', 'max' => 8), + array('mainphone', 'length', 'min' => 7, 'max' => 32), array('last_login', 'safe'), - - array('email', 'required','on'=>'create,createfb,myaccountupdate'), - array('first_name,last_name', 'required','on'=>'create,createfb,myaccountupdate,update,updatepassword'), - array('password,password_repeat', 'required','on'=>'create,updatepassword'), - array('mainphone', 'required','on'=>'create,myaccountupdate,update,updatepassword'), + array('email', 'required', 'on' => 'create,createfb,myaccountupdate'), + array('first_name,last_name', 'required','on' => 'create,createfb,myaccountupdate,update,updatepassword'), + array('password,password_repeat', 'required','on' => 'create,updatepassword'), + array('mainphone', 'required','on' => 'create,myaccountupdate,update,updatepassword'), // email has to be a valid email address array('email', 'email'), array('email,email_repeat', 'safe'), - array('email', 'validateEmailUnique','on'=>'create,createfb'), - array('email_repeat', 'validateEmailRepeat','on'=>'create,createfb'), - + array('email', 'validateEmailUnique','on' => 'create,createfb'), + array('email_repeat', 'validateEmailRepeat','on' => 'create,createfb'), - array('email', 'length', 'max'=>50), - array('email', 'compare', 'on'=>'create'), + array('email', 'length', 'max' => 50), + array('email', 'compare', 'on' => 'create'), array('email_repeat', 'safe'), - array('password', 'length', 'max'=>255), - array('password_repeat', 'length', 'max'=>255), - array('password', 'compare', 'on'=>'create,formSubmitWithAccount,updatepassword,resetpassword'), + array('password', 'length', 'max' => 255), + array('password_repeat', 'length', 'max' => 255), + array('password', 'compare', 'on' => 'create,formSubmitWithAccount,updatepassword,resetpassword'), array('password_repeat', 'safe'), - array('password,password_repeat', 'PasswordLengthValidator', 'on'=>'create,formSubmitWithAccount,updatepassword,resetpassword'), + array('password,password_repeat', 'PasswordLengthValidator', 'on' => 'create,formSubmitWithAccount,updatepassword,resetpassword'), - array('token', 'length', 'max'=>Customer::RESET_PASSWORD_TOKEN_LENGTH), - array('token', 'required', 'on'=>'resetpassword'), - array('token', 'validateToken', 'on'=>'resetpassword'), + array('token', 'length', 'max' => Customer::RESET_PASSWORD_TOKEN_LENGTH), + array('token', 'required', 'on' => 'resetpassword'), + array('token', 'validateToken', 'on' => 'resetpassword'), ); } @@ -103,11 +100,11 @@ public function attributeLabels() return array_merge( parent::attributeLabels(), array( - 'active'=>'This is an active address', - 'email_repeat'=>'Email Address (confirm)', - 'password_repeat'=>'Password (confirm)', - 'newsletter_subscribe'=> 'Allow us to send you emails about our products', - 'mainphone'=>'Phone Number') + 'active' => 'This is an active address', + 'email_repeat' => 'Email Address (confirm)', + 'password_repeat' => 'Password (confirm)', + 'newsletter_subscribe' => 'Allow us to send you emails about our products', + 'mainphone' => 'Phone Number') ); } @@ -123,36 +120,56 @@ public function behaviors() ); } + + /** + * Confirms whether or not the passed email address + * belongs to a registered user. + * + * @param $strEmail + * @return bool + */ + public static function isEmailRegistered($strEmail) + { + + $obj = self::model()->findByAttributes( + array( + 'email' => $strEmail, + 'record_type' => Customer::REGISTERED + ) + ); + + if (is_null($obj)) + { + return false; + } + + return true; + } + /** * @param $attribute * @param $params */ public function validateEmailUnique($attribute, $params) { - if (Yii::app()->user->isGuest && $this->email != '') + if ($this->email == '') { - $objCustomer = Customer::LoadByEmail($this->email); - - if ($objCustomer instanceof Customer) - { - $this->addError('email', - Yii::t('checkout', 'Email address already exists in system. Please log in.') - ); - } + return; } - elseif ($this->email != '') - { - $objCustomer = Customer::GetCurrent(); - $obj = Customer::model()->findAll('email = :email AND id <> :id',array(':email'=>$this->email,':id'=>$objCustomer->id)); - if (count($obj)>0) - { - $this->addError('email', - Yii::t('checkout','This email address already exists in our system for another account.') - ); - } + if (Yii::app()->user->isGuest === false) + { + return; + } + if (self::isEmailRegistered($this->email) === true) + { + $this->addError( + 'email', + Yii::t('checkout', 'Email address already exists in system. Please log in.') + ); } + } /** @@ -164,8 +181,9 @@ public function validateEmailRepeat($attribute, $params) if (Yii::app()->user->isGuest && $this->email != $this->email_repeat) { - $this->addError('email_repeat', - Yii::t('checkout','Email address does not match') + $this->addError( + 'email_repeat', + Yii::t('checkout', 'Email address does not match') ); } } @@ -185,15 +203,21 @@ public function validateToken($attribute, $params) { $url = CHtml::link( Yii::t('customer', 'password reset'), - Yii::app()->createUrl("site/login")); + Yii::app()->createUrl("site/login") + ); - $this->addError($attribute, Yii::t('yii', - 'Security {attribute} is invalid. Please try clicking again' . - ' on the link in the email, or request another {loginurl}.', - array( - '{attribute}'=>$this->getAttributeLabel($attribute), - '{loginurl}'=>$url - ))); + $this->addError( + $attribute, + Yii::t( + 'yii', + 'Security {attribute} is invalid. Please try clicking again' . + ' on the link in the email, or request another {loginurl}.', + array( + '{attribute}' => $this->getAttributeLabel($attribute), + '{loginurl}' => $url + ) + ) + ); } else { @@ -217,37 +241,53 @@ public static function CreateFromCheckoutForm($checkoutForm) $obj->newsletter_subscribe = $checkoutForm->receiveNewsletter; $obj->record_type = Customer::NORMAL_USER; $obj->currency = _xls_get_conf('CURRENCY_DEFAULT'); - $obj->pricing_level=1; + $obj->pricing_level = 1; $obj->allow_login = Customer::NORMAL_USER; $obj->scenario = Customer::SCENARIO_INSERT; if (!$obj->save()) - Yii::log("Error creating user ".print_r($obj->getErrors(),true), 'error', 'application.'.__CLASS__.".".__FUNCTION__); + { + Yii::log("Error creating user " . print_r($obj->getErrors(), true), 'error', 'application.'.__CLASS__.".".__FUNCTION__); + } else - Yii::log("Created user from checkout ".$obj->first_name." ".$obj->last_name." ".$obj->id, - 'info', 'application.'.__CLASS__.".".__FUNCTION__); + { + Yii::log( + sprintf( + "Created user from checkout %s %s id# %d ", + $obj->first_name, + $obj->last_name, + $obj->id + ), + 'info', + 'application.'.__CLASS__.".".__FUNCTION__ + ); + } + return $obj; } - public static function LoadByEmail($strEmail) { - - $objCustomer = Customer::model()->findByAttributes(array('email'=>$strEmail)); + public static function LoadByEmail($strEmail) + { + $objCustomer = Customer::model()->findByAttributes(array('email' => $strEmail)); if ($objCustomer instanceof Customer) + { return $objCustomer; - else return false; + } + return false; } public static function ClearRecord($id) { - $objCustomer = Customer::model()->findByPk($id); $objCustomer->default_billing_id = null; $objCustomer->default_shipping_id = null; $objCustomer->save(); foreach ($objCustomer->customerAddresses as $objAddress) + { $objAddress->delete(); - $objCustomer->delete(); + } + $objCustomer->delete(); } /** @@ -281,9 +321,11 @@ public function authenticate($plain_text) public static function GetCurrent() { if (Yii::app()->user->isGuest) + { return null; - else - return Customer::model()->findByPk(Yii::app()->user->id); + } + + return Customer::model()->findByPk(Yii::app()->user->id); } /** @@ -293,11 +335,12 @@ public static function GetCurrent() */ public function GenerateTempPassword() { - $this->token = Yii::app()->getSecurityManager()-> - generateRandomString(Customer::RESET_PASSWORD_TOKEN_LENGTH); + $this->token = Yii::app()->getSecurityManager()->generateRandomString(Customer::RESET_PASSWORD_TOKEN_LENGTH); if (!$this->token) + { return false; + } $this->temp_password = CPasswordHelper::hashPassword($this->token); return $this->save(false); @@ -309,25 +352,21 @@ public function GenerateTempPassword() */ public function searchAdmin() { - - $criteria=new CDbCriteria; - $criteria->compare('first_name',$this->email,true,'OR'); - $criteria->compare('last_name',$this->email,true,'OR'); - $criteria->compare('email',$this->email,true,'OR'); - $criteria->compare("CONCAT(first_name, ' ', last_name)",$this->email,true,'OR'); + $criteria = new CDbCriteria; + $criteria->compare('first_name', $this->email, true, 'OR'); + $criteria->compare('last_name', $this->email, true, 'OR'); + $criteria->compare('email', $this->email, true, 'OR'); + $criteria->compare("CONCAT(first_name, ' ', last_name)", $this->email, true, 'OR'); $criteria->addCondition("record_type>=0"); - return new CActiveDataProvider($this, array( - 'criteria'=>$criteria, - 'sort'=>array( - 'defaultOrder'=>'last_name ASC', - ), - 'pagination' => array( - 'pageSize' => 80, - ), - )); - - + return new CActiveDataProvider( + $this, + array( + 'criteria' => $criteria, + 'sort' => array('defaultOrder' => 'last_name ASC'), + 'pagination' => array('pageSize' => 80), + ) + ); } public function getFullname() @@ -394,23 +433,31 @@ public function defaultShippingIsNoTax() protected function beforeValidate() { if ($this->isNewRecord) + { $this->created = new CDbExpression('NOW()'); + } + //When resetting a password, we are using the modified //timestamp to determine if a reset token is still valid, //so don't update the timestamp in that scenario. if ($this->scenario != self::SCENARIO_RESETPASSWORD) + { $this->modified = new CDbExpression('NOW()'); + } if (empty($this->preferred_language)) - $this->preferred_language = Yii::app()->language; + { + $this->preferred_language = Yii::app()->language; + } if (empty($this->currency)) - $this->currency = _xls_get_conf('CURRENCY_DEFAULT','USD'); + { + $this->currency = _xls_get_conf('CURRENCY_DEFAULT', 'USD'); + } $this->email = strtolower($this->email); $this->email_repeat = strtolower($this->email_repeat); - return parent::beforeValidate(); } @@ -424,8 +471,7 @@ public function beforeSave() Customer::SCENARIO_UPDATEPASSWORD, Customer::SCENARIO_RESETPASSWORD ) - ) - && + ) && $this->record_type == Customer::REGISTERED && $this->password ) @@ -433,22 +479,28 @@ public function beforeSave() $hashCostParam = _xls_get_conf('PASSWORD_HASH_COST_PARAM'); if ($hashCostParam) + { $this->password = CPasswordHelper::hashPassword($this->password, $hashCostParam); + } else + { $this->password = CPasswordHelper::hashPassword($this->password); + } } // If token is set it means a temp_password has just been created, // in all other situations erase the temp_password on save if (!$this->token) + { $this->temp_password = null; + } return parent::beforeSave(); } protected function afterConstruct() { - $this->newsletter_subscribe = _xls_get_conf('DISABLE_ALLOW_NEWSLETTER',1) == 1 ? 0 : 1; + $this->newsletter_subscribe = _xls_get_conf('DISABLE_ALLOW_NEWSLETTER', 1) == 1 ? 0 : 1; $this->preferred_language = _xls_get_conf('LANG_CODE', 'en'); $this->currency = _xls_get_conf('CURRENCY_DEFAULT', 'USD'); } diff --git a/core/protected/models/Images.php b/core/protected/models/Images.php index 4a296cca..11b8ebf7 100644 --- a/core/protected/models/Images.php +++ b/core/protected/models/Images.php @@ -503,19 +503,21 @@ public static function CalculateNewSize($intWidth, $intHeight, $intNewWidth, $in */ public function DeleteImage() { if ($this->image_path && file_exists(Images::GetImagePath($this->image_path))) + { @unlink($this->GetPath()); + } - - $objEvent = new CEventPhoto('Images','onDeletePhoto',null,null,null); + $objEvent = new CEventPhoto('Images', 'onDeletePhoto', null, null, null); if(isset($this->ImagesCloud) && isset($this->ImagesCloud[0])) + { $objEvent->cloudinary_public_id = $this->ImagesCloud[0]->cloudinary_public_id; + } $objEvent->s3_path = $this->image_path; - _xls_raise_events('CEventPhoto',$objEvent); + _xls_raise_events('CEventPhoto', $objEvent); } - public static function LoadByRowidSize($id, $intSize) { if ($intSize == ImagesType::normal) return Images::model()->findByPk($id); @@ -571,15 +573,47 @@ public static function LoadByWidthHeightParent($intWidth, $intHeight, $intParent */ public function beforeDelete() { + // Null all FK references from Product to this Image. + Product::model()->updateAll( + array('image_id' => null), + 'image_id = :image_id', + array(':image_id' => $this->id) + ); + + // Delete images where this image is the parent. + if ($this->IsPrimary() === true) + { + $arrChildImages = Images::model()->findAllByAttributes( + array('parent' => $this->id) + ); + + foreach ($arrChildImages as $objImage) + { + if ($objImage->id === $this->id) + { + // For primary images, they are actually their own parent. + // Without this check, we'd have an infinite loop. + continue; + } - //In case this delete is pointed to by a product, get rid of that first - Product::model()->updateAll(array('image_id'=>null),'image_id ='.$this->id); - if ($this->IsPrimary()) - foreach (Images::model()->findAllByAttributes(array('parent' => $this->id)) as $objImage) - if (!$objImage->IsPrimary()) - $objImage->delete(); + $objImage->delete(); + } + } + // Delete all ImagesCloud rows that reference this Image to satisfy + // foreign key constraints. + $arrImagesCloud = ImagesCloud::model()->findAllByAttributes( + array('image_id' => $this->id) + ); + + foreach ($arrImagesCloud as $objImagesCloud) + { + $objImagesCloud->delete(); + } + + // Delete the image from the file system. $this->DeleteImage(); + return parent::beforeDelete(); } diff --git a/core/protected/models/Log.php b/core/protected/models/Log.php index 145e8bdc..ec22671d 100644 --- a/core/protected/models/Log.php +++ b/core/protected/models/Log.php @@ -13,38 +13,38 @@ class Log extends BaseLog * Returns the static model of the specified AR class. * @return Log the static model class */ - public static function model($className=__CLASS__) + public static function model($className = __CLASS__) { return parent::model($className); } - public static function GarbageCollect() { - - $intLogRotateDays = _xls_get_conf('LOG_ROTATE_DAYS',0); - if ($intLogRotateDays>0) { - $LastDate = date('YmdHis', strtotime("-".$intLogRotateDays." days")); + public static function garbageCollect() + { + $intLogRotateDays = _xls_get_conf('LOG_ROTATE_DAYS', 0); + if ($intLogRotateDays > 0) + { + $lastDate = date('YmdHis', strtotime("-".$intLogRotateDays." days")); - $sql="DELETE from xlsws_log where DATE_FORMAT(`created`, '%Y%m%d%H%i%s')<'".$LastDate."'"; + $sql = "DELETE from xlsws_log where DATE_FORMAT(`created`, '%Y%m%d%H%i%s')<'".$lastDate."'"; Yii::app()->db->createCommand($sql)->execute(); } - } public function searchAll() { - $criteria=new CDbCriteria; - $criteria->compare('message',$this->message,true,'OR'); + $criteria = new CDbCriteria; + $criteria->compare('message', $this->message, true, 'OR'); return new CActiveDataProvider($this, array( - 'criteria'=>$criteria, - 'sort'=>array( - 'defaultOrder'=>'id DESC', + 'criteria' => $criteria, + 'sort' => array( + 'defaultOrder' => 'id DESC', ), 'pagination' => array( 'pageSize' => 10, ), )); } -} \ No newline at end of file +} diff --git a/core/protected/models/Product.php b/core/protected/models/Product.php index 70f0822b..bf7d77ef 100644 --- a/core/protected/models/Product.php +++ b/core/protected/models/Product.php @@ -1101,12 +1101,16 @@ public static function RecalculateInventory() { * @param float [$fltPrice] :: Price to calculate on * @return array([1] => .... [5]=>)) all the tax components */ - public function CalculateTax($taxCode, $fltPrice = false) { + public function CalculateTax($intTaxCode, $fltPrice = false) + { if ($fltPrice === false) + { $fltPrice = $this->getPriceValue(); + } - list($fltTaxedPrice, $arrTaxes) = - Tax::CalculatePricesWithTax($fltPrice, $taxCode, $this->tax_status_id); + $arr = Tax::calculatePricesWithTax($fltPrice, $intTaxCode, $this->tax_status_id); + $fltTaxedPrice = $arr['fltSellTotalWithTax']; + $arrTaxes = $arr['arrTaxValues']; return $arrTaxes; } @@ -1270,21 +1274,23 @@ public static function LoadByRequestUrl($strName) { return Product::model()->findByAttributes(array('request_url'=>$strName)); } - public function DeleteImages() { - if (is_null($this->id)) { + /** + * Delete all the images associated with this product. + * @return void + */ + public function deleteImages() { + if (is_null($this->id)) + { return; } - $intImageID = $this->image_id; //save it in a variable - $this->image_id = null; - $this->save(); + $arrImage = Images::model()->findAllByAttributes( + array('product_id' => $this->id) + ); - if ($intImageID) { - $objImage = Images::model()->findByPk($intImageID); - if ($objImage) { - @unlink($objImage->image_path); - $objImage->delete(); - } + foreach ($arrImage as $objImage) + { + $objImage->delete(); } } diff --git a/core/protected/models/ProductQtyPricing.php b/core/protected/models/ProductQtyPricing.php index 76db804b..34cb754a 100644 --- a/core/protected/models/ProductQtyPricing.php +++ b/core/protected/models/ProductQtyPricing.php @@ -23,19 +23,22 @@ public function __toString() { return sprintf('ProductQtyPricing Object %s', $this->product_id." ".$this->pricing_level." ".$this->qty); } - public function GetPrice($intTaxCode, $intTaxStatus, - $taxExclusive = false) { - + public function GetPrice($objTaxCode, $intTaxStatus, $taxExclusive = false) + { if ($taxExclusive) + { return $this->price; - else if (_xls_get_conf('TAX_INCLUSIVE_PRICING', '') == '1') { - $arrPrice = Tax::CalculatePricesWithTax( - $this->price, $intTaxCode, $intTaxStatus); - $intPrice = round($arrPrice[0], 2); - return $intPrice; + } + elseif (_xls_get_conf('TAX_INCLUSIVE_PRICING', '') == '1') + { + $arrPrice = Tax::calculatePricesWithTax($this->price, $objTaxCode->id, $intTaxStatus); + + return $arrPrice['fltSellTotalWithTax']; } else + { return $this->price; + } } public function __get($strName) { diff --git a/core/protected/models/Tax.php b/core/protected/models/Tax.php index 8aa03924..c6eb2551 100644 --- a/core/protected/models/Tax.php +++ b/core/protected/models/Tax.php @@ -29,80 +29,119 @@ public function __toString() { /** - * Calculate a price of a product against a provided Tax Code. This will return the total price as well - * as a 5-item array of tax1_rate through tax5_rate + * Calculate taxes given a pre-tax price, the lsid of the TaxCode and the lsid of the TaxStatus. + * The returned array looks like this: + * Array( + * [fltSellTotalWithTax] => + * [arrTaxValues] => Array( + * [1] => + * [2] => + * [3] => + * [4] => + * [5] => + * ) + * [arrTaxRates] => Array( + * [1] => + * [2] => + * [3] => + * [4] => + * [5] => + * ) + * ) + * + * fltSellTotalWithTax is the sum of the pre-tax value and all members of arrTaxValues + * arrTaxValues is an array of values for each tax calculated according to its corresponding rate and the pre-tax value + * arrTaxRate is an array of tax rates which are defined by the TaxCode + * * @param $fltSellTotal * @param $intTaxCodeId * @param $intTaxStatusId * @return array */ - public static function CalculatePricesWithTax($fltSellTotal , $intTaxCodeId , $intTaxStatusId) { - + public static function calculatePricesWithTax($fltSellTotal, $intTaxCodeId, $intTaxStatusId) + { static $objTaxes; // Cached for better performance $fltSellTotalTaxed = $fltSellTotal; - $arrTaxAmount = array(1=>0 , 2=>0 , 3=>0 , 4=> 0 , 5=>0); - $arrTaxRates = array(1=>0 , 2=>0 , 3=>0 , 4=> 0 , 5=>0); + $arrTaxAmount = array(1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0); + $arrTaxRates = array(1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0); + $objTaxCode = TaxCode::model()->findByAttributes(array('lsid' => $intTaxCodeId)); - if($intTaxCodeId instanceof TaxCode ) - $objTaxCode = $intTaxCodeId; - else - $objTaxCode = TaxCode::model()->findByAttributes(array('lsid'=>$intTaxCodeId)); - - if(!$objTaxCode) { - if(!is_null($intTaxCodeId)) //Ignore null at this stage + if (is_null($objTaxCode)) + { + if (!is_null($intTaxCodeId)) //Ignore null at this stage + { Yii::log("Unknown tax code passed: $intTaxCodeId", 'error', 'application.'.__CLASS__.".".__FUNCTION__); + } - return array($fltSellTotalTaxed , $arrTaxAmount, $arrTaxRates); + return array( + 'fltSellTotalWithTax' => $fltSellTotalTaxed, + 'arrTaxValues' => $arrTaxAmount, + 'arrTaxRates' => $arrTaxRates + ); } - if($intTaxStatusId instanceof TaxStatus) - $objTaxStatus = $intTaxStatusId; - elseif($intTaxStatusId >= 0) - $objTaxStatus = TaxStatus::model()->findByAttributes(array('lsid'=>$intTaxStatusId)); - else - $objTaxStatus = false; + $objTaxStatus = TaxStatus::model()->findByAttributes(array('lsid' => $intTaxStatusId)); //For LS Cloud integration, see if we can find the default Tax Status - if($objTaxStatus === false && Yii::app()->params['LIGHTSPEED_CLOUD']>0) + if (is_null($objTaxStatus) && Yii::app()->params['LIGHTSPEED_CLOUD'] > 0) + { $objTaxStatus = TaxStatus::getCloudDefault(); + } - if(!$objTaxes) + if (is_null($objTaxes)) + { $objTaxes = Tax::model()->findAll(); + } $taxtypes = 5; // Number of taxes in LS - // for each exempt, reset the code to 0 - if($objTaxStatus) { - if($objTaxStatus->tax1_status) $objTaxCode->tax1_rate = 0; - if($objTaxStatus->tax2_status) $objTaxCode->tax2_rate = 0; - if($objTaxStatus->tax3_status) $objTaxCode->tax3_rate = 0; - if($objTaxStatus->tax4_status) $objTaxCode->tax4_rate = 0; - if($objTaxStatus->tax5_status) $objTaxCode->tax5_rate = 0; + // for each exempt, reset the corresponding rate to 0 + if ($objTaxStatus instanceof TaxStatus) + { + if ($objTaxStatus->tax1_status == 1) $objTaxCode->tax1_rate = 0; + if ($objTaxStatus->tax2_status == 1) $objTaxCode->tax2_rate = 0; + if ($objTaxStatus->tax3_status == 1) $objTaxCode->tax3_rate = 0; + if ($objTaxStatus->tax4_status == 1) $objTaxCode->tax4_rate = 0; + if ($objTaxStatus->tax5_status == 1) $objTaxCode->tax5_rate = 0; } $i = 0; - foreach($objTaxes as $objTax) { - $strRate = "tax" . ($i+1) . "_rate"; + foreach ($objTaxes as $objTax) + { + $strRate = "tax" . ($i + 1) . "_rate"; - if($objTax->compounded) - $fltTaxAmount = $fltSellTotalTaxed * ($objTaxCode->$strRate/100); + if ($objTax->compounded) + { + $fltTaxAmount = $fltSellTotalTaxed * ($objTaxCode->$strRate / 100); + } else - $fltTaxAmount = $fltSellTotal * ($objTaxCode->$strRate/100); + { + $fltTaxAmount = $fltSellTotal * ($objTaxCode->$strRate / 100); + } - if(($objTax->max_tax > 0) && ($fltTaxAmount >= $objTax->max_tax)) + if (($objTax->max_tax > 0) && ($fltTaxAmount >= $objTax->max_tax)) + { $fltTaxAmount = $objTax->max_tax; + } - $arrTaxAmount[$i+1] = $fltTaxAmount; - $arrTaxRates[$i+1] = $objTaxCode->$strRate; + $arrTaxAmount[$i + 1] = $fltTaxAmount; + $arrTaxRates[$i + 1] = $objTaxCode->$strRate; $fltSellTotalTaxed = $fltSellTotalTaxed + $fltTaxAmount; $i++; - if($i >= $taxtypes) $i = $taxtypes; + if ($i >= $taxtypes) + { + $i = $taxtypes; + } } - return array(round($fltSellTotalTaxed,2,PHP_ROUND_HALF_UP) , $arrTaxAmount, $arrTaxRates); + return array( + 'fltSellTotalWithTax' => round($fltSellTotalTaxed, 2, PHP_ROUND_HALF_UP), + 'arrTaxValues' => $arrTaxAmount, + 'arrTaxRates' => $arrTaxRates + ); } /** diff --git a/core/protected/models/TaxCode.php b/core/protected/models/TaxCode.php index 9a31c205..f8647da1 100644 --- a/core/protected/models/TaxCode.php +++ b/core/protected/models/TaxCode.php @@ -66,10 +66,7 @@ public static function getDefaultCode() { * @return $objTax the tax object */ public static function GetNoTaxCode() { - $objTax = TaxCode::model()->tax_total()->notax()->find(); - if ($objTax) - return $objTax; - return; + return TaxCode::model()->tax_total()->notax()->find(); } /** diff --git a/core/protected/models/Wishlist.php b/core/protected/models/Wishlist.php index 0ba7b646..f69912f8 100644 --- a/core/protected/models/Wishlist.php +++ b/core/protected/models/Wishlist.php @@ -22,7 +22,7 @@ class Wishlist extends BaseWishlist * Returns the static model of the specified AR class. * @return Wishlist the static model class */ - public static function model($className=__CLASS__) + public static function model($className = __CLASS__) { return parent::model($className); } @@ -68,10 +68,10 @@ public function rules() // will receive user inputs. return array( array('registry_name,visibility,ship_option,after_purchase', 'required'), - array('visibility', 'numerical', 'integerOnly'=>true), - array('registry_name, ship_option, gift_code', 'length', 'max'=>100), - array('registry_name,registry_description,event_date','filter','filter'=>array($obj=new CHtmlPurifier(),'purify')), - array('customer_id', 'length', 'max'=>20), + array('visibility', 'numerical', 'integerOnly' => true), + array('registry_name, ship_option, gift_code', 'length', 'max' => 100), + array('registry_name,registry_description,event_date','filter','filter' => array($obj = new CHtmlPurifier(), 'purify')), + array('customer_id', 'length', 'max' => 20), array('registry_description,event_date,deleteMe', 'safe'), ); } @@ -85,16 +85,16 @@ public function search() // Warning: Please modify the following code to remove attributes that // should not be searched. - $criteria=new CDbCriteria; + $criteria = new CDbCriteria; - $criteria->compare('id',$this->id,true); - $criteria->compare('registry_name',$this->registry_name,false); - $criteria->compare('event_date',$this->event_date,false); - $criteria->compare('customer_id',$this->customer_id,false); - $criteria->compare('gift_code',$this->gift_code,false); + $criteria->compare('id', $this->id, true); + $criteria->compare('registry_name', $this->registry_name, false); + $criteria->compare('event_date', $this->event_date, false); + $criteria->compare('customer_id', $this->customer_id, false); + $criteria->compare('gift_code', $this->gift_code, false); return new CActiveDataProvider($this, array( - 'criteria'=>$criteria, + 'criteria' => $criteria, )); } @@ -102,30 +102,30 @@ public function getDataItems() { $objItems = new WishlistItem(); $objItems->registry_id = $this->id; - return $objItems->editSearch(); - - - } public static function LoadUserLists() { if (Yii::app()->user->isGuest) + { return array(); + } - return Wishlist::model()->findAllByAttributes(array('customer_id'=>Yii::app()->user->id)); - - - + return Wishlist::model()->findAllByAttributes(array('customer_id' => Yii::app()->user->id)); } public static function LoadFirstCode() { $objLists = Wishlist::LoadUserLists(); - if (count($objLists)==0) return null; - else return $objLists[0]->gift_code; + if (count($objLists) == 0) + { + return null; + } + + return $objLists[0]->gift_code; } + /** * Determine whether the current user should be able to see this wish list * @return bool @@ -133,8 +133,11 @@ public static function LoadFirstCode() protected function getVisible() { if ($this->visibility == Wishlist::PRIVATELIST && $this->customer_id != Yii::app()->user->id) + { return false; - else return true; + } + + return true; } /** @@ -144,8 +147,11 @@ protected function getVisible() protected function getSharable() { if ($this->visibility == Wishlist::PRIVATELIST) + { return false; - else return true; + } + + return true; } /** @@ -155,8 +161,11 @@ protected function getSharable() protected function getIsMine() { if ($this->customer_id == Yii::app()->user->id) + { return true; - else return false; + } + + return false; } /** @@ -166,9 +175,9 @@ public function getVisibilities() { return array( - Wishlist::PUBLICLIST=> Yii::t('wishlist','Public, searchable by my email address'), - Wishlist::PERSONALLIST=> Yii::t('wishlist','Personal, shared only by a special URL'), - Wishlist::PRIVATELIST=> Yii::t('wishlist','Private, only viewable with my login'), + Wishlist::PUBLICLIST => Yii::t('wishlist', 'Public, searchable by my email address'), + Wishlist::PERSONALLIST => Yii::t('wishlist', 'Personal, shared only by a special URL'), + Wishlist::PRIVATELIST => Yii::t('wishlist', 'Private, only viewable with my login'), ); } @@ -179,15 +188,14 @@ public function getShippingOptions() { $arrReturn = array( - '0'=> Yii::t('wishlist','None') + '0' => Yii::t('wishlist', 'None') ); $objAddresses = CustomerAddress::getActiveAddresses(); foreach ($objAddresses as $objAddress) { - $str = - $objAddress->fullname.", ". + $str = $objAddress->fullname.", ". $objAddress->address1.($objAddress->address2 != '' ? " " : "").$objAddress->address2.", ". $objAddress->city; @@ -198,9 +206,9 @@ public function getShippingOptions() $arrReturn[$objAddress->id] = $str; } - return $arrReturn; } + /** * @return array */ @@ -208,8 +216,8 @@ public function getAfterPurchase() { return array( - Wishlist::LEAVEINLIST=> Yii::t('wishlist','Leave the item in the Wish List, marked as Purchased'), - Wishlist::DELETEFROMLIST=> Yii::t('wishlist','Delete the item automatically from Wish List'), + Wishlist::LEAVEINLIST => Yii::t('wishlist', 'Leave the item in the Wish List, marked as Purchased'), + Wishlist::DELETEFROMLIST => Yii::t('wishlist', 'Delete the item automatically from Wish List'), ); } @@ -218,18 +226,22 @@ public function getAfterPurchase() /** * Because visitor gift purchases are on a time limit to complete, remove any pending incomplete purchases */ - public static function GarbageCollect() { + public static function garbageCollect() { - $intResetHours = _xls_get_conf('RESET_GIFT_REGISTRY_PURCHASE_STATUS',6); - if ($intResetHours<1) $intResetHours=1; //cannot set to 0 - $cutoffDate = date('YmdHis', strtotime("-".$intResetHours." hours")); + $intResetHours = _xls_get_conf('RESET_GIFT_REGISTRY_PURCHASE_STATUS', 6); + if ($intResetHours < 1) + { + // Cannot set to 0. + $intResetHours = 1; + } + $cutoffDate = date('YmdHis', strtotime("-".$intResetHours." hours")); - $arrProducts=Yii::app()->db->createCommand( + $arrProducts = Yii::app()->db->createCommand( 'SELECT * FROM '.Cart::model()->tableName().' WHERE cart_type='.CartType::cart.' ORDER BY id DESC' )->query(); - while(($arrItem=$arrProducts->read())!==false) + while(($arrItem = $arrProducts->read()) !== false) { $objCart = Cart::model()->findByPk($arrItem['id']); //Go through outstanding carts and see if we have any expiring gift items @@ -247,11 +259,13 @@ public static function GarbageCollect() { { $objMessage = new CartMessages(); $objMessage->cart_id = $objCart->id; - $objMessage->message = - Yii::t('cart','You attempted to purchase the product {product} as a gift from the wish list for {wishname}. However, because wish list gift purchases must be completed within {hours} hour(s), the item has been removed from your cart. If it is still available on the wish list, it can be re-added.', - array('{wishname}'=>$item->wishlistItem->registry->customer->fullname, - '{product}'=>$item->product->Title, - '{hours}'=>$intResetHours)); + $objMessage->message = Yii::t( + 'cart', + 'You attempted to purchase the product {product} as a gift from the wish list for {wishname}. However, because wish list gift purchases must be completed within {hours} hour(s), the item has been removed from your cart. If it is still available on the wish list, it can be re-added.', + array('{wishname}' => $item->wishlistItem->registry->customer->fullname, + '{product}' => $item->product->Title, + '{hours}' => $intResetHours) + ); $objMessage->save(); $item->wishlist_item = null; @@ -265,39 +279,33 @@ public static function GarbageCollect() { $objCart->updateTotal(); $objCart->save(); } - - - } - } } - - } - } + /** * Since Validate tests to make sure certain fields have values, populate requirements here such as the modified timestamp * @return boolean from parent */ protected function beforeValidate() { if ($this->isNewRecord) + { $this->created = new CDbExpression('NOW()'); - $this->modified = new CDbExpression('NOW()'); - + } + $this->modified = new CDbExpression('NOW()'); return parent::beforeValidate(); } protected function beforeSave() { - - if($this->event_date=='' || $this->event_date=='0000-00-00') + if($this->event_date == '' || $this->event_date == '0000-00-00') + { $this->event_date = null; - + } return parent::beforeSave(); - } public function __get($strName) { @@ -320,6 +328,4 @@ public function __get($strName) { } } } - - } diff --git a/core/protected/models/forms/LoginForm.php b/core/protected/models/forms/LoginForm.php index cfe5e5c9..f7e91d3a 100644 --- a/core/protected/models/forms/LoginForm.php +++ b/core/protected/models/forms/LoginForm.php @@ -12,12 +12,10 @@ class LoginForm extends CFormModel public $rememberMe = true; public $sharedLogin = false; - /** * Used in the new checkout to set the validation scenario * @var bool */ - public $guest = false; private $_identity; @@ -50,8 +48,8 @@ public function rules() public function attributeLabels() { return array( - 'email' => Yii::t('CheckoutForm','Email Address'), - 'password' => Yii::t('CheckoutForm','Password'), + 'email' => Yii::t('CheckoutForm', 'Email Address'), + 'password' => Yii::t('CheckoutForm', 'Password'), 'rememberMe' => 'Remember me next time', ); } @@ -62,40 +60,37 @@ public function attributeLabels() */ public function authenticate($attribute, $params) { - if(!$this->hasErrors()) + if (!$this->hasErrors()) { - $this->_identity=new UserIdentity($this->email,$this->password); - if(!$this->_identity->authenticate()) + $this->_identity = new UserIdentity($this->email, $this->password); + if (!$this->_identity->authenticate()) { switch ($this->_identity->errorCode) { case UserIdentity::ERROR_NOT_APPROVED: - $this->addError('password',Yii::t('global','Your account has not yet been approved.')); + $this->addError('password', Yii::t('global', 'Your account has not yet been approved.')); Yii::log("Denied: Unapproved user ".$this->email." attempted login", 'error', 'application.'.__CLASS__.".".__FUNCTION__); break; case UserIdentity::ERROR_PASSWORD_FACEBOOK: - $this->addError('password',Yii::t('global','Use Facebook Login.')); + $this->addError('password', Yii::t('global', 'Use Facebook Login.')); break; case UserIdentity::ERROR_PASSWORD_INVALID: - $this->addError('password',Yii::t('global','Incorrect password.')); + $this->addError('password', Yii::t('global', 'Incorrect password.')); Yii::log("Login denied: Incorrect password for ".$this->email." attempted login", 'error', 'application.'.__CLASS__.".".__FUNCTION__); break; case UserIdentity::ERROR_USERNAME_INVALID: - $this->addError('password',Yii::t('global','Unknown email address.')); + $this->addError('password', Yii::t('global', 'Unknown email address.')); Yii::log("Login denied: Unknown email address ".$this->email." attempted login", 'error', 'application.'.__CLASS__.".".__FUNCTION__); break; default: - $this->addError('password',Yii::t('global','Incorrect username or password.')); + $this->addError('password', Yii::t('global', 'Incorrect username or password.')); Yii::log("Login denied: Incorrect username or password for ".$this->email." attempted login", 'error', 'application.'.__CLASS__.".".__FUNCTION__); } - - } - } } @@ -105,27 +100,26 @@ public function authenticate($attribute, $params) */ public function login() { - if($this->_identity===null) + if ($this->_identity === null) { - $this->_identity=new UserIdentity($this->email,$this->password); + $this->_identity = new UserIdentity($this->email, $this->password); $this->_identity->authenticate(); } - if($this->_identity->errorCode===UserIdentity::ERROR_NONE) + if ($this->_identity->errorCode === UserIdentity::ERROR_NONE) { Yii::log("Login authentication passed ", 'info', 'application.'.__CLASS__.".".__FUNCTION__); - $duration=$this->rememberMe ? 3600*24*30 : 0 ; // true = 30 days, false=until browser close - Yii::app()->user->login($this->_identity,$duration); + $duration = $this->rememberMe ? 3600 * 24 * 30 : 0; // true = 30 days, false=until browser close + Yii::app()->user->login($this->_identity, $duration); //afterLogin() in WebUser class will restore prior cart if necessary return true; } else + { return false; - - - + } } /** @@ -134,63 +128,62 @@ public function login() */ public function loginadmin() { - if($this->_identity===null) + if($this->_identity === null) { - $this->_identity=new UserIdentity($this->email,$this->password); + $this->_identity = new UserIdentity($this->email, $this->password); $this->_identity->authenticate(); } - if($this->_identity->errorCode===UserIdentity::ERROR_NONE && $this->_identity->isAdmin) + + if($this->_identity->errorCode === UserIdentity::ERROR_NONE && $this->_identity->isAdmin) { - $duration=$this->rememberMe ? 3600*24*30 : 0 ; // true = 30 days, false=until browser close - Yii::app()->user->login($this->_identity,$duration); + $duration = $this->rememberMe ? 3600 * 24 * 30 : 0; // true = 30 days, false=until browser close + Yii::app()->user->login($this->_identity, $duration); return true; } else + { return false; - - - + } } /** * Logs in the user using the given username and password in the model. * @return boolean whether login is successful */ - public function loginLightspeed($username,$password) + public function loginLightspeed($username, $password) { - if($this->_identity===null) + if ($this->_identity === null) { - $this->_identity=new LSIdentity($username,$password); + $this->_identity = new LSIdentity($username, $password); $this->_identity->authenticate(); } - if($this->_identity->errorCode===UserIdentity::ERROR_NONE) - { - Yii::app()->user->login($this->_identity,1800); - + if ($this->_identity->errorCode === UserIdentity::ERROR_NONE) + { + Yii::app()->user->login($this->_identity, 1800); return true; } else + { return false; - - - + } } - /** - * Since Validate tests to make sure certain fields have values, populate requirements here such as the modified timestamp - * @return boolean from parent - */ - - protected function beforeValidate() { - - $this->email = strtolower($this->email); + /** + * Since Validate tests to make sure certain fields have values, populate requirements here such as the modified timestamp + * @return boolean from parent + */ + protected function beforeValidate() + { + $this->email = strtolower($this->email); - if ($this->getScenario() === '') - $this->setScenario('Existing'); + if ($this->getScenario() === '') + { + $this->setScenario('Existing'); + } - return parent::beforeValidate(); - } + return parent::beforeValidate(); + } } diff --git a/core/protected/modules/admin/controllers/SystemController.php b/core/protected/modules/admin/controllers/SystemController.php index d4efe354..28f4ea45 100644 --- a/core/protected/modules/admin/controllers/SystemController.php +++ b/core/protected/modules/admin/controllers/SystemController.php @@ -193,38 +193,27 @@ public function actionPurge() } + /** + * Erase carts that are over 30 days old, and don't have a customer_id + * associated with them, then optimize the tables related to the shopping + * cart experience. + */ public function actionErasecarts() { - - $sql = " - FROM xlsws_cart P, xlsws_cart_item C - WHERE - P.customer_id IS NULL AND - P.id = C.cart_id AND - P.cart_type IN (" . CartType::cart . "," . CartType::giftregistry . "," . CartType::awaitpayment . ") AND - P.modified < '".date("Y-m-d", strtotime("-".intval(_xls_get_conf('CART_LIFE' , 30))." DAYS"))."' AND - id_str IS NULL"; - - - $intIdStr = Yii::app()->db->createCommand("select count(*) ".$sql)->queryScalar(); - _dbx("set foreign_key_checks=0;"); - _dbx("DELETE P, C ".$sql); - - - _dbx("OPTIMIZE table xlsws_cart"); - _dbx("OPTIMIZE table xlsws_cart_item"); - _dbx("OPTIMIZE table xlsws_customer"); - _dbx("OPTIMIZE table xlsws_wish_list"); - _dbx("OPTIMIZE table xlsws_wish_list_items"); - _dbx("OPTIMIZE table xlsws_product"); - _dbx("OPTIMIZE table xlsws_product_related"); - _dbx("OPTIMIZE table xlsws_category"); - _dbx("OPTIMIZE table xlsws_product_category_assn"); - _dbx("set foreign_key_checks=1;"); - Yii::app()->user->setFlash('success',Yii::t('admin','{qty} old carts removed {time}.',array('{qty}'=>$intIdStr, '{time}'=>date("d F, Y h:i:sa")))); - + $numErased = ShoppingCart::eraseExpired(); + ShoppingCart::optimizeTables(); + Yii::app()->user->setFlash( + 'success', + Yii::t( + 'admin', + '{qty} old carts and cart items removed. {time}', + array( + '{qty}' => $numErased, + '{time}' => date("d F, Y h:i:sa") + ) + ) + ); $this->render("erasecarts"); - } public function sendEmailTest() @@ -249,4 +238,4 @@ public function sendEmailTest() } -} \ No newline at end of file +} diff --git a/core/protected/modules/admin/controllers/ThemeController.php b/core/protected/modules/admin/controllers/ThemeController.php index 83c37061..bfe86a97 100644 --- a/core/protected/modules/admin/controllers/ThemeController.php +++ b/core/protected/modules/admin/controllers/ThemeController.php @@ -106,11 +106,11 @@ public function actionManage() } - if (isset($_POST['yt1']) && $_POST['yt1']=="btnCopy") + if ((isset($_POST['yt1']) && $_POST['yt1'] == "btnCopy") || + (isset($_POST['task']) && $_POST['task'] === "btnCopy")) { $arrThemes = $this->changeTheme($_POST); $arrThemes = $this->copyThemeForCustomization($_POST); - } if (isset($_POST['yt0']) && $_POST['yt0']=="btnSet") diff --git a/core/protected/modules/admin/controllers/UpgradeController.php b/core/protected/modules/admin/controllers/UpgradeController.php index 6bda57b7..a234b8ef 100644 --- a/core/protected/modules/admin/controllers/UpgradeController.php +++ b/core/protected/modules/admin/controllers/UpgradeController.php @@ -378,8 +378,6 @@ public function actionDatabaseUpgrade($online=50, $total=100, $tag='') } - if(is_numeric($oXML->schema)) - _xls_set_conf('DATABASE_SCHEMA_VERSION',$oXML->schema); $oXML = $this->isDatabaseCurrent(true); @@ -417,12 +415,15 @@ protected function isDatabaseCurrent($blnCheckOnly=false) $storeurl = str_replace("https://","",$storeurl); $data['wdb'] = array( - 'schema' => _xls_get_conf('DATABASE_SCHEMA_VERSION'), + // Despite the DATABASE_SCHEMA_VERSION config key no longer existing, we must + // include the schema index key in the array since Updater is expecting it. + 'schema' => _xls_get_conf('DATABASE_SCHEMA_VERSION', 447), 'version' => XLSWS_VERSIONBUILD, 'customer' => $storeurl, - 'type' => (_xls_get_conf('LIGHTSPEED_HOSTING')==1 ? "hosted" : "self") + 'type' => (_xls_get_conf('LIGHTSPEED_HOSTING') == 1 ? "hosted" : "self") ); - if(Yii::app()->params['LIGHTSPEED_MT']=='1') + + if (Yii::app()->params['LIGHTSPEED_MT'] == '1') { //Since we could have two urls on multitenant, just grab the original one $data['customer']=Yii::app()->params['LIGHTSPEED_HOSTING_LIGHTSPEED_URL']; @@ -431,6 +432,7 @@ protected function isDatabaseCurrent($blnCheckOnly=false) $data['type']="mt-cloud"; } + $json = json_encode($data); $ch = curl_init($url); @@ -454,7 +456,9 @@ protected function isDatabaseCurrent($blnCheckOnly=false) $mixSchema = $oXML->wsdb->schema; if ($mixSchema != 'current') + { return $oXML->wsdb; + } $oXML->wsdb->changetype = "yii"; $oXML->wsdb->schema = Yii::t('admin','Updating Database'); //Just because this is displayed during an update @@ -469,11 +473,13 @@ protected function isDatabaseCurrent($blnCheckOnly=false) * New db update routine, this will become the only item in this function later * That's why we're just adding instead of calling another function */ - if(!$blnCheckOnly) + if (!$blnCheckOnly) { $strMigrationResults = _runMigrationTool(1); if (stripos($strMigrationResults, "No new migration found") > 0 ) + { $oXML->wsdb->schema = 'current'; + } } diff --git a/core/protected/modules/admin/views/system/info.php b/core/protected/modules/admin/views/system/info.php index d20ddb2d..da02a3d3 100644 --- a/core/protected/modules/admin/views/system/info.php +++ b/core/protected/modules/admin/views/system/info.php @@ -20,15 +20,6 @@

-
-
- -
-
- params['DATABASE_SCHEMA_VERSION']; ?> -
-
 
-
diff --git a/core/protected/modules/admin/views/theme/manage.php b/core/protected/modules/admin/views/theme/manage.php index b42af050..178cea21 100644 --- a/core/protected/modules/admin/views/theme/manage.php +++ b/core/protected/modules/admin/views/theme/manage.php @@ -70,12 +70,27 @@ 0): ?>

+ Warning: This functionality is intended for web developers only. " . + "Copying a theme for customization may require occasional updates to the custom theme files " . + "as Web Store updates are released. If you are not comfortable with updating CSS or PHP files " . + "as required, we highly recommend that you do not copy a theme."; + ?> + widget('bootstrap.widgets.TbButton', array( - 'buttonType'=>'submit', - 'label'=>'Copy selected theme for customization', - 'type'=>'inverse', - 'size'=>'mini', - 'htmlOptions'=>array('id'=>'btnCopy','value'=>'btnCopy'), + 'label' => 'Copy selected theme for customization', + 'type' => 'inverse', + 'size' => 'mini', + 'htmlOptions' => array( + 'id' => 'btnCopy', + 'value' => 'btnCopy', + 'onclick' => 'js:bootbox.confirm("'. $copyThemeWarningMsg . '", "Cancel", "Continue", function(confirmed) { + if(confirmed) + { + $("#task").val("btnCopy"); + $("#manage").submit(); + } + })'), )); ?> widget('bootstrap.widgets.TbButton', array( 'buttonType'=>'submit', @@ -109,4 +124,4 @@
-
\ No newline at end of file +
diff --git a/core/protected/views-cities3/myaccount/address.php b/core/protected/views-cities3/myaccount/address.php index aaf94b82..6d06d407 100644 --- a/core/protected/views-cities3/myaccount/address.php +++ b/core/protected/views-cities3/myaccount/address.php @@ -9,11 +9,10 @@ /* Create a new wish list form. We use the Checkout ID to reuse our CSS formatting */ ?>
beginWidget( + $form = $this->beginWidget( 'CActiveForm', array( - 'id'=>'wishlistdisplay', - 'enableClientValidation'=>true, - 'focus'=>array($model,'registry_name'), + 'id' => 'wishlistdisplay', + 'enableClientValidation' => true ) ); if ($model->id > 0) { diff --git a/core/protected/views-cities3/myaccount/edit.php b/core/protected/views-cities3/myaccount/edit.php index 655a140f..435f97f4 100644 --- a/core/protected/views-cities3/myaccount/edit.php +++ b/core/protected/views-cities3/myaccount/edit.php @@ -19,11 +19,11 @@
- beginWidget('CActiveForm', array( - 'id'=>'myaccount', - 'enableClientValidation'=>true, - 'focus'=>array($model,'first_name'), - )); + beginWidget('CActiveForm', array( + 'id' => 'myaccount', + 'enableClientValidation' => true + )); ?>
diff --git a/core/protected/views-cities3/myaccount/password.php b/core/protected/views-cities3/myaccount/password.php index efa5be96..95984350 100644 --- a/core/protected/views-cities3/myaccount/password.php +++ b/core/protected/views-cities3/myaccount/password.php @@ -2,11 +2,11 @@
- beginWidget('CActiveForm', array( - 'id'=>'myaccount', - 'enableClientValidation'=>true, - 'focus'=>array($model,'password') - )); + beginWidget('CActiveForm', array( + 'id' => 'myaccount', + 'enableClientValidation' => true + )); ?>
diff --git a/core/protected/views-cities3/search/index.php b/core/protected/views-cities3/search/index.php index bf61a519..b5a4411e 100644 --- a/core/protected/views-cities3/search/index.php +++ b/core/protected/views-cities3/search/index.php @@ -1,41 +1,41 @@

- beginWidget('CActiveForm', array( - 'id'=>'advancedsearch', - 'enableClientValidation'=>true, - 'focus'=>array($model,'q'), - )); + beginWidget('CActiveForm', array( + 'id' => 'advancedsearch', + 'enableClientValidation' => true + )); ?>
-
-
- label($model,'q'); ?> - textField($model,'q'); ?> - error($model,'q'); ?> -
-
+
+
+ label($model,'q'); ?> + textField($model,'q'); ?> + error($model,'q'); ?> +
+
-
-
- label($model,'startprice'); ?> - textField($model,'startprice'); ?> - error($model,'startprice'); ?> -
-
- label($model,'endprice'); ?> - textField($model,'endprice'); ?> - error($model,'endprice'); ?> -
-
+
+
+ label($model,'startprice'); ?> + textField($model,'startprice'); ?> + error($model,'startprice'); ?> +
+
+ label($model,'endprice'); ?> + textField($model,'endprice'); ?> + error($model,'endprice'); ?> +
+
-
-
- label($model,'cat'); ?> - dropDownList($model,'cat',Category::getTopLevelSearch(),array('prompt'=>Yii::t('global','All Categories'))); ?> - error($model,'cat'); ?> -
-
+
+
+ label($model,'cat'); ?> + dropDownList($model,'cat',Category::getTopLevelSearch(),array('prompt'=>Yii::t('global','All Categories'))); ?> + error($model,'cat'); ?> +
+
'btnSubmit')); ?> diff --git a/core/protected/views-cities3/site/login.php b/core/protected/views-cities3/site/login.php index 0f858d0e..b5652e90 100644 --- a/core/protected/views-cities3/site/login.php +++ b/core/protected/views-cities3/site/login.php @@ -16,11 +16,12 @@ )); ?>