From 9cb8c58d78e96017f2d15daacdf953085aa3ed04 Mon Sep 17 00:00:00 2001 From: skiv Date: Thu, 30 Aug 2012 01:32:52 +0400 Subject: [PATCH 01/85] Product classes list --- .dev/macro/core.php | 46 +--- .dev/macro/create-crud-list.php | 166 +------------ .../XLite/Controller/Admin/ProductClass.php | 84 ++----- .../XLite/Controller/Admin/ProductClasses.php | 90 ++++--- src/classes/XLite/Model/Repo/ProductClass.php | 104 ++++++++- .../ItemsList/ProductClass/Table.php} | 20 +- .../Model/ProductClass.php} | 60 +++-- .../View/ItemsList/Model/ProductClass.php | 174 ++++++++++++++ src/classes/XLite/View/Model/ProductClass.php | 117 ++++++++++ src/classes/XLite/View/ProductClass.php | 56 +++++ .../MainInput.php => ProductClasses.php} | 46 ++-- .../StickyPanel/ItemsList/ProductClass.php | 34 +++ .../main_input.tpl => product_class/body.tpl} | 7 +- src/skins/admin/en/product_class/style.css | 10 + src/skins/admin/en/product_classes/body.tpl | 12 + .../{list/parts/columns/main.tpl => list.tpl} | 10 +- .../admin/en/product_classes/list/body.tpl | 36 --- .../en/product_classes/list/css/style.css | 49 ---- .../product_classes/list/images/separator.png | Bin 122 -> 0 bytes .../en/product_classes/list/images/trash.png | Bin 487 -> 0 bytes .../en/product_classes/list/js/script.js | 221 ------------------ .../list/parts/columns/new.tpl | 17 -- .../list/parts/columns/remove.tpl | 17 -- src/skins/admin/en/product_classes/style.css | 14 ++ 24 files changed, 677 insertions(+), 713 deletions(-) rename src/classes/XLite/View/{ProductClass/AProductClass.php => Form/ItemsList/ProductClass/Table.php} (74%) rename src/classes/XLite/View/{ProductClass/ProductClassesList.php => Form/Model/ProductClass.php} (56%) create mode 100644 src/classes/XLite/View/ItemsList/Model/ProductClass.php create mode 100644 src/classes/XLite/View/Model/ProductClass.php create mode 100644 src/classes/XLite/View/ProductClass.php rename src/classes/XLite/View/{ProductClass/MainInput.php => ProductClasses.php} (59%) create mode 100644 src/classes/XLite/View/StickyPanel/ItemsList/ProductClass.php rename src/skins/admin/en/{product_classes/list/main_input.tpl => product_class/body.tpl} (67%) create mode 100644 src/skins/admin/en/product_class/style.css create mode 100644 src/skins/admin/en/product_classes/body.tpl rename src/skins/admin/en/product_classes/{list/parts/columns/main.tpl => list.tpl} (55%) delete mode 100644 src/skins/admin/en/product_classes/list/body.tpl delete mode 100644 src/skins/admin/en/product_classes/list/css/style.css delete mode 100644 src/skins/admin/en/product_classes/list/images/separator.png delete mode 100644 src/skins/admin/en/product_classes/list/images/trash.png delete mode 100644 src/skins/admin/en/product_classes/list/js/script.js delete mode 100644 src/skins/admin/en/product_classes/list/parts/columns/new.tpl delete mode 100644 src/skins/admin/en/product_classes/list/parts/columns/remove.tpl create mode 100644 src/skins/admin/en/product_classes/style.css diff --git a/.dev/macro/core.php b/.dev/macro/core.php index 4ad634daad..7433d15663 100644 --- a/.dev/macro/core.php +++ b/.dev/macro/core.php @@ -18,11 +18,9 @@ * * @category LiteCommerce * @author Creative Development LLC - * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * @see ____file_see____ - * @since 1.0.18 */ define('MACRO_START_DIR', getcwd()); @@ -52,8 +50,6 @@ * @param string $msg Error message * * @return void - * @see ____func_see____ - * @since 1.0.18 */ function macro_error($msg) { @@ -67,8 +63,6 @@ function macro_error($msg) * @param string $name Name * * @return string - * @see ____func_see____ - * @since 1.0.18 */ function macro_get_named_argument($name) { @@ -83,8 +77,6 @@ function macro_get_named_argument($name) * @param integer $number Index * * @return string - * @see ____func_see____ - * @since 1.0.18 */ function macro_get_plain_argument($number) { @@ -97,8 +89,6 @@ function macro_get_plain_argument($number) * @param string $path Path * * @return string - * @see ____func_see____ - * @since 1.0.18 */ function macro_convert_path_to_class_name($path) { @@ -111,8 +101,6 @@ function macro_convert_path_to_class_name($path) * @param string $class Class name * * @return string - * @see ____func_see____ - * @since 1.0.18 */ function macro_convert_class_name_to_path($class) { @@ -126,8 +114,6 @@ function macro_convert_class_name_to_path($class) * @param string $data File content * * @return void - * @see ____func_see____ - * @since 1.0.18 */ function macro_file_put_contents($path, $data) { @@ -146,8 +132,6 @@ function macro_file_put_contents($path, $data) * @param string $path path * * @return boolean - * @see ____func_see____ - * @since 1.0.18 */ function macro_is_entity($path) { @@ -162,8 +146,6 @@ function macro_is_entity($path) * @param string $moduleName Module name OPTIONAL * * @return string - * @see ____func_see____ - * @since 1.0.24 */ function macro_assemble_class_name($suffix, $moduleAuthor = null, $moduleName = null) { @@ -180,8 +162,6 @@ function macro_assemble_class_name($suffix, $moduleAuthor = null, $moduleName = * @param string $moduleName Module name OPTIONAL * * @return string - * @see ____func_see____ - * @since 1.0.24 */ function macro_assemble_tpl_name($suffix, $moduleAuthor = null, $moduleName = null) { @@ -196,8 +176,6 @@ function macro_assemble_tpl_name($suffix, $moduleAuthor = null, $moduleName = nu * @param string $class Class full name * * @return string - * @see ____func_see____ - * @since 1.0.24 */ function macro_get_class_short_name($class) { @@ -212,8 +190,6 @@ function macro_get_class_short_name($class) * @param string $camel Camel case string * * @return string - * @see ____func_see____ - * @since 1.0.24 */ function macro_convert_camel_to_human_readable($camel) { @@ -233,8 +209,6 @@ function macro_convert_camel_to_human_readable($camel) * @param string &$path Path * * @return void - * @see ____func_see____ - * @since 1.0.18 */ function macro_check_file_path(&$path) { @@ -255,8 +229,6 @@ function macro_check_file_path(&$path) * @param string $path Path * * @return void - * @see ____func_see____ - * @since 1.0.18 */ function macro_check_class_file_path($path) { @@ -273,8 +245,6 @@ function macro_check_class_file_path($path) * @param string &$class Class * * @return void - * @see ____func_see____ - * @since 1.0.18 */ function macro_check_class(&$class) { @@ -290,8 +260,6 @@ function macro_check_class(&$class) * @param string $module Name * * @return void - * @see ____func_see____ - * @since 1.0.18 */ function macro_check_module($author, $module) { @@ -315,8 +283,6 @@ function macro_check_module($author, $module) * @param string $path Path * * @return string - * @see ____func_see____ - * @since 1.0.18 */ function macro_get_file_header($path) { @@ -341,11 +307,9 @@ function macro_get_file_header($path) * * @category LiteCommerce * @author Creative Development LLC - * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * @see ____file_see____ - * @since 1.0.0 */ @@ -358,8 +322,6 @@ function macro_get_file_header($path) * @param string $path Path * * @return string - * @see ____func_see____ - * @since 1.0.18 */ function macro_get_class_repo_header($path) { @@ -381,8 +343,6 @@ function macro_get_class_repo_header($path) * @param string $path Path * * @return string - * @see ____func_see____ - * @since 1.0.18 */ function macro_get_class_header($path) { @@ -396,8 +356,6 @@ function macro_get_class_header($path) /** * Abstract widget * - * @see ____class_see____ - * @since 1.0.0 */ HEAD; } diff --git a/.dev/macro/create-crud-list.php b/.dev/macro/create-crud-list.php index 4893b7f681..c5ba1623d3 100755 --- a/.dev/macro/create-crud-list.php +++ b/.dev/macro/create-crud-list.php @@ -19,11 +19,9 @@ * * @category LiteCommerce * @author Creative Development LLC - * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * @see ____file_see____ - * @since 1.0.0 */ /** @@ -225,8 +223,6 @@ function($var) use ($targetOneControllerPath) { /** * $targetHumanReadableName controller * - * @see ____class_see____ - * @since 1.0.0 */ class $targetShort extends \\XLite\\Controller\\Admin\\AAdmin { @@ -240,8 +236,6 @@ class $targetShort extends \\XLite\\Controller\\Admin\\AAdmin * Update list * * @return void - * @see ____func_see____ - * @since 1.0.0 */ protected function doActionUpdate() { @@ -262,8 +256,6 @@ protected function doActionUpdate() * @param string \$paramName Parameter name * * @return mixed - * @see ____func_see____ - * @since 1.0.0 */ public function getCondition(\$paramName) { @@ -278,8 +270,6 @@ public function getCondition(\$paramName) * Save search conditions * * @return void - * @see ____func_see____ - * @since 1.0.0 */ protected function doActionSearch() { @@ -292,8 +282,6 @@ protected function doActionSearch() * Return search parameters * * @return array - * @see ____func_see____ - * @since 1.0.0 */ protected function getSearchParams() { @@ -314,8 +302,6 @@ protected function getSearchParams() * Get search conditions * * @return array - * @see ____func_see____ - * @since 1.0.0 */ protected function getConditions() { @@ -358,8 +344,6 @@ protected function getConditions() /** * $targetHumanReadableName page view * - * @see ____class_see____ - * @since 1.0.0 * * @ListChild (list="admin.center", zone="admin") */ @@ -369,8 +353,6 @@ class $targetShort extends \\XLite\\View\\AView * Return list of allowed targets * * @return array - * @see ____func_see____ - * @since 1.0.0 */ public static function getAllowedTargets() { @@ -381,8 +363,6 @@ public static function getAllowedTargets() * Return widget default template * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getDefaultTemplate() { @@ -393,8 +373,6 @@ protected function getDefaultTemplate() * Check - search box is visible or not * * @return boolean - * @see ____func_see____ - * @since 1.0.0 */ protected function isSearchVisible() { @@ -424,10 +402,9 @@ protected function isSearchVisible() * $targetHumanReadableName page template * * @author Creative Development LLC - * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * @since 1.0.0 *} @@ -467,10 +444,9 @@ protected function isSearchVisible() * $targetHumanReadableName list search template * * @author Creative Development LLC - * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * @since 1.0.0 *} @@ -498,8 +474,6 @@ protected function isSearchVisible() /** * $targetHumanReadableName list search form * - * @see ____class_see____ - * @since 1.0.0 */ class $formListSearchClassShort extends \\XLite\\View\\Form\\AForm { @@ -507,8 +481,6 @@ class $formListSearchClassShort extends \\XLite\\View\\Form\\AForm * Return default value for the "target" parameter * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getDefaultTarget() { @@ -519,8 +491,6 @@ protected function getDefaultTarget() * Return default value for the "action" parameter * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getDefaultAction() { @@ -555,10 +525,9 @@ protected function getDefaultAction() * $fieldHumanReadable condition * * @author Creative Development LLC - * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * @since 1.0.0 * * @ListChild (list="$itemsListViewList.search.conditions", weight="$weight") *} @@ -586,10 +555,9 @@ protected function getDefaultAction() * Search button * * @author Creative Development LLC - * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * @since 1.0.0 * * @ListChild (list="$itemsListViewList.search.conditions", weight="last") *} @@ -621,10 +589,9 @@ protected function getDefaultAction() * $targetHumanReadableName list table template * * @author Creative Development LLC - * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * @since 1.0.0 *} @@ -650,8 +617,6 @@ protected function getDefaultAction() /** * $targetHumanReadableName list table form * - * @see ____class_see____ - * @since 1.0.0 */ class $formListTableClassShort extends \\XLite\\View\\Form\\ItemsList\\AItemsList { @@ -659,8 +624,6 @@ class $formListTableClassShort extends \\XLite\\View\\Form\\ItemsList\\AItemsLis * Return default value for the "target" parameter * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getDefaultTarget() { @@ -671,8 +634,6 @@ protected function getDefaultTarget() * Return default value for the "action" parameter * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getDefaultAction() { @@ -701,8 +662,6 @@ protected function getDefaultAction() /** * $targetHumanReadableName items list * - * @see ____class_see____ - * @since 1.0.0 */ class $itemsListClassShort extends \\XLite\\View\\ItemsList\\Model\\Table { @@ -745,8 +704,6 @@ class $itemsListClassShort extends \\XLite\\View\\ItemsList\\Model\\Table * Get a list of CSS files required to display the widget properly * * @return array - * @see ____func_see____ - * @since 1.0.0 */ public function getCSSFiles() { @@ -769,8 +726,6 @@ public function getCSSFiles() * Define widget parameters * * @return void - * @see ____func_see____ - * @since 1.0.0 */ protected function defineWidgetParams() { @@ -801,8 +756,6 @@ protected function defineWidgetParams() * Define columns structure * * @return array - * @see ____func_see____ - * @since 1.0.0 */ protected function defineColumns() { @@ -843,8 +796,6 @@ protected function defineColumns() * Define repository name * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function defineRepositoryName() { @@ -860,8 +811,6 @@ protected function defineRepositoryName() * Get create entity URL * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getCreateURL() { @@ -878,8 +827,6 @@ protected function getCreateURL() * Get create button label * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getCreateButtonLabel() { @@ -895,8 +842,6 @@ protected function getCreateButtonLabel() * Inline creation mechanism position * * @return integer - * @see ____func_see____ - * @since 1.0.0 */ protected function isInlineCreation() { @@ -924,8 +869,6 @@ protected function isInlineCreation() * Mark list as removable * * @return boolean - * @see ____func_see____ - * @since 1.0.0 */ protected function isRemoved() { @@ -942,8 +885,6 @@ protected function isRemoved() * Mark list as switchyabvle (enable / disable) * * @return boolean - * @see ____func_see____ - * @since 1.0.0 */ protected function isSwitchable() { @@ -960,8 +901,6 @@ protected function isSwitchable() * Mark list as sortable * * @return integer - * @see ____func_see____ - * @since 1.0.0 */ protected function getSortableType() { @@ -989,8 +928,6 @@ protected function getSortableType() * Get container class * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getContainerClass() { @@ -1008,8 +945,6 @@ protected function getContainerClass() * Get panel class * * @return \XLite\View\Base\FormStickyPanel - * @see ____func_see____ - * @since 1.0.0 */ protected function getPanelClass() { @@ -1027,8 +962,6 @@ protected function getPanelClass() * Return class name for the list pager * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getPagerClass() { @@ -1048,8 +981,6 @@ protected function getPagerClass() * Return search parameters. * * @return array - * @see ____func_see____ - * @since 1.0.0 */ static public function getSearchParams() { @@ -1076,8 +1007,6 @@ static public function getSearchParams() * Define so called "request" parameters * * @return void - * @see ____func_see____ - * @since 1.0.0 */ protected function defineRequestParams() { @@ -1102,8 +1031,6 @@ protected function defineRequestParams() * TODO refactor * * @return \XLite\Core\CommonCell - * @see ____func_see____ - * @since 1.0.0 */ protected function getSearchCondition() { @@ -1142,10 +1069,9 @@ protected function getSearchCondition() * $targetHumanReadableName list styles * * @author Creative Development LLC - * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * @since 1.0.0 */ CODE; @@ -1170,8 +1096,6 @@ protected function getSearchCondition() /** * $targetHumanReadableName items list's sticky panel * - * @see ____class_see____ - * @since 1.0.0 */ class $itemsListPanelClassShort extends \\XLite\\View\\StickyPanel\\ItemsListForm { @@ -1206,8 +1130,6 @@ class $itemsListPanelClassShort extends \\XLite\\View\\StickyPanel\\ItemsListFor /** * $targetHumanReadableName repository * - * @see ____class_see____ - * @since 1.0.0 */ class $entityRepoClassShort extends $entityRepoParentClass { @@ -1257,8 +1179,6 @@ class $entityRepoClassShort extends $entityRepoParentClass * @param boolean \$countOnly "Count only" flag. Do not need to add "order by" clauses if only count is needed. * * @return void - * @see ____func_see____ - * @since 1.0.0 */ protected function prepareCnd$fieldUpper(\Doctrine\ORM\QueryBuilder \$queryBuilder, \$value, \$countOnly) { @@ -1287,8 +1207,6 @@ protected function prepareCnd$fieldUpper(\Doctrine\ORM\QueryBuilder \$queryBuild * @param array \$value Condition data * * @return void - * @see ____func_see____ - * @since 1.0.0 */ protected function prepareCndLimit(\Doctrine\ORM\QueryBuilder \$queryBuilder, array \$value) { @@ -1316,8 +1234,6 @@ protected function prepareCndLimit(\Doctrine\ORM\QueryBuilder \$queryBuilder, ar * @param boolean \$countOnly "Count only" flag. Do not need to add "order by" clauses if only count is needed. * * @return void - * @see ____func_see____ - * @since 1.0.0 */ protected function prepareCndOrderBy(\Doctrine\ORM\QueryBuilder \$queryBuilder, \$value, \$countOnly) { @@ -1350,8 +1266,6 @@ protected function prepareCndOrderBy(\Doctrine\ORM\QueryBuilder \$queryBuilder, * @param boolean \$countOnly Return items list or only its size OPTIONAL * * @return \Doctrine\ORM\PersistentCollection|integer - * @see ____func_see____ - * @since 1.0.0 */ public function search(\XLite\Core\CommonCell \$cnd, \$countOnly = false) { @@ -1373,8 +1287,6 @@ public function search(\XLite\Core\CommonCell \$cnd, \$countOnly = false) * @param \Doctrine\ORM\QueryBuilder \$qb Query builder routine * * @return \Doctrine\ORM\PersistentCollection|integer - * @see ____func_see____ - * @since 1.0.0 */ public function searchCount(\Doctrine\ORM\QueryBuilder \$qb) { @@ -1389,8 +1301,6 @@ public function searchCount(\Doctrine\ORM\QueryBuilder \$qb) * @param \Doctrine\ORM\QueryBuilder \$qb Query builder routine * * @return \Doctrine\ORM\PersistentCollection|integer - * @see ____func_see____ - * @since 1.0.0 */ public function searchResult(\Doctrine\ORM\QueryBuilder \$qb) { @@ -1406,8 +1316,6 @@ public function searchResult(\Doctrine\ORM\QueryBuilder \$qb) * @param boolean \$countOnly Count only flag * * @return void - * @see ____func_see____ - * @since 1.0.0 */ protected function callSearchConditionHandler(\$value, \$key, \Doctrine\ORM\QueryBuilder \$queryBuilder, \$countOnly) { @@ -1422,8 +1330,6 @@ protected function callSearchConditionHandler(\$value, \$key, \Doctrine\ORM\Quer * @param string \$param Name of param to check * * @return boolean - * @see ____func_see____ - * @since 1.0.0 */ protected function isSearchParamHasHandler(\$param) { @@ -1434,8 +1340,6 @@ protected function isSearchParamHasHandler(\$param) * Return list of handling search params * * @return array - * @see ____func_see____ - * @since 1.0.0 */ protected function getHandlingSearchParams() { @@ -1473,8 +1377,6 @@ protected function getHandlingSearchParams() /** * $targetHumanReadableName menu item * - * @see ____class_see____ - * @since 1.0.0 * * @ListChild (list="$menuList", weight="last", zone="admin") */ @@ -1484,8 +1386,6 @@ class $menuShortClass extends \\XLite\\View\\TopMenu\\Node\\$menuParent\\A$menuP * Define widget parameters * * @return void - * @see ____func_see____ - * @since 1.0.0 */ protected function defineWidgetParams() { @@ -1522,17 +1422,13 @@ protected function defineWidgetParams() /** * $targetOneHumanReadableName controller * - * @see ____class_see____ - * @since 1.0.0 */ class $targetOneShort extends \\XLite\\Controller\\Admin\\AAdmin { /** * Controller parameters * - * @var array - * @see ____var_see____ - * @since 1.0.0 + * @var array */ protected \$params = array('target', 'id'); @@ -1540,8 +1436,6 @@ class $targetOneShort extends \\XLite\\Controller\\Admin\\AAdmin * Return the current page title (for the content area) * * @return string - * @see ____func_see____ - * @since 1.0.0 */ public function getTitle() { @@ -1559,8 +1453,6 @@ public function getTitle() * Update model * * @return void - * @see ____func_see____ - * @since 1.0.0 */ protected function doActionUpdate() { @@ -1573,8 +1465,6 @@ protected function doActionUpdate() * Get model form class * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getModelFormClass() { @@ -1603,8 +1493,6 @@ protected function getModelFormClass() /** * $targetOneHumanReadableName page view * - * @see ____class_see____ - * @since 1.0.0 * * @ListChild (list="admin.center", zone="admin") */ @@ -1614,8 +1502,6 @@ class $targetOneShort extends \\XLite\\View\\AView * Return list of allowed targets * * @return array - * @see ____func_see____ - * @since 1.0.0 */ public static function getAllowedTargets() { @@ -1626,8 +1512,6 @@ public static function getAllowedTargets() * Return widget default template * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getDefaultTemplate() { @@ -1655,10 +1539,9 @@ protected function getDefaultTemplate() * $targetOneHumanReadableName page template * * @author Creative Development LLC - * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * @since 1.0.0 *} CODE; @@ -1684,17 +1567,13 @@ protected function getDefaultTemplate() /** * $targetOneHumanReadableName view model * - * @see ____class_see____ - * @since 1.0.0 */ class $oneViewModelClassShort extends \\XLite\\View\\Model\\AModel { /** * Shema default * - * @var array - * @see ____var_see____ - * @since 1.0.0 + * @var array */ protected \$schemaDefault = array( @@ -1733,8 +1612,6 @@ class $oneViewModelClassShort extends \\XLite\\View\\Model\\AModel * Return current model ID * * @return integer - * @see ____func_see____ - * @since 1.0.0 */ public function getModelId() { @@ -1745,8 +1622,6 @@ public function getModelId() * This object will be used if another one is not pased * * @return \\$entityClass - * @see ____func_see____ - * @since 1.0.0 */ protected function getDefaultModelObject() { @@ -1761,8 +1636,6 @@ protected function getDefaultModelObject() * Return name of web form widget class * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getFormClass() { @@ -1773,8 +1646,6 @@ protected function getFormClass() * Return list of the "Button" widgets * * @return array - * @see ____func_see____ - * @since 1.0.0 */ protected function getFormButtons() { @@ -1796,8 +1667,6 @@ protected function getFormButtons() * Add top message * * @return void - * @see ____func_see____ - * @since 1.0.0 */ protected function addDataSavedTopMessage() { @@ -1833,8 +1702,6 @@ protected function addDataSavedTopMessage() /** * $targetHumanReadableName list search form * - * @see ____class_see____ - * @since 1.0.0 */ class $formOneClassShort extends \\XLite\\View\\Form\\AForm { @@ -1842,8 +1709,6 @@ class $formOneClassShort extends \\XLite\\View\\Form\\AForm * Register CSS files * * @return array - * @see ____func_see____ - * @since 1.0.0 */ public function getCSSFiles() { @@ -1858,8 +1723,6 @@ public function getCSSFiles() * Return default value for the "target" parameter * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getDefaultTarget() { @@ -1870,8 +1733,6 @@ protected function getDefaultTarget() * Return default value for the "action" parameter * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getDefaultAction() { @@ -1882,8 +1743,6 @@ protected function getDefaultAction() * Get default class name * * @return string - * @see ____func_see____ - * @since 1.0.0 */ protected function getDefaultClassName() { @@ -1894,8 +1753,6 @@ protected function getDefaultClassName() * Return list of the form default parameters * * @return array - * @see ____func_see____ - * @since 1.0.0 */ protected function getDefaultParams() { @@ -1924,10 +1781,9 @@ protected function getDefaultParams() * $targetOneHumanReadableName view model styles * * @author Creative Development LLC - * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * @since 1.0.0 */ CODE; diff --git a/src/classes/XLite/Controller/Admin/ProductClass.php b/src/classes/XLite/Controller/Admin/ProductClass.php index f30c41134f..cc3430ed94 100644 --- a/src/classes/XLite/Controller/Admin/ProductClass.php +++ b/src/classes/XLite/Controller/Admin/ProductClass.php @@ -32,22 +32,11 @@ class ProductClass extends \XLite\Controller\Admin\AAdmin { /** - * Constants - */ - const STATUS_ERROR = 'error'; - const STATUS_INAPPLY = 'inapply'; - const STATUS_SUCCESS = 'success'; - const STATUS_FAILED = 'failed'; - - /** - * data + * Controller parameters * * @var array */ - protected $data = array( - 'status' => self::STATUS_ERROR, - 'data' => '', - ); + protected $params = array('target', 'id'); /** * Check ACL permissions @@ -60,71 +49,42 @@ public function checkACL() } /** - * Remove product class + * Return the current page title (for the content area) * - * @return void + * @return string */ - protected function doActionRemove() + public function getTitle() { - if (isset(\XLite\Core\Request::getInstance()->id)) { - \XLite\Core\Database::getRepo('\XLite\Model\ProductClass')->deleteById( - \XLite\Core\Request::getInstance()->id - ); - } - - $this->setReturnURL($this->buildURL('product_classes')); + $id = intval(\XLite\Core\Request::getInstance()->id); + $model = $id + ? \XLite\Core\Database::getRepo('XLite\Model\ProductClass')->find($id) + : null; + + return ($model && $model->getId()) + ? $model->getName() + : \XLite\Core\Translation::getInstance()->lbl('ProductClass'); } /** - * AJAX product class update + * Update model * * @return void */ protected function doActionUpdate() { - $data = array( - 'name' => \XLite\Core\Request::getInstance()->name, - ); - - \XLite\Core\Database::getRepo('\XLite\Model\ProductClass')->updateById( - \XLite\Core\Request::getInstance()->id, - $data - ); + if ($this->getModelForm()->performAction('modify')) { + $this->setReturnUrl(\XLite\Core\Converter::buildURL('product_classes')); + } } /** - * AJAX product class adding - * - * @return void + * Get model form class + * + * @return string */ - protected function doActionAdd() + protected function getModelFormClass() { - $data = new \XLite\Model\ProductClass(); - $data->setName(\XLite\Core\Request::getInstance()->name); - - $data = \XLite\Core\Database::getRepo('\XLite\Model\ProductClass')->insert($data); - - $this->data['data'] = array( - 'id' => $data->getId(), - 'name' => $data->getName(), - ); - - $this->data['status'] = static::STATUS_SUCCESS; + return 'XLite\View\Model\ProductClass'; } - /** - * Send JSON data after "ADD" action - * - * @return void - */ - protected function actionPostprocessAdd() - { - header('Content-type: application/json'); - $data = json_encode($this->data); - header('Content-Length: ' . strlen($data)); - - echo ($data); - - exit (0); - } } diff --git a/src/classes/XLite/Controller/Admin/ProductClasses.php b/src/classes/XLite/Controller/Admin/ProductClasses.php index 8757fc66c5..8e98604fa8 100644 --- a/src/classes/XLite/Controller/Admin/ProductClasses.php +++ b/src/classes/XLite/Controller/Admin/ProductClasses.php @@ -26,63 +26,101 @@ namespace XLite\Controller\Admin; /** - * Product classes + * Product classes controller * */ class ProductClasses extends \XLite\Controller\Admin\AAdmin { + /** - * Field name for new 'name' value + * Check ACL permissions + * + * @return boolean */ - const NEW_NAME = 'new_name'; + public function checkACL() + { + return parent::checkACL() || \XLite\Core\Auth::getInstance()->isPermissionAllowed('manage catalog'); + } /** - * Field name for 'name' array values + * Update list + * + * @return void */ - const NAME = 'name'; + protected function doActionUpdate() + { + $list = new \XLite\View\ItemsList\Model\ProductClass; + $list->processQuick(); + } + // {{{ Search /** - * Check ACL permissions + * Get search condition parameter by name * - * @return boolean + * @param string $paramName Parameter name + * + * @return mixed */ - public function checkACL() + public function getCondition($paramName) { - return parent::checkACL() || \XLite\Core\Auth::getInstance()->isPermissionAllowed('manage catalog'); + $searchParams = $this->getConditions(); + + return isset($searchParams[$paramName]) + ? $searchParams[$paramName] + : null; } /** - * Update action + * Save search conditions * * @return void */ - protected function doActionUpdate() + protected function doActionSearch() { - $data = $this->getPostedData(); + $cellName = \XLite\View\ItemsList\Model\ProductClass::getSessionCellName(); - if (!empty($data[static::NEW_NAME])) { - $this->addClass($data[static::NEW_NAME]); - } + \XLite\Core\Session::getInstance()->$cellName = $this->getSearchParams(); + } - if (isset($data[static::NEW_NAME])) { - unset($data[static::NEW_NAME]); - } + /** + * Return search parameters + * + * @return array + */ + protected function getSearchParams() + { + $searchParams = $this->getConditions(); - if (!empty($data)) { - \XLite\Core\Database::getRepo('\XLite\Model\ProductClass')->updateInBatchById($data); + foreach ( + \XLite\View\ItemsList\Model\ProductClass::getSearchParams() as $requestParam + ) { + if (isset(\XLite\Core\Request::getInstance()->$requestParam)) { + $searchParams[$requestParam] = \XLite\Core\Request::getInstance()->$requestParam; + } } + + return $searchParams; } /** - * Add product class entry - * - * @param string $name Name value + * Get search conditions * - * @return void + * @return array */ - protected function addClass($name) + protected function getConditions() { - \XLite\Core\Database::getRepo('\XLite\Model\ProductClass')->insert(array(static::NAME => strval($name))); + $cellName = \XLite\View\ItemsList\Model\ProductClass::getSessionCellName(); + + $searchParams = \XLite\Core\Session::getInstance()->$cellName; + + if (!is_array($searchParams)) { + $searchParams = array(); + } + + return $searchParams; } + + // }}} + } diff --git a/src/classes/XLite/Model/Repo/ProductClass.php b/src/classes/XLite/Model/Repo/ProductClass.php index 580fdd9c9b..869f0952ad 100644 --- a/src/classes/XLite/Model/Repo/ProductClass.php +++ b/src/classes/XLite/Model/Repo/ProductClass.php @@ -18,17 +18,115 @@ * * @category LiteCommerce * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ + * @see ____file_see____ + * @since 1.0.0 */ namespace XLite\Model\Repo; /** - * The product classes model repository + * Product classes repository * */ class ProductClass extends \XLite\Model\Repo\Base\I18n { -} + + // {{{ Search + + + /** + * Common search + * + * @param \XLite\Core\CommonCell $cnd Search condition + * @param boolean $countOnly Return items list or only its size OPTIONAL + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function search(\XLite\Core\CommonCell $cnd, $countOnly = false) + { + $queryBuilder = $this->createQueryBuilder('p'); + $this->currentSearchCnd = $cnd; + + foreach ($this->currentSearchCnd as $key => $value) { + $this->callSearchConditionHandler($value, $key, $queryBuilder, $countOnly); + } + + return $countOnly + ? $this->searchCount($queryBuilder) + : $this->searchResult($queryBuilder); + } + + /** + * Search count only routine. + * + * @param \Doctrine\ORM\QueryBuilder $qb Query builder routine + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function searchCount(\Doctrine\ORM\QueryBuilder $qb) + { + $qb->select('COUNT(DISTINCT p.id)'); + + return intval($qb->getSingleScalarResult()); + } + + /** + * Search result routine. + * + * @param \Doctrine\ORM\QueryBuilder $qb Query builder routine + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function searchResult(\Doctrine\ORM\QueryBuilder $qb) + { + return $qb->getResult(); + } + + /** + * Call corresponded method to handle a search condition + * + * @param mixed $value Condition data + * @param string $key Condition name + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param boolean $countOnly Count only flag + * + * @return void + */ + protected function callSearchConditionHandler($value, $key, \Doctrine\ORM\QueryBuilder $queryBuilder, $countOnly) + { + if ($this->isSearchParamHasHandler($key)) { + $this->{'prepareCnd' . ucfirst($key)}($queryBuilder, $value, $countOnly); + } + } + + /** + * Check if param can be used for search + * + * @param string $param Name of param to check + * + * @return boolean + */ + protected function isSearchParamHasHandler($param) + { + return in_array($param, $this->getHandlingSearchParams()); + } + + /** + * Return list of handling search params + * + * @return array + */ + protected function getHandlingSearchParams() + { + return array( + + ); + } + + + // }}} + +} \ No newline at end of file diff --git a/src/classes/XLite/View/ProductClass/AProductClass.php b/src/classes/XLite/View/Form/ItemsList/ProductClass/Table.php similarity index 74% rename from src/classes/XLite/View/ProductClass/AProductClass.php rename to src/classes/XLite/View/Form/ItemsList/ProductClass/Table.php index 5a8e30a50d..1543aac31e 100644 --- a/src/classes/XLite/View/ProductClass/AProductClass.php +++ b/src/classes/XLite/View/Form/ItemsList/ProductClass/Table.php @@ -23,31 +23,31 @@ * @link http://www.litecommerce.com/ */ -namespace XLite\View\ProductClass; +namespace XLite\View\Form\ItemsList\ProductClass; /** - * Product class + * Product classes list table form * */ -abstract class AProductClass extends \XLite\View\Dialog +class Table extends \XLite\View\Form\ItemsList\AItemsList { /** - * Return title + * Return default value for the "target" parameter * * @return string */ - protected function getHead() + protected function getDefaultTarget() { - return 'Product classes'; + return 'product_classes'; } /** - * Return templates directory + * Return default value for the "action" parameter * * @return string */ - protected function getDir() + protected function getDefaultAction() { - return 'product_classes'; + return 'update'; } -} +} \ No newline at end of file diff --git a/src/classes/XLite/View/ProductClass/ProductClassesList.php b/src/classes/XLite/View/Form/Model/ProductClass.php similarity index 56% rename from src/classes/XLite/View/ProductClass/ProductClassesList.php rename to src/classes/XLite/View/Form/Model/ProductClass.php index 52cc5c7f2c..2f83ce9b9f 100644 --- a/src/classes/XLite/View/ProductClass/ProductClassesList.php +++ b/src/classes/XLite/View/Form/Model/ProductClass.php @@ -23,76 +23,68 @@ * @link http://www.litecommerce.com/ */ -namespace XLite\View\ProductClass; +namespace XLite\View\Form\Model; /** - * Product classes list + * Product classes list search form * - * - * @ListChild (list="admin.center", zone="admin") */ -class ProductClassesList extends AProductClass +class ProductClass extends \XLite\View\Form\AForm { /** - * Return allowed targets + * Register CSS files * * @return array */ - public static function getAllowedTargets() + public function getCSSFiles() { - $result = parent::getAllowedTargets(); + $list = parent::getCSSFiles(); - $result[] = 'product_classes'; + $list[] = 'product_class/style.css'; - return $result; + return $list; } /** - * Return CSS files list for widget + * Return default value for the "target" parameter * - * @return array + * @return string */ - public function getCSSFiles() + protected function getDefaultTarget() { - $list = parent::getCSSFiles(); - - $list[] = $this->getDir() . LC_DS . 'css' . LC_DS . 'style.css'; - - return $list; + return 'product_class'; } /** - * Return JS files list for widget + * Return default value for the "action" parameter * - * @return void + * @return string */ - public function getJSFiles() + protected function getDefaultAction() { - $list = parent::getJSFiles(); - - $list[] = $this->getDir() . LC_DS . 'js' . LC_DS . 'script.js'; - - return $list; + return 'update'; } - /** - * Return templates catalog + * Get default class name * * @return string */ - protected function getDir() + protected function getDefaultClassName() { - return parent::getDir() . LC_DS . 'list'; + return trim(parent::getDefaultClassName() . ' validationEngine product-class'); } /** - * Return data + * Return list of the form default parameters * * @return array */ - protected function getData() + protected function getDefaultParams() { - return \XLite\Core\Database::getRepo('\XLite\Model\ProductClass')->findAll(); + return array( + 'id' => \XLite\Core\Request::getInstance()->id, + ); } -} + +} \ No newline at end of file diff --git a/src/classes/XLite/View/ItemsList/Model/ProductClass.php b/src/classes/XLite/View/ItemsList/Model/ProductClass.php new file mode 100644 index 0000000000..db8fc75bb3 --- /dev/null +++ b/src/classes/XLite/View/ItemsList/Model/ProductClass.php @@ -0,0 +1,174 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\ItemsList\Model; + +/** + * Product classes items list + * + */ +class ProductClass extends \XLite\View\ItemsList\Model\Table +{ + /** + * Get a list of CSS files required to display the widget properly + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = 'product_classes/style.css'; + + return $list; + } + + /** + * Define columns structure + * + * @return array + */ + protected function defineColumns() + { + return array( + 'name' => array( + static::COLUMN_NAME => \XLite\Core\Translation::lbl('Name'), + static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text', + static::COLUMN_PARAMS => array('required' => true), + ), + ); + } + + /** + * Define repository name + * + * @return string + */ + protected function defineRepositoryName() + { + return 'XLite\Model\ProductClass'; + } + + /** + * Get create entity URL + * + * @return string + */ + protected function getCreateURL() + { + return \XLite\Core\Converter::buildUrl('product_class'); + } + + /** + * Get create button label + * + * @return string + */ + protected function getCreateButtonLabel() + { + return 'New product class'; + } + + /** + * Inline creation mechanism position + * + * @return integer + */ + protected function isInlineCreation() + { + return static::CREATE_INLINE_TOP; + } + + + // {{{ Behaviors + + /** + * Mark list as removable + * + * @return boolean + */ + protected function isRemoved() + { + return true; + } + + // }}} + + /** + * Get container class + * + * @return string + */ + protected function getContainerClass() + { + return parent::getContainerClass() . ' product_classes'; + } + + /** + * Get panel class + * + * @return \XLite\View\Base\FormStickyPanel + */ + protected function getPanelClass() + { + return 'XLite\View\StickyPanel\ItemsList\ProductClass'; + } + + + // {{{ Search + + /** + * Return search parameters. + * + * @return array + */ + static public function getSearchParams() + { + return array( ); + } + + /** + * Return params list to use for search + * + * @return \XLite\Core\CommonCell + */ + protected function getSearchCondition() + { + $result = parent::getSearchCondition(); + + foreach (static::getSearchParams() as $modelParam => $requestParam) { + $paramValue = $this->getParam($requestParam); + + if ('' !== $paramValue && 0 !== $paramValue) { + $result->$modelParam = $paramValue; + } + } + + return $result; + } + + // }}} + +} diff --git a/src/classes/XLite/View/Model/ProductClass.php b/src/classes/XLite/View/Model/ProductClass.php new file mode 100644 index 0000000000..9c7f902db8 --- /dev/null +++ b/src/classes/XLite/View/Model/ProductClass.php @@ -0,0 +1,117 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Model; + +/** + * Product class view model + * + */ +class ProductClass extends \XLite\View\Model\AModel +{ + /** + * Shema default + * + * @var array + */ + protected $schemaDefault = array( + 'name' => array( + self::SCHEMA_CLASS => 'XLite\View\FormField\Input\Text', + self::SCHEMA_LABEL => 'Name', + self::SCHEMA_REQUIRED => false, + ), + ); + + /** + * Return current model ID + * + * @return integer + */ + public function getModelId() + { + return \XLite\Core\Request::getInstance()->id; + } + + /** + * This object will be used if another one is not pased + * + * @return \XLite\Model\ProductClass + */ + protected function getDefaultModelObject() + { + $model = $this->getModelId() + ? \XLite\Core\Database::getRepo('XLite\Model\ProductClass')->find($this->getModelId()) + : null; + + return $model ?: new \XLite\Model\ProductClass; + } + + /** + * Return name of web form widget class + * + * @return string + */ + protected function getFormClass() + { + return '\XLite\View\Form\Model\ProductClass'; + } + + /** + * Return list of the "Button" widgets + * + * @return array + */ + protected function getFormButtons() + { + $result = parent::getFormButtons(); + + $label = $this->getModelObject()->getId() ? 'Update' : 'Create'; + + $result['submit'] = new \XLite\View\Button\Submit( + array( + \XLite\View\Button\AButton::PARAM_LABEL => $label, + \XLite\View\Button\AButton::PARAM_STYLE => 'action', + ) + ); + + return $result; + } + + /** + * Add top message + * + * @return void + */ + protected function addDataSavedTopMessage() + { + if ('create' != $this->currentAction) { + \XLite\Core\TopMessage::addInfo('The product class has been updated'); + + } else { + \XLite\Core\TopMessage::addInfo('The product class has been added'); + } + } + +} \ No newline at end of file diff --git a/src/classes/XLite/View/ProductClass.php b/src/classes/XLite/View/ProductClass.php new file mode 100644 index 0000000000..d812e532e3 --- /dev/null +++ b/src/classes/XLite/View/ProductClass.php @@ -0,0 +1,56 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View; + +/** + * Product class page view + * + * + * @ListChild (list="admin.center", zone="admin") + */ +class ProductClass extends \XLite\View\AView +{ + /** + * Return list of allowed targets + * + * @return array + */ + public static function getAllowedTargets() + { + return array_merge(parent::getAllowedTargets(), array('product_class')); + } + + /** + * Return widget default template + * + * @return string + */ + protected function getDefaultTemplate() + { + return 'product_class/body.tpl'; + } + +} \ No newline at end of file diff --git a/src/classes/XLite/View/ProductClass/MainInput.php b/src/classes/XLite/View/ProductClasses.php similarity index 59% rename from src/classes/XLite/View/ProductClass/MainInput.php rename to src/classes/XLite/View/ProductClasses.php index 693f59a467..536b92a2d7 100644 --- a/src/classes/XLite/View/ProductClass/MainInput.php +++ b/src/classes/XLite/View/ProductClasses.php @@ -23,54 +23,44 @@ * @link http://www.litecommerce.com/ */ -namespace XLite\View\ProductClass; +namespace XLite\View; /** - * Product classes main input widget + * Product classes page view * + * + * @ListChild (list="admin.center", zone="admin") */ -class MainInput extends \XLite\View\AView +class ProductClasses extends \XLite\View\AView { - - const CLASS_NAME = 'className'; - const CLASS_ID = 'classId'; - /** - * Return allowed targets + * Return list of allowed targets * * @return array */ public static function getAllowedTargets() { - $result = parent::getAllowedTargets(); - - $result[] = 'product_classes'; - - return $result; + return array_merge(parent::getAllowedTargets(), array('product_classes')); } /** - * Define widget parameters + * Return widget default template * - * @return void + * @return string */ - protected function defineWidgetParams() + protected function getDefaultTemplate() { - parent::defineWidgetParams(); - - $this->widgetParams += array( - self::CLASS_NAME => new \XLite\Model\WidgetParam\String('className', null), - self::CLASS_ID => new \XLite\Model\WidgetParam\String('classId', null), - ); + return 'product_classes/body.tpl'; } /** - * getDefaultTemplate() - * - * @return string + * Check - search box is visible or not + * + * @return boolean */ - protected function getDefaultTemplate() + protected function isSearchVisible() { - return 'product_classes/list/main_input.tpl'; + return 0 < \XLite\Core\Database::getRepo('XLite\Model\ProductClass')->count(); } -} + +} \ No newline at end of file diff --git a/src/classes/XLite/View/StickyPanel/ItemsList/ProductClass.php b/src/classes/XLite/View/StickyPanel/ItemsList/ProductClass.php new file mode 100644 index 0000000000..2a5c19787f --- /dev/null +++ b/src/classes/XLite/View/StickyPanel/ItemsList/ProductClass.php @@ -0,0 +1,34 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\StickyPanel\ItemsList; + +/** + * Product classes items list's sticky panel + * + */ +class ProductClass extends \XLite\View\StickyPanel\ItemsListForm +{ +} \ No newline at end of file diff --git a/src/skins/admin/en/product_classes/list/main_input.tpl b/src/skins/admin/en/product_class/body.tpl similarity index 67% rename from src/skins/admin/en/product_classes/list/main_input.tpl rename to src/skins/admin/en/product_class/body.tpl index 31fb47d8ef..14db7a8af5 100644 --- a/src/skins/admin/en/product_classes/list/main_input.tpl +++ b/src/skins/admin/en/product_class/body.tpl @@ -1,14 +1,11 @@ {* vim: set ts=2 sw=2 sts=2 et: *} {** - * Product classes main input widget + * Product class page template * * @author Creative Development LLC * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ *} - - - - + \ No newline at end of file diff --git a/src/skins/admin/en/product_class/style.css b/src/skins/admin/en/product_class/style.css new file mode 100644 index 0000000000..1eeef3b5b2 --- /dev/null +++ b/src/skins/admin/en/product_class/style.css @@ -0,0 +1,10 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Product class view model styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ diff --git a/src/skins/admin/en/product_classes/body.tpl b/src/skins/admin/en/product_classes/body.tpl new file mode 100644 index 0000000000..f6a9b2fab1 --- /dev/null +++ b/src/skins/admin/en/product_classes/body.tpl @@ -0,0 +1,12 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Product classes page template + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + \ No newline at end of file diff --git a/src/skins/admin/en/product_classes/list/parts/columns/main.tpl b/src/skins/admin/en/product_classes/list.tpl similarity index 55% rename from src/skins/admin/en/product_classes/list/parts/columns/main.tpl rename to src/skins/admin/en/product_classes/list.tpl index 6c5ce34dbe..0f0fbf9121 100644 --- a/src/skins/admin/en/product_classes/list/parts/columns/main.tpl +++ b/src/skins/admin/en/product_classes/list.tpl @@ -1,16 +1,14 @@ {* vim: set ts=2 sw=2 sts=2 et: *} {** - * Product classes list item + * Product classes list table template * * @author Creative Development LLC * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * - * @ListChild (list="product_classes.main_input", weight="100") *} - - - + + + \ No newline at end of file diff --git a/src/skins/admin/en/product_classes/list/body.tpl b/src/skins/admin/en/product_classes/list/body.tpl deleted file mode 100644 index fca0463e90..0000000000 --- a/src/skins/admin/en/product_classes/list/body.tpl +++ /dev/null @@ -1,36 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Product classes list page - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - *} - -{* Refactor to ItemsList*} - -
- -
- - - - - - - - - - - - -
- - - -
-
diff --git a/src/skins/admin/en/product_classes/list/css/style.css b/src/skins/admin/en/product_classes/list/css/style.css deleted file mode 100644 index 03868b4690..0000000000 --- a/src/skins/admin/en/product_classes/list/css/style.css +++ /dev/null @@ -1,49 +0,0 @@ -/* vim: set ts=2 sw=2 sts=2 et: */ - -/** - * Product classes list styles - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - */ - -table.product-classes-list { - border-spacing: 0px; -} - -table.product-classes-list td { - border-bottom: solid 1px #eaeaea; -} - -table.product-classes-list tr:first-child td { - border-top: solid 1px #eaeaea; -} - -table.product-classes-list td.input-name { - width: 530px; -} - -.remove-product-class img.remove { - background: transparent url(../images/trash.png) 0 0 no-repeat; - width: 17px; - height: 16px; -} - -.remove-product-class img.separator { - background: transparent url(../images/separator.png) 0 0 repeat-y; - width: 1px; - height: 15px; - margin-right: 10px; -} - -.new-product-class .advanced-input-text .original-label:hover { - background-color: inherit; -} - -.new-product-class .advanced-input-text .original-label { - text-decoration: underline; - color: #154E9C; - cursor: pointer; -} diff --git a/src/skins/admin/en/product_classes/list/images/separator.png b/src/skins/admin/en/product_classes/list/images/separator.png deleted file mode 100644 index 6dab8c00eb99cfe12f965855acf1d805aa15b6eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1SBVv2j2s6ii6yp7}lMWc?slj7I;J!Gca%q zgD@k*tT_@uLG}_)Usv|q%>3-E=GocVtUw_iPZ!4!j_b)4Utftbur@I5e{S;xB+lUJ L>gTe~DWM4fe%>1W diff --git a/src/skins/admin/en/product_classes/list/images/trash.png b/src/skins/admin/en/product_classes/list/images/trash.png deleted file mode 100644 index 25cda0df6ef1645af71303348f3796bdd3d8cf18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 487 zcmVPx#32;bRa{vGf6951U69E94oEQKA00(qQO+^RW0}loz4xlKlm;e9)c}YY;R4C7t zl1+*NF%X4Q`H`kKc0g#vo#4u?-~j}89zi^vYmcCK0N0}6QkzDxHMG%AIyH;TD5LZH zRw2|^^{@ggED{wZ<3^7e%q%ZU=+G!`u0MUa!}i%|=RDtJMf0TI)Q| zl~SkENhyVhK@imI^-ibrm_rB|kH_6^S4w$29;KAa`x zcv+Ul7_D`y)mkhTLWslRu;1^qEHlRVfxTWYNs?-{8it_|0-SUHz!1?|TYktn=YjX$ doO{mz@CJOs=(8gpA#?x$002ovPDHLkV1gET(+&Ut diff --git a/src/skins/admin/en/product_classes/list/js/script.js b/src/skins/admin/en/product_classes/list/js/script.js deleted file mode 100644 index f6c9206508..0000000000 --- a/src/skins/admin/en/product_classes/list/js/script.js +++ /dev/null @@ -1,221 +0,0 @@ -/* vim: set ts=2 sw=2 sts=2 et: */ - -/** - * Product classes list controller - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - */ - -// Update with AJAX product class widget -window.core.updateProductClassAJAX = function (obj, widget) -{ - widget.input.attr('readonly', 'readonly'); - jQuery('img.progress', widget.inputBlock).addClass('ajax-progress'); - widget.cancel.hide(); - - var id = core.getProductClassId(widget); - var name = widget.input.val(); - var action = core.getProductClassAction(widget); - - jQuery.ajax( - { - type: 'get', - url: URLHandler.buildURL({'target': 'product_class', 'action': action, 'name': name, 'id' : id}), - timeout: 15000, - complete: function(xhr, s) { - widget.input.removeAttr('readonly'); - jQuery('img.progress', widget.inputBlock).removeClass('ajax-progress'); - widget.cancel.show(); - widget.cancelValue = name; - - obj.enterValue(widget); - - if ('add' === action) { - widget.input.val(''); - core.addProductClass(widget, jQuery.parseJSON(xhr.responseText).data); - } - } - } - ); // jQuery.ajax - -} - -window.core.addProductClass = function (widget, data) -{ - jQuery('img.progress', widget.inputBlock).addClass('ajax-progress'); - - jQuery.ajax( - { - type: 'get', - url: URLHandler.buildURL( - { - 'target': 'product_classes', - 'widget': '\\XLite\\View\\ProductClass\\MainInput', - 'className': data.name, - 'classId' : data.id - } - ), - timeout: 15000, - complete: function(xhr, s) { - - // TODO!!!! change it - var newRow = xhr.responseText.match(/
((\W|\w)+)<\/div>$/)[1]; - - jQuery('table.product-classes-list tr:last-child').before(newRow); - - var newHandler = new AdvancedInputHandler(); - - newHandler.changeActions(); - - jQuery('img.progress', widget.inputBlock).removeClass('ajax-progress'); - } - } - ); -} - -// Return product class id from widget -window.core.getProductClassId = function (widget) -{ - return widget.input.attr('id').toString().replace(/posteddata-|-name/g, ''); -} - -// Return product class action from widget -window.core.getProductClassAction = function (widget) -{ - return 'new' == core.getProductClassId(widget) ? 'add' : 'update'; -} - -// Decoration of the products list widget class -core.bind( - 'load', - function() { - - // Standard submit event handler is removed (AJAX is used) - jQuery('#product-class-form').submit( - function (event) { - event.preventDefault(); - } - ); - - // Decoration of 'enterValue' method of Advanced Input widget - decorate( - 'AdvancedInputHandler', - 'enterValue', - function (widget) - { - var prevLabel = widget.label.html(); - arguments.callee.previousMethod.apply(this, arguments); - - if (widget.label.closest('td').hasClass('new-product-class')) { - widget.label.html(prevLabel); - } - } - ); - - // Decoration of 'addActions' method of Advanced Input widget - decorate( - 'AdvancedInputHandler', - 'addActions', - function(widget) - { - // previous method call - arguments.callee.previousMethod.apply(this, arguments); - - var o = this; - - widget.input.keypress( - function (event) { - event.stopImmediatePropagation(); - - if (13 === event.which) { - event.preventDefault(); - - core.updateProductClassAJAX(o, widget); - } - } - ); - - widget.label.click(function (e) { - var obj = jQuery(this); - - e.stopImmediatePropagation(); - - jQuery(o.pattern).each(function () { - var widgetToUpdate = this.widget; - - if ( - widget.input.attr('name') != widgetToUpdate.input.attr('name') - ) { - if ( - 'add' != core.getProductClassAction(widgetToUpdate) - && 'none' != widgetToUpdate.inputBlock.css('display') - && widgetToUpdate.input.cancelValue != widgetToUpdate.input.val() - ) { - core.updateProductClassAJAX(o, widgetToUpdate); - } else { - o.enterValue(widgetToUpdate); - } - } - }); - - jQuery('body') - .unbind('click') - .bind( - 'click', - function (event) { - event.stopImmediatePropagation(); - - if ( - widget.input.cancelValue !== widget.input.val() - && 'update' === core.getProductClassAction(widget) - ) { - core.updateProductClassAJAX(o, widget); - } else { - o.enterValue(widget); - } - - }); - }); - - widget.cancel.click(function (event) { - event.stopImmediatePropagation(); - - o.cancel(widget); - }); - - var removeActionObject = jQuery('.remove-product-class a.remove', widget.inputBlock.closest('tr')); - var href = removeActionObject.attr('href'); - - removeActionObject.attr('href', 'javascript:void(0);'); - - removeActionObject.click( - function (event) { - var o = jQuery(this); - - event.stopPropagation(); - - jQuery('img.remove', o).removeClass('remove').addClass('ajax-progress'); - - jQuery.ajax( - { - type: 'get', - url: href, - timeout: 15000, - complete: function(xhr, s) { - jQuery('img.ajax-progress', o).addClass('remove').removeClass('ajax-progress'); - - o.closest('tr').slideUp('slow').remove(); - } - } - ); // jQuery.ajax - } - ); // o.click - - } // addActions method - ); // 'postprocess' method decoration (EXISTING method) - - } -); // core.bind() diff --git a/src/skins/admin/en/product_classes/list/parts/columns/new.tpl b/src/skins/admin/en/product_classes/list/parts/columns/new.tpl deleted file mode 100644 index a30ebcb3b1..0000000000 --- a/src/skins/admin/en/product_classes/list/parts/columns/new.tpl +++ /dev/null @@ -1,17 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Product class new element - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="productClasses.list.columns.new", weight="100") - *} - - - - -  diff --git a/src/skins/admin/en/product_classes/list/parts/columns/remove.tpl b/src/skins/admin/en/product_classes/list/parts/columns/remove.tpl deleted file mode 100644 index dfba38d548..0000000000 --- a/src/skins/admin/en/product_classes/list/parts/columns/remove.tpl +++ /dev/null @@ -1,17 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Remove button - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="product_classes.main_input", weight="200") - *} - - - | - {t(#Remove#)} - diff --git a/src/skins/admin/en/product_classes/style.css b/src/skins/admin/en/product_classes/style.css new file mode 100644 index 0000000000..85a84c62e2 --- /dev/null +++ b/src/skins/admin/en/product_classes/style.css @@ -0,0 +1,14 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Product classes list styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +th.name { + width: 300px; +} From 893f2b9c2f62e68dbf44aefab3ed04dc6b487054 Mon Sep 17 00:00:00 2001 From: skiv Date: Thu, 30 Aug 2012 11:12:58 +0400 Subject: [PATCH 02/85] Product classes list --- .gitignore | 1 + src/classes/XLite/Model/ProductClass.php | 10 ++++++++++ .../XLite/View/ItemsList/Model/ProductClass.php | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/.gitignore b/.gitignore index ea15a9b47c..983469d58b 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ /src/var/.decorator.unsafe_modules.ini.php /src/var/.disabled.structures.php /nbproject +*.swp diff --git a/src/classes/XLite/Model/ProductClass.php b/src/classes/XLite/Model/ProductClass.php index bcb21eebc9..c1656a5ab4 100644 --- a/src/classes/XLite/Model/ProductClass.php +++ b/src/classes/XLite/Model/ProductClass.php @@ -80,4 +80,14 @@ public function __construct(array $data = array()) parent::__construct($data); } + + /** + * Return number of products associated with this class + * + * @return integer + */ + public function getProductsCount() + { + return count($this->products); + } } diff --git a/src/classes/XLite/View/ItemsList/Model/ProductClass.php b/src/classes/XLite/View/ItemsList/Model/ProductClass.php index db8fc75bb3..108083961a 100644 --- a/src/classes/XLite/View/ItemsList/Model/ProductClass.php +++ b/src/classes/XLite/View/ItemsList/Model/ProductClass.php @@ -58,6 +58,10 @@ protected function defineColumns() static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text', static::COLUMN_PARAMS => array('required' => true), ), + 'count' => array( + static::COLUMN_NAME => \XLite\Core\Translation::lbl('Products'), + static::COLUMN_TEMPLATE => 'product_classes/parts/products_count.tpl', + ), ); } From c3bb97e2b069070699b0f04f74d9c4b2c993c4f8 Mon Sep 17 00:00:00 2001 From: skiv Date: Thu, 30 Aug 2012 11:13:11 +0400 Subject: [PATCH 03/85] Product classes list --- .../en/product_classes/parts/products_count.tpl | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/skins/admin/en/product_classes/parts/products_count.tpl diff --git a/src/skins/admin/en/product_classes/parts/products_count.tpl b/src/skins/admin/en/product_classes/parts/products_count.tpl new file mode 100644 index 0000000000..49366e800d --- /dev/null +++ b/src/skins/admin/en/product_classes/parts/products_count.tpl @@ -0,0 +1,12 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Products count + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + +{entity.getProductsCount()} From 8994520fc46ad054ad6b0036f12df7a21436260a Mon Sep 17 00:00:00 2001 From: skiv Date: Thu, 30 Aug 2012 16:22:27 +0400 Subject: [PATCH 04/85] Product classes list --- .../XLite/Controller/Admin/ProductClasses.php | 12 +++ src/classes/XLite/Model/ProductClass.php | 23 +++++- src/classes/XLite/Model/Repo/ProductClass.php | 8 +- .../Inline/Input/Text/ProductClass.php | 79 +++++++++++++++++++ .../View/ItemsList/Model/ProductClass.php | 20 +++-- .../inline/input/text/product-class.js | 19 +++++ .../inline/input/text/product-class.tpl} | 5 +- src/skins/admin/en/product_classes/style.css | 14 +++- 8 files changed, 165 insertions(+), 15 deletions(-) create mode 100644 src/classes/XLite/View/FormField/Inline/Input/Text/ProductClass.php create mode 100644 src/skins/admin/en/form_field/inline/input/text/product-class.js rename src/skins/admin/en/{product_classes/parts/products_count.tpl => form_field/inline/input/text/product-class.tpl} (67%) diff --git a/src/classes/XLite/Controller/Admin/ProductClasses.php b/src/classes/XLite/Controller/Admin/ProductClasses.php index 8e98604fa8..f5f42fee94 100644 --- a/src/classes/XLite/Controller/Admin/ProductClasses.php +++ b/src/classes/XLite/Controller/Admin/ProductClasses.php @@ -42,6 +42,18 @@ public function checkACL() return parent::checkACL() || \XLite\Core\Auth::getInstance()->isPermissionAllowed('manage catalog'); } + /** + * Return the current page title (for the content area) + * + * @return string + * @see ____func_see____ + * @since 1.0.0 + */ + public function getTitle() + { + return static::t('Product classes'); + } + /** * Update list * diff --git a/src/classes/XLite/Model/ProductClass.php b/src/classes/XLite/Model/ProductClass.php index c1656a5ab4..cd12ba8a25 100644 --- a/src/classes/XLite/Model/ProductClass.php +++ b/src/classes/XLite/Model/ProductClass.php @@ -45,6 +45,16 @@ class ProductClass extends \XLite\Model\Base\I18n */ protected $id; + /** + * Position + * + * @var integer + * @see ____var_see____ + * @since 1.0.0 + * + * @Column (type="integer") + */ + protected $position = 0; /** * Products @@ -88,6 +98,17 @@ public function __construct(array $data = array()) */ public function getProductsCount() { - return count($this->products); + return count($this->getProducts()); + } + + /** + * Return number of attributes associated with this class + * + * @return integer + */ + public function getAttributesCount() + { + return 0; +// return count($this->getAttributes()); } } diff --git a/src/classes/XLite/Model/Repo/ProductClass.php b/src/classes/XLite/Model/Repo/ProductClass.php index 869f0952ad..c82a7245be 100644 --- a/src/classes/XLite/Model/Repo/ProductClass.php +++ b/src/classes/XLite/Model/Repo/ProductClass.php @@ -18,11 +18,9 @@ * * @category LiteCommerce * @author Creative Development LLC - * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ - * @see ____file_see____ - * @since 1.0.0 */ namespace XLite\Model\Repo; @@ -82,7 +80,7 @@ public function searchCount(\Doctrine\ORM\QueryBuilder $qb) */ public function searchResult(\Doctrine\ORM\QueryBuilder $qb) { - return $qb->getResult(); + return $qb->addOrderBy('p.position', 'ASC')->getResult(); } /** @@ -129,4 +127,4 @@ protected function getHandlingSearchParams() // }}} -} \ No newline at end of file +} diff --git a/src/classes/XLite/View/FormField/Inline/Input/Text/ProductClass.php b/src/classes/XLite/View/FormField/Inline/Input/Text/ProductClass.php new file mode 100644 index 0000000000..bacd573e47 --- /dev/null +++ b/src/classes/XLite/View/FormField/Inline/Input/Text/ProductClass.php @@ -0,0 +1,79 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\FormField\Inline\Input\Text; + +/** + * Product class + * + */ +class ProductClass extends \XLite\View\FormField\Inline\Base\Single +{ + /** + * Register JS files + * + * @return array + */ + public function getJSFiles() + { + $list = parent::getJSFiles(); + + $list[] = 'form_field/inline/input/text/product-class.js'; + + return $list; + } + + /** + * Define form field + * + * @return string + */ + protected function defineFieldClass() + { + return 'XLite\View\FormField\Input\Text'; + } + + /** + * Get container class + * + * @return string + */ + protected function getContainerClass() + { + return parent::getContainerClass() . ' inline-product-class'; + } + + /** + * Get view template + * + * @return string + */ + protected function getViewTemplate() + { + return 'form_field/inline/input/text/product-class.tpl'; + } + +} + diff --git a/src/classes/XLite/View/ItemsList/Model/ProductClass.php b/src/classes/XLite/View/ItemsList/Model/ProductClass.php index 108083961a..5e9910b314 100644 --- a/src/classes/XLite/View/ItemsList/Model/ProductClass.php +++ b/src/classes/XLite/View/ItemsList/Model/ProductClass.php @@ -54,13 +54,11 @@ protected function defineColumns() { return array( 'name' => array( - static::COLUMN_NAME => \XLite\Core\Translation::lbl('Name'), - static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text', + static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text\ProductClass', static::COLUMN_PARAMS => array('required' => true), ), - 'count' => array( - static::COLUMN_NAME => \XLite\Core\Translation::lbl('Products'), - static::COLUMN_TEMPLATE => 'product_classes/parts/products_count.tpl', + 'attributes' => array( + static::COLUMN_TEMPLATE => 'product_classes/parts/edit_attributes.tpl', ), ); } @@ -118,6 +116,16 @@ protected function isRemoved() return true; } + /** + * Mark list as sortable + * + * @return integer + */ + protected function getSortableType() + { + return static::SORT_TYPE_MOVE; + } + // }}} /** @@ -150,7 +158,7 @@ protected function getPanelClass() */ static public function getSearchParams() { - return array( ); + return array(); } /** diff --git a/src/skins/admin/en/form_field/inline/input/text/product-class.js b/src/skins/admin/en/form_field/inline/input/text/product-class.js new file mode 100644 index 0000000000..870502eb28 --- /dev/null +++ b/src/skins/admin/en/form_field/inline/input/text/product-class.js @@ -0,0 +1,19 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Product class field controller + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +CommonForm.elementControllers.push( + { + pattern: '.inline-field.inline-product-class', + handler: function () { + this.viewValuePattern = '.view .value'; + } + } +); diff --git a/src/skins/admin/en/product_classes/parts/products_count.tpl b/src/skins/admin/en/form_field/inline/input/text/product-class.tpl similarity index 67% rename from src/skins/admin/en/product_classes/parts/products_count.tpl rename to src/skins/admin/en/form_field/inline/input/text/product-class.tpl index 49366e800d..5e49ab35d0 100644 --- a/src/skins/admin/en/product_classes/parts/products_count.tpl +++ b/src/skins/admin/en/form_field/inline/input/text/product-class.tpl @@ -1,7 +1,7 @@ {* vim: set ts=2 sw=2 sts=2 et: *} {** - * Products count + * Product class inline view * * @author Creative Development LLC * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved @@ -9,4 +9,5 @@ * @link http://www.litecommerce.com/ *} -{entity.getProductsCount()} +{getViewValue(singleField):h} +({entity.getProductsCount()} {t(#products#)}) diff --git a/src/skins/admin/en/product_classes/style.css b/src/skins/admin/en/product_classes/style.css index 85a84c62e2..ab3424ff47 100644 --- a/src/skins/admin/en/product_classes/style.css +++ b/src/skins/admin/en/product_classes/style.css @@ -9,6 +9,18 @@ * @link http://www.litecommerce.com/ */ -th.name { +td.name { width: 300px; } +.items-list-table table.list tbody.lines td.name div.inline-product-class span.value { + color: #456583; + font-size: 16px; +} +.items-list-table table.list tbody.lines td.cell span, +.items-list-table table.list tbody.lines td.cell a +{ + color: #8f8f8f; +} +.items-list-table table.list tbody.lines td.cell a { + text-decoration: underline; +} From f16a282b655aa2b9795c0321e0fc1cf5f54d8f21 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Tue, 4 Sep 2012 17:27:16 +0400 Subject: [PATCH 05/85] [*] Address Field models are added initially. --- src/classes/XLite/Model/AEntity.php | 52 ++++++-- src/classes/XLite/Model/Address.php | 41 +++++++ src/classes/XLite/Model/AddressField.php | 116 ++++++++++++++++++ .../XLite/Model/AddressFieldTranslation.php | 46 +++++++ src/classes/XLite/Model/AddressFieldValue.php | 76 ++++++++++++ 5 files changed, 320 insertions(+), 11 deletions(-) create mode 100644 src/classes/XLite/Model/AddressField.php create mode 100644 src/classes/XLite/Model/AddressFieldTranslation.php create mode 100644 src/classes/XLite/Model/AddressFieldValue.php diff --git a/src/classes/XLite/Model/AEntity.php b/src/classes/XLite/Model/AEntity.php index c519be5c76..33d70baad9 100644 --- a/src/classes/XLite/Model/AEntity.php +++ b/src/classes/XLite/Model/AEntity.php @@ -197,28 +197,58 @@ public function __call($method, array $args = array()) if ($result) { $property = \XLite\Core\Converter::convertFromCamelCase($matches[2]); + } + + $return = 'set' === $matches[1] + ? $this->setterProperty($property, array_shift($args)) + : $this->getterProperty($property); - $result = property_exists($this, $property); + if (is_null($return)) { + + throw new \BadMethodCallException( + get_class($this) . '::' . $method . '() - method not exists or invalid getter/setter' + ); } - $return = null; + return $return; + } + + /** + * Universal setter + * + * @param string $property + * @param mixed $value + * + * @return true|null Returns TRUE if the setting succeeds. NULL if the setting fails + */ + public function setterProperty($property, $value) + { + $result = property_exists($this, $property); if ($result) { - if ('set' === $matches[1]) { + $this->$property = $value; + } - $this->$property = array_shift($args); + return $result ?: null; + } - } else { + /** + * Universal getter + * + * @param string $property + * + * @return mixed|null Returns NULL if it is impossible to get the property + */ + public function getterProperty($property) + { + $result = property_exists($this, $property); - $return = $this->$property; - } + $return = null; - } else { + if ($result) { - throw new \BadMethodCallException( - get_class($this) . '::' . $method . '() - method not exists or invalid getter/setter' - ); + $return = $this->$property; } return $return; diff --git a/src/classes/XLite/Model/Address.php b/src/classes/XLite/Model/Address.php index 928d1ba69b..ef535d1814 100644 --- a/src/classes/XLite/Model/Address.php +++ b/src/classes/XLite/Model/Address.php @@ -76,6 +76,47 @@ class Address extends \XLite\Model\Base\PersonalAddress */ protected $profile; + /** + * Address field value relation + * + * @var \Doctrine\Common\Collections\ArrayCollection + * + * @OneToMany (targetEntity="XLite\Model\AddressFieldValue", mappedBy="address", cascade={"all"}) + * @JoinColumn(name="id", referencedColumnName="id") + */ + protected $fieldValue; + + + /** + * Universal getter + * + * @param string $property + * + * @return mixed|null Returns NULL if it is impossible to get the property + */ + public function getterProperty($property) + { + $result = parent::getterProperty($property); + + if (is_null($result)) { + + $addressField = \XLite\Core\Database::getRepo('XLite\Model\AddressField') + ->findOneBy(array('serviceName' => $property)); + + if ($addressField) { + + $addressFieldValue = \XLite\Core\Database::getRepo('XLite\Model\AddressFieldValue') + ->findOneBy(array( + 'address' => $this->getAddressId(), + 'addressField' => $addressField->getId(), + )); + + $result = $addressFieldValue ? $addressFieldValue->getValue() : $result; + } + } + + return $result; + } /** * Get billing address-specified required fields diff --git a/src/classes/XLite/Model/AddressField.php b/src/classes/XLite/Model/AddressField.php new file mode 100644 index 0000000000..2b663feff4 --- /dev/null +++ b/src/classes/XLite/Model/AddressField.php @@ -0,0 +1,116 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model; + +/** + * Address field model + * + * + * @Entity (repositoryClass="\XLite\Model\Repo\AddressField") + * @Table (name="address_field") + */ +class AddressField extends \XLite\Model\Base\I18n +{ + /** + * Unique id + * + * @var integer + * + * @Id + * @GeneratedValue (strategy="AUTO") + * @Column (type="integer", nullable=false) + */ + protected $id; + + /** + * Service name for address field + * For example: firstname, lastname, country_code and so on. + * + * The field is named with this value in the address forms. + * Also the "service-name-{$serviceName}" CSS class is added to the field + * + * @var string + * @Column(type="string", length=128, unique=true, nullable=false) + */ + protected $serviceName; + + /** + * Schema class for "Form field widget". + * This class will be used in form widgets + * + * Possible values are: + * + * \XLite\View\FormField\Input\Text + * \XLite\View\FormField\Select\Country + * \XLite\View\FormField\Select\Title + * + * For more information check "\XLite\View\FormField\*" class family. + * + * The '\XLite\View\FormField\Input\Text' class (standard input text field) + * is taken for additional fields by default. + * + * @var string + * @Column(type="string", length=256, nullable=false) + */ + protected $schemaClass = '\XLite\View\FormField\Input\Text'; + + /** + * Flag if the field is an additional one (This field could be removed) + * + * @var boolean + * @Column(type="boolean") + */ + protected $additional = true; + + /** + * Flag if the field is a required one + * + * @var boolean + * @Column(type="boolean") + */ + protected $required = true; + + /** + * Position + * + * @var integer + * + * @Column (type="integer") + */ + protected $position = 0; + + + /** + * Address field value model relation + * + * @var \Doctrine\Common\Collections\ArrayCollection + * + * @OneToMany (targetEntity="XLite\Model\AddressFieldValue", mappedBy="addressField", cascade={"all"}) + * @JoinColumn(name="id", referencedColumnName="id") + */ + protected $value; + +} diff --git a/src/classes/XLite/Model/AddressFieldTranslation.php b/src/classes/XLite/Model/AddressFieldTranslation.php new file mode 100644 index 0000000000..2911d96543 --- /dev/null +++ b/src/classes/XLite/Model/AddressFieldTranslation.php @@ -0,0 +1,46 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model; + +/** + * Category multilingual data + * + * + * @Entity + * @Table (name="address_field_translation") + */ +class AddressFieldTranslation extends \XLite\Model\Base\Translation +{ + /** + * Field name + * + * @var string + * + * @Column (type="string", length=255) + */ + protected $name; + +} diff --git a/src/classes/XLite/Model/AddressFieldValue.php b/src/classes/XLite/Model/AddressFieldValue.php new file mode 100644 index 0000000000..ad696541ba --- /dev/null +++ b/src/classes/XLite/Model/AddressFieldValue.php @@ -0,0 +1,76 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model; + +/** + * Address field value (additional fields) model + * + * + * @Entity (repositoryClass="\XLite\Model\Repo\AddressFieldValue") + * @Table (name="address_field_value") + */ +class AddressFieldValue extends \XLite\Model\AEntity +{ + /** + * Unique id + * + * @var integer + * + * @Id + * @GeneratedValue (strategy="AUTO") + * @Column (type="integer", nullable=false) + */ + protected $id; + + /** + * Additional field value + * + * @var string + * @Column(type="string", length=255, nullable=false) + */ + protected $value = ''; + + /** + * Address field model relation + * + * @var \Doctrine\Common\Collections\ArrayCollection + * + * @ManyToOne (targetEntity="XLite\Model\AddressField", inversedBy="value", cascade={"all"}) + * @JoinColumn(name="id", referencedColumnName="id") + */ + protected $addressField; + + /** + * Address model relation + * + * @var \Doctrine\Common\Collections\ArrayCollection + * + * @ManyToOne (targetEntity="XLite\Model\Address", inversedBy="fieldValue", cascade={"all"}) + * @JoinColumn(name="address_id", referencedColumnName="address_id") + */ + protected $address; + +} From 1a7586dfc5544b25a7f7b2d66736a6bddd01f6c1 Mon Sep 17 00:00:00 2001 From: skiv Date: Thu, 6 Sep 2012 14:30:29 +0400 Subject: [PATCH 06/85] Product classes --- src/classes/XLite/Model/ProductClass.php | 23 ++++++++++++++++--- .../XLite/View/FormField/Select/Classes.php | 2 +- .../View/FormField/Select/ProductClasses.php | 2 +- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/classes/XLite/Model/ProductClass.php b/src/classes/XLite/Model/ProductClass.php index cd12ba8a25..ba95d20cce 100644 --- a/src/classes/XLite/Model/ProductClass.php +++ b/src/classes/XLite/Model/ProductClass.php @@ -65,7 +65,6 @@ class ProductClass extends \XLite\Model\Base\I18n */ protected $products; - /** * Shipping methods * @@ -75,6 +74,23 @@ class ProductClass extends \XLite\Model\Base\I18n */ protected $shipping_methods; + /** + * Attributes + * + * @var \Doctrine\Common\Collections\Collection + * + * @OneToMany (targetEntity="XLite\Model\Attribute", mappedBy="product_class", cascade={"all"}) + */ + protected $attributes; + + /** + * Attribute groups + * + * @var \Doctrine\Common\Collections\Collection + * + * @OneToMany (targetEntity="XLite\Model\AttributeGroup", mappedBy="product_class", cascade={"all"}) + */ + protected $attribute_groups; /** * Constructor @@ -87,6 +103,8 @@ public function __construct(array $data = array()) { $this->products = new \Doctrine\Common\Collections\ArrayCollection(); $this->shipping_methods = new \Doctrine\Common\Collections\ArrayCollection(); + $this->attributes = new \Doctrine\Common\Collections\ArrayCollection(); + $this->attribute_groups = new \Doctrine\Common\Collections\ArrayCollection(); parent::__construct($data); } @@ -108,7 +126,6 @@ public function getProductsCount() */ public function getAttributesCount() { - return 0; -// return count($this->getAttributes()); + return count($this->getAttributes()); } } diff --git a/src/classes/XLite/View/FormField/Select/Classes.php b/src/classes/XLite/View/FormField/Select/Classes.php index 230ac48ac2..054276c1a5 100644 --- a/src/classes/XLite/View/FormField/Select/Classes.php +++ b/src/classes/XLite/View/FormField/Select/Classes.php @@ -78,7 +78,7 @@ protected function getFieldTemplate() protected function getDefaultOptions() { $list = array(); - foreach (\XLite\Core\Database::getRepo('\XLite\Model\ProductClass')->findAll() as $class) { + foreach (\XLite\Core\Database::getRepo('\XLite\Model\ProductClass')->search() as $class) { $list[$class->getId()] = $class->getName(); } diff --git a/src/classes/XLite/View/FormField/Select/ProductClasses.php b/src/classes/XLite/View/FormField/Select/ProductClasses.php index e8e42e9fda..2ccf3221c9 100644 --- a/src/classes/XLite/View/FormField/Select/ProductClasses.php +++ b/src/classes/XLite/View/FormField/Select/ProductClasses.php @@ -39,7 +39,7 @@ class ProductClasses extends \XLite\View\FormField\Select\Multiple protected function getProductClassesList() { $list = array(); - foreach (\XLite\Core\Database::getRepo('\XLite\Model\ProductClass')->findAll() as $e) { + foreach (\XLite\Core\Database::getRepo('\XLite\Model\ProductClass')->search() as $e) { $list[$e->getId()] = $e->getName(); } From a1a01173387f69d79dc64ee4a3018153fe94b206 Mon Sep 17 00:00:00 2001 From: skiv Date: Thu, 6 Sep 2012 17:01:06 +0400 Subject: [PATCH 07/85] Attributes --- src/classes/XLite/Model/Attribute.php | 140 ++++++++++++++++++ src/classes/XLite/Model/AttributeGroup.php | 68 +++++++++ .../XLite/Model/AttributeGroupTranslation.php | 51 +++++++ .../XLite/Model/AttributeTranslation.php | 51 +++++++ .../product_classes/parts/edit_attributes.tpl | 12 ++ 5 files changed, 322 insertions(+) create mode 100644 src/classes/XLite/Model/Attribute.php create mode 100644 src/classes/XLite/Model/AttributeGroup.php create mode 100644 src/classes/XLite/Model/AttributeGroupTranslation.php create mode 100644 src/classes/XLite/Model/AttributeTranslation.php create mode 100644 src/skins/admin/en/product_classes/parts/edit_attributes.tpl diff --git a/src/classes/XLite/Model/Attribute.php b/src/classes/XLite/Model/Attribute.php new file mode 100644 index 0000000000..9bbc118d79 --- /dev/null +++ b/src/classes/XLite/Model/Attribute.php @@ -0,0 +1,140 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model; + +/** + * Attribute + * + * @Entity + * @Table (name="attributes") + */ +class Attribute extends \XLite\Model\Base\I18n +{ + /* + * Attribute types + */ + const TYPE_NUMBER = 'N'; + const TYPE_TEXT = 'T'; + const TYPE_CHECKBOX = 'C'; + const TYPE_SELECT = 'S'; + + /** + * ID + * + * @var integer + * + * @Id + * @GeneratedValue (strategy="AUTO") + * @Column (type="uinteger") + */ + protected $id; + + /** + * Position + * + * @var integer + * @see ____var_see____ + * @since 1.0.0 + * + * @Column (type="integer") + */ + protected $position = 0; + + /** + * Product class + * + * @var \XLite\Model\ProductClass + * + * @ManyToOne (targetEntity="XLite\Model\ProductClass", inversedBy="attributes") + * @JoinColumn (name="product_class_id", referencedColumnName="id") + */ + protected $product_class; + + /** + * Attribute group + * + * @var \XLite\Model\AttributeGroup + * + * @ManyToOne (targetEntity="XLite\Model\AttributeGroup", inversedBy="attributes") + * @JoinColumn (name="attribute_group_id", referencedColumnName="id", onDelete="SET NULL") + */ + protected $attribute_group; + + /** + * Option type + * + * @var string + * + * @Column (type="fixedstring", length=1) + */ + protected $type = self::TYPE_NUMBER; + + /** + * Constructor + * + * @param array $data Entity properties OPTIONAL + * + * @return void + */ + public function __construct(array $data = array()) + { + $this->attribute_values = new \Doctrine\Common\Collections\ArrayCollection(); + + parent::__construct($data); + } + + /** + * Return number of products associated with this attribute + * + * @return integer + */ + public function getProductsCount() + { + return count($this->getClass()->getProducts()); + } + + /** + * Return list of types or type + * + * @param string $type Type OPTIONAL + * + * @return array | string + */ + public static function getTypes($type = null) + { + $list = array( + self::TYPE_NUMBER => 'Number', + self::TYPE_TEXT => 'Text', + self::TYPE_CHECKBOX => 'Checkbox', + self::TYPE_SELECT => 'Select', + ); + + return isset($type) + ? (isset($list[$type]) ? $list[$type] : null) + : $list; + } + +} diff --git a/src/classes/XLite/Model/AttributeGroup.php b/src/classes/XLite/Model/AttributeGroup.php new file mode 100644 index 0000000000..ac1433dca6 --- /dev/null +++ b/src/classes/XLite/Model/AttributeGroup.php @@ -0,0 +1,68 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model; + +/** + * Attribute group + * + * @Entity + * @Table (name="attribute_groups") + */ +class AttributeGroup extends \XLite\Model\Base\I18n +{ + /** + * ID + * + * @var integer + * + * @Id + * @GeneratedValue (strategy="AUTO") + * @Column (type="uinteger") + */ + protected $id; + + /** + * Position + * + * @var integer + * @see ____var_see____ + * @since 1.0.0 + * + * @Column (type="integer") + */ + protected $position = 0; + + /** + * Product class + * + * @var \XLite\Model\ProductClass + * + * @ManyToOne (targetEntity="XLite\Model\ProductClass", inversedBy="attribute_groups") + * @JoinColumn (name="product_class_id", referencedColumnName="id") + */ + protected $product_class; + +} diff --git a/src/classes/XLite/Model/AttributeGroupTranslation.php b/src/classes/XLite/Model/AttributeGroupTranslation.php new file mode 100644 index 0000000000..9c13cf7d30 --- /dev/null +++ b/src/classes/XLite/Model/AttributeGroupTranslation.php @@ -0,0 +1,51 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model; + +/** + * Attribute group multilingual data + * + * + * @Entity + * + * @Table (name="attribute_group_translations", + * indexes={ + * @Index (name="ci", columns={"code","id"}), + * @Index (name="id", columns={"id"}) + * } + * ) + */ +class AttributeGroupTranslation extends \XLite\Model\Base\Translation +{ + /** + * Name + * + * @var string + * + * @Column (type="string", length=255) + */ + protected $name; +} diff --git a/src/classes/XLite/Model/AttributeTranslation.php b/src/classes/XLite/Model/AttributeTranslation.php new file mode 100644 index 0000000000..00370c45f1 --- /dev/null +++ b/src/classes/XLite/Model/AttributeTranslation.php @@ -0,0 +1,51 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model; + +/** + * Attribute multilingual data + * + * + * @Entity + * + * @Table (name="attribute_translations", + * indexes={ + * @Index (name="ci", columns={"code","id"}), + * @Index (name="id", columns={"id"}) + * } + * ) + */ +class AttributeTranslation extends \XLite\Model\Base\Translation +{ + /** + * Name + * + * @var string + * + * @Column (type="string", length=255) + */ + protected $name; +} diff --git a/src/skins/admin/en/product_classes/parts/edit_attributes.tpl b/src/skins/admin/en/product_classes/parts/edit_attributes.tpl new file mode 100644 index 0000000000..10c734ddc7 --- /dev/null +++ b/src/skins/admin/en/product_classes/parts/edit_attributes.tpl @@ -0,0 +1,12 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Edit attributes + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + +{t(#Edit attributes#)} ({entity.getAttributesCount()}) From 9af606d1ee97886a5941403ca8c2fb6814e93517 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Wed, 12 Sep 2012 14:31:00 +0400 Subject: [PATCH 08/85] [*] Address fields feature further changes. --- src/Includes/install/install.php | 14 +- .../XLite/Controller/Admin/AddressField.php | 93 +++++++++ .../XLite/Controller/Admin/AddressFields.php | 54 ++++++ src/classes/XLite/Core/Auth.php | 4 +- src/classes/XLite/Model/AEntity.php | 4 +- src/classes/XLite/Model/Address.php | 54 +++++- src/classes/XLite/Model/AddressField.php | 9 +- src/classes/XLite/Model/AddressFieldValue.php | 6 +- src/classes/XLite/Model/Base/Address.php | 36 ---- .../XLite/Model/Base/PersonalAddress.php | 27 --- src/classes/XLite/Model/Repo/AddressField.php | 140 ++++++++++++++ src/classes/XLite/View/Address.php | 25 ++- src/classes/XLite/View/Address/Field.php | 72 +++++++ src/classes/XLite/View/Address/Fields.php | 82 ++++++++ src/classes/XLite/View/Form/AddressField.php | 88 +++++++++ .../View/Form/ItemsList/AddressField/Main.php | 43 +++++ .../XLite/View/ItemsList/Model/AModel.php | 6 +- .../View/ItemsList/Model/Address/Fields.php | 177 ++++++++++++++++++ .../XLite/View/ItemsList/Model/Table.php | 70 ++++--- src/classes/XLite/View/Model/AModel.php | 14 +- .../XLite/View/Model/Address/Address.php | 78 ++------ .../XLite/View/Model/Address/Field.php | 155 +++++++++++++++ .../View/TopMenu/Node/Users/AddressFields.php | 49 +++++ src/skins/admin/en/address/field/body.tpl | 12 ++ src/skins/admin/en/address/field/style.css | 13 ++ src/skins/admin/en/address/fields/body.tpl | 13 ++ .../admin/en/items_list/model/table/body.tpl | 7 +- src/sql/xlite_data.yaml | 14 ++ 28 files changed, 1161 insertions(+), 198 deletions(-) create mode 100644 src/classes/XLite/Controller/Admin/AddressField.php create mode 100644 src/classes/XLite/Controller/Admin/AddressFields.php create mode 100644 src/classes/XLite/Model/Repo/AddressField.php create mode 100644 src/classes/XLite/View/Address/Field.php create mode 100644 src/classes/XLite/View/Address/Fields.php create mode 100644 src/classes/XLite/View/Form/AddressField.php create mode 100644 src/classes/XLite/View/Form/ItemsList/AddressField/Main.php create mode 100644 src/classes/XLite/View/ItemsList/Model/Address/Fields.php create mode 100644 src/classes/XLite/View/Model/Address/Field.php create mode 100644 src/classes/XLite/View/TopMenu/Node/Users/AddressFields.php create mode 100644 src/skins/admin/en/address/field/body.tpl create mode 100644 src/skins/admin/en/address/field/style.css create mode 100644 src/skins/admin/en/address/fields/body.tpl diff --git a/src/Includes/install/install.php b/src/Includes/install/install.php index f51cfba47e..235f3deb87 100644 --- a/src/Includes/install/install.php +++ b/src/Includes/install/install.php @@ -1194,7 +1194,7 @@ function doUpdateMainHtaccess(&$params, $silentMode = false) $util = '\Includes\Utils\FileManager'; $util::replace( - $util::getDir($util::getDir(__DIR__)) . LC_DS . '.htaccess', + $util::getDir($util::getDir(__DIR__)) . LC_DS . '.htaccess', '\1RewriteBase ' . $params['xlite_web_dir'], '/^(\s*)#\s*RewriteBase\s+____WEB_DIR____\s*$/mi' ); @@ -1400,9 +1400,9 @@ function doCreateAdminAccount(&$params, $silentMode = false) $role = \XLite\Core\Database::getRepo('XLite\Model\Role')->findOneByName('Administrator'); $profile->addRoles($role); - + $profile->create(); - + $role->addProfiles($profile); \XLite\Core\Database::getEM()->persist($role); \XLite\Core\Database::getEM()->flush(); @@ -1545,9 +1545,9 @@ function doFinishInstallation(&$params, $silentMode = false) /** * Sanitize host value (remove port as some servers include it to HTTP_HOST variable) - * + * * @param string $host Host value - * + * * @return string */ function x_install_get_host($host) @@ -1883,7 +1883,7 @@ function change_config(&$params) '/^socket.*=.*/', '/^http_host.*=.*/', '/^https_host.*=.*/', - '/^web_dir.*=.*/' + '/^web_dir.*=.*/', '/^shared_secret_key.*=.*/' ); @@ -1896,7 +1896,7 @@ function change_config(&$params) 'socket = "' . $_params['mysqlsock'] . '"', 'http_host = "' . $_params['xlite_http_host'] . '"', 'https_host = "' . $_params['xlite_https_host'] . '"', - 'web_dir = "' . $_params['xlite_web_dir'] . '"' + 'web_dir = "' . $_params['xlite_web_dir'] . '"', 'shared_secret_key = "' . uniqid('', true) . '"' ); diff --git a/src/classes/XLite/Controller/Admin/AddressField.php b/src/classes/XLite/Controller/Admin/AddressField.php new file mode 100644 index 0000000000..6c22f289a3 --- /dev/null +++ b/src/classes/XLite/Controller/Admin/AddressField.php @@ -0,0 +1,93 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Controller\Admin; + +/** + * Address field + * + */ +class AddressField extends \XLite\Controller\Admin\AAdmin +{ + /** + * Controller parameters + * + * @var array + */ + protected $param = array('target', 'id'); + + /** + * Address field id + * + * @var integer + */ + protected $id; + + /** + * Return the current page title (for the content area) + * + * @return string + */ + public function getTitle() + { + return 'Address field'; + } + + /** + * Common method to determine current location + * + * @return string + */ + protected function getLocation() + { + return $this->getTitle(); + } + + /** + * Update address field + * + * @return void + */ + public function doActionUpdate() + { + $this->getModelForm()->performAction('modify'); + + if ($this->getModelForm()->getModelObject()->getId()) { + $this->setReturnUrl(\XLite\Core\Converter::buildURL('address_fields')); + } + } + + /** + * Get model form class + * + * @return void + */ + protected function getModelFormClass() + { + return 'XLite\View\Model\Address\Field'; + } + +} + diff --git a/src/classes/XLite/Controller/Admin/AddressFields.php b/src/classes/XLite/Controller/Admin/AddressFields.php new file mode 100644 index 0000000000..b91fe03f10 --- /dev/null +++ b/src/classes/XLite/Controller/Admin/AddressFields.php @@ -0,0 +1,54 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Controller\Admin; + +/** + * Address fields controller + * + */ +class AddressFields extends \XLite\Controller\Admin\AAdmin +{ + /** + * Return the current page title (for the content area) + * + * @return string + */ + public function getTitle() + { + return 'Address fields'; + } + + /** + * Update list + * + * @return void + */ + protected function doActionUpdate() + { + $list = new \XLite\View\ItemsList\Model\Address\Fields(); + $list->processQuick(); + } +} diff --git a/src/classes/XLite/Core/Auth.php b/src/classes/XLite/Core/Auth.php index 82b88efb5a..30a8afdd6b 100644 --- a/src/classes/XLite/Core/Auth.php +++ b/src/classes/XLite/Core/Auth.php @@ -320,7 +320,9 @@ public function getProfile($profileId = null) */ public function getMembershipId() { - return $this->getProfile() ? $this->getProfile()->getMembership()->getMembershipId() : null; + return $this->getProfile() + ? ($this->getProfile()->getMembership() ? $this->getProfile()->getMembership()->getMembershipId() : null) + : null; } /** diff --git a/src/classes/XLite/Model/AEntity.php b/src/classes/XLite/Model/AEntity.php index 33d70baad9..374c66489b 100644 --- a/src/classes/XLite/Model/AEntity.php +++ b/src/classes/XLite/Model/AEntity.php @@ -80,9 +80,9 @@ public function map(array $data) // $method is assembled from 'set' + getMethodName() $this->$method($value); - } elseif (property_exists($this, $key)) { + } else { - $this->$key = $value; + $this->setterProperty($key, $value); } } } diff --git a/src/classes/XLite/Model/Address.php b/src/classes/XLite/Model/Address.php index ef535d1814..8976d9d861 100644 --- a/src/classes/XLite/Model/Address.php +++ b/src/classes/XLite/Model/Address.php @@ -69,7 +69,7 @@ class Address extends \XLite\Model\Base\PersonalAddress /** * Profile: many-to-one relation with profile entity * - * @var \Doctrine\Common\Collections\ArrayCollection + * @var \XLite\Model\Profile * * @ManyToOne (targetEntity="XLite\Model\Profile", inversedBy="addresses") * @JoinColumn (name="profile_id", referencedColumnName="profile_id") @@ -77,16 +77,62 @@ class Address extends \XLite\Model\Base\PersonalAddress protected $profile; /** - * Address field value relation + * Address field value relation. one-to-many relation with address field entities * * @var \Doctrine\Common\Collections\ArrayCollection * * @OneToMany (targetEntity="XLite\Model\AddressFieldValue", mappedBy="address", cascade={"all"}) - * @JoinColumn(name="id", referencedColumnName="id") */ protected $fieldValue; + /** + * Universal setter + * + * @param string $property + * @param mixed $value + * + * @return true|null Returns TRUE if the setting succeeds. NULL if the setting fails + */ + public function setterProperty($property, $value) + { + $result = parent::setterProperty($property, $value); + + if (is_null($result)) { + + $addressField = \XLite\Core\Database::getRepo('XLite\Model\AddressField') + ->findOneBy(array('serviceName' => $property)); + + if ($addressField) { + + $repo = \XLite\Core\Database::getRepo('XLite\Model\AddressFieldValue'); + + $data = array( + 'address' => $this, + 'addressField' => $addressField, + ); + + $addressFieldValue = $repo->findOneBy($data); + + if ($addressFieldValue) { + $addressFieldValue->setValue($value); + + $repo->update($addressFieldValue); + } else { + + $data['value'] = $value; + $addressFieldValue = new \XLite\Model\AddressFieldValue($data); + + $repo->insert($addressFieldValue); + } + + $result = true; + } + } + + return $result; + } + /** * Universal getter * @@ -111,7 +157,7 @@ public function getterProperty($property) 'addressField' => $addressField->getId(), )); - $result = $addressFieldValue ? $addressFieldValue->getValue() : $result; + $result = $addressFieldValue ? $addressFieldValue->getValue() : ''; } } diff --git a/src/classes/XLite/Model/AddressField.php b/src/classes/XLite/Model/AddressField.php index 2b663feff4..b046b761e1 100644 --- a/src/classes/XLite/Model/AddressField.php +++ b/src/classes/XLite/Model/AddressField.php @@ -93,6 +93,14 @@ class AddressField extends \XLite\Model\Base\I18n */ protected $required = true; + /** + * Flag if the field is an enabled one + * + * @var boolean + * @Column(type="boolean") + */ + protected $enabled = true; + /** * Position * @@ -102,7 +110,6 @@ class AddressField extends \XLite\Model\Base\I18n */ protected $position = 0; - /** * Address field value model relation * diff --git a/src/classes/XLite/Model/AddressFieldValue.php b/src/classes/XLite/Model/AddressFieldValue.php index ad696541ba..efda7f444d 100644 --- a/src/classes/XLite/Model/AddressFieldValue.php +++ b/src/classes/XLite/Model/AddressFieldValue.php @@ -56,17 +56,17 @@ class AddressFieldValue extends \XLite\Model\AEntity /** * Address field model relation * - * @var \Doctrine\Common\Collections\ArrayCollection + * @var \XLite\Model\AddressField * * @ManyToOne (targetEntity="XLite\Model\AddressField", inversedBy="value", cascade={"all"}) - * @JoinColumn(name="id", referencedColumnName="id") + * @JoinColumn(name="address_field_id", referencedColumnName="id") */ protected $addressField; /** * Address model relation * - * @var \Doctrine\Common\Collections\ArrayCollection + * @var \XLite\Model\Address * * @ManyToOne (targetEntity="XLite\Model\Address", inversedBy="fieldValue", cascade={"all"}) * @JoinColumn(name="address_id", referencedColumnName="address_id") diff --git a/src/classes/XLite/Model/Base/Address.php b/src/classes/XLite/Model/Base/Address.php index e96fe33eea..fe191037db 100644 --- a/src/classes/XLite/Model/Base/Address.php +++ b/src/classes/XLite/Model/Base/Address.php @@ -53,33 +53,6 @@ abstract class Address extends \XLite\Model\AEntity */ protected $address_type = 'R'; - /** - * Phone - * - * @var string - * - * @Column (type="string", length=32) - */ - protected $phone = ''; - - /** - * Street, number of building, apartment etc - * - * @var string - * - * @Column (type="string", length=255) - */ - protected $street = ''; - - /** - * City - * - * @var string - * - * @Column (type="string", length=255) - */ - protected $city = ''; - /** * State * @@ -109,15 +82,6 @@ abstract class Address extends \XLite\Model\AEntity */ protected $country; - /** - * Zip/postal code - * - * @var string - * - * @Column (type="string", length=32) - */ - protected $zipcode = ''; - /** * Get address fields list * diff --git a/src/classes/XLite/Model/Base/PersonalAddress.php b/src/classes/XLite/Model/Base/PersonalAddress.php index d0963aaaf0..9c514678c9 100644 --- a/src/classes/XLite/Model/Base/PersonalAddress.php +++ b/src/classes/XLite/Model/Base/PersonalAddress.php @@ -33,33 +33,6 @@ */ abstract class PersonalAddress extends \XLite\Model\Base\Address { - /** - * Title - * - * @var string - * - * @Column (type="string", length=32) - */ - protected $title = ''; - - /** - * First name - * - * @var string - * - * @Column (type="string", length=128) - */ - protected $firstname = ''; - - /** - * Last name - * - * @var string - * - * @Column (type="string", length=128) - */ - protected $lastname = ''; - /** * Get address fields list * diff --git a/src/classes/XLite/Model/Repo/AddressField.php b/src/classes/XLite/Model/Repo/AddressField.php new file mode 100644 index 0000000000..cf0440cba6 --- /dev/null +++ b/src/classes/XLite/Model/Repo/AddressField.php @@ -0,0 +1,140 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\Repo; + +/** + * The "address field" model repository + * + */ +class AddressField extends \XLite\Model\Repo\Base\I18n +{ + /** + * Default 'order by' field name + * + * @var string + */ + protected $defaultOrderBy = 'position'; + + /** + * currentSearchCnd + * + * @var \XLite\Core\CommonCell + */ + protected $currentSearchCnd = null; + + + /** + * Common search + * + * @param \XLite\Core\CommonCell $cnd Search condition + * @param boolean $countOnly Return items list or only its size OPTIONAL + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function search(\XLite\Core\CommonCell $cnd, $countOnly = false) + { + $queryBuilder = $countOnly + ? $this->createPureQueryBuilder() + : $this->createQueryBuilder(); + + $this->currentSearchCnd = $cnd; + + foreach ($this->currentSearchCnd as $key => $value) { + $this->callSearchConditionHandler($value, $key, $queryBuilder, $countOnly); + } + + return $countOnly + ? $this->searchCount($queryBuilder) + : $this->searchResult($queryBuilder); + } + + /** + * Search count only routine. + * + * @param \Doctrine\ORM\QueryBuilder $qb Query builder routine + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function searchCount(\Doctrine\ORM\QueryBuilder $qb) + { + $qb->select('COUNT(DISTINCT ' . $this->getMainAlias($qb) . '.' . $this->getPrimaryKeyField() . ')'); + + return intval($qb->getSingleScalarResult()); + } + + /** + * Search result routine. + * + * @param \Doctrine\ORM\QueryBuilder $qb Query builder routine + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function searchResult(\Doctrine\ORM\QueryBuilder $qb) + { + return $qb->getResult(); + } + + /** + * Return list of handling search params + * + * @return array + */ + protected function getHandlingSearchParams() + { + return array(); + } + + /** + * Check if param can be used for search + * + * @param string $param Name of param to check + * + * @return boolean + */ + protected function isSearchParamHasHandler($param) + { + return in_array($param, $this->getHandlingSearchParams()); + } + + /** + * Call corresponded method to handle a search condition + * + * @param mixed $value Condition data + * @param string $key Condition name + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * + * @return void + */ + protected function callSearchConditionHandler($value, $key, \Doctrine\ORM\QueryBuilder $queryBuilder, $countOnly) + { + if ($this->isSearchParamHasHandler($key)) { + $this->{'prepareCnd' . ucfirst($key)}($queryBuilder, $value, $countOnly); + + } else { + // TODO - add logging here + } + } +} diff --git a/src/classes/XLite/View/Address.php b/src/classes/XLite/View/Address.php index 0ba26a8e12..8e4b6da27d 100644 --- a/src/classes/XLite/View/Address.php +++ b/src/classes/XLite/View/Address.php @@ -141,23 +141,20 @@ public function getFieldValue($fieldName, $processValue = false) $methodName = 'get' . \XLite\Core\Converter::getInstance()->convertToCamelCase($fieldName); - if (method_exists($address, $methodName)) { + // $methodName assembled from 'get' + camelized $fieldName + $result = $address->$methodName(); - // $methodName assembled from 'get' + camelized $fieldName - $result = $address->$methodName(); + if ($result && false !== $processValue) { + switch ($fieldName) { + case 'state_id': + $result = $address->getState()->getState(); + break; - if (false !== $processValue) { - switch($fieldName) { - case 'state_id': - $result = $address->getState()->getState(); - break; + case 'country_code': + $result = $address->getCountry()->getCountry(); + break; - case 'country_code': - $result = $address->getCountry()->getCountry(); - break; - - default: - } + default: } } diff --git a/src/classes/XLite/View/Address/Field.php b/src/classes/XLite/View/Address/Field.php new file mode 100644 index 0000000000..f9e2271c57 --- /dev/null +++ b/src/classes/XLite/View/Address/Field.php @@ -0,0 +1,72 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Address; + +/** + * Address Field form widget + * + * @ListChild (list="admin.center", zone="admin") + */ +class Field extends \XLite\View\Dialog +{ + /** + * Register CSS files + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = $this->getDir() . '/style.css'; + + return $list; + } + + /** + * Return list of allowed targets + * + * @return array + */ + public static function getAllowedTargets() + { + $list = parent::getAllowedTargets(); + + $list[] = 'address_field'; + + return $list; + } + + /** + * Return templates directory name + * + * @return string + */ + protected function getDir() + { + return 'address/field'; + } +} diff --git a/src/classes/XLite/View/Address/Fields.php b/src/classes/XLite/View/Address/Fields.php new file mode 100644 index 0000000000..a3840a496b --- /dev/null +++ b/src/classes/XLite/View/Address/Fields.php @@ -0,0 +1,82 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Address; + +/** + * Address fields list + * + * @ListChild (list="admin.center", zone="admin") + */ +class Fields extends \XLite\View\Dialog +{ + /** + * Return list of allowed targets + * + * @return array + */ + public static function getAllowedTargets() + { + $list = parent::getAllowedTargets(); + + $list[] = 'address_fields'; + + return $list; + } + + /** + * Register CSS files + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + return $list; + } + + /** + * Register JS files + * + * @return array + */ + public function getJSFiles() + { + $list = parent::getJSFiles(); + + return $list; + } + + /** + * Return templates directory name + * + * @return string + */ + protected function getDir() + { + return 'address/fields'; + } +} diff --git a/src/classes/XLite/View/Form/AddressField.php b/src/classes/XLite/View/Form/AddressField.php new file mode 100644 index 0000000000..0ff46f70d2 --- /dev/null +++ b/src/classes/XLite/View/Form/AddressField.php @@ -0,0 +1,88 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Form; + +/** + * Address field form + * + */ +class AddressField extends \XLite\View\Form\AForm +{ + /** + * Register CSS files + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + return $list; + } + + /** + * Return default value for the "target" parameter + * + * @return string + */ + protected function getDefaultTarget() + { + return 'address_field'; + } + + /** + * Return default value for the "action" parameter + * + * @return string + */ + protected function getDefaultAction() + { + return 'update'; + } + + /** + * Get default class name + * + * @return string + */ + protected function getDefaultClassName() + { + return trim(parent::getDefaultClassName() . ' validationEngine role'); + } + + /** + * Return list of the form default parameters + * + * @return array + */ + protected function getDefaultParams() + { + return array( + 'id' => \XLite\Core\Request::getInstance()->id, + ); + } +} + diff --git a/src/classes/XLite/View/Form/ItemsList/AddressField/Main.php b/src/classes/XLite/View/Form/ItemsList/AddressField/Main.php new file mode 100644 index 0000000000..0ae03f02ef --- /dev/null +++ b/src/classes/XLite/View/Form/ItemsList/AddressField/Main.php @@ -0,0 +1,43 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Form\ItemsList\AddressField; + +/** + * Main address fields items list form + * + */ +class Main extends \XLite\View\Form\ItemsList\AItemsList +{ + /** + * getDefaultTarget + * + * @return string + */ + protected function getDefaultTarget() + { + return 'address_fields'; + } +} diff --git a/src/classes/XLite/View/ItemsList/Model/AModel.php b/src/classes/XLite/View/ItemsList/Model/AModel.php index 758b0a7f0a..9ecf028d33 100644 --- a/src/classes/XLite/View/ItemsList/Model/AModel.php +++ b/src/classes/XLite/View/ItemsList/Model/AModel.php @@ -791,8 +791,8 @@ protected function getListNameSuffixes() protected function buildEntityURL(\XLite\Model\AEntity $entity, array $column) { return \XLite\Core\Converter::buildURL( - $column[static::COLUMN_LINK], - '', + $column[static::COLUMN_LINK], + '', array($entity->getUniqueIdentifierName() => $entity->getUniqueIdentifier()) ); } @@ -853,7 +853,7 @@ protected function getSortableType() } /** - * Mark list as switchyabvle (enable / disable) + * Mark list as switchable (enable / disable) * * @return boolean */ diff --git a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php new file mode 100644 index 0000000000..9a5a405f09 --- /dev/null +++ b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php @@ -0,0 +1,177 @@ + + * @copyright Copyright (c) 2010-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\ItemsList\Model\Address; + +/** + * Address fields items list + * + */ +class Fields extends \XLite\View\ItemsList\Model\Table +{ + /** + * Define columns structure + * + * @return array + */ + protected function defineColumns() + { + return array( + 'name' => array( + static::COLUMN_NAME => static::t('Name'), + static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text', + static::COLUMN_PARAMS => array('required' => true), + ), + 'serviceName' => array( + static::COLUMN_NAME => static::t('Service name'), + static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text', + static::COLUMN_PARAMS => array('required' => true), + ), + 'required' => array( + static::COLUMN_NAME => static::t('Required'), + static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Checkbox\Switcher\Enabled', + static::COLUMN_PARAMS => array(), + ), + ); + } + + /** + * Define repository name + * + * @return string + */ + protected function defineRepositoryName() + { + return 'XLite\Model\AddressField'; + } + + // {{{ Behaviors + + /** + * Mark list as removable + * + * @return boolean + */ + protected function isRemoved() + { + return true; + } + + /** + * Mark list as switchable (enable / disable) + * + * @return boolean + */ + protected function isSwitchable() + { + return true; + } + + /** + * Mark list as sortable + * + * @return integer + */ + protected function getSortableType() + { + return static::SORT_TYPE_MOVE; + } + + /** + * Get create entity URL + * + * @return string + */ + protected function getCreateURL() + { + return \XLite\Core\Converter::buildURL('address_field'); + } + + /** + * Get create button label + * + * @return string + */ + protected function getCreateButtonLabel() + { + return 'New address field'; + } + + /** + * Creation button position + * + * @return integer + */ + protected function isCreation() + { + return static::CREATE_INLINE_TOP; + } + + // }}} + + /** + * Get container class + * + * @return string + */ + protected function getContainerClass() + { + return parent::getContainerClass() . ' address-fields'; + } + + /** + * Return params list to use for search + * + * @return \XLite\Core\CommonCell + */ + protected function getSearchCondition() + { + $result = parent::getSearchCondition(); + + return $result; + } + + /** + * Return "empty list" catalog + * + * @return string + */ + protected function getEmptyListDir() + { + return parent::getEmptyListDir(); + } + + /** + * Check - remove entity or not + * + * @param \XLite\Model\AEntity $entity Entity + * + * @return boolean + */ + protected function isAllowEntityRemove(\XLite\Model\AEntity $entity) + { + return $entity->getAdditional() && parent::isAllowEntityRemove($entity); + } +} diff --git a/src/classes/XLite/View/ItemsList/Model/Table.php b/src/classes/XLite/View/ItemsList/Model/Table.php index f2498d8516..f8be074b7f 100644 --- a/src/classes/XLite/View/ItemsList/Model/Table.php +++ b/src/classes/XLite/View/ItemsList/Model/Table.php @@ -148,7 +148,7 @@ protected function getColumns() /** * Returnd columns count - * + * * @return integer */ protected function getColumnsCount() @@ -158,7 +158,7 @@ protected function getColumnsCount() /** * Check - table header is visible or not - * + * * @return boolean */ protected function isTableHeaderVisible() @@ -295,8 +295,8 @@ protected function getFieldObjects() } /** - * Get switcher field - * + * Get switcher field + * * @return array */ protected function getSwitcherField() @@ -309,8 +309,8 @@ protected function getSwitcherField() } /** - * Get sort field - * + * Get sort field + * * @return array */ protected function getSortField() @@ -609,7 +609,7 @@ protected function getLeftActions() } /** - * Get right actions tempaltes + * Get right actions templates * * @return array */ @@ -626,9 +626,9 @@ protected function getRightActions() /** * Check - remove entity or not - * + * * @param \XLite\Model\AEntity $entity Entity - * + * * @return boolean */ protected function isAllowEntityRemove(\XLite\Model\AEntity $entity) @@ -708,9 +708,9 @@ protected function removeEntity(\XLite\Model\AEntity $entity) /** * Check - specified column is sorted or not - * + * * @param array $column COlumn - * + * * @return boolean */ protected function isColumnSorted(array $column) @@ -722,9 +722,9 @@ protected function isColumnSorted(array $column) /** * Get next sort direction - * + * * @param array $column Column - * + * * @return string */ protected function getSortDirectionNext(array $column) @@ -740,10 +740,10 @@ protected function getSortDirectionNext(array $column) } /** - * Get sort link class - * + * Get sort link class + * * @param array $column Column - * + * * @return string */ protected function getSortLinkClass(array $column) @@ -762,7 +762,7 @@ protected function getSortLinkClass(array $column) /** * Check - search-in-head mechanism is available or not - * + * * @return boolean */ protected function isHeadSearchVisible() @@ -781,9 +781,9 @@ protected function isHeadSearchVisible() /** * Check - specified column has search widget or not - * + * * @param array $column Column info - * + * * @return boolean */ protected function isSearchColumn(array $column) @@ -793,10 +793,10 @@ protected function isSearchColumn(array $column) /** - * Get search cell class - * + * Get search cell class + * * @param array $column ____param_comment____ - * + * * @return void */ protected function getSearchCellClass(array $column) @@ -806,5 +806,31 @@ protected function getSearchCellClass(array $column) } // }}} + + /** + * Check if the column template is used for widget displaying + * + * @param array $column + * @param \XLite\Model\AEntity $entity + * + * @return boolean + */ + protected function isTemplateColumnVisible(array $column, \XLite\Model\AEntity $entity) + { + return isset($column[static::COLUMN_TEMPLATE]); + } + + /** + * Check if the simple class is used for widget displaying + * + * @param array $column + * @param \XLite\Model\AEntity $entity + * + * @return boolean + */ + protected function isClassColumnVisible(array $column, \XLite\Model\AEntity $entity) + { + return !isset($column[static::COLUMN_TEMPLATE]); + } } diff --git a/src/classes/XLite/View/Model/AModel.php b/src/classes/XLite/View/Model/AModel.php index d0587d1ca3..dbce3f3267 100644 --- a/src/classes/XLite/View/Model/AModel.php +++ b/src/classes/XLite/View/Model/AModel.php @@ -1205,8 +1205,6 @@ protected function performActionDelete() return $this->getModelObject()->delete(); } - - /** * Retrieve property from the model object * @@ -1216,16 +1214,10 @@ protected function performActionDelete() */ protected function getModelObjectValue($name) { - $methodName = 'get' . \XLite\Core\Converter::getInstance()->convertToCamelCase($name); + $model = $this->getModelObject(); + $method = 'get' . \XLite\Core\Converter::convertToCamelCase($name); - $value = null; - - if (method_exists($this->getModelObject(), $methodName)) { - // Call the corresponded method - $value = $this->getModelObject()->$methodName(); - } - - return $value; + return method_exists($model, $method) ? $model->$method() : $model->getterProperty($name); } /** diff --git a/src/classes/XLite/View/Model/Address/Address.php b/src/classes/XLite/View/Model/Address/Address.php index 2e405d601e..d477ab6e26 100644 --- a/src/classes/XLite/View/Model/Address/Address.php +++ b/src/classes/XLite/View/Model/Address/Address.php @@ -43,39 +43,7 @@ class Address extends \XLite\View\Model\AModel * @var array */ protected $addressSchema = array( - 'title' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Select\Title', - self::SCHEMA_LABEL => 'Title', - self::SCHEMA_REQUIRED => false, - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-title', - ), - 'firstname' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'First name', - self::SCHEMA_REQUIRED => true, - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-firstname', - self::SCHEMA_MODEL_ATTRIBUTES => array( - \XLite\View\FormField\Input\Base\String::PARAM_MAX_LENGTH => 'length', - ), - ), - 'lastname' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'Last name', - self::SCHEMA_REQUIRED => true, - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-lastname', - self::SCHEMA_MODEL_ATTRIBUTES => array( - \XLite\View\FormField\Input\Base\String::PARAM_MAX_LENGTH => 'length', - ), - ), - 'street' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'Address', - self::SCHEMA_REQUIRED => true, - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-street', - self::SCHEMA_MODEL_ATTRIBUTES => array( - \XLite\View\FormField\Input\Base\String::PARAM_MAX_LENGTH => 'length', - ), - ), + /* 'country_code' => array( self::SCHEMA_CLASS => '\XLite\View\FormField\Select\Country', self::SCHEMA_LABEL => 'Country', @@ -94,33 +62,7 @@ class Address extends \XLite\View\Model\AModel self::SCHEMA_REQUIRED => false, \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-customer-state', ), - 'city' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'City', - self::SCHEMA_REQUIRED => true, - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-city', - self::SCHEMA_MODEL_ATTRIBUTES => array( - \XLite\View\FormField\Input\Base\String::PARAM_MAX_LENGTH => 'length', - ), - ), - 'zipcode' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'Zip code', - self::SCHEMA_REQUIRED => true, - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-zipcode', - self::SCHEMA_MODEL_ATTRIBUTES => array( - \XLite\View\FormField\Input\Base\String::PARAM_MAX_LENGTH => 'length', - ), - ), - 'phone' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'Phone', - self::SCHEMA_REQUIRED => true, - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-phone', - self::SCHEMA_MODEL_ATTRIBUTES => array( - \XLite\View\FormField\Input\Base\String::PARAM_MAX_LENGTH => 'length', - ), - ), + */ ); /** @@ -145,6 +87,20 @@ public function getAddressSchema() $result[$addressId . '_' . $key] = $data; } + foreach ( + \XLite\Core\Database::getRepo('XLite\Model\AddressField')->search(new \XLite\Core\CommonCell(array('enabled' => true))) as $field + ) { + $result[$addressId . '_' . $field->getServiceName()] = array( + static::SCHEMA_CLASS => $field->getSchemaClass(), + static::SCHEMA_LABEL => $field->getName(), + static::SCHEMA_REQUIRED => $field->getRequired(), + static::SCHEMA_MODEL_ATTRIBUTES => array( + \XLite\View\FormField\Input\Base\String::PARAM_MAX_LENGTH => 'length', + ), + \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-' . $field->getServiceName(), + ); + } + return $result; } @@ -239,8 +195,6 @@ protected function getDefaultModelObject() $this->address->setProfile($profile); } } - - $this->address->setZipcode(\XLite\Core\Config::getInstance()->General->default_zipcode); } } diff --git a/src/classes/XLite/View/Model/Address/Field.php b/src/classes/XLite/View/Model/Address/Field.php new file mode 100644 index 0000000000..3ccb0fcae5 --- /dev/null +++ b/src/classes/XLite/View/Model/Address/Field.php @@ -0,0 +1,155 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Model\Address; + +/** + * Field + * + */ +class Field extends \XLite\View\Model\AModel +{ + /** + * Shema default + * + * @var array + */ + protected $schemaDefault = array( + 'name' => array( + self::SCHEMA_CLASS => 'XLite\View\FormField\Input\Text', + self::SCHEMA_LABEL => 'Name of address field', + self::SCHEMA_REQUIRED => true, + ), + 'serviceName' => array( + self::SCHEMA_CLASS => 'XLite\View\FormField\Input\Text', + self::SCHEMA_LABEL => 'Service name of address field', + self::SCHEMA_REQUIRED => true, + ), + ); + + /** + * Return current model ID + * + * @return integer + */ + public function getModelId() + { + return \XLite\Core\Request::getInstance()->id; + } + + /** + * Return fields list by the corresponding schema + * + * @return array + */ + protected function getFormFieldsForSectionDefault() + { + return $this->getFieldsBySchema($this->schemaDefault); + } + + /** + * This object will be used if another one is not pased + * + * @return \XLite\Model\AddressField + */ + protected function getDefaultModelObject() + { + $model = $this->getModelId() + ? \XLite\Core\Database::getRepo('XLite\Model\AddressField')->find($this->getModelId()) + : null; + + return $model ?: new \XLite\Model\AddressField(); + } + + /** + * Return name of web form widget class + * + * @return string + */ + protected function getFormClass() + { + return '\XLite\View\Form\AddressField'; + } + + /** + * Return list of the "Button" widgets + * + * @return array + */ + protected function getFormButtons() + { + $result = parent::getFormButtons(); + + $label = $this->getModelObject()->getId() ? 'Update' : 'Create'; + + $result['submit'] = new \XLite\View\Button\Submit( + array( + \XLite\View\Button\AButton::PARAM_LABEL => $label, + \XLite\View\Button\AButton::PARAM_STYLE => 'action', + ) + ); + + return $result; + } + + /** + * Populate model object properties by the passed data + * + * @param array $data Data to set + * + * @return void + */ + protected function setModelProperties(array $data) + { + parent::setModelProperties($data); + } + + /** + * Add top message + * + * @return void + */ + protected function addDataSavedTopMessage() + { + if ($this->getModelObject()->getId()) { + \XLite\Core\TopMessage::addInfo('The address field has been updated'); + } else { + \XLite\Core\TopMessage::addInfo('The address field has been added'); + } + } + + /** + * Retrieve property from the model object + * + * @param mixed $name Field/property name + * + * @return mixed + */ + protected function getModelObjectValue($name) + { + return parent::getModelObjectValue($name); + } + +} diff --git a/src/classes/XLite/View/TopMenu/Node/Users/AddressFields.php b/src/classes/XLite/View/TopMenu/Node/Users/AddressFields.php new file mode 100644 index 0000000000..83043c7a74 --- /dev/null +++ b/src/classes/XLite/View/TopMenu/Node/Users/AddressFields.php @@ -0,0 +1,49 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\TopMenu\Node\Users; + +/** + * Address fields management + * + * + * @ListChild (list="menu.users", weight="600", zone="admin") + */ +class AddressFields extends \XLite\View\TopMenu\Node\Users\AUsers +{ + /** + * Define widget parameters + * + * @return void + */ + protected function defineWidgetParams() + { + parent::defineWidgetParams(); + + $this->widgetParams[self::PARAM_TITLE]->setValue(static::t('Address fields')); + $this->widgetParams[self::PARAM_TARGET]->setValue('address_fields'); + } +} + diff --git a/src/skins/admin/en/address/field/body.tpl b/src/skins/admin/en/address/field/body.tpl new file mode 100644 index 0000000000..13840ce996 --- /dev/null +++ b/src/skins/admin/en/address/field/body.tpl @@ -0,0 +1,12 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Address field modify + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + diff --git a/src/skins/admin/en/address/field/style.css b/src/skins/admin/en/address/field/style.css new file mode 100644 index 0000000000..490d90e474 --- /dev/null +++ b/src/skins/admin/en/address/field/style.css @@ -0,0 +1,13 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Address form styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + + + \ No newline at end of file diff --git a/src/skins/admin/en/address/fields/body.tpl b/src/skins/admin/en/address/fields/body.tpl new file mode 100644 index 0000000000..3f8fd4d99b --- /dev/null +++ b/src/skins/admin/en/address/fields/body.tpl @@ -0,0 +1,13 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Address fields page + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + + \ No newline at end of file diff --git a/src/skins/admin/en/items_list/model/table/body.tpl b/src/skins/admin/en/items_list/model/table/body.tpl index 415fdad6ca..8abe34708f 100644 --- a/src/skins/admin/en/items_list/model/table/body.tpl +++ b/src/skins/admin/en/items_list/model/table/body.tpl @@ -31,11 +31,8 @@ {foreach:getPageData(),idx,entity} - {if:column.template} - - {else:} - - {end:} + + diff --git a/src/sql/xlite_data.yaml b/src/sql/xlite_data.yaml index c022451d7e..4d00789797 100644 --- a/src/sql/xlite_data.yaml +++ b/src/sql/xlite_data.yaml @@ -1163,3 +1163,17 @@ XLite\Model\Role\Permission: - { code: manage catalog, section: Catalog, translations: [{ code: en, name: Manage catalog }] } - { code: manage users, section: Users, translations: [{ code: en, name: Manage users }] } - { code: manage orders, section: Sales, translations: [{ code: en, name: Manage orders }] } + +XLite\Model\AddressField: + - { serviceName: title, additional: false, required: false, translations: [{ code: en, name: Title }], schemaClass: \XLite\View\FormField\Select\Title } + - { serviceName: firstname, additional: false, required: true, translations: [{ code: en, name: First name }] } + - { serviceName: lastname, additional: false, required: true, translations: [{ code: en, name: Last name }] } + - { serviceName: street, additional: false, required: true, translations: [{ code: en, name: Address }] } + - { serviceName: city, additional: false, required: true, translations: [{ code: en, name: City }] } + - { serviceName: zipcode, additional: false, required: true, translations: [{ code: en, name: Zip code }] } + - { serviceName: phone, additional: false, required: true, translations: [{ code: en, name: Phone }] } + - { serviceName: country_code, additional: false, required: true, translations: [{ code: en, name: Country }], schemaClass: \XLite\View\FormField\Select\Country } + - { serviceName: state_id, additional: false, required: true, translations: [{ code: en, name: State }], schemaClass: \XLite\View\FormField\Select\State } + - { serviceName: custom_state, additional: false, required: false, translations: [{ code: en, name: State }]} + + From 42b8f7dc0671d0af4827a0ac0d1e28ccdb0304db Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Wed, 12 Sep 2012 18:00:35 +0400 Subject: [PATCH 09/85] [*] Address fields feature further changes. --- src/classes/XLite/Model/Address.php | 10 --- src/classes/XLite/Model/AddressField.php | 10 --- src/classes/XLite/Model/AddressFieldValue.php | 6 +- src/classes/XLite/Model/Repo/AddressField.php | 22 +++++- src/classes/XLite/View/Address.php | 75 ++++--------------- .../XLite/View/Model/Address/Address.php | 33 ++------ 6 files changed, 45 insertions(+), 111 deletions(-) diff --git a/src/classes/XLite/Model/Address.php b/src/classes/XLite/Model/Address.php index 8976d9d861..4848f080a4 100644 --- a/src/classes/XLite/Model/Address.php +++ b/src/classes/XLite/Model/Address.php @@ -76,16 +76,6 @@ class Address extends \XLite\Model\Base\PersonalAddress */ protected $profile; - /** - * Address field value relation. one-to-many relation with address field entities - * - * @var \Doctrine\Common\Collections\ArrayCollection - * - * @OneToMany (targetEntity="XLite\Model\AddressFieldValue", mappedBy="address", cascade={"all"}) - */ - protected $fieldValue; - - /** * Universal setter * diff --git a/src/classes/XLite/Model/AddressField.php b/src/classes/XLite/Model/AddressField.php index b046b761e1..3e3f9bb9f3 100644 --- a/src/classes/XLite/Model/AddressField.php +++ b/src/classes/XLite/Model/AddressField.php @@ -110,14 +110,4 @@ class AddressField extends \XLite\Model\Base\I18n */ protected $position = 0; - /** - * Address field value model relation - * - * @var \Doctrine\Common\Collections\ArrayCollection - * - * @OneToMany (targetEntity="XLite\Model\AddressFieldValue", mappedBy="addressField", cascade={"all"}) - * @JoinColumn(name="id", referencedColumnName="id") - */ - protected $value; - } diff --git a/src/classes/XLite/Model/AddressFieldValue.php b/src/classes/XLite/Model/AddressFieldValue.php index efda7f444d..d76cd33d80 100644 --- a/src/classes/XLite/Model/AddressFieldValue.php +++ b/src/classes/XLite/Model/AddressFieldValue.php @@ -58,8 +58,8 @@ class AddressFieldValue extends \XLite\Model\AEntity * * @var \XLite\Model\AddressField * - * @ManyToOne (targetEntity="XLite\Model\AddressField", inversedBy="value", cascade={"all"}) - * @JoinColumn(name="address_field_id", referencedColumnName="id") + * @ManyToOne (targetEntity="XLite\Model\AddressField", cascade="all") + * @JoinColumn(name="address_field_id", referencedColumnName="id", onDelete="SET NULL") */ protected $addressField; @@ -68,7 +68,7 @@ class AddressFieldValue extends \XLite\Model\AEntity * * @var \XLite\Model\Address * - * @ManyToOne (targetEntity="XLite\Model\Address", inversedBy="fieldValue", cascade={"all"}) + * @ManyToOne (targetEntity="XLite\Model\Address", cascade="all") * @JoinColumn(name="address_id", referencedColumnName="address_id") */ protected $address; diff --git a/src/classes/XLite/Model/Repo/AddressField.php b/src/classes/XLite/Model/Repo/AddressField.php index cf0440cba6..5a8293abd1 100644 --- a/src/classes/XLite/Model/Repo/AddressField.php +++ b/src/classes/XLite/Model/Repo/AddressField.php @@ -45,7 +45,7 @@ class AddressField extends \XLite\Model\Repo\Base\I18n */ protected $currentSearchCnd = null; - + /** * Common search * @@ -104,7 +104,9 @@ public function searchResult(\Doctrine\ORM\QueryBuilder $qb) */ protected function getHandlingSearchParams() { - return array(); + return array( + 'enabled', + ); } /** @@ -137,4 +139,20 @@ protected function callSearchConditionHandler($value, $key, \Doctrine\ORM\QueryB // TODO - add logging here } } + + /** + * Prepare query builder for enabled status search + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder + * @param boolean $value + * @param boolean $countOnly + * + * @return void + */ + protected function prepareCndEnabled(\Doctrine\ORM\QueryBuilder $queryBuilder, $value, $countOnly) + { + $queryBuilder + ->andWhere($this->getMainAlias($queryBuilder) . '.enabled = :enabled_value') + ->setParameter('enabled_value', $value); + } } diff --git a/src/classes/XLite/View/Address.php b/src/classes/XLite/View/Address.php index 8e4b6da27d..99f5136178 100644 --- a/src/classes/XLite/View/Address.php +++ b/src/classes/XLite/View/Address.php @@ -56,73 +56,28 @@ class Address extends \XLite\View\Dialog * * @var array */ - protected $schema = array( - 'title' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Select\Title', - self::SCHEMA_LABEL => 'Title', - ), - 'firstname' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'First name', - self::SCHEMA_REQUIRED => true, - ), - 'lastname' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'Last name', - self::SCHEMA_REQUIRED => true, - ), - 'street' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'Street', - self::SCHEMA_REQUIRED => true, - ), - 'city' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'City', - self::SCHEMA_REQUIRED => true, - ), - 'state_id' => array( - self::SCHEMA_CLASS => '\XLite\View\StateSelect', - self::SCHEMA_LABEL => 'State', - self::SCHEMA_REQUIRED => true, - ), - 'custom_state' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'Another state', - self::SCHEMA_REQUIRED => false, - ), - 'zipcode' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'Zip code', - self::SCHEMA_REQUIRED => true, - ), - 'country_code' => array( - self::SCHEMA_CLASS => '\XLite\View\CountrySelect', - self::SCHEMA_LABEL => 'Country', - self::SCHEMA_REQUIRED => true, - ), - 'phone' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'Phone', - self::SCHEMA_REQUIRED => true, - ), - /* TODO: move to the shipping module where this field is required - 'address_type' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Select\AddressType', - self::SCHEMA_LABEL => 'Address type', - self::SCHEMA_REQUIRED => true, - ), - */ - ); + protected $schema = array(); /** * getSchemaFields * - * @return void + * @return array */ public function getSchemaFields() { - return $this->schema; + $result = $this->schema; + + foreach ( + \XLite\Core\Database::getRepo('XLite\Model\AddressField')->search(new \XLite\Core\CommonCell(array('enabled' => true))) as $field + ) { + $result[$field->getServiceName()] = array( + static::SCHEMA_CLASS => $field->getSchemaClass(), + static::SCHEMA_LABEL => $field->getName(), + static::SCHEMA_REQUIRED => $field->getRequired(), + ); + } + + return $result; } /** diff --git a/src/classes/XLite/View/Model/Address/Address.php b/src/classes/XLite/View/Model/Address/Address.php index d477ab6e26..aaedcb41e8 100644 --- a/src/classes/XLite/View/Model/Address/Address.php +++ b/src/classes/XLite/View/Model/Address/Address.php @@ -42,28 +42,7 @@ class Address extends \XLite\View\Model\AModel * * @var array */ - protected $addressSchema = array( - /* - 'country_code' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Select\Country', - self::SCHEMA_LABEL => 'Country', - self::SCHEMA_REQUIRED => true, - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-country', - ), - 'state_id' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Select\State', - self::SCHEMA_LABEL => 'State', - self::SCHEMA_REQUIRED => true, - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-state', - ), - 'custom_state' => array( - self::SCHEMA_CLASS => '\XLite\View\FormField\Input\Text', - self::SCHEMA_LABEL => 'State', - self::SCHEMA_REQUIRED => false, - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-customer-state', - ), - */ - ); + protected $addressSchema = array(); /** * Address instance @@ -234,10 +213,12 @@ protected function setStateSelectorIds(array &$fields) { $addressId = $this->getAddressId(); - $fields[$addressId . '_country_code']->setStateSelectorIds( - $fields[$addressId . '_state_id']->getFieldId(), - $fields[$addressId . '_custom_state']->getFieldId() - ); + if ($fields[$addressId . '_state_id'] && $fields[$addressId . '_custom_state']) { + $fields[$addressId . '_country_code']->setStateSelectorIds( + $fields[$addressId . '_state_id']->getFieldId(), + $fields[$addressId . '_custom_state']->getFieldId() + ); + } } /** From f28bf95543056b71865ad36c042b09ff5a010ea5 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Fri, 14 Sep 2012 17:12:51 +0400 Subject: [PATCH 10/85] [*] Checkout is changed for address fields feature. Address clone improvement. [*] Some checkout optimization. Address cache using. --- src/classes/XLite/Model/Address.php | 18 +++++++++++++++++ src/classes/XLite/Model/Profile.php | 20 ++++++++++++++++--- src/classes/XLite/Model/Repo/AddressField.php | 10 ++++++++++ .../XLite/View/Checkout/ShippingAddress.php | 2 +- .../XLite/View/Model/Address/Address.php | 5 ++--- .../en/checkout/steps/payment/address.tpl | 2 +- .../steps/payment/parts/address.address.tpl | 2 +- .../steps/payment/parts/address.city.tpl | 2 +- .../steps/payment/parts/address.country.tpl | 2 +- .../steps/payment/parts/address.name.tpl | 2 +- .../steps/payment/parts/address.phone.tpl | 2 +- .../steps/payment/parts/address.state.tpl | 2 +- .../steps/payment/parts/address.zipcode.tpl | 2 +- .../en/checkout/steps/shipping/address.tpl | 2 +- .../invoice/parts/bottom.address.billing.tpl | 12 +++++------ .../invoice/parts/bottom.address.shipping.tpl | 14 ++++++------- .../en/order/invoice/parts/bottom.address.tpl | 2 +- 17 files changed, 71 insertions(+), 30 deletions(-) diff --git a/src/classes/XLite/Model/Address.php b/src/classes/XLite/Model/Address.php index 4848f080a4..46f62c5636 100644 --- a/src/classes/XLite/Model/Address.php +++ b/src/classes/XLite/Model/Address.php @@ -223,6 +223,24 @@ public function cloneEntity() { $entity = parent::cloneEntity(); + $cnd = array('address' => $this); + + foreach (\XLite\Core\Database::getRepo('XLite\Model\AddressField')->findAllEnabled() as $field) { + + $cnd['addressField'] = $field; + + $fieldValue = \XLite\Core\Database::getRepo('XLite\Model\AddressFieldValue')->findOneBy($cnd); + + if ($fieldValue) { + + $newFieldValue = $fieldValue->cloneEntity(); + $newFieldValue->setAddress($entity); + $newFieldValue->setAddressField($field); + } + + \XLite\Core\Database::getEM()->persist($newFieldValue); + } + if ($this->getProfile()) { $entity->setProfile($this->getProfile()); } diff --git a/src/classes/XLite/Model/Profile.php b/src/classes/XLite/Model/Profile.php index 414697daa3..4d3b092ec4 100644 --- a/src/classes/XLite/Model/Profile.php +++ b/src/classes/XLite/Model/Profile.php @@ -257,6 +257,14 @@ class Profile extends \XLite\Model\AEntity protected $orders_count = null; + /** + * Cache for address types + * + * @var array Array of \XLite\Model\Address elements + */ + protected $addressCache = array(); + + /** * Set membership * @@ -308,7 +316,9 @@ public function getPendingMembershipId() */ public function getBillingAddress() { - return $this->getAddressByType(\XLite\Model\Address::BILLING); + return isset($this->addressCache[\XLite\Model\Address::BILLING]) + ? $this->addressCache[\XLite\Model\Address::BILLING] + : $this->getAddressByType(\XLite\Model\Address::BILLING); } /** @@ -318,7 +328,9 @@ public function getBillingAddress() */ public function getShippingAddress() { - return $this->getAddressByType(\XLite\Model\Address::SHIPPING); + return isset($this->addressCache[\XLite\Model\Address::SHIPPING]) + ? $this->addressCache[\XLite\Model\Address::SHIPPING] + : $this->getAddressByType(\XLite\Model\Address::SHIPPING); } /** @@ -578,7 +590,7 @@ public function setOrder(\XLite\Model\Order $order = null) /** * Get password hash algorhitm - * + * * @return string */ public function getPasswordAlgo() @@ -647,6 +659,8 @@ protected function getAddressByType($atype = \XLite\Model\Address::BILLING) } } + $this->addressCache[$atype] = $result; + return $result; } diff --git a/src/classes/XLite/Model/Repo/AddressField.php b/src/classes/XLite/Model/Repo/AddressField.php index 5a8293abd1..273f177583 100644 --- a/src/classes/XLite/Model/Repo/AddressField.php +++ b/src/classes/XLite/Model/Repo/AddressField.php @@ -97,6 +97,16 @@ public function searchResult(\Doctrine\ORM\QueryBuilder $qb) return $qb->getResult(); } + /** + * Get all enabled address fields + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function findAllEnabled() + { + return $this->search(new \XLite\Core\CommonCell(array('enabled' => true))); + } + /** * Return list of handling search params * diff --git a/src/classes/XLite/View/Checkout/ShippingAddress.php b/src/classes/XLite/View/Checkout/ShippingAddress.php index 118e2a07ea..5c860c57a4 100644 --- a/src/classes/XLite/View/Checkout/ShippingAddress.php +++ b/src/classes/XLite/View/Checkout/ShippingAddress.php @@ -36,7 +36,7 @@ class ShippingAddress extends \XLite\View\AView * * @return \XLite\Model\Address */ - public function getAddress() + public function getShippingAddress() { $address = null; diff --git a/src/classes/XLite/View/Model/Address/Address.php b/src/classes/XLite/View/Model/Address/Address.php index aaedcb41e8..0c3ca3f0fb 100644 --- a/src/classes/XLite/View/Model/Address/Address.php +++ b/src/classes/XLite/View/Model/Address/Address.php @@ -66,9 +66,8 @@ public function getAddressSchema() $result[$addressId . '_' . $key] = $data; } - foreach ( - \XLite\Core\Database::getRepo('XLite\Model\AddressField')->search(new \XLite\Core\CommonCell(array('enabled' => true))) as $field - ) { + foreach (\XLite\Core\Database::getRepo('XLite\Model\AddressField')->findAllEnabled() as $field) { + $result[$addressId . '_' . $field->getServiceName()] = array( static::SCHEMA_CLASS => $field->getSchemaClass(), static::SCHEMA_LABEL => $field->getName(), diff --git a/src/skins/default/en/checkout/steps/payment/address.tpl b/src/skins/default/en/checkout/steps/payment/address.tpl index f9d3ebedb1..f98034ce31 100644 --- a/src/skins/default/en/checkout/steps/payment/address.tpl +++ b/src/skins/default/en/checkout/steps/payment/address.tpl @@ -21,7 +21,7 @@ {else:}
    - +
{if:!isAnonymous()} diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.address.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.address.tpl index c28f35a3fc..48fc84d54c 100644 --- a/src/skins/default/en/checkout/steps/payment/parts/address.address.tpl +++ b/src/skins/default/en/checkout/steps/payment/parts/address.address.tpl @@ -12,5 +12,5 @@ *}
  • - +
  • diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.city.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.city.tpl index 1ebb56c099..a0d674f9ef 100644 --- a/src/skins/default/en/checkout/steps/payment/parts/address.city.tpl +++ b/src/skins/default/en/checkout/steps/payment/parts/address.city.tpl @@ -12,5 +12,5 @@ *}
  • - +
  • diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.country.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.country.tpl index 620805ccce..e966ae05de 100644 --- a/src/skins/default/en/checkout/steps/payment/parts/address.country.tpl +++ b/src/skins/default/en/checkout/steps/payment/parts/address.country.tpl @@ -12,5 +12,5 @@ *}
  • - +
  • diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.name.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.name.tpl index 8dfffb9ec2..5d2f2b4022 100644 --- a/src/skins/default/en/checkout/steps/payment/parts/address.name.tpl +++ b/src/skins/default/en/checkout/steps/payment/parts/address.name.tpl @@ -12,5 +12,5 @@ *}
  • - +
  • diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.phone.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.phone.tpl index 5f3dbc6327..a27e08bb8b 100644 --- a/src/skins/default/en/checkout/steps/payment/parts/address.phone.tpl +++ b/src/skins/default/en/checkout/steps/payment/parts/address.phone.tpl @@ -12,5 +12,5 @@ *}
  • - +
  • diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.state.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.state.tpl index 6714a9fa47..ec95a3fc6a 100644 --- a/src/skins/default/en/checkout/steps/payment/parts/address.state.tpl +++ b/src/skins/default/en/checkout/steps/payment/parts/address.state.tpl @@ -12,5 +12,5 @@ *}
  • - +
  • diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.zipcode.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.zipcode.tpl index b6ce4b798d..c8f9d080ac 100644 --- a/src/skins/default/en/checkout/steps/payment/parts/address.zipcode.tpl +++ b/src/skins/default/en/checkout/steps/payment/parts/address.zipcode.tpl @@ -12,5 +12,5 @@ *}
  • - +
  • diff --git a/src/skins/default/en/checkout/steps/shipping/address.tpl b/src/skins/default/en/checkout/steps/shipping/address.tpl index 85bb47e2c0..461d480ea2 100644 --- a/src/skins/default/en/checkout/steps/shipping/address.tpl +++ b/src/skins/default/en/checkout/steps/shipping/address.tpl @@ -9,5 +9,5 @@ * @link http://www.litecommerce.com/ *}
      - +
    diff --git a/src/skins/default/en/order/invoice/parts/bottom.address.billing.tpl b/src/skins/default/en/order/invoice/parts/bottom.address.billing.tpl index 6786323c56..2e99cb49e3 100644 --- a/src/skins/default/en/order/invoice/parts/bottom.address.billing.tpl +++ b/src/skins/default/en/order/invoice/parts/bottom.address.billing.tpl @@ -13,17 +13,17 @@ {t(#Billing address#)}

    - {order.profile.billing_address.title} {order.profile.billing_address.firstname} {order.profile.billing_address.lastname} + {baddress.title} {baddress.firstname} {baddress.lastname}

    - {order.profile.billing_address.street}
    - {order.profile.billing_address.city}, {order.profile.billing_address.state.state}, {order.profile.billing_address.zipcode}
    - {order.profile.billing_address.country.country} + {baddress.street}
    + {baddress.city}, {baddress.state.state}, {baddress.zipcode}
    + {baddress.country.country}

    -

    - {t(#Phone#)}: {order.profile.billing_address.phone} +

    + {t(#Phone#)}: {baddress.phone}

    diff --git a/src/skins/default/en/order/invoice/parts/bottom.address.shipping.tpl b/src/skins/default/en/order/invoice/parts/bottom.address.shipping.tpl index a236824fee..3c0a19ae9d 100644 --- a/src/skins/default/en/order/invoice/parts/bottom.address.shipping.tpl +++ b/src/skins/default/en/order/invoice/parts/bottom.address.shipping.tpl @@ -10,19 +10,19 @@ * * @ListChild (list="invoice.bottom.address", weight="10") *} - + {t(#Shipping address#)}

    - {order.profile.shipping_address.title} {order.profile.shipping_address.firstname} {order.profile.shipping_address.lastname} + {saddress.title} {saddress.firstname} {saddress.lastname}

    - {order.profile.shipping_address.street}
    - {order.profile.shipping_address.city}, {order.profile.shipping_address.state.state}, {order.profile.shipping_address.zipcode}
    - {order.profile.shipping_address.country.country} + {saddress.street}
    + {saddress.city}, {saddress.state.state}, {saddress.zipcode}
    + {saddress.country.country}

    -

    - {t(#Phone#)}: {order.profile.shipping_address.phone} +

    + {t(#Phone#)}: {saddress.phone}

    diff --git a/src/skins/default/en/order/invoice/parts/bottom.address.tpl b/src/skins/default/en/order/invoice/parts/bottom.address.tpl index b763e4bf7f..3533bf7096 100644 --- a/src/skins/default/en/order/invoice/parts/bottom.address.tpl +++ b/src/skins/default/en/order/invoice/parts/bottom.address.tpl @@ -10,4 +10,4 @@ * * @ListChild (list="invoice.bottom", weight="10") *} - + From 2a7e672828cd3f1ebdeb32bcb7e91b968a66b6e1 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Sat, 15 Sep 2012 01:01:50 +0400 Subject: [PATCH 11/85] [*] Order details page changes for address fields feature. --- src/classes/XLite/Model/AddressField.php | 14 +++++++ src/classes/XLite/Model/Base/Address.php | 20 ++++++++++ src/classes/XLite/View/AView.php | 28 ++++++++++++++ .../XLite/View/Order/Details/Admin/Info.php | 2 +- src/skins/admin/en/order/page/info.css | 37 +++++++++++++++++-- .../en/order/page/parts/payment.address.tpl | 17 ++++----- .../en/order/page/parts/shipping.address.tpl | 17 ++++----- src/sql/xlite_data.yaml | 6 +-- 8 files changed, 114 insertions(+), 27 deletions(-) diff --git a/src/classes/XLite/Model/AddressField.php b/src/classes/XLite/Model/AddressField.php index 3e3f9bb9f3..8897f54e57 100644 --- a/src/classes/XLite/Model/AddressField.php +++ b/src/classes/XLite/Model/AddressField.php @@ -57,6 +57,20 @@ class AddressField extends \XLite\Model\Base\I18n */ protected $serviceName; + /** + * Getter name for address field (for AView::getAddressSectionData) + * For example: + * country for country_code + * state for state_id, custom_state + * + * The field is named with this value in the address forms. + * Also the "service-name-{$serviceName}" CSS class is added to the field + * + * @var string + * @Column(type="string", length=128, nullable=false) + */ + protected $viewGetterName = ''; + /** * Schema class for "Form field widget". * This class will be used in form widgets diff --git a/src/classes/XLite/Model/Base/Address.php b/src/classes/XLite/Model/Base/Address.php index fe191037db..4de176ab52 100644 --- a/src/classes/XLite/Model/Base/Address.php +++ b/src/classes/XLite/Model/Base/Address.php @@ -180,6 +180,26 @@ public function getCountryCode() return $this->getCountry() ? $this->getCountry()->getCode() : null; } + /** + * Get country name + * + * @return string + */ + public function getCountryName() + { + return $this->getCountry() ? $this->getCountry()->getCountry() : null; + } + + /** + * Get state name + * + * @return string + */ + public function getStateName() + { + return $this->getState()->getState(); + } + /** * Get required fields by address type * diff --git a/src/classes/XLite/View/AView.php b/src/classes/XLite/View/AView.php index 51fa3347f8..542e25a9de 100644 --- a/src/classes/XLite/View/AView.php +++ b/src/classes/XLite/View/AView.php @@ -1840,4 +1840,32 @@ public function getInvoiceLogo() ); } + /** + * Return specific data for address entry. Helper. + * + * @param \XLite\Model\Address $address + * + * @return array + */ + protected function getAddressSectionData(\XLite\Model\Address $address) + { + $result = array(); + $repo = \XLite\Core\Database::getRepo('XLite\Model\AddressFieldValue'); + + foreach (\XLite\Core\Database::getRepo('XLite\Model\AddressField')->findAllEnabled() as $field) { + + $addressFieldValue = $address->{'get' . \Includes\Utils\Converter::convertToCamelCase($field->getViewGetterName() ?: $field->getServiceName())}(); + + if ($addressFieldValue) { + $result[$field->getServiceName()] = array( + 'css_class' => 'address-' . $field->getServiceName(), + 'title' => $field->getName(), + 'value' => $addressFieldValue, + ); + } + } + + return $result; + } + } diff --git a/src/classes/XLite/View/Order/Details/Admin/Info.php b/src/classes/XLite/View/Order/Details/Admin/Info.php index b090d62406..f57b5f9165 100644 --- a/src/classes/XLite/View/Order/Details/Admin/Info.php +++ b/src/classes/XLite/View/Order/Details/Admin/Info.php @@ -268,6 +268,6 @@ protected function hasPaymentTransactionSums() } // }}} - + } diff --git a/src/skins/admin/en/order/page/info.css b/src/skins/admin/en/order/page/info.css index 0b2c975f21..9907bbd013 100644 --- a/src/skins/admin/en/order/page/info.css +++ b/src/skins/admin/en/order/page/info.css @@ -166,16 +166,47 @@ div.line-2 .box .address strong { display: block; } -div.line-2 .box .address p { +div.line-2 .box .address ul.address-section { + padding-top: 12px; +} + +div.line-2 .box .address ul.address-section li.address-field { + padding-right: 4px; +} + +div.line-2 .box .address ul.address-section li.address-field.address-custom_state { + display: none; +} + +div.line-2 .box .address ul.address-section li.address-field span { font-size: 14px; line-height: 20px; padding-top: 8px; } -div.line-2 .box .address p.name { - padding-top: 12px; +ul.address-section li.address-field .address-title, + ul.address-section li.address-field .address-comma +{ + display: none; } +ul.address-section li.address-field.address-phone .address-title, + ul.address-section li.address-field.address-city .address-comma, + ul.address-section li.address-field.address-street .address-comma, + ul.address-section li.address-field.address-state .address-comma +{ + display: inline; +} + +ul.address-section li.address-field.address-title, + ul.address-section li.address-field.address-firstname, + ul.address-section li.address-field.address-city, + ul.address-section li.address-field.address-state +{ + float: left; +} + + /* Payment */ div.payment { float: left; diff --git a/src/skins/admin/en/order/page/parts/payment.address.tpl b/src/skins/admin/en/order/page/parts/payment.address.tpl index 73ed39864d..8496235560 100644 --- a/src/skins/admin/en/order/page/parts/payment.address.tpl +++ b/src/skins/admin/en/order/page/parts/payment.address.tpl @@ -13,15 +13,12 @@
    {t(#Billing address#)} -

    {order.profile.billing_address.title} {order.profile.billing_address.firstname} {order.profile.billing_address.lastname}

    -

    - {order.profile.billing_address.street}
    - {order.profile.billing_address.city}, {order.profile.billing_address.state.state}, {order.profile.billing_address.zipcode}
    - {order.profile.billing_address.country.country} -

    - -

    - {t(#Phone#)}: {order.profile.billing_address.phone} -

    +
      +
    • + {field.title}: + {field.value} + , +
    • +
    diff --git a/src/skins/admin/en/order/page/parts/shipping.address.tpl b/src/skins/admin/en/order/page/parts/shipping.address.tpl index 09af8d6817..b7b64cc43a 100644 --- a/src/skins/admin/en/order/page/parts/shipping.address.tpl +++ b/src/skins/admin/en/order/page/parts/shipping.address.tpl @@ -13,15 +13,12 @@
    {t(#Shipping address#)} -

    {order.profile.shipping_address.title} {order.profile.shipping_address.firstname} {order.profile.shipping_address.lastname}

    -

    - {order.profile.shipping_address.street}
    - {order.profile.shipping_address.city}, {order.profile.shipping_address.state.state}, {order.profile.shipping_address.zipcode}
    - {order.profile.shipping_address.country.country} -

    - -

    - {t(#Phone#)}: {order.profile.shipping_address.phone} -

    +
      +
    • + {t(field.title)}: + {field.value} + , +
    • +
    diff --git a/src/sql/xlite_data.yaml b/src/sql/xlite_data.yaml index 4d00789797..1515005898 100644 --- a/src/sql/xlite_data.yaml +++ b/src/sql/xlite_data.yaml @@ -1170,10 +1170,10 @@ XLite\Model\AddressField: - { serviceName: lastname, additional: false, required: true, translations: [{ code: en, name: Last name }] } - { serviceName: street, additional: false, required: true, translations: [{ code: en, name: Address }] } - { serviceName: city, additional: false, required: true, translations: [{ code: en, name: City }] } + - { serviceName: country_code, additional: false, required: true, translations: [{ code: en, name: Country }], schemaClass: \XLite\View\FormField\Select\Country, viewGetterName: country_name } + - { serviceName: state_id, additional: false, required: true, translations: [{ code: en, name: State }], schemaClass: \XLite\View\FormField\Select\State, viewGetterName: state_name } + - { serviceName: custom_state, additional: false, required: false, translations: [{ code: en, name: State }], viewGetterName: state_name } - { serviceName: zipcode, additional: false, required: true, translations: [{ code: en, name: Zip code }] } - { serviceName: phone, additional: false, required: true, translations: [{ code: en, name: Phone }] } - - { serviceName: country_code, additional: false, required: true, translations: [{ code: en, name: Country }], schemaClass: \XLite\View\FormField\Select\Country } - - { serviceName: state_id, additional: false, required: true, translations: [{ code: en, name: State }], schemaClass: \XLite\View\FormField\Select\State } - - { serviceName: custom_state, additional: false, required: false, translations: [{ code: en, name: State }]} From f5c60585d43065ec22dbce5a3d948283fafe0fe4 Mon Sep 17 00:00:00 2001 From: skiv Date: Fri, 21 Sep 2012 10:24:56 +0400 Subject: [PATCH 12/85] Attributes --- .../XLite/Controller/Admin/Attribute.php | 128 +++++++++ .../XLite/Controller/Admin/AttributeGroup.php | 116 ++++++++ .../Controller/Admin/AttributeGroups.php | 170 ++++++++++++ .../XLite/Controller/Admin/Attributes.php | 185 +++++++++++++ .../XLite/Controller/Admin/ProductClasses.php | 2 - src/classes/XLite/Model/Attribute.php | 99 ++++++- src/classes/XLite/Model/AttributeGroup.php | 32 +++ src/classes/XLite/Model/AttributeOption.php | 67 +++++ .../Model/AttributeOptionTranslation.php | 51 ++++ src/classes/XLite/Model/ProductClass.php | 1 + src/classes/XLite/Model/Repo/Attribute.php | 173 ++++++++++++ .../XLite/Model/Repo/AttributeGroup.php | 150 ++++++++++ src/classes/XLite/View/Attribute.php | 56 ++++ src/classes/XLite/View/AttributeGroup.php | 56 ++++ src/classes/XLite/View/AttributeGroups.php | 66 +++++ src/classes/XLite/View/Attributes.php | 122 +++++++++ .../View/Form/ItemsList/Attribute/Table.php | 66 +++++ .../Form/ItemsList/AttributeGroup/Table.php | 66 +++++ .../XLite/View/Form/Model/Attribute.php | 91 +++++++ .../XLite/View/Form/Model/AttributeGroup.php | 90 ++++++ .../XLite/View/FormField/AFormField.php | 17 +- .../XLite/View/FormField/ItemsList.php | 83 ++++++ .../View/FormField/Select/AttributeGroups.php | 63 +++++ .../View/FormField/Select/AttributeTypes.php | 43 +++ .../XLite/View/FormField/Select/Decimals.php | 54 ++++ .../XLite/View/ItemsList/Model/Attribute.php | 251 +++++++++++++++++ .../View/ItemsList/Model/AttributeGroup.php | 200 ++++++++++++++ .../View/ItemsList/Model/ProductClass.php | 1 + src/classes/XLite/View/Model/Attribute.php | 200 ++++++++++++++ .../XLite/View/Model/AttributeGroup.php | 122 +++++++++ src/classes/XLite/View/ProductClass.php | 2 +- .../View/StickyPanel/ItemsList/Attribute.php | 34 +++ src/classes/XLite/View/TopMenu.php | 4 + src/skins/admin/en/attribute/body.tpl | 11 + src/skins/admin/en/attribute/footer.tpl | 14 + src/skins/admin/en/attribute/select.tpl | 1 + src/skins/admin/en/attribute/style.css | 10 + src/skins/admin/en/attribute_group/body.tpl | 11 + src/skins/admin/en/attribute_group/style.css | 10 + src/skins/admin/en/attribute_groups/body.tpl | 12 + src/skins/admin/en/attribute_groups/list.tpl | 17 ++ src/skins/admin/en/attribute_groups/style.css | 10 + src/skins/admin/en/attributes/body.tpl | 18 ++ src/skins/admin/en/attributes/list.tpl | 17 ++ src/skins/admin/en/attributes/parts/type.tpl | 13 + src/skins/admin/en/attributes/script.js | 45 +++ src/skins/admin/en/attributes/style.css | 256 ++++++++++++++++++ src/skins/admin/en/css/style.css | 4 + src/skins/admin/en/form_field/items_list.tpl | 12 + src/skins/admin/en/images/icon_folder.png | Bin 0 -> 454 bytes src/skins/admin/en/images/icon_list.png | Bin 0 -> 456 bytes .../admin/en/images/icon_warning_round.png | Bin 0 -> 797 bytes .../admin/en/items_list/model/table/style.css | 7 + src/skins/admin/en/product_classes/style.css | 9 +- 54 files changed, 3318 insertions(+), 20 deletions(-) create mode 100644 src/classes/XLite/Controller/Admin/Attribute.php create mode 100644 src/classes/XLite/Controller/Admin/AttributeGroup.php create mode 100644 src/classes/XLite/Controller/Admin/AttributeGroups.php create mode 100644 src/classes/XLite/Controller/Admin/Attributes.php create mode 100644 src/classes/XLite/Model/AttributeOption.php create mode 100644 src/classes/XLite/Model/AttributeOptionTranslation.php create mode 100644 src/classes/XLite/Model/Repo/Attribute.php create mode 100644 src/classes/XLite/Model/Repo/AttributeGroup.php create mode 100644 src/classes/XLite/View/Attribute.php create mode 100644 src/classes/XLite/View/AttributeGroup.php create mode 100644 src/classes/XLite/View/AttributeGroups.php create mode 100644 src/classes/XLite/View/Attributes.php create mode 100644 src/classes/XLite/View/Form/ItemsList/Attribute/Table.php create mode 100644 src/classes/XLite/View/Form/ItemsList/AttributeGroup/Table.php create mode 100644 src/classes/XLite/View/Form/Model/Attribute.php create mode 100644 src/classes/XLite/View/Form/Model/AttributeGroup.php create mode 100644 src/classes/XLite/View/FormField/ItemsList.php create mode 100644 src/classes/XLite/View/FormField/Select/AttributeGroups.php create mode 100644 src/classes/XLite/View/FormField/Select/AttributeTypes.php create mode 100644 src/classes/XLite/View/FormField/Select/Decimals.php create mode 100644 src/classes/XLite/View/ItemsList/Model/Attribute.php create mode 100644 src/classes/XLite/View/ItemsList/Model/AttributeGroup.php create mode 100644 src/classes/XLite/View/Model/Attribute.php create mode 100644 src/classes/XLite/View/Model/AttributeGroup.php create mode 100644 src/classes/XLite/View/StickyPanel/ItemsList/Attribute.php create mode 100644 src/skins/admin/en/attribute/body.tpl create mode 100644 src/skins/admin/en/attribute/footer.tpl create mode 100644 src/skins/admin/en/attribute/select.tpl create mode 100644 src/skins/admin/en/attribute/style.css create mode 100644 src/skins/admin/en/attribute_group/body.tpl create mode 100644 src/skins/admin/en/attribute_group/style.css create mode 100644 src/skins/admin/en/attribute_groups/body.tpl create mode 100644 src/skins/admin/en/attribute_groups/list.tpl create mode 100644 src/skins/admin/en/attribute_groups/style.css create mode 100644 src/skins/admin/en/attributes/body.tpl create mode 100644 src/skins/admin/en/attributes/list.tpl create mode 100644 src/skins/admin/en/attributes/parts/type.tpl create mode 100644 src/skins/admin/en/attributes/script.js create mode 100644 src/skins/admin/en/attributes/style.css create mode 100644 src/skins/admin/en/form_field/items_list.tpl create mode 100644 src/skins/admin/en/images/icon_folder.png create mode 100644 src/skins/admin/en/images/icon_list.png create mode 100644 src/skins/admin/en/images/icon_warning_round.png diff --git a/src/classes/XLite/Controller/Admin/Attribute.php b/src/classes/XLite/Controller/Admin/Attribute.php new file mode 100644 index 0000000000..abb2d6c389 --- /dev/null +++ b/src/classes/XLite/Controller/Admin/Attribute.php @@ -0,0 +1,128 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Controller\Admin; + +/** + * Attribute controller + * + */ +class Attribute extends \XLite\Controller\Admin\AAdmin +{ + /** + * Controller parameters + * + * @var array + */ + protected $params = array('target', 'id', 'product_class_id'); + + /** + * Product class + * + * @var \XLite\Model\ProductClass + */ + protected $productClass; + + /** + * Check ACL permissions + * + * @return boolean + */ + public function checkACL() + { + return (parent::checkACL() || \XLite\Core\Auth::getInstance()->isPermissionAllowed('manage catalog')) + && $this->getProductClass() + && $this->isAJAX(); + } + + /** + * Get product class + * + * @return \XLite\Model\ProductClass + */ + public function getProductClass() + { + if ( + is_null($this->productClass) + && \XLite\Core\Request::getInstance()->product_class_id + ) { + $this->productClass = \XLite\Core\Database::getRepo('XLite\Model\ProductClass') + ->find(intval(\XLite\Core\Request::getInstance()->product_class_id)); + } + + return $this->productClass; + } + + /** + * Return the current page title (for the content area) + * + * @return string + */ + public function getTitle() + { + $id = intval(\XLite\Core\Request::getInstance()->id); + $model = $id + ? \XLite\Core\Database::getRepo('XLite\Model\Attribute')->find($id) + : null; + + return ($model && $model->getId()) + ? \XLite\Core\Translation::getInstance()->lbl('Edit attribute values') + : \XLite\Core\Translation::getInstance()->lbl('New attribute'); + } + + /** + * Update model + * + * @return void + */ + protected function doActionUpdate() + { + $this->setInternalRedirect(); + if ($this->getModelForm()->performAction('modify')) { + $this->setReturnUrl( + \XLite\Core\Converter::buildURL( + 'attribute', + '', + array( + 'id' => $this->getModelForm()->getModelObject()->getId(), + 'product_class_id' => \XLite\Core\Request::getInstance()->product_class_id, + 'widget' => 'XLite\View\Attribute' + ) + ) + ); + } + } + + /** + * Get model form class + * + * @return string + */ + protected function getModelFormClass() + { + return 'XLite\View\Model\Attribute'; + } + +} diff --git a/src/classes/XLite/Controller/Admin/AttributeGroup.php b/src/classes/XLite/Controller/Admin/AttributeGroup.php new file mode 100644 index 0000000000..b9670b85b3 --- /dev/null +++ b/src/classes/XLite/Controller/Admin/AttributeGroup.php @@ -0,0 +1,116 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Controller\Admin; + +/** + * Attribute group controller + * + */ +class AttributeGroup extends \XLite\Controller\Admin\AAdmin +{ + /** + * Controller parameters + * + * @var array + */ + protected $params = array('target', 'id', 'product_class_id'); + + /** + * Product class + * + * @var \XLite\Model\ProductClass + */ + protected $productClass; + + /** + * Check ACL permissions + * + * @return boolean + */ + public function checkACL() + { + return (parent::checkACL() || \XLite\Core\Auth::getInstance()->isPermissionAllowed('manage catalog')) + && $this->getProductClass(); + } + + /** + * Get product class + * + * @return \XLite\Model\ProductClass + */ + public function getProductClass() + { + if ( + is_null($this->productClass) + && \XLite\Core\Request::getInstance()->product_class_id + ) { + $this->productClass = \XLite\Core\Database::getRepo('XLite\Model\ProductClass') + ->find(intval(\XLite\Core\Request::getInstance()->product_class_id)); + } + + return $this->productClass; + } + + /** + * Return the current page title (for the content area) + * + * @return string + */ + public function getTitle() + { + $id = intval(\XLite\Core\Request::getInstance()->id); + $model = $id + ? \XLite\Core\Database::getRepo('XLite\Model\AttributeGroup')->find($id) + : null; + + return ($model && $model->getId()) + ? $model->getName() + : \XLite\Core\Translation::getInstance()->lbl('AttributeGroup'); + } + + /** + * Update model + * + * @return void + */ + protected function doActionUpdate() + { + if ($this->getModelForm()->performAction('modify')) { + $this->setReturnUrl(\XLite\Core\Converter::buildURL('attribute_groups')); + } + } + + /** + * Get model form class + * + * @return string + */ + protected function getModelFormClass() + { + return 'XLite\View\Model\AttributeGroup'; + } + +} diff --git a/src/classes/XLite/Controller/Admin/AttributeGroups.php b/src/classes/XLite/Controller/Admin/AttributeGroups.php new file mode 100644 index 0000000000..ab505f5394 --- /dev/null +++ b/src/classes/XLite/Controller/Admin/AttributeGroups.php @@ -0,0 +1,170 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Controller\Admin; + +/** + * Attribute groups controller + * + */ +class AttributeGroups extends \XLite\Controller\Admin\AAdmin +{ + /** + * Controller parameters + * + * @var array + */ + protected $params = array('target', 'product_class_id'); + + /** + * Product class + * + * @var \XLite\Model\ProductClass + */ + protected $productClass; + + /** + * Check ACL permissions + * + * @return boolean + */ + public function checkACL() + { + return (parent::checkACL() || \XLite\Core\Auth::getInstance()->isPermissionAllowed('manage catalog')) + && $this->getProductClass() + && $this->isAJAX(); + } + + /** + * Get product class + * + * @return \XLite\Model\ProductClass + */ + public function getProductClass() + { + if ( + is_null($this->productClass) + && \XLite\Core\Request::getInstance()->product_class_id + ) { + $this->productClass = \XLite\Core\Database::getRepo('XLite\Model\ProductClass') + ->find(intval(\XLite\Core\Request::getInstance()->product_class_id)); + } + + return $this->productClass; + } + + /** + * Update list + * + * @return void + */ + protected function doActionUpdate() + { + $this->setInternalRedirect(); + $list = new \XLite\View\ItemsList\Model\AttributeGroup; + $list->processQuick(); + } + + /** + * Return the current page title (for the content area) + * + * @return string + */ + public function getTitle() + { + return static::t('Manage attribute groups'); + } + + // {{{ Search + + /** + * Get search condition parameter by name + * + * @param string $paramName Parameter name + * + * @return mixed + */ + public function getCondition($paramName) + { + $searchParams = $this->getConditions(); + + return isset($searchParams[$paramName]) + ? $searchParams[$paramName] + : null; + } + + /** + * Save search conditions + * + * @return void + */ + protected function doActionSearch() + { + $cellName = \XLite\View\ItemsList\Model\AttributeGroup::getSessionCellName(); + + \XLite\Core\Session::getInstance()->$cellName = $this->getSearchParams(); + } + + /** + * Return search parameters + * + * @return array + */ + protected function getSearchParams() + { + $searchParams = $this->getConditions(); + + foreach ( + \XLite\View\ItemsList\Model\AttributeGroup::getSearchParams() as $requestParam + ) { + if (isset(\XLite\Core\Request::getInstance()->$requestParam)) { + $searchParams[$requestParam] = \XLite\Core\Request::getInstance()->$requestParam; + } + } + + return $searchParams; + } + + /** + * Get search conditions + * + * @return array + */ + protected function getConditions() + { + $cellName = \XLite\View\ItemsList\Model\AttributeGroup::getSessionCellName(); + + $searchParams = \XLite\Core\Session::getInstance()->$cellName; + + if (!is_array($searchParams)) { + $searchParams = array(); + } + + return $searchParams; + } + + // }}} + +} diff --git a/src/classes/XLite/Controller/Admin/Attributes.php b/src/classes/XLite/Controller/Admin/Attributes.php new file mode 100644 index 0000000000..82f6da3c86 --- /dev/null +++ b/src/classes/XLite/Controller/Admin/Attributes.php @@ -0,0 +1,185 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Controller\Admin; + +/** + * Attributes controller + * + */ +class Attributes extends \XLite\Controller\Admin\AAdmin +{ + /** + * Controller parameters + * + * @var array + */ + protected $params = array('target', 'product_class_id'); + + /** + * Product class + * + * @var \XLite\Model\ProductClass + */ + protected $productClass; + + /** + * Check ACL permissions + * + * @return boolean + */ + public function checkACL() + { + return (parent::checkACL() || \XLite\Core\Auth::getInstance()->isPermissionAllowed('manage catalog')) + && $this->getProductClass(); + } + + /** + * Get product class + * + * @return \XLite\Model\ProductClass + */ + public function getProductClass() + { + if ( + is_null($this->productClass) + && \XLite\Core\Request::getInstance()->product_class_id + ) { + $this->productClass = \XLite\Core\Database::getRepo('XLite\Model\ProductClass') + ->find(intval(\XLite\Core\Request::getInstance()->product_class_id)); + } + + return $this->productClass; + } + + /** + * Get product class + * + * @return \Doctrine\ORM\PersistentCollection + */ + public function getAttributeGroups() + { + return $this->getProductClass()->getAttributeGroups(); + } + + /** + * Update list + * + * @return void + */ + protected function doActionUpdate() + { + $list = new \XLite\View\ItemsList\Model\Attribute; + $list->processQuick(); + } + + /** + * Return the current page title (for the content area) + * + * @return string + */ + public function getTitle() + { + return $this->getProductClass() + ? \XLite\Core\Translation::getInstance()->lbl( + 'Attributes for "{{class}}" product class', + array( + 'class' => $this->getProductClass()->getName() + ) + ) + : null; + } + + // {{{ Search + + /** + * Get search condition parameter by name + * + * @param string $paramName Parameter name + * + * @return mixed + */ + public function getCondition($paramName) + { + $searchParams = $this->getConditions(); + + return isset($searchParams[$paramName]) + ? $searchParams[$paramName] + : null; + } + + /** + * Save search conditions + * + * @return void + */ + protected function doActionSearch() + { + $cellName = \XLite\View\ItemsList\Model\Attribute::getSessionCellName(); + + \XLite\Core\Session::getInstance()->$cellName = $this->getSearchParams(); + } + + /** + * Return search parameters + * + * @return array + */ + protected function getSearchParams() + { + $searchParams = $this->getConditions(); + + foreach ( + \XLite\View\ItemsList\Model\Attribute::getSearchParams() as $requestParam + ) { + if (isset(\XLite\Core\Request::getInstance()->$requestParam)) { + $searchParams[$requestParam] = \XLite\Core\Request::getInstance()->$requestParam; + } + } + + return $searchParams; + } + + /** + * Get search conditions + * + * @return array + */ + protected function getConditions() + { + $cellName = \XLite\View\ItemsList\Model\Attribute::getSessionCellName(); + + $searchParams = \XLite\Core\Session::getInstance()->$cellName; + + if (!is_array($searchParams)) { + $searchParams = array(); + } + + return $searchParams; + } + + // }}} + +} diff --git a/src/classes/XLite/Controller/Admin/ProductClasses.php b/src/classes/XLite/Controller/Admin/ProductClasses.php index f5f42fee94..fb6360c33d 100644 --- a/src/classes/XLite/Controller/Admin/ProductClasses.php +++ b/src/classes/XLite/Controller/Admin/ProductClasses.php @@ -46,8 +46,6 @@ public function checkACL() * Return the current page title (for the content area) * * @return string - * @see ____func_see____ - * @since 1.0.0 */ public function getTitle() { diff --git a/src/classes/XLite/Model/Attribute.php b/src/classes/XLite/Model/Attribute.php index 9bbc118d79..2327fab1fd 100644 --- a/src/classes/XLite/Model/Attribute.php +++ b/src/classes/XLite/Model/Attribute.php @@ -63,6 +63,39 @@ class Attribute extends \XLite\Model\Base\I18n */ protected $position = 0; + /** + * Default value + * + * @var text + * @see ____var_see____ + * @since 1.0.0 + * + * @Column (type="text") + */ + protected $defaultValue; + + /** + * Decimals + * + * @var integer + * @see ____var_see____ + * @since 1.0.0 + * + * @Column (type="integer", length=1) + */ + protected $decimals = 0; + + /** + * Unit + * + * @var string + * @see ____var_see____ + * @since 1.0.0 + * + * @Column (type="string") + */ + protected $unit; + /** * Product class * @@ -101,7 +134,7 @@ class Attribute extends \XLite\Model\Base\I18n */ public function __construct(array $data = array()) { - $this->attribute_values = new \Doctrine\Common\Collections\ArrayCollection(); +// $this->attribute_values = new \Doctrine\Common\Collections\ArrayCollection(); parent::__construct($data); } @@ -137,4 +170,68 @@ public static function getTypes($type = null) : $list; } + /** + * Return number of values associated with this attribute + * + * @return integer + */ + public function getValuesCount() + { + return 1; + } + + /** + * Set type + * + * @param string $type Type + * + * @return void + */ + public function setType($type) + { + $types = static::getTypes(); + + if (isset($types[$type])) { + if ( + $this->type + && $type != $this->type + ) { + $this->setDefaultValue($this->defaultValue); + } + $this->type = $type; + } + } + + /** + * Set default type + * + * @param string $value Value + * + * @return void + */ + public function setDefaultValue($value) + { + if (self::TYPE_NUMBER == $this->type) { + $value = (float)$value; + + } elseif (self::TYPE_CHECKBOX == $this->type) { + $value = (boolean)$value; + + } + + $this->defaultValue = $value; + } + + /** + * Get default value + * + * @return mixed + */ + public function getDefaultValue() + { + return self::TYPE_CHECKBOX == $this->type + ? (boolean)$this->defaultValue + : $this->defaultValue; + } + } diff --git a/src/classes/XLite/Model/AttributeGroup.php b/src/classes/XLite/Model/AttributeGroup.php index ac1433dca6..f21f746cd4 100644 --- a/src/classes/XLite/Model/AttributeGroup.php +++ b/src/classes/XLite/Model/AttributeGroup.php @@ -65,4 +65,36 @@ class AttributeGroup extends \XLite\Model\Base\I18n */ protected $product_class; + /** + * Attributes + * + * @var \Doctrine\Common\Collections\Collection + * + * @OneToMany (targetEntity="XLite\Model\Attribute", mappedBy="attribute_group") + */ + protected $attributes; + + /** + * Constructor + * + * @param array $data Entity properties OPTIONAL + * + * @return void + */ + public function __construct(array $data = array()) + { + $this->attributes = new \Doctrine\Common\Collections\ArrayCollection(); + + parent::__construct($data); + } + + /** + * Return number of attributes associated with this class + * + * @return integer + */ + public function getAttributesCount() + { + return count($this->getAttributes()); + } } diff --git a/src/classes/XLite/Model/AttributeOption.php b/src/classes/XLite/Model/AttributeOption.php new file mode 100644 index 0000000000..b5ad81f8e7 --- /dev/null +++ b/src/classes/XLite/Model/AttributeOption.php @@ -0,0 +1,67 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model; + +/** + * Attribute option + * + * @Entity + * @Table (name="attribute_options") + */ +class AttributeOption extends \XLite\Model\Base\I18n +{ + /** + * ID + * + * @var integer + * + * @Id + * @GeneratedValue (strategy="AUTO") + * @Column (type="uinteger") + */ + protected $id; + + /** + * Default flag + * + * @var boolean + * @see ____var_see____ + * @since 1.0.0 + * + * @Column (type="boolean") + */ + protected $default = false; + + /** + * Attribute + * + * @var \XLite\Model\AttributeGroup + * + * @ManyToOne (targetEntity="XLite\Model\Attribute", inversedBy="attribute_options") + * @JoinColumn (name="attribute_id", referencedColumnName="id") + */ + protected $attribute; +} diff --git a/src/classes/XLite/Model/AttributeOptionTranslation.php b/src/classes/XLite/Model/AttributeOptionTranslation.php new file mode 100644 index 0000000000..a0a2d9bbef --- /dev/null +++ b/src/classes/XLite/Model/AttributeOptionTranslation.php @@ -0,0 +1,51 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model; + +/** + * Attribute option multilingual data + * + * + * @Entity + * + * @Table (name="attribute_option_translations", + * indexes={ + * @Index (name="ci", columns={"code","id"}), + * @Index (name="id", columns={"id"}) + * } + * ) + */ +class AttributeOptionTranslation extends \XLite\Model\Base\Translation +{ + /** + * Name + * + * @var string + * + * @Column (type="string", length=255) + */ + protected $name; +} diff --git a/src/classes/XLite/Model/ProductClass.php b/src/classes/XLite/Model/ProductClass.php index ba95d20cce..891d1759b1 100644 --- a/src/classes/XLite/Model/ProductClass.php +++ b/src/classes/XLite/Model/ProductClass.php @@ -89,6 +89,7 @@ class ProductClass extends \XLite\Model\Base\I18n * @var \Doctrine\Common\Collections\Collection * * @OneToMany (targetEntity="XLite\Model\AttributeGroup", mappedBy="product_class", cascade={"all"}) + * @OrderBy ({"position" = "ASC"}) */ protected $attribute_groups; diff --git a/src/classes/XLite/Model/Repo/Attribute.php b/src/classes/XLite/Model/Repo/Attribute.php new file mode 100644 index 0000000000..104bdee0ac --- /dev/null +++ b/src/classes/XLite/Model/Repo/Attribute.php @@ -0,0 +1,173 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\Repo; + +/** + * Attributes repository + * + */ +class Attribute extends \XLite\Model\Repo\Base\I18n +{ + /** + * Allowable search params + */ + const SEARCH_PRODUCT_CLASS = 'productClass'; + const SEARCH_ATTRIBUTE_GROUP = 'attributeGroup'; + + // {{{ Search + + /** + * Common search + * + * @param \XLite\Core\CommonCell $cnd Search condition + * @param boolean $countOnly Return items list or only its size OPTIONAL + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function search(\XLite\Core\CommonCell $cnd, $countOnly = false) + { + $queryBuilder = $this->createQueryBuilder('a'); + $this->currentSearchCnd = $cnd; + + foreach ($this->currentSearchCnd as $key => $value) { + $this->callSearchConditionHandler($value, $key, $queryBuilder, $countOnly); + } + + return $countOnly + ? $this->searchCount($queryBuilder) + : $this->searchResult($queryBuilder); + } + + /** + * Search count only routine. + * + * @param \Doctrine\ORM\QueryBuilder $qb Query builder routine + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function searchCount(\Doctrine\ORM\QueryBuilder $qb) + { + $qb->select('COUNT(DISTINCT a.id)'); + + return intval($qb->getSingleScalarResult()); + } + + /** + * Search result routine. + * + * @param \Doctrine\ORM\QueryBuilder $qb Query builder routine + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function searchResult(\Doctrine\ORM\QueryBuilder $qb) + { + return $qb->addOrderBy('a.position', 'ASC')->getResult(); + } + + /** + * Call corresponded method to handle a search condition + * + * @param mixed $value Condition data + * @param string $key Condition name + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param boolean $countOnly Count only flag + * + * @return void + */ + protected function callSearchConditionHandler($value, $key, \Doctrine\ORM\QueryBuilder $queryBuilder, $countOnly) + { + if ($this->isSearchParamHasHandler($key)) { + $this->{'prepareCnd' . ucfirst($key)}($queryBuilder, $value, $countOnly); + } + } + + /** + * Check if param can be used for search + * + * @param string $param Name of param to check + * + * @return boolean + */ + protected function isSearchParamHasHandler($param) + { + return in_array($param, $this->getHandlingSearchParams()); + } + + /** + * Return list of handling search params + * + * @return array + */ + protected function getHandlingSearchParams() + { + return array( + static::SEARCH_PRODUCT_CLASS, + static::SEARCH_ATTRIBUTE_GROUP, + ); + } + + /** + * Prepare certain search condition + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param string $value Condition OPTIONAL + * + * @return void + * @see ____func_see____ + * @since 1.0.0 + */ + protected function prepareCndProductClass(\Doctrine\ORM\QueryBuilder $queryBuilder, $value = null) + { + if ($value) { + $queryBuilder->andWhere('a.product_class = :productClass') + ->setParameter('productClass', $value); + } + } + + /** + * Prepare certain search condition + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param string $value Condition OPTIONAL + * + * @return void + * @see ____func_see____ + * @since 1.0.0 + */ + protected function prepareCndAttributeGroup(\Doctrine\ORM\QueryBuilder $queryBuilder, $value = null) + { + if ($value) { + $queryBuilder->andWhere('a.attribute_group = :attributeGroup') + ->setParameter('attributeGroup', $value); + + } else { + $queryBuilder->andWhere('a.attribute_group is null'); + } + } + + // }}} + +} diff --git a/src/classes/XLite/Model/Repo/AttributeGroup.php b/src/classes/XLite/Model/Repo/AttributeGroup.php new file mode 100644 index 0000000000..2692574fa4 --- /dev/null +++ b/src/classes/XLite/Model/Repo/AttributeGroup.php @@ -0,0 +1,150 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\Repo; + +/** + * Attribute groups repository + * + */ +class AttributeGroup extends \XLite\Model\Repo\Base\I18n +{ + /** + * Allowable search params + */ + const SEARCH_PRODUCT_CLASS = 'productClass'; + + // {{{ Search + + /** + * Common search + * + * @param \XLite\Core\CommonCell $cnd Search condition + * @param boolean $countOnly Return items list or only its size OPTIONAL + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function search(\XLite\Core\CommonCell $cnd, $countOnly = false) + { + $queryBuilder = $this->createQueryBuilder('a'); + $this->currentSearchCnd = $cnd; + + foreach ($this->currentSearchCnd as $key => $value) { + $this->callSearchConditionHandler($value, $key, $queryBuilder, $countOnly); + } + + return $countOnly + ? $this->searchCount($queryBuilder) + : $this->searchResult($queryBuilder); + } + + /** + * Search count only routine. + * + * @param \Doctrine\ORM\QueryBuilder $qb Query builder routine + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function searchCount(\Doctrine\ORM\QueryBuilder $qb) + { + $qb->select('COUNT(DISTINCT a.id)'); + + return intval($qb->getSingleScalarResult()); + } + + /** + * Search result routine. + * + * @param \Doctrine\ORM\QueryBuilder $qb Query builder routine + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function searchResult(\Doctrine\ORM\QueryBuilder $qb) + { + return $qb->addOrderBy('a.position', 'ASC')->getResult(); + } + + /** + * Call corresponded method to handle a search condition + * + * @param mixed $value Condition data + * @param string $key Condition name + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param boolean $countOnly Count only flag + * + * @return void + */ + protected function callSearchConditionHandler($value, $key, \Doctrine\ORM\QueryBuilder $queryBuilder, $countOnly) + { + if ($this->isSearchParamHasHandler($key)) { + $this->{'prepareCnd' . ucfirst($key)}($queryBuilder, $value, $countOnly); + } + } + + /** + * Check if param can be used for search + * + * @param string $param Name of param to check + * + * @return boolean + */ + protected function isSearchParamHasHandler($param) + { + return in_array($param, $this->getHandlingSearchParams()); + } + + /** + * Return list of handling search params + * + * @return array + */ + protected function getHandlingSearchParams() + { + return array( + static::SEARCH_PRODUCT_CLASS, + ); + } + + /** + * Prepare certain search condition + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param string $value Condition OPTIONAL + * + * @return void + * @see ____func_see____ + * @since 1.0.0 + */ + protected function prepareCndProductClass(\Doctrine\ORM\QueryBuilder $queryBuilder, $value = null) + { + if ($value) { + $queryBuilder->andWhere('a.product_class = :productClass') + ->setParameter('productClass', $value); + } + } + + // }}} + +} diff --git a/src/classes/XLite/View/Attribute.php b/src/classes/XLite/View/Attribute.php new file mode 100644 index 0000000000..4d4231a115 --- /dev/null +++ b/src/classes/XLite/View/Attribute.php @@ -0,0 +1,56 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View; + +/** + * Attribute page view + * + * + * @ListChild (list="admin.center", zone="admin") + */ +class Attribute extends \XLite\View\AView +{ + /** + * Return list of allowed targets + * + * @return array + */ + public static function getAllowedTargets() + { + return array_merge(parent::getAllowedTargets(), array('attribute')); + } + + /** + * Return widget default template + * + * @return string + */ + protected function getDefaultTemplate() + { + return 'attribute/body.tpl'; + } + +} \ No newline at end of file diff --git a/src/classes/XLite/View/AttributeGroup.php b/src/classes/XLite/View/AttributeGroup.php new file mode 100644 index 0000000000..1be7467f07 --- /dev/null +++ b/src/classes/XLite/View/AttributeGroup.php @@ -0,0 +1,56 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View; + +/** + * Attribute group page view + * + * + * @ListChild (list="admin.center", zone="admin") + */ +class AttributeGroup extends \XLite\View\AView +{ + /** + * Return list of allowed targets + * + * @return array + */ + public static function getAllowedTargets() + { + return array_merge(parent::getAllowedTargets(), array('attribute_group')); + } + + /** + * Return widget default template + * + * @return string + */ + protected function getDefaultTemplate() + { + return 'attribute_group/body.tpl'; + } + +} \ No newline at end of file diff --git a/src/classes/XLite/View/AttributeGroups.php b/src/classes/XLite/View/AttributeGroups.php new file mode 100644 index 0000000000..3c56dc53a2 --- /dev/null +++ b/src/classes/XLite/View/AttributeGroups.php @@ -0,0 +1,66 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View; + +/** + * Attribute groups page view + * + * + * @ListChild (list="admin.center", zone="admin") + */ +class AttributeGroups extends \XLite\View\AView +{ + /** + * Return list of allowed targets + * + * @return array + */ + public static function getAllowedTargets() + { + return array_merge(parent::getAllowedTargets(), array('attribute_groups')); + } + + /** + * Return widget default template + * + * @return string + */ + protected function getDefaultTemplate() + { + return 'attribute_groups/body.tpl'; + } + + /** + * Check - search box is visible or not + * + * @return boolean + */ + protected function isSearchVisible() + { + return 0 < \XLite\Core\Database::getRepo('XLite\Model\AttributeGroup')->count(); + } + +} \ No newline at end of file diff --git a/src/classes/XLite/View/Attributes.php b/src/classes/XLite/View/Attributes.php new file mode 100644 index 0000000000..7f60d5c010 --- /dev/null +++ b/src/classes/XLite/View/Attributes.php @@ -0,0 +1,122 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View; + +/** + * Attributes page view + * + * + * @ListChild (list="admin.center", zone="admin") + */ +class Attributes extends \XLite\View\AView +{ + /** + * Return list of allowed targets + * + * @return array + */ + public static function getAllowedTargets() + { + return array_merge(parent::getAllowedTargets(), array('attributes')); + } + + /** + * Get a list of CSS files required to display the widget properly + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = 'attributes/style.css'; + $list[] = 'form_field/inline/style.css'; + $list[] = 'form_field/inline/input/text/position/move.css'; + $list[] = 'form_field/inline/input/text/position.css'; + $list[] = 'form_field/form_field.css'; + $list[] = 'form_field/input/text/position.css'; + $list[] = 'items_list/items_list.css'; + $list[] = 'items_list/model/style.css'; + $list[] = 'items_list/model/table/style.css'; + + return $list; + } + + /** + * Get a list of JavaScript files required to display the widget properly + * + * @return array + */ + public function getJSFiles() + { + $list = parent::getJSFiles(); + + $list[] = 'attributes/script.js'; + $list[] = 'form_field/inline/controller.js'; + $list[] = 'form_field/inline/input/text/position/move.js'; + $list[] = 'form_field/js/text.js'; + $list[] = 'form_field/input/text/integer.js'; + $list[] = 'button/js/remove.js'; + $list[] = 'items_list/items_list.js'; + $list[] = 'items_list/model/table/controller.js'; + + return $list; + } + + /** + * Register files from common repository + * + * @return array + */ + public function getCommonFiles() + { + $list = parent::getCommonFiles(); + $list['js'][] = 'js/jquery.blockUI.js'; + + return $list; + } + + /** + * Return widget default template + * + * @return string + */ + protected function getDefaultTemplate() + { + return 'attributes/body.tpl'; + } + + /** + * Check - search box is visible or not + * + * @return boolean + */ + protected function isSearchVisible() + { + return 0 < \XLite\Core\Database::getRepo('XLite\Model\Attribute')->count(); + } + +} diff --git a/src/classes/XLite/View/Form/ItemsList/Attribute/Table.php b/src/classes/XLite/View/Form/ItemsList/Attribute/Table.php new file mode 100644 index 0000000000..445d6fe909 --- /dev/null +++ b/src/classes/XLite/View/Form/ItemsList/Attribute/Table.php @@ -0,0 +1,66 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Form\ItemsList\Attribute; + +/** + * Attributes list table form + * + */ +class Table extends \XLite\View\Form\ItemsList\AItemsList +{ + /** + * Return default value for the "target" parameter + * + * @return string + */ + protected function getDefaultTarget() + { + return 'attributes'; + } + + /** + * Return default value for the "action" parameter + * + * @return string + */ + protected function getDefaultAction() + { + return 'update'; + } + + /** + * Return list of the form default parameters + * + * @return array + */ + protected function getDefaultParams() + { + return array( + 'product_class_id' => intval(\XLite\Core\Request::getInstance()->product_class_id), + ); + } + +} diff --git a/src/classes/XLite/View/Form/ItemsList/AttributeGroup/Table.php b/src/classes/XLite/View/Form/ItemsList/AttributeGroup/Table.php new file mode 100644 index 0000000000..2aa3444dbf --- /dev/null +++ b/src/classes/XLite/View/Form/ItemsList/AttributeGroup/Table.php @@ -0,0 +1,66 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Form\ItemsList\AttributeGroup; + +/** + * Attribute groups list table form + * + */ +class Table extends \XLite\View\Form\ItemsList\AItemsList +{ + /** + * Return default value for the "target" parameter + * + * @return string + */ + protected function getDefaultTarget() + { + return 'attribute_groups'; + } + + /** + * Return default value for the "action" parameter + * + * @return string + */ + protected function getDefaultAction() + { + return 'update'; + } + + /** + * Return list of the form default parameters + * + * @return array + */ + protected function getDefaultParams() + { + return array( + 'product_class_id' => intval(\XLite\Core\Request::getInstance()->product_class_id), + ); + } + +} diff --git a/src/classes/XLite/View/Form/Model/Attribute.php b/src/classes/XLite/View/Form/Model/Attribute.php new file mode 100644 index 0000000000..da64f1c820 --- /dev/null +++ b/src/classes/XLite/View/Form/Model/Attribute.php @@ -0,0 +1,91 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Form\Model; + +/** + * Attributes list search form + * + */ +class Attribute extends \XLite\View\Form\AForm +{ + /** + * Register CSS files + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = 'attribute/style.css'; + + return $list; + } + + /** + * Return default value for the "target" parameter + * + * @return string + */ + protected function getDefaultTarget() + { + return 'attribute'; + } + + /** + * Return default value for the "action" parameter + * + * @return string + */ + protected function getDefaultAction() + { + return 'update'; + } + + /** + * Get default class name + * + * @return string + */ + protected function getDefaultClassName() + { + return trim(parent::getDefaultClassName() . ' validationEngine attribute'); + } + + /** + * Return list of the form default parameters + * + * @return array + */ + protected function getDefaultParams() + { + return array( + 'id' => \XLite\Core\Request::getInstance()->id, + 'product_class_id' => \XLite\Core\Request::getInstance()->product_class_id, + ); + } + +} diff --git a/src/classes/XLite/View/Form/Model/AttributeGroup.php b/src/classes/XLite/View/Form/Model/AttributeGroup.php new file mode 100644 index 0000000000..8a821e1082 --- /dev/null +++ b/src/classes/XLite/View/Form/Model/AttributeGroup.php @@ -0,0 +1,90 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Form\Model; + +/** + * Attribute groups list search form + * + */ +class AttributeGroup extends \XLite\View\Form\AForm +{ + /** + * Register CSS files + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = 'attribute_group/style.css'; + + return $list; + } + + /** + * Return default value for the "target" parameter + * + * @return string + */ + protected function getDefaultTarget() + { + return 'attribute_group'; + } + + /** + * Return default value for the "action" parameter + * + * @return string + */ + protected function getDefaultAction() + { + return 'update'; + } + + /** + * Get default class name + * + * @return string + */ + protected function getDefaultClassName() + { + return trim(parent::getDefaultClassName() . ' validationEngine attribute-group'); + } + + /** + * Return list of the form default parameters + * + * @return array + */ + protected function getDefaultParams() + { + return array( + 'id' => \XLite\Core\Request::getInstance()->id, + ); + } + +} \ No newline at end of file diff --git a/src/classes/XLite/View/FormField/AFormField.php b/src/classes/XLite/View/FormField/AFormField.php index aa47ab9592..50f2cc7aee 100644 --- a/src/classes/XLite/View/FormField/AFormField.php +++ b/src/classes/XLite/View/FormField/AFormField.php @@ -50,14 +50,15 @@ abstract class AFormField extends \XLite\View\AView /** * Available field types */ - const FIELD_TYPE_LABEL = 'label'; - const FIELD_TYPE_TEXT = 'text'; - const FIELD_TYPE_PASSWORD = 'password'; - const FIELD_TYPE_SELECT = 'select'; - const FIELD_TYPE_CHECKBOX = 'checkbox'; - const FIELD_TYPE_RADIO = 'radio'; - const FIELD_TYPE_TEXTAREA = 'textarea'; - const FIELD_TYPE_SEPARATOR = 'separator'; + const FIELD_TYPE_LABEL = 'label'; + const FIELD_TYPE_TEXT = 'text'; + const FIELD_TYPE_PASSWORD = 'password'; + const FIELD_TYPE_SELECT = 'select'; + const FIELD_TYPE_CHECKBOX = 'checkbox'; + const FIELD_TYPE_RADIO = 'radio'; + const FIELD_TYPE_TEXTAREA = 'textarea'; + const FIELD_TYPE_SEPARATOR = 'separator'; + const FIELD_TYPE_ITEMS_LIST = 'itemsList'; /** * name diff --git a/src/classes/XLite/View/FormField/ItemsList.php b/src/classes/XLite/View/FormField/ItemsList.php new file mode 100644 index 0000000000..2a143f7f38 --- /dev/null +++ b/src/classes/XLite/View/FormField/ItemsList.php @@ -0,0 +1,83 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\FormField; + +/** + * Items list + * + */ +class ItemsList extends \XLite\View\FormField\AFormField +{ + /** + * Widget parameters + */ + const PARAM_LIST_CLASS = 'listClass'; + + /** + * Return field type + * + * @return string + */ + public function getFieldType() + { + return self::FIELD_TYPE_ITEMS_LIST; + } + + /** + * Return field template + * + * @return string + */ + protected function getFieldTemplate() + { + return 'items_list.tpl'; + } + + /** + * Define widget params + * + * @return void + */ + protected function defineWidgetParams() + { + parent::defineWidgetParams(); + + $this->widgetParams += array( + self::PARAM_LIST_CLASS => new \XLite\Model\WidgetParam\String('List class', ''), + ); + } + + /** + * Get list class + * + * @return string + */ + protected function getListClass() + { + return $this->getParam(self::PARAM_LIST_CLASS); + } + +} diff --git a/src/classes/XLite/View/FormField/Select/AttributeGroups.php b/src/classes/XLite/View/FormField/Select/AttributeGroups.php new file mode 100644 index 0000000000..fcb6d9716e --- /dev/null +++ b/src/classes/XLite/View/FormField/Select/AttributeGroups.php @@ -0,0 +1,63 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\FormField\Select; + +/** + * Attribute groups selector + * + */ +class AttributeGroups extends \XLite\View\FormField\Select\Regular +{ + /** + * Get attribute groups list + * + * @return array + */ + protected function getAttributeGroupsList() + { + $list = array(); + $cnd = new \XLite\Core\CommonCell; + if ($this->getProductClass()) { + $cnd->productClass = $this->getProductClass(); + } + + foreach (\XLite\Core\Database::getRepo('\XLite\Model\AttributeGroup')->search($cnd) as $e) { + $list[$e->getId()] = $e->getName(); + } + + return $list; + } + + /** + * Get default options + * + * @return array + */ + protected function getDefaultOptions() + { + return array('0' => 'No group') + $this->getAttributeGroupsList(); + } +} diff --git a/src/classes/XLite/View/FormField/Select/AttributeTypes.php b/src/classes/XLite/View/FormField/Select/AttributeTypes.php new file mode 100644 index 0000000000..37e9d57755 --- /dev/null +++ b/src/classes/XLite/View/FormField/Select/AttributeTypes.php @@ -0,0 +1,43 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\FormField\Select; + +/** + * Attribute types selector + * + */ +class AttributeTypes extends \XLite\View\FormField\Select\Regular +{ + /** + * Get default options + * + * @return array + */ + protected function getDefaultOptions() + { + return \XLite\Model\Attribute::getTypes(); + } +} diff --git a/src/classes/XLite/View/FormField/Select/Decimals.php b/src/classes/XLite/View/FormField/Select/Decimals.php new file mode 100644 index 0000000000..cdff6788a9 --- /dev/null +++ b/src/classes/XLite/View/FormField/Select/Decimals.php @@ -0,0 +1,54 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\FormField\Select; + +/** + * Decimals selector + * + */ +class Decimals extends \XLite\View\FormField\Select\Regular +{ + /** + * Get default options + * + * @return array + */ + protected function getDefaultOptions() + { + return array( + 0 => 0, + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5, + 6 => 6, + 7 => 7, + 8 => 8, + 9 => 9 + ); + } +} diff --git a/src/classes/XLite/View/ItemsList/Model/Attribute.php b/src/classes/XLite/View/ItemsList/Model/Attribute.php new file mode 100644 index 0000000000..d685a95a1b --- /dev/null +++ b/src/classes/XLite/View/ItemsList/Model/Attribute.php @@ -0,0 +1,251 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\ItemsList\Model; + +/** + * Attributes items list + * + */ +class Attribute extends \XLite\View\ItemsList\Model\Table +{ + /** + * Widget param names + */ + + const PARAM_GROUP = 'group'; + + /** + * Define columns structure + * + * @return array + */ + protected function defineColumns() + { + return array( + 'name' => array( + static::COLUMN_NAME => $this->getAttributeGroup() + ? $this->getAttributeGroup()->getName() + : \XLite\Core\Translation::lbl('No group'), + static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text', + static::COLUMN_PARAMS => array('required' => true), + ), + 'type' => array( + static::COLUMN_NAME => $this->getAttributeGroup() + ? \XLite\Core\Translation::getInstance()->lbl( + '{{count}} attributes in group', + array( + 'count' => $this->getAttributeGroup()->getAttributesCount() + ) + ) + : null, + static::COLUMN_TEMPLATE => 'attributes/parts/type.tpl', + ), + ); + } + + /** + * Define repository name + * + * @return string + */ + protected function defineRepositoryName() + { + return 'XLite\Model\Attribute'; + } + + /** + * Get create entity URL + * + * @return string + */ + protected function getCreateURL() + { + return \XLite\Core\Converter::buildUrl('attribute'); + } + + /** + * Get create button label + * + * @return string + */ + protected function getCreateButtonLabel() + { + return 'New attribute'; + } + + /** + * Define widget params + * + * @return void + */ + protected function defineWidgetParams() + { + parent::defineWidgetParams(); + + $this->widgetParams += array( + self::PARAM_GROUP => new \XLite\Model\WidgetParam\Object( + 'Group', null, false, '\XLite\Model\AttributeGroup' + ), + ); + } + + /** + * Get attribute group + * + * @return \XLite\Model\AttributeGroup + */ + protected function getAttributeGroup() + { + return $this->getParam(static::PARAM_GROUP); + } + + // {{{ Behaviors + + /** + * Mark list as removable + * + * @return boolean + */ + protected function isRemoved() + { + return true; + } + + /** + * Mark list as sortable + * + * @return integer + */ + protected function getSortableType() + { + return static::SORT_TYPE_MOVE; + } + + /** + * Check if there are any results to display in list + * + * @return void + */ + protected function hasResults() + { + return true; + } + + /** + * Check if widget is visible + * + * @return boolean + */ + protected function isVisible() + { + return $this->getAttributeGroup() + || 0 < $this->getItemsCount(); + } + + // }}} + + /** + * Get container class + * + * @return string + */ + protected function getContainerClass() + { + $class = parent::getContainerClass() . ' attributes'; + + if ($this->getAttributeGroup()) { + $class = parent::getContainerClass() + . ' group'; + } + + return $class; + } + + /** + * Get panel class + * + * @return \XLite\View\Base\FormStickyPanel + */ + protected function getPanelClass() + { + $groups = $this->getAttributeGroups(); + + return ( + $this->getProductClass()->getAttributesCount() + && ( + !$groups->count() + || ( + $this->getAttributeGroup() + && $groups->last()->getId() == $this->getAttributeGroup()->getId() + ) + ) + ) + ? 'XLite\View\StickyPanel\ItemsList\Attribute' + : null; + } + + + // {{{ Search + + /** + * Return search parameters. + * + * @return array + */ + static public function getSearchParams() + { + return array(); + } + + /** + * Return params list to use for search + * TODO refactor + * + * @return \XLite\Core\CommonCell + */ + protected function getSearchCondition() + { + $result = parent::getSearchCondition(); + + foreach (static::getSearchParams() as $modelParam => $requestParam) { + $paramValue = $this->getParam($requestParam); + + if ('' !== $paramValue && 0 !== $paramValue) { + $result->$modelParam = $paramValue; + } + } + + $result->productClass = $this->getProductClass(); + if (\XLite\Core\Request::getInstance()->isGet()) { + $result->attributeGroup = $this->getAttributeGroup(); + } + + return $result; + } + + // }}} + +} diff --git a/src/classes/XLite/View/ItemsList/Model/AttributeGroup.php b/src/classes/XLite/View/ItemsList/Model/AttributeGroup.php new file mode 100644 index 0000000000..432a9a5f5d --- /dev/null +++ b/src/classes/XLite/View/ItemsList/Model/AttributeGroup.php @@ -0,0 +1,200 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\ItemsList\Model; + +/** + * Attribute groups items list + * + */ +class AttributeGroup extends \XLite\View\ItemsList\Model\Table +{ + /** + * Get a list of CSS files required to display the widget properly + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = 'attribute_groups/style.css'; + + return $list; + } + + /** + * Define columns structure + * + * @return array + */ + protected function defineColumns() + { + return array( + 'name' => array( + static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text', + static::COLUMN_MAIN => true, + static::COLUMN_PARAMS => array('required' => true), + ), + ); + } + + /** + * Define repository name + * + * @return string + */ + protected function defineRepositoryName() + { + return 'XLite\Model\AttributeGroup'; + } + + /** + * Get create entity URL + * + * @return string + */ + protected function getCreateURL() + { + return \XLite\Core\Converter::buildUrl('attribute_group'); + } + + /** + * Get create button label + * + * @return string + */ + protected function getCreateButtonLabel() + { + return 'New group'; + } + + /** + * Inline creation mechanism position + * + * @return integer + */ + protected function isInlineCreation() + { + return static::CREATE_INLINE_TOP; + } + + // {{{ Behaviors + + /** + * Mark list as removable + * + * @return boolean + */ + protected function isRemoved() + { + return true; + } + + /** + * Mark list as sortable + * + * @return integer + */ + protected function getSortableType() + { + return static::SORT_TYPE_MOVE; + } + + // }}} + + /** + * Get container class + * + * @return string + */ + protected function getContainerClass() + { + return parent::getContainerClass() . ' attribute_groups'; + } + + /** + * Get panel class + * + * @return \XLite\View\Base\FormStickyPanel + */ + protected function getPanelClass() + { + return null; + } + + /** + * Create entity + * + * @return \XLite\Model\AEntity + */ + protected function createEntity() + { + $entity = parent::createEntity(); + + $entity->setProductClass($this->getProductClass()); + + return $entity; + } + + + // {{{ Search + + /** + * Return search parameters. + * + * @return array + */ + static public function getSearchParams() + { + return array(); + } + + /** + * Return params list to use for search + * TODO refactor + * + * @return \XLite\Core\CommonCell + */ + protected function getSearchCondition() + { + $result = parent::getSearchCondition(); + + foreach (static::getSearchParams() as $modelParam => $requestParam) { + $paramValue = $this->getParam($requestParam); + + if ('' !== $paramValue && 0 !== $paramValue) { + $result->$modelParam = $paramValue; + } + } + + $result->productClass = $this->getProductClass(); + + return $result; + } + + // }}} + +} diff --git a/src/classes/XLite/View/ItemsList/Model/ProductClass.php b/src/classes/XLite/View/ItemsList/Model/ProductClass.php index 5e9910b314..102fbc543c 100644 --- a/src/classes/XLite/View/ItemsList/Model/ProductClass.php +++ b/src/classes/XLite/View/ItemsList/Model/ProductClass.php @@ -56,6 +56,7 @@ protected function defineColumns() 'name' => array( static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text\ProductClass', static::COLUMN_PARAMS => array('required' => true), + static::COLUMN_MAIN => true, ), 'attributes' => array( static::COLUMN_TEMPLATE => 'product_classes/parts/edit_attributes.tpl', diff --git a/src/classes/XLite/View/Model/Attribute.php b/src/classes/XLite/View/Model/Attribute.php new file mode 100644 index 0000000000..b55e340932 --- /dev/null +++ b/src/classes/XLite/View/Model/Attribute.php @@ -0,0 +1,200 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Model; + +/** + * Attribute view model + * + */ +class Attribute extends \XLite\View\Model\AModel +{ + /** + * Shema default + * + * @var array + */ + protected $schemaDefault = array( + 'name' => array( + self::SCHEMA_CLASS => 'XLite\View\FormField\Input\Text', + self::SCHEMA_LABEL => 'Attribute', + self::SCHEMA_REQUIRED => true, + ), + 'attribute_group' => array( + self::SCHEMA_CLASS => 'XLite\View\FormField\Select\AttributeGroups', + self::SCHEMA_LABEL => 'Attribute group', + self::SCHEMA_REQUIRED => false, + ), + 'type' => array( + self::SCHEMA_CLASS => 'XLite\View\FormField\Select\AttributeTypes', + self::SCHEMA_LABEL => 'Type', + self::SCHEMA_REQUIRED => false, + ), + ); + + /** + * Return current model ID + * + * @return integer + */ + public function getModelId() + { + return \XLite\Core\Request::getInstance()->id; + } + + /** + * Return fields list by the corresponding schema + * + * @return array + */ + protected function getFormFieldsForSectionDefault() + { + if ($this->getModelObject()->getId()) { + if ($this->getModelObject()->getValuesCount()) { + $this->schemaDefault['type'][self::SCHEMA_COMMENT] = 'There are products using this attribute!'; + } + + if ( + \XLite\Model\Attribute::TYPE_NUMBER == $this->getModelObject()->getType() + ) { + $this->schemaDefault['decimals'] = array( + self::SCHEMA_CLASS => 'XLite\View\FormField\Select\Decimals', + self::SCHEMA_LABEL => 'Decimals', + self::SCHEMA_REQUIRED => false, + \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'edit-decimals', + ); + $this->schemaDefault['unit'] = array( + self::SCHEMA_CLASS => 'XLite\View\FormField\Input\Text', + self::SCHEMA_LABEL => 'Unit', + self::SCHEMA_REQUIRED => false, + self::SCHEMA_COMMENT => '(suffix)', + \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'edit-unit', + ); + } + + if ( + \XLite\Model\Attribute::TYPE_NUMBER == $this->getModelObject()->getType() + || \XLite\Model\Attribute::TYPE_TEXT == $this->getModelObject()->getType() + || \XLite\Model\Attribute::TYPE_CHECKBOX == $this->getModelObject()->getType() + ) { + $this->schemaDefault['default_value'] = array( + self::SCHEMA_CLASS => \XLite\Model\Attribute::TYPE_CHECKBOX == $this->getModelObject()->getType() + ? 'XLite\View\FormField\Input\Checkbox\Enabled' + : 'XLite\View\FormField\Input\Text', + self::SCHEMA_LABEL => 'Default value', + self::SCHEMA_REQUIRED => false, + ); + } + + if ( + \XLite\Model\Attribute::TYPE_SELECT == $this->getModelObject()->getType() + ) { + $this->schemaDefault['values'] = array( + self::SCHEMA_CLASS => 'XLite\View\FormField\ItemsList', + self::SCHEMA_LABEL => 'Allowed attribute values and default one', + self::SCHEMA_REQUIRED => false, + \XLite\View\FormField\ItemsList::PARAM_LIST_CLASS => 'XLite\View\ItemsList\Model\ProductClass', + ); + } + } + + return $this->getFieldsBySchema($this->schemaDefault); + } + + /** + * Populate model object properties by the passed data + * + * @param array $data Data to set + * + * @return void + */ + protected function setModelProperties(array $data) + { + $data['attribute_group'] = \XLite\Core\Database::getRepo('XLite\Model\AttributeGroup')->find($data['attribute_group']); + + parent::setModelProperties($data); + + $this->getModelObject()->setProductClass($this->getProductClass()); + } + + /** + * This object will be used if another one is not pased + * + * @return \XLite\Model\Attribute + */ + protected function getDefaultModelObject() + { + $model = $this->getModelId() + ? \XLite\Core\Database::getRepo('XLite\Model\Attribute')->find($this->getModelId()) + : null; + + return $model ?: new \XLite\Model\Attribute; + } + + /** + * Return name of web form widget class + * + * @return string + */ + protected function getFormClass() + { + return '\XLite\View\Form\Model\Attribute'; + } + + /** + * Return list of the "Button" widgets + * + * @return array + */ + protected function getFormButtons() + { + $result = parent::getFormButtons(); + + $result['submit'] = new \XLite\View\Button\Submit( + array( + \XLite\View\Button\AButton::PARAM_LABEL => 'Apply changes', + \XLite\View\Button\AButton::PARAM_STYLE => 'action', + ) + ); + + return $result; + } + + /** + * Add top message + * + * @return void + */ + protected function addDataSavedTopMessage() + { + if ('create' != $this->currentAction) { + \XLite\Core\TopMessage::addInfo('The attribute has been updated'); + + } else { + \XLite\Core\TopMessage::addInfo('The attribute has been added'); + } + } + +} diff --git a/src/classes/XLite/View/Model/AttributeGroup.php b/src/classes/XLite/View/Model/AttributeGroup.php new file mode 100644 index 0000000000..3449627ffb --- /dev/null +++ b/src/classes/XLite/View/Model/AttributeGroup.php @@ -0,0 +1,122 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Model; + +/** + * Attribute group view model + * + */ +class AttributeGroup extends \XLite\View\Model\AModel +{ + /** + * Shema default + * + * @var array + */ + protected $schemaDefault = array( + 'position' => array( + self::SCHEMA_CLASS => 'XLite\View\FormField\Input\Text\Integer', + self::SCHEMA_LABEL => 'Position', + self::SCHEMA_REQUIRED => false, + ), + 'name' => array( + self::SCHEMA_CLASS => 'XLite\View\FormField\Input\Text', + self::SCHEMA_LABEL => 'Name', + self::SCHEMA_REQUIRED => false, + ), + ); + + /** + * Return current model ID + * + * @return integer + */ + public function getModelId() + { + return \XLite\Core\Request::getInstance()->id; + } + + /** + * This object will be used if another one is not pased + * + * @return \XLite\Model\AttributeGroup + */ + protected function getDefaultModelObject() + { + $model = $this->getModelId() + ? \XLite\Core\Database::getRepo('XLite\Model\AttributeGroup')->find($this->getModelId()) + : null; + + return $model ?: new \XLite\Model\AttributeGroup; + } + + /** + * Return name of web form widget class + * + * @return string + */ + protected function getFormClass() + { + return '\XLite\View\Form\Model\AttributeGroup'; + } + + /** + * Return list of the "Button" widgets + * + * @return array + */ + protected function getFormButtons() + { + $result = parent::getFormButtons(); + + $label = $this->getModelObject()->getId() ? 'Update' : 'Create'; + + $result['submit'] = new \XLite\View\Button\Submit( + array( + \XLite\View\Button\AButton::PARAM_LABEL => $label, + \XLite\View\Button\AButton::PARAM_STYLE => 'action', + ) + ); + + return $result; + } + + /** + * Add top message + * + * @return void + */ + protected function addDataSavedTopMessage() + { + if ('create' != $this->currentAction) { + \XLite\Core\TopMessage::addInfo('The attribute group has been updated'); + + } else { + \XLite\Core\TopMessage::addInfo('The attribute group has been added'); + } + } + +} \ No newline at end of file diff --git a/src/classes/XLite/View/ProductClass.php b/src/classes/XLite/View/ProductClass.php index d812e532e3..299c2abe42 100644 --- a/src/classes/XLite/View/ProductClass.php +++ b/src/classes/XLite/View/ProductClass.php @@ -53,4 +53,4 @@ protected function getDefaultTemplate() return 'product_class/body.tpl'; } -} \ No newline at end of file +} diff --git a/src/classes/XLite/View/StickyPanel/ItemsList/Attribute.php b/src/classes/XLite/View/StickyPanel/ItemsList/Attribute.php new file mode 100644 index 0000000000..5621f22647 --- /dev/null +++ b/src/classes/XLite/View/StickyPanel/ItemsList/Attribute.php @@ -0,0 +1,34 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\StickyPanel\ItemsList; + +/** + * Attributes items list's sticky panel + * + */ +class Attribute extends \XLite\View\StickyPanel\ItemsListForm +{ +} \ No newline at end of file diff --git a/src/classes/XLite/View/TopMenu.php b/src/classes/XLite/View/TopMenu.php index 854bdc2a23..9d8c77778f 100644 --- a/src/classes/XLite/View/TopMenu.php +++ b/src/classes/XLite/View/TopMenu.php @@ -64,6 +64,10 @@ class TopMenu extends \XLite\View\AView 'db_backup' => array( 'db_restore', ), + 'product_classes' => array( + 'product_class', + 'attributes', + ), ); diff --git a/src/skins/admin/en/attribute/body.tpl b/src/skins/admin/en/attribute/body.tpl new file mode 100644 index 0000000000..31de80cd6f --- /dev/null +++ b/src/skins/admin/en/attribute/body.tpl @@ -0,0 +1,11 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Attribute page template + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + diff --git a/src/skins/admin/en/attribute/footer.tpl b/src/skins/admin/en/attribute/footer.tpl new file mode 100644 index 0000000000..6507546d56 --- /dev/null +++ b/src/skins/admin/en/attribute/footer.tpl @@ -0,0 +1,14 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Attribute footer + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + * + * @ListChild (list="crud.attribute.footer", zone="admin", weight="100") + *} + +
    {t(#Editing attribute groups on this page won't affect other product classes which use these groups. Removing a group doesn't delete attributes from the group, but makes them show up among other attributes having no associated groups.#)}
    diff --git a/src/skins/admin/en/attribute/select.tpl b/src/skins/admin/en/attribute/select.tpl new file mode 100644 index 0000000000..d862b5e04b --- /dev/null +++ b/src/skins/admin/en/attribute/select.tpl @@ -0,0 +1 @@ +sdfsdfsdfds diff --git a/src/skins/admin/en/attribute/style.css b/src/skins/admin/en/attribute/style.css new file mode 100644 index 0000000000..c0837929f8 --- /dev/null +++ b/src/skins/admin/en/attribute/style.css @@ -0,0 +1,10 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Attribute view model styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ diff --git a/src/skins/admin/en/attribute_group/body.tpl b/src/skins/admin/en/attribute_group/body.tpl new file mode 100644 index 0000000000..df399b6405 --- /dev/null +++ b/src/skins/admin/en/attribute_group/body.tpl @@ -0,0 +1,11 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Attribute group page template + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + \ No newline at end of file diff --git a/src/skins/admin/en/attribute_group/style.css b/src/skins/admin/en/attribute_group/style.css new file mode 100644 index 0000000000..d52a4746b2 --- /dev/null +++ b/src/skins/admin/en/attribute_group/style.css @@ -0,0 +1,10 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Attribute group view model styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ diff --git a/src/skins/admin/en/attribute_groups/body.tpl b/src/skins/admin/en/attribute_groups/body.tpl new file mode 100644 index 0000000000..239c7e60d7 --- /dev/null +++ b/src/skins/admin/en/attribute_groups/body.tpl @@ -0,0 +1,12 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Attribute groups page template + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + diff --git a/src/skins/admin/en/attribute_groups/list.tpl b/src/skins/admin/en/attribute_groups/list.tpl new file mode 100644 index 0000000000..141a4cc50d --- /dev/null +++ b/src/skins/admin/en/attribute_groups/list.tpl @@ -0,0 +1,17 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Attribute groups list table template + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + + +
    + +
    + diff --git a/src/skins/admin/en/attribute_groups/style.css b/src/skins/admin/en/attribute_groups/style.css new file mode 100644 index 0000000000..880d5660fa --- /dev/null +++ b/src/skins/admin/en/attribute_groups/style.css @@ -0,0 +1,10 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Attribute groups list styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ diff --git a/src/skins/admin/en/attributes/body.tpl b/src/skins/admin/en/attributes/body.tpl new file mode 100644 index 0000000000..feb33ccfe8 --- /dev/null +++ b/src/skins/admin/en/attributes/body.tpl @@ -0,0 +1,18 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Attributes page template + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + + + +
    +
    + + diff --git a/src/skins/admin/en/attributes/list.tpl b/src/skins/admin/en/attributes/list.tpl new file mode 100644 index 0000000000..1505da9488 --- /dev/null +++ b/src/skins/admin/en/attributes/list.tpl @@ -0,0 +1,17 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Attributes list table template + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + + +{foreach:getAttributeGroups(),group} + +{end:} + diff --git a/src/skins/admin/en/attributes/parts/type.tpl b/src/skins/admin/en/attributes/parts/type.tpl new file mode 100644 index 0000000000..3cc1c52f95 --- /dev/null +++ b/src/skins/admin/en/attributes/parts/type.tpl @@ -0,0 +1,13 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Type + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + +{t(entity.getTypes(entity.getType()))} diff --git a/src/skins/admin/en/attributes/script.js b/src/skins/admin/en/attributes/script.js new file mode 100644 index 0000000000..8c8788d51a --- /dev/null +++ b/src/skins/admin/en/attributes/script.js @@ -0,0 +1,45 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Attributes + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +var ppr = popup.postprocessRequest; +popup.postprocessRequest = function(XMLHttpRequest, textStatus, data, isValid) { + ppr.call(this, XMLHttpRequest, textStatus, data, isValid); + TableItemsListQueue(); +} + +function popup_attribute_groups(product_class_id) { + return !popup.load( + URLHandler.buildURL({ + target: 'attribute_groups', + product_class_id: product_class_id, + widget: 'XLite\\View\\AttributeGroups' + }), + null, + function () { + self.location.reload(); + } + ); +} + +function popup_attribute(product_class_id, id) { + return !popup.load( + URLHandler.buildURL({ + target: 'attribute', + product_class_id: product_class_id, + id: id, + widget: 'XLite\\View\\Attribute' + }), + null, + function () { + self.location.reload(); + } + ); +} diff --git a/src/skins/admin/en/attributes/style.css b/src/skins/admin/en/attributes/style.css new file mode 100644 index 0000000000..9ede8a8647 --- /dev/null +++ b/src/skins/admin/en/attributes/style.css @@ -0,0 +1,256 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Attributes list styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +.items-list-table table.list th.name { + width: 500px; + color: #456583; + font-size: 16px; +} + +.items-list-table table.list th.type { + width: 200px; + text-align: right; +} + +.items-list-table table.list td.type { + text-align: right; + color: #8f8f8f; +} + +.items-list-table table.list .edit-mark td.type { + color: #333333; +} + +.items-list-table table.list th.actions.left { + width: 30px; +} + +.items-list-table table.list th.actions.right { + width: 25px; +} + +.items-list-table.group { + margin-top: 20px; +} + +button.new-attribute span { + background: url("../images/icon_list.png") no-repeat scroll left top transparent; + padding: 2px 0 2px 25px; +} + +button.manage-groups span { + background: url("../images/icon_folder.png") no-repeat scroll left top transparent; + padding: 2px 0 2px 25px; +} + +div.group table.list th.actions.left { + background: url("../images/icon_folder.png") no-repeat scroll center center transparent; +} + +/* + * Popup box + */ + +.blockMsg +{ + background: transparent none; + margin: 0px; + padding: 0px; + z-index: 1001; + position: absolute; + top: 30%; +} + +.blockMsg .close-link +{ + display: block; + position: absolute; + background: transparent url(../../../common/ui/images/icon_window_close.png) no-repeat 10px 10px; + top: 0px; + right: 0px; + width: 41px; + height: 41px; + outline: none; + -moz-border-radius-bottomright: 11px; + -moz-border-radius-topright: 11px; + -webkit-border-bottom-right-radius: 11px; + -webkit-border-top-right-radius: 11px; + border-bottom-right-radius: 11px; + border-top-right-radius: 11px; +} + +.blockMsg .block-container +{ + margin-right: 31px; + border-style: none; + -moz-border-radius: 11px; + -webkit-border-radius: 11px; + border-radius: 11px; + padding: 10px; +} + +.blockMsg .block-subcontainer +{ + padding: 40px; + padding-top: 30px; + background: white; + overflow: auto; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; +} + +.block-wait +{ + text-align: left; + vertical-align: middle; + font-weight: bold; + min-width: 200px; + border: 1px solid #cadce8; + background: #fff none; +} + +.block-wait div +{ + background: transparent url(../images/progress.gif) repeat-x left top; + height: 11px; + margin: 10px; +} + +.mini-block-wait div +{ + margin: 0px; +} + +/* Background overlay */ + +.blockOverlay +{ + background: transparent url(../../../common/ui/images/popup_overlay.png) repeat top left !important; +} + +.blockMsg .close-link, +.blockMsg .block-container +{ + background-color: #7a7a7a; +} + +/* Common popup styles */ + +.blockMsg h2 +{ + margin-top: 0px; + font-size: 32px; +} + +.blockMsg h3 +{ + font-size: 24px; +} + +.blockMsg .model-properties ul.table { + min-width: 450px; +} + +.edit-attribute { + background: url("../images/tri_right_button.png") no-repeat scroll right top transparent; + padding: 0 11px 0 0; + border: none; + border-radius: 0; + display: none; + margin: 0 5px 0 0; +} +.edit-mark .edit-attribute { + display: inline; +} +.edit-attribute span { + background-color: #eff9fe; + border: 1px solid #CADCE8; + border-bottom-left-radius: 3px; + border-right: 0 none; + border-top-left-radius: 3px; + padding: 5px 0 5px 10px; + background-color: #EFF8FE; + color: #154E9C; + line-height: 24px; +} + +.ajax-container-loadable .model-properties ul.table div.table-label label { + font-size: 16px; + color: #456583; + width: auto; +} + +.ajax-container-loadable .model-properties div.table-value { + width: auto; + margin-left: 10px; + float: left; +} + +.ajax-container-loadable div.button.submit { + text-align: center; +} + +.ajax-container-loadable div.table-value select { + width: auto; + max-width: 200px; + float: left; +} + +.ajax-container-loadable .select-attributetypes div.table-value .form-field-comment { + background: url("../images/icon_warning_round.png") no-repeat scroll 10px center transparent; + padding-left: 45px; + color: #456583; + float: left; +} + +.ajax-container-loadable div.table-value .form-field-comment { + float: right; + font-size: 12px; +} + +.ajax-container-loadable .star { + display: none; +} + +.ajax-container-loadable li.edit-unit { + display: inline; + position: absolute; + margin-left: 10px; +} + +.ajax-container-loadable li.edit-unit div.table-value input { + width: 50px; + margin-right: 5px; +} + +.ajax-container-loadable .model-properties ul.table li { + margin-bottom: 10px; +} + +.ajax-container-loadable li.edit-decimals { + float: left; +} + +.ajax-container-loadable div.note { + color: #456583; + text-align: center; + width: 440px; + margin-top: 10px; +} + +.ajax-container-loadable .model-form-buttons { + padding: 0px; +} + +.ajax-container-loadable { + width: 500px; +} diff --git a/src/skins/admin/en/css/style.css b/src/skins/admin/en/css/style.css index 0c4a740e82..c6253f5e73 100644 --- a/src/skins/admin/en/css/style.css +++ b/src/skins/admin/en/css/style.css @@ -1645,6 +1645,10 @@ div.table-label { width: 80px; } +.model-properties ul.table li.itemslist div.table-value { + width: 100%; +} + div.star { float: right; width: 10px; diff --git a/src/skins/admin/en/form_field/items_list.tpl b/src/skins/admin/en/form_field/items_list.tpl new file mode 100644 index 0000000000..7697b01a79 --- /dev/null +++ b/src/skins/admin/en/form_field/items_list.tpl @@ -0,0 +1,12 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Items list + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + diff --git a/src/skins/admin/en/images/icon_folder.png b/src/skins/admin/en/images/icon_folder.png new file mode 100644 index 0000000000000000000000000000000000000000..92d96393d1d4b9e0c1b499b4d6ebc7f83765ceaa GIT binary patch literal 454 zcmV;%0XhDOP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyq< z4Ffvd7BwCK00BlxL_t(I%gvO(N&`U))VL~y+3i#6QACtw9M#G^x1j1yNS5|AS==`O zrV)9w%MZuO`Yu@M5vBupyYuVH)*yX4fa*2x8)rrbO0xoa$49?bHa)C%UC^!~vt150 z_0g|5h2`~P1D|fupB|~pFg63*8NQHo3OUZ%-W;iZRVD;B0ZB$~xwAQ{zQS*ia{_q^ z(is_Kr3=zNk3@u7Nx_bhk!0SZ{)|M#8!hR`AaMm5J?akb=3=a8F|~F;1yB_8+VTS# w$C0+xsyuE5C8xG07*qoM6N<$g2b-93jhEB literal 0 HcmV?d00001 diff --git a/src/skins/admin/en/images/icon_list.png b/src/skins/admin/en/images/icon_list.png new file mode 100644 index 0000000000000000000000000000000000000000..60de63671b12aa93b84f521302597ce387269a66 GIT binary patch literal 456 zcmV;(0XP1MP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyq< z4FMr!MV@c~00BrzL_t(I%bk+TO2a@DhW|icKsUK)77Z>GFQrl!Qt^_72-1x!-@s=Q ze1M7|sB~c$AtEl^R&b$qibP`{AXkNqi$G$+bTaj<<{bWW=Ks!&1OTTu4-}<1>9i$G z5j6n#jzS#mn_2O)Z(-V~0YDu3h=1~89Qx??ELzn(uW8t7E=t*;DDdFLxgZKWtRHj$ z0Q&6YL07kS$x-0r;{2?rqQHwopwAdWXoZD#dlqfBcJbPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyq~ z2r@eiKxcda00Ny!L_t(Y$E}q=XcR#d#(%RrGq-bhG4Wp^A{=b0kWvB%fq-Bo2!Ryo z>}?c;aDkM8gn(dWZzm$8va$*Yfz%QZvT%)sl?2S)-puTsMea72y~`$`9}LUm&3x~h zotgIuO3+S{Ch!b+3e4N5Jc8MZ^^19jR2S5=B&^i0jZxQ+jENcW$>4$D32h+es1vA1lVJRckfEFw7@e z-{OQl+-R^wk_YBi)%t#*91R9@d?jy7Vo>kZ)cB8X=}CAIEG} z<=<&)FF#EIpe0}#3@8?uARqpgStBQMqA2b>ZzXWzv+TYUqEyW4;|DxhxR>vsOo-1i zfD;KEW!^WXl%)&is*<^?oSG{t&%6gXlEA*R_EoV-jT3Zj#>)@i^Z5OXMT`!wBzM*V z><5iFKJd;R+Fp$g?rWm#7Zl{Ay)4Z>bzn(3dru*Ga=lXj*<+coo_kpdcPBb)(Z7F3-M-l40N0h=@ zi%nC!_q)K>$SBG@bQyRXO1Y$zLMnw2f*=g(4?Wa7hjWh1`y=2@BaXk_$e^!r{~y5V bP2B%4r(tRJUJE8N00000NkvXXu0mjf^*v%l literal 0 HcmV?d00001 diff --git a/src/skins/admin/en/items_list/model/table/style.css b/src/skins/admin/en/items_list/model/table/style.css index 6ed73442bf..1f9f24e386 100644 --- a/src/skins/admin/en/items_list/model/table/style.css +++ b/src/skins/admin/en/items_list/model/table/style.css @@ -46,7 +46,14 @@ border-bottom: 1px solid #e9e9e9; } +.items-list-table table.list tbody td.main div span.value, +.items-list-table table.list tbody td.main div { + color: #456583; + font-size: 16px; +} + .items-list-table table.list tbody td.main { + width: 300px; } .items-list-table table.list tbody td { diff --git a/src/skins/admin/en/product_classes/style.css b/src/skins/admin/en/product_classes/style.css index ab3424ff47..8e5d03470d 100644 --- a/src/skins/admin/en/product_classes/style.css +++ b/src/skins/admin/en/product_classes/style.css @@ -9,14 +9,7 @@ * @link http://www.litecommerce.com/ */ -td.name { - width: 300px; -} -.items-list-table table.list tbody.lines td.name div.inline-product-class span.value { - color: #456583; - font-size: 16px; -} -.items-list-table table.list tbody.lines td.cell span, +.items-list-table table.list tbody.lines td.cell span.products, .items-list-table table.list tbody.lines td.cell a { color: #8f8f8f; From 0fcdd0a00e9acf0ede978ddc5099b13116074e15 Mon Sep 17 00:00:00 2001 From: skiv Date: Thu, 27 Sep 2012 10:21:40 +0400 Subject: [PATCH 13/85] Attributes --- .../XLite/Controller/Admin/Attribute.php | 28 +++ .../Controller/Admin/AttributeOption.php | 80 +++++++ .../Controller/Admin/AttributeOptions.php | 105 +++++++++ .../XLite/Controller/Admin/Product.php | 35 +++ src/classes/XLite/Model/Attribute.php | 158 ++++++++++++-- src/classes/XLite/Model/AttributeOption.php | 4 +- .../XLite/Model/AttributeTranslation.php | 12 ++ .../Model/AttributeValue/AAttributeValue.php | 65 ++++++ .../AttributeValue/AttributeValueCheckbox.php | 50 +++++ .../AttributeValue/AttributeValueNumber.php | 50 +++++ .../AttributeValue/AttributeValueSelect.php | 51 +++++ .../AttributeValue/AttributeValueText.php | 49 +++++ src/classes/XLite/Model/Product.php | 11 + src/classes/XLite/Model/Repo/Attribute.php | 27 ++- .../XLite/Model/Repo/AttributeGroup.php | 2 +- .../XLite/Model/Repo/AttributeOption.php | 150 +++++++++++++ .../Repo/AttributeValue/AAttributeValue.php | 170 +++++++++++++++ .../AttributeValue/AttributeValueCheckbox.php | 34 +++ .../AttributeValue/AttributeValueNumber.php | 34 +++ .../AttributeValue/AttributeValueSelect.php | 67 ++++++ .../AttributeValue/AttributeValueText.php | 34 +++ src/classes/XLite/View/AttributeOption.php | 56 +++++ src/classes/XLite/View/AttributeOptions.php | 66 ++++++ src/classes/XLite/View/Attributes.php | 1 + .../Form/ItemsList/AttributeOption/Table.php | 53 +++++ .../XLite/View/Form/Model/AttributeOption.php | 90 ++++++++ .../View/Form/Product/Modify/Attributes.php | 43 ++++ .../XLite/View/FormField/Input/Radio.php | 53 +++++ .../View/FormField/Select/AttributeValues.php | 92 ++++++++ .../XLite/View/FormField/Select/Decimals.php | 7 +- .../XLite/View/ItemsList/Model/AModel.php | 13 ++ .../View/ItemsList/Model/AttributeGroup.php | 1 - .../View/ItemsList/Model/AttributeOption.php | 199 ++++++++++++++++++ .../XLite/View/ItemsList/Model/Table.php | 4 + src/classes/XLite/View/Model/Attribute.php | 12 +- .../XLite/View/Model/AttributeOption.php | 122 +++++++++++ .../View/Product/Details/AAttributes.php | 106 ++++++++++ .../View/Product/Details/Admin/Attributes.php | 100 +++++++++ .../Product/Details/Customer/Attributes.php | 43 ++++ .../Product/Details/Customer/Page/APage.php | 9 + src/skins/admin/en/attribute_option/body.tpl | 11 + src/skins/admin/en/attribute_option/style.css | 10 + src/skins/admin/en/attribute_options/body.tpl | 12 ++ src/skins/admin/en/attribute_options/list.tpl | 14 ++ .../admin/en/attribute_options/style.css | 10 + src/skins/admin/en/attributes/style.css | 19 ++ src/skins/admin/en/form_field/radio.tpl | 12 ++ .../items_list/model/table/parts/default.tpl | 12 ++ .../admin/en/items_list/model/table/style.css | 123 +++++------ src/skins/admin/en/product/attributes.tpl | 31 +++ .../admin/en/product/attributes/fields.tpl | 17 ++ .../admin/en/product/attributes/style.css | 40 ++++ src/skins/default/en/css/lc.css | 32 ++- src/skins/default/en/images/dotted.png | Bin 0 -> 188 bytes .../en/product/details/parts/attribute.tpl | 22 ++ .../parts/common.product-attributes-list.tpl | 18 ++ .../common.product-attributes.attributes.tpl | 14 ++ .../parts/common.product-attributes.sku.tpl | 2 +- .../common.product-attributes.weight.tpl | 2 +- .../details/parts/page.tabs.attributes.tpl | 15 ++ 60 files changed, 2595 insertions(+), 107 deletions(-) create mode 100644 src/classes/XLite/Controller/Admin/AttributeOption.php create mode 100644 src/classes/XLite/Controller/Admin/AttributeOptions.php create mode 100644 src/classes/XLite/Model/AttributeValue/AAttributeValue.php create mode 100644 src/classes/XLite/Model/AttributeValue/AttributeValueCheckbox.php create mode 100644 src/classes/XLite/Model/AttributeValue/AttributeValueNumber.php create mode 100644 src/classes/XLite/Model/AttributeValue/AttributeValueSelect.php create mode 100644 src/classes/XLite/Model/AttributeValue/AttributeValueText.php create mode 100644 src/classes/XLite/Model/Repo/AttributeOption.php create mode 100644 src/classes/XLite/Model/Repo/AttributeValue/AAttributeValue.php create mode 100644 src/classes/XLite/Model/Repo/AttributeValue/AttributeValueCheckbox.php create mode 100644 src/classes/XLite/Model/Repo/AttributeValue/AttributeValueNumber.php create mode 100644 src/classes/XLite/Model/Repo/AttributeValue/AttributeValueSelect.php create mode 100644 src/classes/XLite/Model/Repo/AttributeValue/AttributeValueText.php create mode 100644 src/classes/XLite/View/AttributeOption.php create mode 100644 src/classes/XLite/View/AttributeOptions.php create mode 100644 src/classes/XLite/View/Form/ItemsList/AttributeOption/Table.php create mode 100644 src/classes/XLite/View/Form/Model/AttributeOption.php create mode 100644 src/classes/XLite/View/Form/Product/Modify/Attributes.php create mode 100644 src/classes/XLite/View/FormField/Input/Radio.php create mode 100644 src/classes/XLite/View/FormField/Select/AttributeValues.php create mode 100644 src/classes/XLite/View/ItemsList/Model/AttributeOption.php create mode 100644 src/classes/XLite/View/Model/AttributeOption.php create mode 100644 src/classes/XLite/View/Product/Details/AAttributes.php create mode 100644 src/classes/XLite/View/Product/Details/Admin/Attributes.php create mode 100644 src/classes/XLite/View/Product/Details/Customer/Attributes.php create mode 100644 src/skins/admin/en/attribute_option/body.tpl create mode 100644 src/skins/admin/en/attribute_option/style.css create mode 100644 src/skins/admin/en/attribute_options/body.tpl create mode 100644 src/skins/admin/en/attribute_options/list.tpl create mode 100644 src/skins/admin/en/attribute_options/style.css create mode 100644 src/skins/admin/en/form_field/radio.tpl create mode 100644 src/skins/admin/en/items_list/model/table/parts/default.tpl create mode 100644 src/skins/admin/en/product/attributes.tpl create mode 100644 src/skins/admin/en/product/attributes/fields.tpl create mode 100644 src/skins/admin/en/product/attributes/style.css create mode 100644 src/skins/default/en/images/dotted.png create mode 100644 src/skins/default/en/product/details/parts/attribute.tpl create mode 100644 src/skins/default/en/product/details/parts/common.product-attributes-list.tpl create mode 100644 src/skins/default/en/product/details/parts/common.product-attributes.attributes.tpl create mode 100644 src/skins/default/en/product/details/parts/page.tabs.attributes.tpl diff --git a/src/classes/XLite/Controller/Admin/Attribute.php b/src/classes/XLite/Controller/Admin/Attribute.php index abb2d6c389..e34dd29950 100644 --- a/src/classes/XLite/Controller/Admin/Attribute.php +++ b/src/classes/XLite/Controller/Admin/Attribute.php @@ -45,6 +45,13 @@ class Attribute extends \XLite\Controller\Admin\AAdmin */ protected $productClass; + /** + * Attribute + * + * @var \XLite\Model\Attribute + */ + protected $attribute; + /** * Check ACL permissions * @@ -75,6 +82,24 @@ public function getProductClass() return $this->productClass; } + /** + * Get attribute + * + * @return \XLite\Model\Attribute + */ + public function getAttribute() + { + if ( + is_null($this->attribute) + && \XLite\Core\Request::getInstance()->id + ) { + $this->attribute = \XLite\Core\Database::getRepo('XLite\Model\Attribute') + ->find(intval(\XLite\Core\Request::getInstance()->id)); + } + + return $this->attribute; + } + /** * Return the current page title (for the content area) * @@ -100,6 +125,9 @@ public function getTitle() protected function doActionUpdate() { $this->setInternalRedirect(); + $list = new \XLite\View\ItemsList\Model\AttributeOption; + $list->processQuick(); + if ($this->getModelForm()->performAction('modify')) { $this->setReturnUrl( \XLite\Core\Converter::buildURL( diff --git a/src/classes/XLite/Controller/Admin/AttributeOption.php b/src/classes/XLite/Controller/Admin/AttributeOption.php new file mode 100644 index 0000000000..778f80f9f7 --- /dev/null +++ b/src/classes/XLite/Controller/Admin/AttributeOption.php @@ -0,0 +1,80 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Controller\Admin; + +/** + * Attribute option controller + * + */ +class AttributeOption extends \XLite\Controller\Admin\AAdmin +{ + /** + * Controller parameters + * + * @var array + */ + protected $params = array('target', 'id'); + + /** + * Return the current page title (for the content area) + * + * @return string + */ + public function getTitle() + { + $id = intval(\XLite\Core\Request::getInstance()->id); + $model = $id + ? \XLite\Core\Database::getRepo('XLite\Model\AttributeOption')->find($id) + : null; + + return ($model && $model->getId()) + ? $model->getName() + : \XLite\Core\Translation::getInstance()->lbl('AttributeOption'); + } + + /** + * Update model + * + * @return void + */ + protected function doActionUpdate() + { + if ($this->getModelForm()->performAction('modify')) { + $this->setReturnUrl(\XLite\Core\Converter::buildURL('attribute_options')); + } + } + + /** + * Get model form class + * + * @return string + */ + protected function getModelFormClass() + { + return 'XLite\View\Model\AttributeOption'; + } + +} \ No newline at end of file diff --git a/src/classes/XLite/Controller/Admin/AttributeOptions.php b/src/classes/XLite/Controller/Admin/AttributeOptions.php new file mode 100644 index 0000000000..5dd8d4d0a7 --- /dev/null +++ b/src/classes/XLite/Controller/Admin/AttributeOptions.php @@ -0,0 +1,105 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Controller\Admin; + +/** + * Attribute options controller + * + */ +class AttributeOptions extends \XLite\Controller\Admin\AAdmin +{ + + // {{{ Search + + /** + * Get search condition parameter by name + * + * @param string $paramName Parameter name + * + * @return mixed + */ + public function getCondition($paramName) + { + $searchParams = $this->getConditions(); + + return isset($searchParams[$paramName]) + ? $searchParams[$paramName] + : null; + } + + /** + * Save search conditions + * + * @return void + */ + protected function doActionSearch() + { + $cellName = \XLite\View\ItemsList\Model\AttributeOption::getSessionCellName(); + + \XLite\Core\Session::getInstance()->$cellName = $this->getSearchParams(); + } + + /** + * Return search parameters + * + * @return array + */ + protected function getSearchParams() + { + $searchParams = $this->getConditions(); + + foreach ( + \XLite\View\ItemsList\Model\AttributeOption::getSearchParams() as $requestParam + ) { + if (isset(\XLite\Core\Request::getInstance()->$requestParam)) { + $searchParams[$requestParam] = \XLite\Core\Request::getInstance()->$requestParam; + } + } + + return $searchParams; + } + + /** + * Get search conditions + * + * @return array + */ + protected function getConditions() + { + $cellName = \XLite\View\ItemsList\Model\AttributeOption::getSessionCellName(); + + $searchParams = \XLite\Core\Session::getInstance()->$cellName; + + if (!is_array($searchParams)) { + $searchParams = array(); + } + + return $searchParams; + } + + // }}} + +} \ No newline at end of file diff --git a/src/classes/XLite/Controller/Admin/Product.php b/src/classes/XLite/Controller/Admin/Product.php index 1789eb07dd..cfe7a1d316 100644 --- a/src/classes/XLite/Controller/Admin/Product.php +++ b/src/classes/XLite/Controller/Admin/Product.php @@ -99,6 +99,9 @@ public function getPages() if (!$this->isNew()) { $list['images'] = 'Product images'; $list['inventory'] = 'Inventory tracking'; + if ($this->getProduct()->getClasses()->count()) { + $list['attributes'] = 'Attributes'; + } } return $list; @@ -118,6 +121,9 @@ protected function getPageTemplates() if (!$this->isNew()) { $list['images'] = 'product/product_images.tpl'; $list['inventory'] = 'product/inventory.tpl'; + if ($this->getProduct()->getClasses()->count()) { + $list['attributes'] = 'product/attributes.tpl'; + } } return $list; @@ -446,5 +452,34 @@ protected function doActionUpdateInventory() \XLite\Core\Database::getEM()->flush(); } + /** + * Update attributes + * + * @return void + */ + protected function doActionUpdateAttributes() + { + $this->getProduct()->setAttrSepTab((bool) \XLite\Core\Request::getInstance()->attrSepTab); + $cnd = new \XLite\Core\CommonCell; + $cnd->product = $this->getProduct(); + $attributes = \XLite\Core\Database::getRepo('\XLite\Model\Attribute')->search($cnd); + $attributeValues = \XLite\Core\Request::getInstance()->attributeValues; + + if ( + count($attributes) + && $attributeValues + && is_array($attributeValues) + ) { + foreach ($attributes as $a) { + if (isset($attributeValues[$a->getId()])) { + $a->setAttributeValue($this->getProduct(), $attributeValues[$a->getId()]); + } + } + } + + \XLite\Core\Database::getEM()->flush(); + \XLite\Core\TopMessage::addInfo('Attributes have been updated successfully'); + } + // }}} } diff --git a/src/classes/XLite/Model/Attribute.php b/src/classes/XLite/Model/Attribute.php index 2327fab1fd..b479cff6fa 100644 --- a/src/classes/XLite/Model/Attribute.php +++ b/src/classes/XLite/Model/Attribute.php @@ -72,7 +72,7 @@ class Attribute extends \XLite\Model\Base\I18n * * @Column (type="text") */ - protected $defaultValue; + protected $defaultValue = ''; /** * Decimals @@ -85,17 +85,6 @@ class Attribute extends \XLite\Model\Base\I18n */ protected $decimals = 0; - /** - * Unit - * - * @var string - * @see ____var_see____ - * @since 1.0.0 - * - * @Column (type="string") - */ - protected $unit; - /** * Product class * @@ -109,13 +98,22 @@ class Attribute extends \XLite\Model\Base\I18n /** * Attribute group * - * @var \XLite\Model\AttributeGroup + * @var selfGroup * * @ManyToOne (targetEntity="XLite\Model\AttributeGroup", inversedBy="attributes") * @JoinColumn (name="attribute_group_id", referencedColumnName="id", onDelete="SET NULL") */ protected $attribute_group; + /** + * Attribute options + * + * @var \Doctrine\Common\Collections\Collection + * + * @OneToMany (targetEntity="XLite\Model\AttributeOption", mappedBy="attribute") + */ + protected $attribute_options; + /** * Option type * @@ -134,7 +132,7 @@ class Attribute extends \XLite\Model\Base\I18n */ public function __construct(array $data = array()) { -// $this->attribute_values = new \Doctrine\Common\Collections\ArrayCollection(); + $this->attribute_options = new \Doctrine\Common\Collections\ArrayCollection(); parent::__construct($data); } @@ -175,9 +173,13 @@ public static function getTypes($type = null) * * @return integer */ - public function getValuesCount() + public function getAttributeValuesCount() { - return 1; + $cnd = new \XLite\Core\CommonCell; + $cnd->attribute = $this; + + return \XLite\Core\Database::getRepo($this->getAttributeValueClass()) + ->search($cnd, true); } /** @@ -197,6 +199,9 @@ public function setType($type) && $type != $this->type ) { $this->setDefaultValue($this->defaultValue); + foreach ($this->getAttributeOptions() as $option) { + \XLite\Core\Database::getEM()->remove($option); + } } $this->type = $type; } @@ -234,4 +239,125 @@ public function getDefaultValue() : $this->defaultValue; } + /** + * Return name of widget class + * + * @return string + */ + public function getWidgetClass() + { + switch ($this->getType()) { + case self::TYPE_NUMBER: + $class = '\XLite\View\FormField\Input\Text\Float'; + break; + + case self::TYPE_TEXT: + $class = '\XLite\View\FormField\Textarea\Simple'; + break; + + case self::TYPE_CHECKBOX: + $class = '\XLite\View\FormField\Input\Checkbox\Enabled'; + break; + + case self::TYPE_SELECT: + $class = '\XLite\View\FormField\Select\AttributeValues'; + break; + + } + + return $class; + } + + /** + * Return name of value class + * + * @return string + */ + public function getAttributeValueClass() + { + return '\XLite\Model\AttributeValue\AttributeValue' + . $this->getTypes($this->getType()); + } + + /** + * Set attribute value + * + * @param \XLite\Model\Product $product Product + * @param mixed $value Value + * + * @return void + */ + public function setAttributeValue(\XLite\Model\Product $product, $value) + { + $class = $this->getAttributeValueClass(); + $attributeValue = \XLite\Core\Database::getRepo($class) + ->findOneBy(array('product' => $product, 'attribute' => $this)); + + if (!$attributeValue) { + !$attributeValue = new $class(); + $attributeValue->setProduct($product); + $attributeValue->setAttribute($this); + \XLite\Core\Database::getEM()->persist($attributeValue); + } + + if (self::TYPE_SELECT == $this->getType()) { + $attributeOption = \XLite\Core\Database::getRepo('XLite\Model\AttributeOption')->find($value); + if ($attributeOption) { + $attributeValue->setAttributeOption($attributeOption); + } + + } else { + $attributeValue->setValue($value); + } + } + + /** + * Get attribute value + * + * @param \XLite\Model\Product $product Product + * @param bollean $asString As string flag OPTIONAL + * + * @return mixed + */ + public function getAttributeValue(\XLite\Model\Product $product, $asString = false) + { + $attributeValue = \XLite\Core\Database::getRepo($this->getAttributeValueClass()) + ->findOneBy(array('product' => $product, 'attribute' => $this)); + + if (self::TYPE_SELECT == $this->getType()) { + if ($attributeValue) { + $attributeValue = $attributeValue->getAttributeOption(); + } else { + $attributeValue = \XLite\Core\Database::getRepo('XLite\Model\AttributeOption') + ->findOneBy(array('defaultValue' => 1, 'attribute' => $this)); + } + + if ($attributeValue) { + $attributeValue = $asString + ? $attributeValue->getName() + : $attributeValue->getId(); + } + + } elseif ($attributeValue) { + $attributeValue = $attributeValue->getValue(); + } + + if (is_null($attributeValue)) { + $attributeValue = self::TYPE_SELECT == $this->getType() + ? '' + : $this->getDefaultValue(); + } + + if ($asString) { + if(self::TYPE_NUMBER == $this->getType()) { + $attributeValue = number_format($attributeValue, $this->getDecimals()) + . ' ' . $this->getUnit(); + + } elseif (self::TYPE_CHECKBOX == $this->getType()) { + $attributeValue = static::t($attributeValue ? 'yes' : 'no'); + } + } + + return $attributeValue; + } } diff --git a/src/classes/XLite/Model/AttributeOption.php b/src/classes/XLite/Model/AttributeOption.php index b5ad81f8e7..52ce7a6ae4 100644 --- a/src/classes/XLite/Model/AttributeOption.php +++ b/src/classes/XLite/Model/AttributeOption.php @@ -53,12 +53,12 @@ class AttributeOption extends \XLite\Model\Base\I18n * * @Column (type="boolean") */ - protected $default = false; + protected $defaultValue = false; /** * Attribute * - * @var \XLite\Model\AttributeGroup + * @var \XLite\Model\Attribute * * @ManyToOne (targetEntity="XLite\Model\Attribute", inversedBy="attribute_options") * @JoinColumn (name="attribute_id", referencedColumnName="id") diff --git a/src/classes/XLite/Model/AttributeTranslation.php b/src/classes/XLite/Model/AttributeTranslation.php index 00370c45f1..14566904e1 100644 --- a/src/classes/XLite/Model/AttributeTranslation.php +++ b/src/classes/XLite/Model/AttributeTranslation.php @@ -48,4 +48,16 @@ class AttributeTranslation extends \XLite\Model\Base\Translation * @Column (type="string", length=255) */ protected $name; + + /** + * Unit + * + * @var string + * @see ____var_see____ + * @since 1.0.0 + * + * @Column (type="string", length=255) + */ + protected $unit = ''; + } diff --git a/src/classes/XLite/Model/AttributeValue/AAttributeValue.php b/src/classes/XLite/Model/AttributeValue/AAttributeValue.php new file mode 100644 index 0000000000..7d8bd307a7 --- /dev/null +++ b/src/classes/XLite/Model/AttributeValue/AAttributeValue.php @@ -0,0 +1,65 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\AttributeValue; + +/** + * Abstract attribute value + * + * @MappedSuperclass + */ +abstract class AAttributeValue extends \XLite\Model\AEntity +{ + /** + * ID + * + * @var integer + * + * @Id + * @GeneratedValue (strategy="AUTO") + * @Column (type="uinteger") + */ + protected $id; + + /** + * Product + * + * @var \XLite\Model\Product + * + * @ManyToOne (targetEntity="XLite\Model\Product") + * @JoinColumn (name="product_id", referencedColumnName="product_id") + */ + protected $product; + + /** + * Attribute + * + * @var \XLite\Model\Attribute + * + * @ManyToOne (targetEntity="XLite\Model\Attribute") + * @JoinColumn (name="attribute_id", referencedColumnName="id") + */ + protected $attribute; +} diff --git a/src/classes/XLite/Model/AttributeValue/AttributeValueCheckbox.php b/src/classes/XLite/Model/AttributeValue/AttributeValueCheckbox.php new file mode 100644 index 0000000000..560ea05954 --- /dev/null +++ b/src/classes/XLite/Model/AttributeValue/AttributeValueCheckbox.php @@ -0,0 +1,50 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\AttributeValue; + +/** + * Attribute value (checkbox) + * + * @Entity (repositoryClass="\XLite\Model\Repo\AttributeValue\AttributeValueCheckbox") + * @Table (name="attribute_values_checkbox", + * indexes={ + * @Index (name="product_id", columns={"product_id"}), + * @Index (name="attribute_id", columns={"attribute_id"}), + * @Index (name="value", columns={"value"}) + * } + * ) + */ +class AttributeValueCheckbox extends \XLite\Model\AttributeValue\AAttributeValue +{ + /** + * Value + * + * @var boolean + * + * @Column (type="boolean") + */ + protected $value = 0; +} diff --git a/src/classes/XLite/Model/AttributeValue/AttributeValueNumber.php b/src/classes/XLite/Model/AttributeValue/AttributeValueNumber.php new file mode 100644 index 0000000000..e0cf31e4e4 --- /dev/null +++ b/src/classes/XLite/Model/AttributeValue/AttributeValueNumber.php @@ -0,0 +1,50 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\AttributeValue; + +/** + * Attribute value (number) + * + * @Entity (repositoryClass="\XLite\Model\Repo\AttributeValue\AttributeValueNumber") + * @Table (name="attribute_values_number", + * indexes={ + * @Index (name="product_id", columns={"product_id"}), + * @Index (name="attribute_id", columns={"attribute_id"}), + * @Index (name="value", columns={"value"}) + * } + * ) + */ +class AttributeValueNumber extends \XLite\Model\AttributeValue\AAttributeValue +{ + /** + * Value + * + * @var float + * + * @Column (type="decimal", precision=14, scale=4) + */ + protected $value = 0; +} diff --git a/src/classes/XLite/Model/AttributeValue/AttributeValueSelect.php b/src/classes/XLite/Model/AttributeValue/AttributeValueSelect.php new file mode 100644 index 0000000000..8ad6158e55 --- /dev/null +++ b/src/classes/XLite/Model/AttributeValue/AttributeValueSelect.php @@ -0,0 +1,51 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\AttributeValue; + +/** + * Attribute value (select) + * + * @Entity (repositoryClass="\XLite\Model\Repo\AttributeValue\AttributeValueSelect") + * @Table (name="attribute_values_select", + * indexes={ + * @Index (name="product_id", columns={"product_id"}), + * @Index (name="attribute_id", columns={"attribute_id"}), + * @Index (name="attribute_option_id", columns={"attribute_option_id"}) + * } + * ) + */ +class AttributeValueSelect extends \XLite\Model\AttributeValue\AAttributeValue +{ + /** + * Attribute option + * + * @var \XLite\Model\AttributeOption + * + * @ManyToOne (targetEntity="XLite\Model\AttributeOption") + * @JoinColumn (name="attribute_option_id", referencedColumnName="id") + */ + protected $attribute_option; +} diff --git a/src/classes/XLite/Model/AttributeValue/AttributeValueText.php b/src/classes/XLite/Model/AttributeValue/AttributeValueText.php new file mode 100644 index 0000000000..ef42289b46 --- /dev/null +++ b/src/classes/XLite/Model/AttributeValue/AttributeValueText.php @@ -0,0 +1,49 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\AttributeValue; + +/** + * Attribute value (text) + * + * @Entity (repositoryClass="\XLite\Model\Repo\AttributeValue\AttributeValueText") + * @Table (name="attribute_values_text", + * indexes={ + * @Index (name="product_id", columns={"product_id"}), + * @Index (name="attribute_id", columns={"attribute_id"}) + * } + * ) + */ +class AttributeValueText extends \XLite\Model\AttributeValue\AAttributeValue +{ + /** + * Value + * + * @var text + * + * @Column (type="text") + */ + protected $value; +} diff --git a/src/classes/XLite/Model/Product.php b/src/classes/XLite/Model/Product.php index ad9e385bdc..300a93a878 100644 --- a/src/classes/XLite/Model/Product.php +++ b/src/classes/XLite/Model/Product.php @@ -193,9 +193,20 @@ class Product extends \XLite\Model\Base\Catalog implements \XLite\Model\Base\IOr * joinColumns={@JoinColumn(name="product_id", referencedColumnName="product_id")}, * inverseJoinColumns={@JoinColumn(name="class_id", referencedColumnName="id")} * ) + * @OrderBy ({"position" = "ASC"}) */ protected $classes; + /** + * Show product attributes in a separate tab + * + * @var boolean + * + * @Column (type="boolean") + */ + protected $attrSepTab = true; + + /** * Constructor * diff --git a/src/classes/XLite/Model/Repo/Attribute.php b/src/classes/XLite/Model/Repo/Attribute.php index 104bdee0ac..923bcc8693 100644 --- a/src/classes/XLite/Model/Repo/Attribute.php +++ b/src/classes/XLite/Model/Repo/Attribute.php @@ -34,6 +34,7 @@ class Attribute extends \XLite\Model\Repo\Base\I18n /** * Allowable search params */ + const SEARCH_PRODUCT = 'product'; const SEARCH_PRODUCT_CLASS = 'productClass'; const SEARCH_ATTRIBUTE_GROUP = 'attributeGroup'; @@ -124,6 +125,7 @@ protected function isSearchParamHasHandler($param) protected function getHandlingSearchParams() { return array( + static::SEARCH_PRODUCT, static::SEARCH_PRODUCT_CLASS, static::SEARCH_ATTRIBUTE_GROUP, ); @@ -133,7 +135,28 @@ protected function getHandlingSearchParams() * Prepare certain search condition * * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare - * @param string $value Condition OPTIONAL + * @param mixed $value Condition OPTIONAL + * + * @return void + * @see ____func_see____ + * @since 1.0.0 + */ + protected function prepareCndProduct(\Doctrine\ORM\QueryBuilder $queryBuilder, $value = null) + { + if ($value) { + $queryBuilder->linkInner('a.product_class') + ->linkInner('product_class.products') + ->andWhere('products.product_id = :productId') + ->addOrderBy('product_class.position', 'ASC') + ->setParameter('productId', $value->getProductId()); + } + } + + /** + * Prepare certain search condition + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param mixed $value Condition OPTIONAL * * @return void * @see ____func_see____ @@ -151,7 +174,7 @@ protected function prepareCndProductClass(\Doctrine\ORM\QueryBuilder $queryBuild * Prepare certain search condition * * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare - * @param string $value Condition OPTIONAL + * @param mixed $value Condition OPTIONAL * * @return void * @see ____func_see____ diff --git a/src/classes/XLite/Model/Repo/AttributeGroup.php b/src/classes/XLite/Model/Repo/AttributeGroup.php index 2692574fa4..b57edd9ef4 100644 --- a/src/classes/XLite/Model/Repo/AttributeGroup.php +++ b/src/classes/XLite/Model/Repo/AttributeGroup.php @@ -131,7 +131,7 @@ protected function getHandlingSearchParams() * Prepare certain search condition * * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare - * @param string $value Condition OPTIONAL + * @param mixed $value Condition OPTIONAL * * @return void * @see ____func_see____ diff --git a/src/classes/XLite/Model/Repo/AttributeOption.php b/src/classes/XLite/Model/Repo/AttributeOption.php new file mode 100644 index 0000000000..a24fae09b0 --- /dev/null +++ b/src/classes/XLite/Model/Repo/AttributeOption.php @@ -0,0 +1,150 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\Repo; + +/** + * Attribute options repository + * + */ +class AttributeOption extends \XLite\Model\Repo\Base\I18n +{ + /** + * Allowable search params + */ + const SEARCH_ATTRIBUTE = 'attribute'; + + // {{{ Search + + /** + * Common search + * + * @param \XLite\Core\CommonCell $cnd Search condition + * @param boolean $countOnly Return items list or only its size OPTIONAL + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function search(\XLite\Core\CommonCell $cnd, $countOnly = false) + { + $queryBuilder = $this->createQueryBuilder('a'); + $this->currentSearchCnd = $cnd; + + foreach ($this->currentSearchCnd as $key => $value) { + $this->callSearchConditionHandler($value, $key, $queryBuilder, $countOnly); + } + + return $countOnly + ? $this->searchCount($queryBuilder) + : $this->searchResult($queryBuilder); + } + + /** + * Search count only routine. + * + * @param \Doctrine\ORM\QueryBuilder $qb Query builder routine + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function searchCount(\Doctrine\ORM\QueryBuilder $qb) + { + $qb->select('COUNT(DISTINCT a.id)'); + + return intval($qb->getSingleScalarResult()); + } + + /** + * Search result routine. + * + * @param \Doctrine\ORM\QueryBuilder $qb Query builder routine + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function searchResult(\Doctrine\ORM\QueryBuilder $qb) + { + return $qb->getResult(); + } + + /** + * Call corresponded method to handle a search condition + * + * @param mixed $value Condition data + * @param string $key Condition name + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param boolean $countOnly Count only flag + * + * @return void + */ + protected function callSearchConditionHandler($value, $key, \Doctrine\ORM\QueryBuilder $queryBuilder, $countOnly) + { + if ($this->isSearchParamHasHandler($key)) { + $this->{'prepareCnd' . ucfirst($key)}($queryBuilder, $value, $countOnly); + } + } + + /** + * Check if param can be used for search + * + * @param string $param Name of param to check + * + * @return boolean + */ + protected function isSearchParamHasHandler($param) + { + return in_array($param, $this->getHandlingSearchParams()); + } + + /** + * Return list of handling search params + * + * @return array + */ + protected function getHandlingSearchParams() + { + return array( + static::SEARCH_ATTRIBUTE, + ); + } + + /** + * Prepare certain search condition + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param mixed $value Condition OPTIONAL + * + * @return void + * @see ____func_see____ + * @since 1.0.0 + */ + protected function prepareCndAttribute(\Doctrine\ORM\QueryBuilder $queryBuilder, $value = null) + { + if ($value) { + $queryBuilder->andWhere('a.attribute = :attribute') + ->setParameter('attribute', $value); + } + } + + // }}} + +} diff --git a/src/classes/XLite/Model/Repo/AttributeValue/AAttributeValue.php b/src/classes/XLite/Model/Repo/AttributeValue/AAttributeValue.php new file mode 100644 index 0000000000..74781cf30e --- /dev/null +++ b/src/classes/XLite/Model/Repo/AttributeValue/AAttributeValue.php @@ -0,0 +1,170 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\Repo\AttributeValue; + +/** + * Attribute values repository + * + */ +class AAttributeValue extends \XLite\Model\Repo\ARepo +{ + /** + * Allowable search params + */ + const SEARCH_PRODUCT = 'product'; + const SEARCH_ATTRIBUTE = 'attribute'; + + // {{{ Search + + /** + * Common search + * + * @param \XLite\Core\CommonCell $cnd Search condition + * @param boolean $countOnly Return items list or only its size OPTIONAL + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function search(\XLite\Core\CommonCell $cnd, $countOnly = false) + { + $queryBuilder = $this->createQueryBuilder('a'); + $this->currentSearchCnd = $cnd; + + foreach ($this->currentSearchCnd as $key => $value) { + $this->callSearchConditionHandler($value, $key, $queryBuilder, $countOnly); + } + + return $countOnly + ? $this->searchCount($queryBuilder) + : $this->searchResult($queryBuilder); + } + + /** + * Search count only routine. + * + * @param \Doctrine\ORM\QueryBuilder $qb Query builder routine + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function searchCount(\Doctrine\ORM\QueryBuilder $qb) + { + $qb->select('COUNT(DISTINCT a.id)'); + + return intval($qb->getSingleScalarResult()); + } + + /** + * Search result routine. + * + * @param \Doctrine\ORM\QueryBuilder $qb Query builder routine + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function searchResult(\Doctrine\ORM\QueryBuilder $qb) + { + return $qb->getResult(); + } + + /** + * Call corresponded method to handle a search condition + * + * @param mixed $value Condition data + * @param string $key Condition name + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param boolean $countOnly Count only flag + * + * @return void + */ + protected function callSearchConditionHandler($value, $key, \Doctrine\ORM\QueryBuilder $queryBuilder, $countOnly) + { + if ($this->isSearchParamHasHandler($key)) { + $this->{'prepareCnd' . ucfirst($key)}($queryBuilder, $value, $countOnly); + } + } + + /** + * Check if param can be used for search + * + * @param string $param Name of param to check + * + * @return boolean + */ + protected function isSearchParamHasHandler($param) + { + return in_array($param, $this->getHandlingSearchParams()); + } + + /** + * Return list of handling search params + * + * @return array + */ + protected function getHandlingSearchParams() + { + return array( + static::SEARCH_PRODUCT, + static::SEARCH_ATTRIBUTE, + ); + } + + /** + * Prepare certain search condition + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param mixed $value Condition OPTIONAL + * + * @return void + * @see ____func_see____ + * @since 1.0.0 + */ + protected function prepareCndProduct(\Doctrine\ORM\QueryBuilder $queryBuilder, $value = null) + { + if ($value) { + $queryBuilder->andWhere('a.product = :product') + ->setParameter('product', $value); + } + } + + /** + * Prepare certain search condition + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param mixed $value Condition OPTIONAL + * + * @return void + * @see ____func_see____ + * @since 1.0.0 + */ + protected function prepareCndAttribute(\Doctrine\ORM\QueryBuilder $queryBuilder, $value = null) + { + if ($value) { + $queryBuilder->andWhere('a.attribute = :attribute') + ->setParameter('attribute', $value); + } + } + + // }}} + +} diff --git a/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueCheckbox.php b/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueCheckbox.php new file mode 100644 index 0000000000..abcda37b26 --- /dev/null +++ b/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueCheckbox.php @@ -0,0 +1,34 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\Repo\AttributeValue; + +/** + * Attribute values repository + * + */ +class AttributeValueCheckbox extends \XLite\Model\Repo\AttributeValue\AAttributeValue +{ +} diff --git a/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueNumber.php b/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueNumber.php new file mode 100644 index 0000000000..14e64c63ba --- /dev/null +++ b/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueNumber.php @@ -0,0 +1,34 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\Repo\AttributeValue; + +/** + * Attribute values repository + * + */ +class AttributeValueNumber extends \XLite\Model\Repo\AttributeValue\AAttributeValue +{ +} diff --git a/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueSelect.php b/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueSelect.php new file mode 100644 index 0000000000..8aa14c2804 --- /dev/null +++ b/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueSelect.php @@ -0,0 +1,67 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\Repo\AttributeValue; + +/** + * Attribute values repository + * + */ +class AttributeValueSelect extends \XLite\Model\Repo\AttributeValue\AAttributeValue +{ + /** + * Allowable search params + */ + const SEARCH_ATTRIBUTE_OPTION = 'attributeOption'; + + /** + * Return list of handling search params + * + * @return array + */ + protected function getHandlingSearchParams() + { + return parent::getHandlingSearchParams() + array(static::SEARCH_ATTRIBUTE_OPTION); + } + + /** + * Prepare certain search condition + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param mixed $value Condition OPTIONAL + * + * @return void + * @see ____func_see____ + * @since 1.0.0 + */ + protected function prepareCndAttributeOption(\Doctrine\ORM\QueryBuilder $queryBuilder, $value = null) + { + if ($value) { + $queryBuilder->andWhere('a.attribute_option = :attributeOption') + ->setParameter('attributeOption', $value); + } + } + +} diff --git a/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueText.php b/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueText.php new file mode 100644 index 0000000000..c46ae10916 --- /dev/null +++ b/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueText.php @@ -0,0 +1,34 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Model\Repo\AttributeValue; + +/** + * Attribute values repository + * + */ +class AttributeValueText extends \XLite\Model\Repo\AttributeValue\AAttributeValue +{ +} diff --git a/src/classes/XLite/View/AttributeOption.php b/src/classes/XLite/View/AttributeOption.php new file mode 100644 index 0000000000..ed97f0a972 --- /dev/null +++ b/src/classes/XLite/View/AttributeOption.php @@ -0,0 +1,56 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View; + +/** + * Attribute option page view + * + * + * @ListChild (list="admin.center", zone="admin") + */ +class AttributeOption extends \XLite\View\AView +{ + /** + * Return list of allowed targets + * + * @return array + */ + public static function getAllowedTargets() + { + return array_merge(parent::getAllowedTargets(), array('attribute_option')); + } + + /** + * Return widget default template + * + * @return string + */ + protected function getDefaultTemplate() + { + return 'attribute_option/body.tpl'; + } + +} \ No newline at end of file diff --git a/src/classes/XLite/View/AttributeOptions.php b/src/classes/XLite/View/AttributeOptions.php new file mode 100644 index 0000000000..22804d60bb --- /dev/null +++ b/src/classes/XLite/View/AttributeOptions.php @@ -0,0 +1,66 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View; + +/** + * Attribute options page view + * + * + * @ListChild (list="admin.center", zone="admin") + */ +class AttributeOptions extends \XLite\View\AView +{ + /** + * Return list of allowed targets + * + * @return array + */ + public static function getAllowedTargets() + { + return array_merge(parent::getAllowedTargets(), array('attribute_options')); + } + + /** + * Return widget default template + * + * @return string + */ + protected function getDefaultTemplate() + { + return 'attribute_options/body.tpl'; + } + + /** + * Check - search box is visible or not + * + * @return boolean + */ + protected function isSearchVisible() + { + return 0 < \XLite\Core\Database::getRepo('XLite\Model\AttributeOption')->count(); + } + +} \ No newline at end of file diff --git a/src/classes/XLite/View/Attributes.php b/src/classes/XLite/View/Attributes.php index 7f60d5c010..0ac1100cd7 100644 --- a/src/classes/XLite/View/Attributes.php +++ b/src/classes/XLite/View/Attributes.php @@ -95,6 +95,7 @@ public function getCommonFiles() { $list = parent::getCommonFiles(); $list['js'][] = 'js/jquery.blockUI.js'; + $list['js'][] = 'js/jquery.textarea-expander.js'; return $list; } diff --git a/src/classes/XLite/View/Form/ItemsList/AttributeOption/Table.php b/src/classes/XLite/View/Form/ItemsList/AttributeOption/Table.php new file mode 100644 index 0000000000..312bb3e438 --- /dev/null +++ b/src/classes/XLite/View/Form/ItemsList/AttributeOption/Table.php @@ -0,0 +1,53 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Form\ItemsList\AttributeOption; + +/** + * Attribute options list table form + * + */ +class Table extends \XLite\View\Form\ItemsList\AItemsList +{ + /** + * Return default value for the "target" parameter + * + * @return string + */ + protected function getDefaultTarget() + { + return 'attribute_options'; + } + + /** + * Return default value for the "action" parameter + * + * @return string + */ + protected function getDefaultAction() + { + return 'update'; + } +} \ No newline at end of file diff --git a/src/classes/XLite/View/Form/Model/AttributeOption.php b/src/classes/XLite/View/Form/Model/AttributeOption.php new file mode 100644 index 0000000000..28642ca745 --- /dev/null +++ b/src/classes/XLite/View/Form/Model/AttributeOption.php @@ -0,0 +1,90 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Form\Model; + +/** + * Attribute options list search form + * + */ +class AttributeOption extends \XLite\View\Form\AForm +{ + /** + * Register CSS files + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = 'attribute_option/style.css'; + + return $list; + } + + /** + * Return default value for the "target" parameter + * + * @return string + */ + protected function getDefaultTarget() + { + return 'attribute_option'; + } + + /** + * Return default value for the "action" parameter + * + * @return string + */ + protected function getDefaultAction() + { + return 'update'; + } + + /** + * Get default class name + * + * @return string + */ + protected function getDefaultClassName() + { + return trim(parent::getDefaultClassName() . ' validationEngine attribute-option'); + } + + /** + * Return list of the form default parameters + * + * @return array + */ + protected function getDefaultParams() + { + return array( + 'id' => \XLite\Core\Request::getInstance()->id, + ); + } + +} \ No newline at end of file diff --git a/src/classes/XLite/View/Form/Product/Modify/Attributes.php b/src/classes/XLite/View/Form/Product/Modify/Attributes.php new file mode 100644 index 0000000000..a59648a6c4 --- /dev/null +++ b/src/classes/XLite/View/Form/Product/Modify/Attributes.php @@ -0,0 +1,43 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Form\Product\Modify; + +/** + * Attributes + * + */ +class Attributes extends \XLite\View\Form\Product\Modify\Base\Single +{ + /** + * Get default action + * + * @return string + */ + protected function getDefaultAction() + { + return 'update_attributes'; + } +} diff --git a/src/classes/XLite/View/FormField/Input/Radio.php b/src/classes/XLite/View/FormField/Input/Radio.php new file mode 100644 index 0000000000..33840ca47f --- /dev/null +++ b/src/classes/XLite/View/FormField/Input/Radio.php @@ -0,0 +1,53 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\FormField\Input; + +/** + * Radio + * + */ +class Radio extends \XLite\View\FormField\Input\Checkbox +{ + /** + * Return field type + * + * @return string + */ + public function getFieldType() + { + return self::FIELD_TYPE_RADIO; + } + + /** + * Return field template + * + * @return string + */ + protected function getFieldTemplate() + { + return 'radio.tpl'; + } +} diff --git a/src/classes/XLite/View/FormField/Select/AttributeValues.php b/src/classes/XLite/View/FormField/Select/AttributeValues.php new file mode 100644 index 0000000000..15aa469fe8 --- /dev/null +++ b/src/classes/XLite/View/FormField/Select/AttributeValues.php @@ -0,0 +1,92 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\FormField\Select; + +/** + * Attribute groups selector + * + */ +class AttributeValues extends \XLite\View\FormField\Select\Regular +{ + /** + * Common params + */ + const PARAM_ATTRIBUTE = 'attribute'; + + /** + * Get attribute groups list + * + * @return array + */ + protected function getAttributeValuesList() + { + $list = array(); + $cnd = new \XLite\Core\CommonCell; + $cnd->attribute = $this->getParam(self::PARAM_ATTRIBUTE); + + foreach (\XLite\Core\Database::getRepo('\XLite\Model\AttributeOption')->search($cnd) as $e) { + $list[$e->getId()] = $e->getName(); + } + + return $list; + } + + /** + * Define widget params + * + * @return void + */ + protected function defineWidgetParams() + { + parent::defineWidgetParams(); + + $this->widgetParams += array( + self::PARAM_ATTRIBUTE => new \XLite\Model\WidgetParam\Object( + 'Attribute', null, false, 'XLite\Model\Attribute' + ), + ); + } + + /** + * Get options + * + * @return array + */ + protected function getOptions() + { + return $this->getAttributeValuesList(); + } + + /** + * Get default options + * + * @return array + */ + protected function getDefaultOptions() + { + return array(); + } +} diff --git a/src/classes/XLite/View/FormField/Select/Decimals.php b/src/classes/XLite/View/FormField/Select/Decimals.php index cdff6788a9..98f27cee37 100644 --- a/src/classes/XLite/View/FormField/Select/Decimals.php +++ b/src/classes/XLite/View/FormField/Select/Decimals.php @@ -43,12 +43,7 @@ protected function getDefaultOptions() 1 => 1, 2 => 2, 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - 9 => 9 + 4 => 4 ); } } diff --git a/src/classes/XLite/View/ItemsList/Model/AModel.php b/src/classes/XLite/View/ItemsList/Model/AModel.php index f969edd54f..970a77327e 100644 --- a/src/classes/XLite/View/ItemsList/Model/AModel.php +++ b/src/classes/XLite/View/ItemsList/Model/AModel.php @@ -494,6 +494,9 @@ protected function update() foreach ($this->getPageData() as $entity) { $entity->getRepository()->update($entity, array(), false); + if ($this->isDefault()) { + $entity->setDefaultValue(isset($this->requestData['defaultValue']) && $this->requestData['defaultValue'] == $entity->getId()); + } } return $count; @@ -872,6 +875,16 @@ protected function isRemoved() return false; } + /** + * Mark list iten as default + * + * @return boolean + */ + protected function isDefault() + { + return false; + } + /** * Mark list as selectable * diff --git a/src/classes/XLite/View/ItemsList/Model/AttributeGroup.php b/src/classes/XLite/View/ItemsList/Model/AttributeGroup.php index 432a9a5f5d..b4ac05e786 100644 --- a/src/classes/XLite/View/ItemsList/Model/AttributeGroup.php +++ b/src/classes/XLite/View/ItemsList/Model/AttributeGroup.php @@ -159,7 +159,6 @@ protected function createEntity() return $entity; } - // {{{ Search /** diff --git a/src/classes/XLite/View/ItemsList/Model/AttributeOption.php b/src/classes/XLite/View/ItemsList/Model/AttributeOption.php new file mode 100644 index 0000000000..8808ca5cf2 --- /dev/null +++ b/src/classes/XLite/View/ItemsList/Model/AttributeOption.php @@ -0,0 +1,199 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\ItemsList\Model; + +/** + * Attribute options items list + * + */ +class AttributeOption extends \XLite\View\ItemsList\Model\Table +{ + /** + * Get a list of CSS files required to display the widget properly + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = 'attribute_options/style.css'; + + return $list; + } + + /** + * Define columns structure + * + * @return array + */ + protected function defineColumns() + { + return array( + 'name' => array( + static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text', + static::COLUMN_MAIN => true, + static::COLUMN_PARAMS => array('required' => true), + ), + ); + } + + /** + * Define repository name + * + * @return string + */ + protected function defineRepositoryName() + { + return 'XLite\Model\AttributeOption'; + } + + /** + * Get create entity URL + * + * @return string + */ + protected function getCreateURL() + { + return \XLite\Core\Converter::buildUrl('attribute_option'); + } + + /** + * Get create button label + * + * @return string + */ + protected function getCreateButtonLabel() + { + return 'New value'; + } + + /** + * Inline creation mechanism position + * + * @return integer + */ + protected function isInlineCreation() + { + return static::CREATE_INLINE_BOTTOM; + } + + // {{{ Behaviors + + /** + * Mark list as removable + * + * @return boolean + */ + protected function isRemoved() + { + return true; + } + + /** + * Mark list iten as default + * + * @return boolean + */ + protected function isDefault() + { + return true; + } + + // }}} + + /** + * Get container class + * + * @return string + */ + protected function getContainerClass() + { + return parent::getContainerClass() . ' attribute_options'; + } + + /** + * Get panel class + * + * @return \XLite\View\Base\FormStickyPanel + */ + protected function getPanelClass() + { + return null; + } + + /** + * Create entity + * + * @return \XLite\Model\AEntity + */ + protected function createEntity() + { + $entity = parent::createEntity(); + + $entity->setAttribute($this->getAttribute()); + + return $entity; + } + + // {{{ Search + + /** + * Return search parameters. + * + * @return array + */ + static public function getSearchParams() + { + return array(); + } + + /** + * Return params list to use for search + * TODO refactor + * + * @return \XLite\Core\CommonCell + */ + protected function getSearchCondition() + { + $result = parent::getSearchCondition(); + + foreach (static::getSearchParams() as $modelParam => $requestParam) { + $paramValue = $this->getParam($requestParam); + + if ('' !== $paramValue && 0 !== $paramValue) { + $result->$modelParam = $paramValue; + } + } + + $result->attribute = $this->getAttribute(); + + return $result; + } + + // }}} + +} diff --git a/src/classes/XLite/View/ItemsList/Model/Table.php b/src/classes/XLite/View/ItemsList/Model/Table.php index ad309227a6..26143cdc75 100644 --- a/src/classes/XLite/View/ItemsList/Model/Table.php +++ b/src/classes/XLite/View/ItemsList/Model/Table.php @@ -607,6 +607,10 @@ protected function getLeftActions() $list[] = 'items_list/model/table/parts/switcher.tpl'; } + if ($this->isDefault()) { + $list[] = 'items_list/model/table/parts/default.tpl'; + } + return $list; } diff --git a/src/classes/XLite/View/Model/Attribute.php b/src/classes/XLite/View/Model/Attribute.php index b55e340932..019f925160 100644 --- a/src/classes/XLite/View/Model/Attribute.php +++ b/src/classes/XLite/View/Model/Attribute.php @@ -72,7 +72,7 @@ public function getModelId() protected function getFormFieldsForSectionDefault() { if ($this->getModelObject()->getId()) { - if ($this->getModelObject()->getValuesCount()) { + if ($this->getModelObject()->getAttributeValuesCount()) { $this->schemaDefault['type'][self::SCHEMA_COMMENT] = 'There are products using this attribute!'; } @@ -96,15 +96,15 @@ protected function getFormFieldsForSectionDefault() if ( \XLite\Model\Attribute::TYPE_NUMBER == $this->getModelObject()->getType() - || \XLite\Model\Attribute::TYPE_TEXT == $this->getModelObject()->getType() || \XLite\Model\Attribute::TYPE_CHECKBOX == $this->getModelObject()->getType() + || \XLite\Model\Attribute::TYPE_TEXT == $this->getModelObject()->getType() ) { $this->schemaDefault['default_value'] = array( - self::SCHEMA_CLASS => \XLite\Model\Attribute::TYPE_CHECKBOX == $this->getModelObject()->getType() - ? 'XLite\View\FormField\Input\Checkbox\Enabled' - : 'XLite\View\FormField\Input\Text', + self::SCHEMA_CLASS => $this->getModelObject()->getWidgetClass(), self::SCHEMA_LABEL => 'Default value', self::SCHEMA_REQUIRED => false, + 'rows' => 1, + 'maxHeight' => 100, ); } @@ -115,7 +115,7 @@ protected function getFormFieldsForSectionDefault() self::SCHEMA_CLASS => 'XLite\View\FormField\ItemsList', self::SCHEMA_LABEL => 'Allowed attribute values and default one', self::SCHEMA_REQUIRED => false, - \XLite\View\FormField\ItemsList::PARAM_LIST_CLASS => 'XLite\View\ItemsList\Model\ProductClass', + \XLite\View\FormField\ItemsList::PARAM_LIST_CLASS => 'XLite\View\ItemsList\Model\AttributeOption', ); } } diff --git a/src/classes/XLite/View/Model/AttributeOption.php b/src/classes/XLite/View/Model/AttributeOption.php new file mode 100644 index 0000000000..06804f3909 --- /dev/null +++ b/src/classes/XLite/View/Model/AttributeOption.php @@ -0,0 +1,122 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Model; + +/** + * Attribute option view model + * + */ +class AttributeOption extends \XLite\View\Model\AModel +{ + /** + * Shema default + * + * @var array + */ + protected $schemaDefault = array( + 'default' => array( + self::SCHEMA_CLASS => 'XLite\View\FormField\Input\Checkbox\Enabled', + self::SCHEMA_LABEL => 'Default', + self::SCHEMA_REQUIRED => false, + ), + 'name' => array( + self::SCHEMA_CLASS => 'XLite\View\FormField\Input\Text', + self::SCHEMA_LABEL => 'Name', + self::SCHEMA_REQUIRED => false, + ), + ); + + /** + * Return current model ID + * + * @return integer + */ + public function getModelId() + { + return \XLite\Core\Request::getInstance()->id; + } + + /** + * This object will be used if another one is not pased + * + * @return \XLite\Model\AttributeOption + */ + protected function getDefaultModelObject() + { + $model = $this->getModelId() + ? \XLite\Core\Database::getRepo('XLite\Model\AttributeOption')->find($this->getModelId()) + : null; + + return $model ?: new \XLite\Model\AttributeOption; + } + + /** + * Return name of web form widget class + * + * @return string + */ + protected function getFormClass() + { + return '\XLite\View\Form\Model\AttributeOption'; + } + + /** + * Return list of the "Button" widgets + * + * @return array + */ + protected function getFormButtons() + { + $result = parent::getFormButtons(); + + $label = $this->getModelObject()->getId() ? 'Update' : 'Create'; + + $result['submit'] = new \XLite\View\Button\Submit( + array( + \XLite\View\Button\AButton::PARAM_LABEL => $label, + \XLite\View\Button\AButton::PARAM_STYLE => 'action', + ) + ); + + return $result; + } + + /** + * Add top message + * + * @return void + */ + protected function addDataSavedTopMessage() + { + if ('create' != $this->currentAction) { + \XLite\Core\TopMessage::addInfo('The attribute option has been updated'); + + } else { + \XLite\Core\TopMessage::addInfo('The attribute option has been added'); + } + } + +} \ No newline at end of file diff --git a/src/classes/XLite/View/Product/Details/AAttributes.php b/src/classes/XLite/View/Product/Details/AAttributes.php new file mode 100644 index 0000000000..ca2e9b76bf --- /dev/null +++ b/src/classes/XLite/View/Product/Details/AAttributes.php @@ -0,0 +1,106 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Product\Details; + +/** + * Product attributes + * + */ +abstract class AAttributes extends \XLite\View\AView +{ + /** + * Widget param names + */ + const PARAM_GROUP = 'group'; + + /** + * Get step title + * + * @return string + */ + public function getTitle() + { + return $this->getAttributeGroup() + ? $this->getAttributeGroup()->getName() + : null; + } + + /** + * Check if widget is visible + * + * @return boolean + */ + protected function isVisible() + { + return parent::isVisible() + && $this->getAttributesList(true); + } + + /** + * Define widget params + * + * @return void + */ + protected function defineWidgetParams() + { + parent::defineWidgetParams(); + + $this->widgetParams += array( + self::PARAM_GROUP => new \XLite\Model\WidgetParam\Object( + 'Group', null, false, '\XLite\Model\AttributeGroup' + ), + ); + } + + /** + * Get attribute group + * + * @return \XLite\Model\AttributeGroup + */ + protected function getAttributeGroup() + { + return $this->getParam(static::PARAM_GROUP); + } + + /** + * Get attributes list + * + * @param boolean $countOnly Return items list or only its size OPTIONAL + * + * @return array|integer + */ + protected function getAttributesList($countOnly = false) + { + $cnd = new \XLite\Core\CommonCell; + $cnd->attributeGroup = $this->getAttributeGroup(); + if (!$this->getAttributeGroup()) { + $cnd->product = $this->getProduct(); + } + + return \XLite\Core\Database::getRepo('\XLite\Model\Attribute')->search($cnd, $countOnly); + } + +} diff --git a/src/classes/XLite/View/Product/Details/Admin/Attributes.php b/src/classes/XLite/View/Product/Details/Admin/Attributes.php new file mode 100644 index 0000000000..6eb15297cd --- /dev/null +++ b/src/classes/XLite/View/Product/Details/Admin/Attributes.php @@ -0,0 +1,100 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Product\Details\Admin; + +/** + * Product attributes + * + */ +class Attributes extends \XLite\View\Product\Details\AAttributes +{ + /** + * Register CSS files + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = 'product/attributes/style.css'; + + return $list; + } + + /** + * Return widget default template + * + * @return string + */ + protected function getDefaultTemplate() + { + return 'product/attributes/fields.tpl'; + } + + /** + * Get attributes list + * + * @param boolean $countOnly Return items list or only its size OPTIONAL + * + * @return array|integer + */ + protected function getAttributesList($countOnly = false) + { + $cnd = new \XLite\Core\CommonCell; + $cnd->attributeGroup = $this->getAttributeGroup(); + if (!$this->getAttributeGroup()) { + $cnd->product = $this->getProduct(); + } + + $data = parent::getAttributesList($countOnly); + + if ($countOnly) { + $result = $data; + + } else { + $result = array(); + foreach ($data as $attribute) { + $result[] = $this->getWidget( + array( + 'fieldName' => 'attributeValues[' . $attribute->getId() . ']', + 'label' => $attribute->getName(), + 'maxHeight' => 100, + 'rows' => 1, + 'attribute' => $attribute, + 'comment' => \XLite\Model\Attribute::TYPE_NUMBER == $attribute->getType() + ? $attribute->getUnit() + : '', + 'value' => $attribute->getAttributeValue($this->getProduct()) + ), + $attribute->getWidgetClass() + ); + } + } + + return $result; + } +} diff --git a/src/classes/XLite/View/Product/Details/Customer/Attributes.php b/src/classes/XLite/View/Product/Details/Customer/Attributes.php new file mode 100644 index 0000000000..c2c729a61f --- /dev/null +++ b/src/classes/XLite/View/Product/Details/Customer/Attributes.php @@ -0,0 +1,43 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Product\Details\Customer; + +/** + * Product attributes + * + */ +class Attributes extends \XLite\View\Product\Details\AAttributes +{ + /** + * Return widget default template + * + * @return string + */ + protected function getDefaultTemplate() + { + return 'product/details/parts/attribute.tpl'; + } +} diff --git a/src/classes/XLite/View/Product/Details/Customer/Page/APage.php b/src/classes/XLite/View/Product/Details/Customer/Page/APage.php index acc1458a85..8d34cf76a8 100644 --- a/src/classes/XLite/View/Product/Details/Customer/Page/APage.php +++ b/src/classes/XLite/View/Product/Details/Customer/Page/APage.php @@ -135,6 +135,15 @@ protected function defineTabs() ); } + if ( + $this->getProduct()->getAttrSepTab() + && $this->getProduct()->getClasses() + ) { + $list['Specification'] = array( + 'list' => 'product.details.page.tab.attributes' + ); + } + return $list; } diff --git a/src/skins/admin/en/attribute_option/body.tpl b/src/skins/admin/en/attribute_option/body.tpl new file mode 100644 index 0000000000..8b1aa553f4 --- /dev/null +++ b/src/skins/admin/en/attribute_option/body.tpl @@ -0,0 +1,11 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Attribute option page template + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + \ No newline at end of file diff --git a/src/skins/admin/en/attribute_option/style.css b/src/skins/admin/en/attribute_option/style.css new file mode 100644 index 0000000000..ac508f99cd --- /dev/null +++ b/src/skins/admin/en/attribute_option/style.css @@ -0,0 +1,10 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Attribute option view model styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ diff --git a/src/skins/admin/en/attribute_options/body.tpl b/src/skins/admin/en/attribute_options/body.tpl new file mode 100644 index 0000000000..c5d0cf00b1 --- /dev/null +++ b/src/skins/admin/en/attribute_options/body.tpl @@ -0,0 +1,12 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Attribute options page template + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + \ No newline at end of file diff --git a/src/skins/admin/en/attribute_options/list.tpl b/src/skins/admin/en/attribute_options/list.tpl new file mode 100644 index 0000000000..35e1d099f8 --- /dev/null +++ b/src/skins/admin/en/attribute_options/list.tpl @@ -0,0 +1,14 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Attribute options list table template + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + + + \ No newline at end of file diff --git a/src/skins/admin/en/attribute_options/style.css b/src/skins/admin/en/attribute_options/style.css new file mode 100644 index 0000000000..3e84d34c29 --- /dev/null +++ b/src/skins/admin/en/attribute_options/style.css @@ -0,0 +1,10 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Attribute options list styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ diff --git a/src/skins/admin/en/attributes/style.css b/src/skins/admin/en/attributes/style.css index 9ede8a8647..1b75d2d0dd 100644 --- a/src/skins/admin/en/attributes/style.css +++ b/src/skins/admin/en/attributes/style.css @@ -254,3 +254,22 @@ div.group table.list th.actions.left { .ajax-container-loadable { width: 500px; } + +.ajax-container-loadable .list-footer { + margin: 0; + padding: 0; +} + +.ajax-container-loadable .itemslist button { + border: 0; + background: none; +} + +.ajax-container-loadable .itemslist button span { + text-decoration: underline; + font-size: 14px; +} + +.ajax-container-loadable .main .view { + position: relative; +} diff --git a/src/skins/admin/en/form_field/radio.tpl b/src/skins/admin/en/form_field/radio.tpl new file mode 100644 index 0000000000..8c73e31668 --- /dev/null +++ b/src/skins/admin/en/form_field/radio.tpl @@ -0,0 +1,12 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Radio template + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + diff --git a/src/skins/admin/en/items_list/model/table/parts/default.tpl b/src/skins/admin/en/items_list/model/table/parts/default.tpl new file mode 100644 index 0000000000..e024205f49 --- /dev/null +++ b/src/skins/admin/en/items_list/model/table/parts/default.tpl @@ -0,0 +1,12 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Default radio + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + diff --git a/src/skins/admin/en/items_list/model/table/style.css b/src/skins/admin/en/items_list/model/table/style.css index 97ddf7b113..55c7c13ade 100644 --- a/src/skins/admin/en/items_list/model/table/style.css +++ b/src/skins/admin/en/items_list/model/table/style.css @@ -4,9 +4,10 @@ * Table-based model list * * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ + * @since 1.0.15 */ /** @@ -35,53 +36,25 @@ border-bottom: 1px solid #d5d5d5; } -.items-list-table table.list tbody tr.line td { +.items-list-table table.list tbody.lines tr.line td { border-top: 1px solid #e9e9e9; padding: 8px 12px 6px; line-height: 30px; white-space: nowrap; } -.items-list-table table.list tbody.lines tr.line td .plain-value { - line-height: 30px; - white-space: nowrap; -} - .items-list-table table.list tbody.lines tr.line.last td { border-bottom: 1px solid #e9e9e9; } -.items-list-table table.list tbody td.main div span.value, -.items-list-table table.list tbody td.main div { - color: #456583; - font-size: 16px; -} - -.items-list-table table.list tbody td.main { - width: 300px; +.items-list-table table.list tbody.lines td.main { } .items-list-table table.list tbody.lines td, - .items-list-table table.list tbody.lines td .view, - .items-list-table table.list tbody.lines td .view *, - .items-list-table table.list tbody.lines td .plain-value -{ - font-size: 14px; -} - -.items-list-table table.list tbody.lines td.no-wrap .plain-value { - position: relative; - overflow: hidden; -} - -.items-list-table table.list tbody.lines td { - cursor: pointer; -} - .items-list-table table.list tbody.lines td .view, - .items-list-table table.list tbody.lines td .view * +.items-list-table table.list tbody.lines td .view * { - cursor: text; + font-size: 14px; } .items-list-table table.list tbody.lines td, @@ -90,9 +63,8 @@ vertical-align: middle; } -.items-list-table table.list tbody td.actions .separator { - position: absolute; - top: 16px; +.items-list-table table.list tbody.lines td.actions .separator { + display: inline-block; width: 3px; height: 20px; background-image: url(images/line-separator.png); @@ -100,36 +72,36 @@ background-position: top left; } -.items-list-table table.list tbody td.actions.left { - padding-right: 6px; +.items-list-table table.list tbody.lines td.actions.left { + padding-right: 0px; padding-left: 7px; } -.items-list-table table.list tbody td.actions.left .separator { - right: 0px; +.items-list-table table.list tbody.lines td.actions.left .separator { + margin-left: 6px; } -.items-list-table table.list tbody td.actions.right { - padding-left: 15px; +.items-list-table table.list tbody.lines td.actions.right { + padding-left: 0px; padding-right: 6px; } -.items-list-table table.list tbody td.actions.right .separator { - left: 0px; +.items-list-table table.list tbody.lines td.actions.right .separator { + margin-right: 12px; } -.items-list-table table.list tbody td.actions .action { +.items-list-table table.list tbody.lines td.actions .action { display: inline-block; padding-right: 2px; vertical-align: top; } -.items-list-table table.list tbody td.actions .action.next { +.items-list-table table.list tbody.lines td.actions .action.next { padding-left: 7px; background: transparent url(../../../images/actions_separator.png) no-repeat left 7px; } -.items-list-table table.list tbody td.actions div.selector { +.items-list-table table.list tbody.lines td.actions div.selector { width: 31px; height: 31px; text-align: center; @@ -137,68 +109,69 @@ margin-right: 5px; } -.items-list-table table.list tbody td.actions div.selector.checked { +.items-list-table table.list tbody.lines td.actions div.selector.checked { background-color: #d2f5cc; } -.items-list-table table.list tbody td.actions div.selector input { +.items-list-table table.list tbody.lines td.actions div.selector input { margin: 0px; vertical-align: middle; } -.items-list-table table.list tbody td.actions .inline-field .view { +.items-list-table table.list tbody.lines td.actions .inline-field .view { padding-top: 4px; } -.items-list-table table.list tbody td.actions .inline-switcher { +.items-list-table table.list tbody.lines td.actions .inline-switcher { width: 31px; padding-top: 7px; } -.items-list-table table.list tbody td.actions .inline-move { +.items-list-table table.list tbody.lines td.actions .inline-move { + height: 31px; padding-top: 8px; width: 37px; } -.items-list-table table.list tbody td.actions .inline-switcher .field { +.items-list-table table.list tbody.lines td.actions .inline-switcher .field { text-align: center; } -.items-list-table table.list tbody td a.link { +.items-list-table table.list tbody.lines td a.link { text-decoration: none; color: #456583; } -.items-list-table table.list tbody td.attention, -.items-list-table table.list tbody td.attention .view, -.items-list-table table.list tbody td.attention .view * +.items-list-table table.list tbody.lines td.attention, +.items-list-table table.list tbody.lines td.attention .view, +.items-list-table table.list tbody.lines td.attention .view * { color: #d91a1a; } -.items-list-table table.list tbody tr.line.remove-mark { +.items-list-table table.list tbody.lines tr.line.remove-mark { opacity: .3; } -.items-list-table table.list tbody .inline-field .field { +.items-list-table table.list tbody.lines .inline-field .field { line-height: normal; } -.items-list-table table.list tbody .inline-field .field input, -.items-list-table table.list tbody .inline-field .field select, -.items-list-table table.list tbody .inline-field .field textarea, -.items-list-table table.list tbody .inline-field .field span.text +.items-list-table table.list tbody.lines .inline-field .field input, +.items-list-table table.list tbody.lines .inline-field .field select, +.items-list-table table.list tbody.lines .inline-field .field textarea, +.items-list-table table.list tbody.lines .inline-field .field span.text { font-size: 14px; } -.items-list-table table.list tbody .inline-field .field input, -.items-list-table table.list tbody .inline-field .field select +.items-list-table table.list tbody.lines .inline-field .field input, +.items-list-table table.list tbody.lines .inline-field .field select { line-height: 18px; } -.items-list-table table.list tbody .inline-field .field input { +.items-list-table table.list tbody.lines .inline-field .field input { height: 19px; padding-top: 5px; padding-left: 6px; @@ -206,14 +179,14 @@ font-size: 14px; } -.items-list-table table.list tbody .inline-field .field select { +.items-list-table table.list tbody.lines .inline-field .field select { height: 29px; width: auto; margin-bottom: -2px; padding-top: 6px; } -.items-list-table table.list tbody .inline-field .table-value { +.items-list-table table.list tbody.lines .inline-field .table-value { float: none; } @@ -221,8 +194,8 @@ text-align: center; } -.items-list-table table.list tbody .field .subfield, -.items-list-table table.list tbody .field .subfield .table-value +.items-list-table table.list tbody.lines .field .subfield, +.items-list-table table.list tbody.lines .field .subfield .table-value { display: inline; } @@ -256,3 +229,13 @@ margin-top: 3px; margin-bottom: 3px; } + +.items-list-table table.list tbody td.main div span.value, +.items-list-table table.list tbody td.main div { + color: #456583; + font-size: 16px; +} + +.items-list-table table.list tbody td.main { + width: 300px; +} diff --git a/src/skins/admin/en/product/attributes.tpl b/src/skins/admin/en/product/attributes.tpl new file mode 100644 index 0000000000..a92cda8309 --- /dev/null +++ b/src/skins/admin/en/product/attributes.tpl @@ -0,0 +1,31 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * "Attributes" tab + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + + +{foreach:product.getClasses(),class} + {foreach:class.getAttributeGroups(),group} + + {end:} +{end:} +
    + + +
    +
    + +
    + diff --git a/src/skins/admin/en/product/attributes/fields.tpl b/src/skins/admin/en/product/attributes/fields.tpl new file mode 100644 index 0000000000..302fa2af59 --- /dev/null +++ b/src/skins/admin/en/product/attributes/fields.tpl @@ -0,0 +1,17 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Fields + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + +

    {getTitle()}

    +
      +
    • + {w.display()} +
    • +
    diff --git a/src/skins/admin/en/product/attributes/style.css b/src/skins/admin/en/product/attributes/style.css new file mode 100644 index 0000000000..b09610620d --- /dev/null +++ b/src/skins/admin/en/product/attributes/style.css @@ -0,0 +1,40 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Attributes + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +.tab-content h3 { + color: #333; +} + +.table-label label { + color: #456583; + font-size: 16px; +} + +.table-value span.input-field-wrapper { + float: left; +} + +.tab-content .form-field-comment { + font-size: 16px; + color: #8f8f8f; +} + +.tab-content label.separ-tab { + color: #456583; + font-size: 16px; + float: left; + margin: 5px; +} + +.tab-content .attrSepTab-value { + width: auto; + float: left; +} diff --git a/src/skins/default/en/css/lc.css b/src/skins/default/en/css/lc.css index 6da8c7fd59..323bcba76a 100644 --- a/src/skins/default/en/css/lc.css +++ b/src/skins/default/en/css/lc.css @@ -1242,10 +1242,40 @@ div.product-details .continue-button-intend .product-details .extra-fields li strong { - width: 80px; font-weight: normal; + background-color: #fff; + padding-right: 3px; +} + +.product-details .extra-fields li h3 +{ + margin: 15px 0 0 0; + color: #456583; +} + +.product-details .extra-fields li span +{ + display: inline-block; + color: #1f1f1f; +} + +.product-details .extra-fields li div +{ + width: 300px; display: inline-block; color: #7e7e7e; + background: url(../images/dotted.png) repeat-x scroll 0 bottom transparent; + vertical-align: top; +} + +.product-details .extra-fields li ul li div +{ + width: 250px; +} + +.product-details .extra-fields li ul +{ + margin: 0 0 0 50px; } table.list-body td.hproduct a.product-thumbnail diff --git a/src/skins/default/en/images/dotted.png b/src/skins/default/en/images/dotted.png new file mode 100644 index 0000000000000000000000000000000000000000..aa09c98f42fec307b750912d05962b8c5c2f332d GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-W!3HE>s{0!ODaPU;cPEB*=VV@jWRkqyT^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgf + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} +{if:getAttributeGroup()} +
  • {getTitle()}

    +
      +{end:} +
    • +
      {a.getName()}
      + {a.getAttributeValue(product,#true#):nl2br} +
    • +{if:getAttributeGroup()} +
    +
  • +{end:} diff --git a/src/skins/default/en/product/details/parts/common.product-attributes-list.tpl b/src/skins/default/en/product/details/parts/common.product-attributes-list.tpl new file mode 100644 index 0000000000..f7f265a275 --- /dev/null +++ b/src/skins/default/en/product/details/parts/common.product-attributes-list.tpl @@ -0,0 +1,18 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Product attributes + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + * + * @ListChild (list="product.details.common.product-attributes.attributes", weight="10") + *} + +{foreach:product.getClasses(),class} + {foreach:class.getAttributeGroups(),group} + + {end:} +{end:} diff --git a/src/skins/default/en/product/details/parts/common.product-attributes.attributes.tpl b/src/skins/default/en/product/details/parts/common.product-attributes.attributes.tpl new file mode 100644 index 0000000000..218a8127c6 --- /dev/null +++ b/src/skins/default/en/product/details/parts/common.product-attributes.attributes.tpl @@ -0,0 +1,14 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Product attributes + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + * + * @ListChild (list="product.details.common.product-attributes", weight="300") + *} + + diff --git a/src/skins/default/en/product/details/parts/common.product-attributes.sku.tpl b/src/skins/default/en/product/details/parts/common.product-attributes.sku.tpl index 54a51128f2..4ed35ef694 100644 --- a/src/skins/default/en/product/details/parts/common.product-attributes.sku.tpl +++ b/src/skins/default/en/product/details/parts/common.product-attributes.sku.tpl @@ -11,6 +11,6 @@ * @ListChild (list="product.details.common.product-attributes", weight="200") *}
  • - {t(#SKU#)}: +
    {t(#SKU#)}
    {product.sku}
  • diff --git a/src/skins/default/en/product/details/parts/common.product-attributes.weight.tpl b/src/skins/default/en/product/details/parts/common.product-attributes.weight.tpl index fe587bea36..3dad39bc8b 100644 --- a/src/skins/default/en/product/details/parts/common.product-attributes.weight.tpl +++ b/src/skins/default/en/product/details/parts/common.product-attributes.weight.tpl @@ -11,6 +11,6 @@ * @ListChild (list="product.details.common.product-attributes", weight="100") *}
  • - {t(#Weight#)}: +
    {t(#Weight#)}
    {product.weight} {config.General.weight_symbol}
  • diff --git a/src/skins/default/en/product/details/parts/page.tabs.attributes.tpl b/src/skins/default/en/product/details/parts/page.tabs.attributes.tpl new file mode 100644 index 0000000000..9de4974935 --- /dev/null +++ b/src/skins/default/en/product/details/parts/page.tabs.attributes.tpl @@ -0,0 +1,15 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Product details attributes tab + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + * + * @ListChild (list="product.details.page.tab.attributes", weight="10") + *} +
      + +
    From b90f413dae34e835309b66fb20b1d96c284413db Mon Sep 17 00:00:00 2001 From: skiv Date: Thu, 27 Sep 2012 17:46:25 +0400 Subject: [PATCH 14/85] Attributes --- .../XLite/Controller/Admin/Autocomplete.php | 32 +++++- src/classes/XLite/Model/Attribute.php | 23 ++-- .../XLite/Model/Repo/AttributeOption.php | 50 +++++++- .../FormField/Input/Text/AttributeOption.php | 107 ++++++++++++++++++ .../en/form_field/input/text/autocomplete.js | 12 +- src/skins/default/en/css/lc.css | 9 ++ 6 files changed, 218 insertions(+), 15 deletions(-) create mode 100644 src/classes/XLite/View/FormField/Input/Text/AttributeOption.php diff --git a/src/classes/XLite/Controller/Admin/Autocomplete.php b/src/classes/XLite/Controller/Admin/Autocomplete.php index b1b0d9cb88..f15b1cdb02 100644 --- a/src/classes/XLite/Controller/Admin/Autocomplete.php +++ b/src/classes/XLite/Controller/Admin/Autocomplete.php @@ -51,7 +51,7 @@ protected function doNoAction() $method = 'assembleDictionary' . \XLite\Core\Converter::convertToCamelCase($dictionary); if (method_exists($this, $method)) { $this->data = $this->processData( - $this->$method(strval(\XLite\Core\Request::getInstance()->erm)) + $this->$method(strval(\XLite\Core\Request::getInstance()->term)) ); } } @@ -95,4 +95,34 @@ public function processRequest() print ($content); } + + + /** + * Assemble dictionary - conversation recipient + * + * @param string $term Term + * + * @return array + */ + protected function assembleDictionaryAttributeOption($term) + { + $cnd = new \XLite\Core\CommonCell; + if ($term) { + $cnd->{\XLite\Model\Repo\AttributeOption::SEARCH_NAME} = $term; + } + + $id = intval(\XLite\Core\Request::getInstance()->id); + if ($id) { + $cnd->{\XLite\Model\Repo\AttributeOption::SEARCH_ATTRIBUTE} = $id; + } + + $list = array(); + + foreach (\XLite\Core\Database::getRepo('\XLite\Model\AttributeOption')->search($cnd) as $a) { + $list[$a->getName()] = $a->getName(); + } + + return $list; + } + } diff --git a/src/classes/XLite/Model/Attribute.php b/src/classes/XLite/Model/Attribute.php index b479cff6fa..3040c936f8 100644 --- a/src/classes/XLite/Model/Attribute.php +++ b/src/classes/XLite/Model/Attribute.php @@ -260,7 +260,7 @@ public function getWidgetClass() break; case self::TYPE_SELECT: - $class = '\XLite\View\FormField\Select\AttributeValues'; + $class = '\XLite\View\FormField\Input\Text\AttributeOption'; break; } @@ -301,8 +301,16 @@ public function setAttributeValue(\XLite\Model\Product $product, $value) } if (self::TYPE_SELECT == $this->getType()) { - $attributeOption = \XLite\Core\Database::getRepo('XLite\Model\AttributeOption')->find($value); - if ($attributeOption) { + if ($value) { + $attributeOption = \XLite\Core\Database::getRepo('XLite\Model\AttributeOption') + ->findOneByNameAndAttribute($value, $this); + + if (!$attributeOption) { + $attributeOption = new \XLite\Model\AttributeOption(); + $attributeOption->setAttribute($this); + $attributeOption->setName($value); + \XLite\Core\Database::getEM()->persist($attributeOption); + } $attributeValue->setAttributeOption($attributeOption); } @@ -332,10 +340,11 @@ public function getAttributeValue(\XLite\Model\Product $product, $asString = fal ->findOneBy(array('defaultValue' => 1, 'attribute' => $this)); } - if ($attributeValue) { - $attributeValue = $asString - ? $attributeValue->getName() - : $attributeValue->getId(); + if ( + $attributeValue + && $asString + ) { + $attributeValue = $attributeValue->getName(); } } elseif ($attributeValue) { diff --git a/src/classes/XLite/Model/Repo/AttributeOption.php b/src/classes/XLite/Model/Repo/AttributeOption.php index a24fae09b0..56fb35b4f7 100644 --- a/src/classes/XLite/Model/Repo/AttributeOption.php +++ b/src/classes/XLite/Model/Repo/AttributeOption.php @@ -34,7 +34,8 @@ class AttributeOption extends \XLite\Model\Repo\Base\I18n /** * Allowable search params */ - const SEARCH_ATTRIBUTE = 'attribute'; + const SEARCH_ATTRIBUTE = 'attribute'; + const SEARCH_NAME = 'name'; // {{{ Search @@ -86,6 +87,25 @@ public function searchResult(\Doctrine\ORM\QueryBuilder $qb) return $qb->getResult(); } + /** + * Find one option by name and attribute + * + * @param string $name Name + * @param \XLite\Model\Attribute $attribute Attribute + * + * @return \XLite\Model\AttributeOption + */ + public function findOneByNameAndAttribute($name, \XLite\Model\Attribute $attribute) + { + return $this->createQueryBuilder('a') + ->andWhere('translations.name = :name') + ->andWhere('a.attribute = :attribute') + ->setParameter('name', $name) + ->setParameter('attribute', $attribute) + ->setMaxResults(1) + ->getSingleResult(); + } + /** * Call corresponded method to handle a search condition * @@ -124,6 +144,7 @@ protected function getHandlingSearchParams() { return array( static::SEARCH_ATTRIBUTE, + static::SEARCH_NAME, ); } @@ -134,14 +155,33 @@ protected function getHandlingSearchParams() * @param mixed $value Condition OPTIONAL * * @return void - * @see ____func_see____ - * @since 1.0.0 */ protected function prepareCndAttribute(\Doctrine\ORM\QueryBuilder $queryBuilder, $value = null) { if ($value) { - $queryBuilder->andWhere('a.attribute = :attribute') - ->setParameter('attribute', $value); + if (is_object($value)) { + $queryBuilder->andWhere('a.attribute = :attribute'); + + } else { + $queryBuilder->linkInner('a.attribute')->andWhere('attribute.id = :attribute'); + } + $queryBuilder->setParameter('attribute', $value); + } + } + + /** + * Prepare certain search condition + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare + * @param mixed $value Condition OPTIONAL + * + * @return void + */ + protected function prepareCndName(\Doctrine\ORM\QueryBuilder $queryBuilder, $value = null) + { + if ($value) { + $queryBuilder->andWhere('translations.name LIKE :name') + ->setParameter('name', '%' . $value . '%'); } } diff --git a/src/classes/XLite/View/FormField/Input/Text/AttributeOption.php b/src/classes/XLite/View/FormField/Input/Text/AttributeOption.php new file mode 100644 index 0000000000..3020e43e89 --- /dev/null +++ b/src/classes/XLite/View/FormField/Input/Text/AttributeOption.php @@ -0,0 +1,107 @@ + + * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\FormField\Input\Text; + +/** + * Atutribute option + * + */ +class AttributeOption extends \XLite\View\FormField\Input\Text\Base\Autocomplete +{ + /** + * Common params + */ + const PARAM_ATTRIBUTE = 'attribute'; + + /** + * Define widget params + * + * @return void + */ + protected function defineWidgetParams() + { + parent::defineWidgetParams(); + + $this->widgetParams += array( + self::PARAM_ATTRIBUTE => new \XLite\Model\WidgetParam\Object( + 'Attribute', null, false, 'XLite\Model\Attribute' + ), + ); + } + + /** + * Assemble classes + * + * @param array $classes Classes + * + * @return array + */ + protected function assembleClasses(array $classes) + { + $classes = parent::assembleClasses($classes); + + $classes[] = 'combobox'; + + return $classes; + } + + /** + * Get URL + * + * @return string + */ + protected function getURL() + { + return parent::getURL() . '&id=' + . $this->getParam(self::PARAM_ATTRIBUTE)->getId(); + } + + /** + * Set value + * + * @param mixed $value Value to set + * + * @return void + */ + public function setValue($value) + { + if ($value && is_object($value) && $value instanceOf \XLite\Model\AttributeOption) { + $value = $value->getName(); + } + + parent::setValue($value); + } + + /** + * Get dictionary name + * + * @return string + */ + protected function getDictionary() + { + return 'attributeOption'; + } +} diff --git a/src/skins/admin/en/form_field/input/text/autocomplete.js b/src/skins/admin/en/form_field/input/text/autocomplete.js index 84ebfa96b6..ed805d4f7f 100644 --- a/src/skins/admin/en/form_field/input/text/autocomplete.js +++ b/src/skins/admin/en/form_field/input/text/autocomplete.js @@ -18,7 +18,7 @@ CommonForm.elementControllers.push( this.autocompleteSource = function(request, response) { core.get( - jQuery(this).data('source-url').replace('%term%', request.term), + unescape(jQuery(this).data('source-url')).replace('%term%', request.term), null, {}, { @@ -40,12 +40,20 @@ CommonForm.elementControllers.push( source: function(request, response) { input.autocompleteSource(request, response); }, - minLength: jQuery(this).data('min-length') || 2, + minLength: jQuery(this).hasClass('combobox') ? 0 : jQuery(this).data('min-length') || 2, }; } } jQuery(this).autocomplete(this.autocompleteAssembleOptions()); + + if (jQuery(this).hasClass('combobox')) { + jQuery(this).click( + function () { + jQuery(this).keydown(); + } + ); + } } } ); diff --git a/src/skins/default/en/css/lc.css b/src/skins/default/en/css/lc.css index 323bcba76a..050f31d0b4 100644 --- a/src/skins/default/en/css/lc.css +++ b/src/skins/default/en/css/lc.css @@ -1273,11 +1273,20 @@ div.product-details .continue-button-intend width: 250px; } +.product-details .extra-fields li ul li +{ + margin-top: 5px; +} + .product-details .extra-fields li ul { margin: 0 0 0 50px; } +.product-details .extra-fields ul { + line-height: 20px; +} + table.list-body td.hproduct a.product-thumbnail { width: 194px; From 1e375bd13355c1436726fd65489c955dc25f5d02 Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Mon, 1 Oct 2012 17:04:43 +0400 Subject: [PATCH 15/85] [*] Address fields refactoring: design of address popup window corrected on admin and customer interfaces; Address fields on checkout page refactored (partly; need to be corrected) Please enter the commit message for your changes. Lines starting --- .../XLite/Controller/Customer/ACustomer.php | 60 +++++++++++++ .../XLite/Controller/Customer/Checkout.php | 16 +++- src/classes/XLite/Model/Address.php | 51 +++++++++-- src/classes/XLite/View/Address/Fields.php | 2 + .../XLite/View/Checkout/ShippingAddress.php | 86 +++++++++++++++++++ .../View/Form/Checkout/UpdateProfile.php | 50 ++++++++--- src/skins/admin/en/address/fields/style.css | 23 +++++ src/skins/admin/en/address/style.css | 38 ++++---- src/skins/admin/en/css/style.css | 6 +- src/skins/admin/en/form_field.tpl | 7 +- src/skins/default/en/address/style.css | 3 - src/skins/default/en/checkout/controller.js | 2 +- .../en/checkout/parts/address.plain.tpl | 37 ++++++++ .../en/checkout/steps/shipping/address.tpl | 4 + .../steps/shipping/parts/address.address.tpl | 16 ---- .../steps/shipping/parts/address.city.tpl | 16 ---- .../steps/shipping/parts/address.country.tpl | 16 ---- .../steps/shipping/parts/address.name.tpl | 16 ---- .../steps/shipping/parts/address.phone.tpl | 16 ---- .../steps/shipping/parts/address.state.tpl | 16 ---- .../steps/shipping/parts/address.zipcode.tpl | 16 ---- 21 files changed, 340 insertions(+), 157 deletions(-) create mode 100644 src/skins/admin/en/address/fields/style.css delete mode 100644 src/skins/default/en/checkout/steps/shipping/parts/address.address.tpl delete mode 100644 src/skins/default/en/checkout/steps/shipping/parts/address.city.tpl delete mode 100644 src/skins/default/en/checkout/steps/shipping/parts/address.country.tpl delete mode 100644 src/skins/default/en/checkout/steps/shipping/parts/address.name.tpl delete mode 100644 src/skins/default/en/checkout/steps/shipping/parts/address.phone.tpl delete mode 100644 src/skins/default/en/checkout/steps/shipping/parts/address.state.tpl delete mode 100644 src/skins/default/en/checkout/steps/shipping/parts/address.zipcode.tpl diff --git a/src/classes/XLite/Controller/Customer/ACustomer.php b/src/classes/XLite/Controller/Customer/ACustomer.php index 80916c3141..a607fac69d 100644 --- a/src/classes/XLite/Controller/Customer/ACustomer.php +++ b/src/classes/XLite/Controller/Customer/ACustomer.php @@ -407,4 +407,64 @@ protected function performRedirectToCleanURL() } // }}} + + public function getAddressFields() + { + $result = array(); + + foreach (\XLite\Core\Database::getRepo('XLite\Model\AddressField')->findAllEnabled() as $field) { + $result[$field->getServiceName()] = array( + \XLite\View\Model\Address\Address::SCHEMA_CLASS => $field->getSchemaClass(), + \XLite\View\Model\Address\Address::SCHEMA_LABEL => $field->getName(), + \XLite\View\Model\Address\Address::SCHEMA_REQUIRED => $field->getRequired(), + \XLite\View\Model\Address\Address::SCHEMA_MODEL_ATTRIBUTES => array( + \XLite\View\FormField\Input\Base\String::PARAM_MAX_LENGTH => 'length', + ), + \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-' . $field->getServiceName(), + ); + } + + return $result; + } + + /** + * getFieldValue + * + * @param string $fieldName Field name + * @param boolean $processValue Process value flag OPTIONAL + * + * @return string + **/ + public function getFieldValue($fieldName, $address, $processValue = false) + { + $result = ''; + + if (isset($address)) { + + $methodName = 'get' . \XLite\Core\Converter::getInstance()->convertToCamelCase($fieldName); + + // $methodName assembled from 'get' + camelized $fieldName + $result = $address->$methodName(); + + if ($result && false !== $processValue) { + + switch ($fieldName) { + + case 'state_id': + $result = $address->getState()->getState(); + break; + + case 'country_code': + $result = $address->getCountry()->getCountry(); + break; + + default: + + } + } + } + + return $result; + } + } diff --git a/src/classes/XLite/Controller/Customer/Checkout.php b/src/classes/XLite/Controller/Customer/Checkout.php index 6de366d595..7a3efb66d7 100644 --- a/src/classes/XLite/Controller/Customer/Checkout.php +++ b/src/classes/XLite/Controller/Customer/Checkout.php @@ -707,7 +707,7 @@ protected function updateShippingAddress() } } - $address->map($this->prepareAddressData($data)); + $address->map($this->prepareAddressData($data, 'shipping')); if (!$profile->getBillingAddress()) { @@ -801,7 +801,7 @@ protected function updateBillingAddress() } } - $address->map($this->prepareAddressData($data)); + $address->map($this->prepareAddressData($data, 'billing')); \XLite\Core\Event::updateCart( array( @@ -823,10 +823,20 @@ protected function updateBillingAddress() * * @return array */ - protected function prepareAddressData(array $data) + protected function prepareAddressData(array $data, $type = 'shipping') { unset($data['save_as_new']); + $requiredFields = 'shipping' == $type + ? \XLite\Model\Address::getShippingRequiredFields() + : \XLite\Model\Address::getBillingRequiredFields(); + + foreach ($requiredFields as $fieldName) { + if (!isset($data[$fieldName]) && \XLite\Model\Address::getDefaultFieldValue($fieldName)) { + $data[$fieldName] = \XLite\Model\Address::getDefaultFieldValue($fieldName); + } + } + return $data; } diff --git a/src/classes/XLite/Model/Address.php b/src/classes/XLite/Model/Address.php index 46f62c5636..1a830b5dc4 100644 --- a/src/classes/XLite/Model/Address.php +++ b/src/classes/XLite/Model/Address.php @@ -159,10 +159,11 @@ public function getterProperty($property) * * @return array */ - public function getBillingRequiredFields() + public static function getBillingRequiredFields() { return array( - 'name', + 'firstname', + 'lastname', 'street', 'city', 'zipcode', @@ -176,10 +177,11 @@ public function getBillingRequiredFields() * * @return array */ - public function getShippingRequiredFields() + public static function getShippingRequiredFields() { return array( - 'name', + 'firstname', + 'lastname', 'street', 'city', 'zipcode', @@ -188,6 +190,43 @@ public function getShippingRequiredFields() ); } + /** + * Get default value for the field + * + * @param string $fieldName Field service name + * + * @return mixed + */ + public static function getDefaultFieldValue($fieldName) + { + $result = null; + + switch ($fieldName) { + case 'country': + $code = \XLite\Core\Config::getInstance()->Shipping->anonymous_country; + $result = \XLite\Core\Database::getRepo('XLite\Model\Country')->findOneByCode($code); + break; + + case 'state': + $id = \XLite\Core\Config::getInstance()->Shipping->anonymous_state; + $result = \XLite\Core\Database::getRepo('XLite\Model\State')->find($id); + break; + + case 'zipcode': + $result = \XLite\Core\Config::getInstance()->Shipping->anonymous_zipcode; + break; + + case 'city': + $result = \XLite\Core\Config::getInstance()->Shipping->anonymous_city; + break; + + default: + } + + return $result; + } + + /** * Get required fields by address type * @@ -199,11 +238,11 @@ public function getRequiredFieldsByType($atype) { switch ($atype) { case self::BILLING: - $list = $this->getBillingRequiredFields(); + $list = static::getBillingRequiredFields(); break; case self::SHIPPING: - $list = $this->getShippingRequiredFields(); + $list = static::getShippingRequiredFields(); break; default: diff --git a/src/classes/XLite/View/Address/Fields.php b/src/classes/XLite/View/Address/Fields.php index a3840a496b..8d7499bc78 100644 --- a/src/classes/XLite/View/Address/Fields.php +++ b/src/classes/XLite/View/Address/Fields.php @@ -55,6 +55,8 @@ public function getCSSFiles() { $list = parent::getCSSFiles(); + $list[] = $this->getDir() . '/style.css'; + return $list; } diff --git a/src/classes/XLite/View/Checkout/ShippingAddress.php b/src/classes/XLite/View/Checkout/ShippingAddress.php index 5c860c57a4..e143b2d793 100644 --- a/src/classes/XLite/View/Checkout/ShippingAddress.php +++ b/src/classes/XLite/View/Checkout/ShippingAddress.php @@ -59,6 +59,92 @@ public function getShippingAddress() return $address; } + /** + * Get an array of address fields + * + * @return array + */ + public function getAddressFields() + { + $result = array(); + + foreach (\XLite\Core\Database::getRepo('XLite\Model\AddressField')->findAllEnabled() as $field) { + $result[$field->getServiceName()] = array( + \XLite\View\Model\Address\Address::SCHEMA_CLASS => $field->getSchemaClass(), + \XLite\View\Model\Address\Address::SCHEMA_LABEL => $field->getName(), + \XLite\View\Model\Address\Address::SCHEMA_REQUIRED => $field->getRequired(), + \XLite\View\Model\Address\Address::SCHEMA_MODEL_ATTRIBUTES => array( + \XLite\View\FormField\Input\Base\String::PARAM_MAX_LENGTH => 'length', + ), + \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-' . $field->getServiceName(), + ); + } + + return $result; + } + + /** + * Add CSS classes to the list of attributes + * + * @param string $fieldName Field service name + * @param array $fieldData Array of field properties (see getAddressFields() for the details) + * + * @return array + */ + public function getFieldAttributes($fieldName, $fieldData) + { + $classes = array('field-' . $fieldName); + + if ($fieldData[\XLite\View\Model\Address\Address::SCHEMA_REQUIRED]) { + $classes[] = 'field-required'; + } + + return array( + 'class' => implode(' ', $classes), + ); + } + + /** + * getFieldValue + * + * @param string $fieldName Field name + * @param boolean $processValue Process value flag OPTIONAL + * + * @return string + */ + public function getFieldValue($fieldName, $processValue = false) + { + $result = ''; + + $address = $this->getShippingAddress(); + + if (isset($address)) { + + $methodName = 'get' . \XLite\Core\Converter::getInstance()->convertToCamelCase($fieldName); + + // $methodName assembled from 'get' + camelized $fieldName + $result = $address->$methodName(); + + if ($result && false !== $processValue) { + + switch ($fieldName) { + + case 'state_id': + $result = $address->getState()->getState(); + break; + + case 'country_code': + $result = $address->getCountry()->getCountry(); + break; + + default: + + } + } + } + + return $result; + } /** * Return widget default template diff --git a/src/classes/XLite/View/Form/Checkout/UpdateProfile.php b/src/classes/XLite/View/Form/Checkout/UpdateProfile.php index 7cc587478d..430d3382e1 100644 --- a/src/classes/XLite/View/Form/Checkout/UpdateProfile.php +++ b/src/classes/XLite/View/Form/Checkout/UpdateProfile.php @@ -78,12 +78,26 @@ protected function getValidator() new \XLite\Core\Validator\HashArray, \XLite\Core\Validator\Pair\APair::SOFT ); - $shippingAddress->addPair('name', new \XLite\Core\Validator\String($nonEmpty), $mode); - $shippingAddress->addPair('street', new \XLite\Core\Validator\String($nonEmpty), $mode); - $shippingAddress->addPair('city', new \XLite\Core\Validator\String($nonEmpty), $mode); - $shippingAddress->addPair('zipcode', new \XLite\Core\Validator\String(true)); - $shippingAddress->addPair('phone', new \XLite\Core\Validator\String(), $mode); - $shippingAddress->addPair(new \XLite\Core\Validator\Pair\CountryState()); + + $addressFields = \XLite::getController()->getAddressFields(); + + $isCountryStateAdded = false; + + foreach ($addressFields as $fieldName => $fieldData) { + + if (!$isCountryStateAdded && in_array($fieldName, array('country', 'state'))) { + $shippingAddress->addPair(new \XLite\Core\Validator\Pair\CountryState()); + $isCountryStateAdded = true; + + } else { + $shippingAddress->addPair( + $fieldName, + new \XLite\Core\Validator\String($nonEmpty && $fieldData[\XLite\View\Model\Address\Address::SCHEMA_REQUIRED]), + $mode + ); + } + } + $shippingAddress->addPair( 'save_as_new', new \XLite\Core\Validator\String\Switcher(), @@ -97,12 +111,24 @@ protected function getValidator() new \XLite\Core\Validator\HashArray, \XLite\Core\Validator\Pair\APair::SOFT ); - $billingAddress->addPair('name', new \XLite\Core\Validator\String(true)); - $billingAddress->addPair('street', new \XLite\Core\Validator\String(true)); - $billingAddress->addPair('city', new \XLite\Core\Validator\String(true)); - $billingAddress->addPair('zipcode', new \XLite\Core\Validator\String(true)); - $billingAddress->addPair('phone', new \XLite\Core\Validator\String()); - $billingAddress->addPair(new \XLite\Core\Validator\Pair\CountryState()); + + $isCountryStateAdded = false; + + foreach ($addressFields as $fieldName => $fieldData) { + + if (!$isCountryStateAdded && in_array($fieldName, array('country', 'state'))) { + $shippingAddress->addPair(new \XLite\Core\Validator\Pair\CountryState()); + $isCountryStateAdded = true; + + } else { + $shippingAddress->addPair( + $fieldName, + new \XLite\Core\Validator\String($nonEmpty && $fieldData[\XLite\View\Model\Address\Address::SCHEMA_REQUIRED]), + $mode + ); + } + } + $billingAddress->addPair( 'save_as_new', new \XLite\Core\Validator\String\Switcher(), diff --git a/src/skins/admin/en/address/fields/style.css b/src/skins/admin/en/address/fields/style.css new file mode 100644 index 0000000000..6f1a32320c --- /dev/null +++ b/src/skins/admin/en/address/fields/style.css @@ -0,0 +1,23 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * CSS styles for address fields management page + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +.items-list-table.address-fields table.list tbody td.name { + width: 200px; +} + +.items-list-table.address-fields table.list tbody td.serviceName { + width: 200px; +} + +.items-list-table.address-fields table.list tbody td input[type="text"] { + width: 150px; +} + diff --git a/src/skins/admin/en/address/style.css b/src/skins/admin/en/address/style.css index c9536b3fe2..fa5da4474c 100644 --- a/src/skins/admin/en/address/style.css +++ b/src/skins/admin/en/address/style.css @@ -23,7 +23,7 @@ padding-bottom: 10px; } -.address-dialog label { +.address-dialog .model-properties label { font-size: 14px; font-weight: normal; color: #53769d; @@ -36,44 +36,44 @@ margin-bottom: 6px; } -.address-dialog ul li +.address-dialog .model-properties ul li { padding: 0px 5px 6px 0px; } -.address-dialog input { +.address-dialog .model-properties input { width: 300px; } -span.address-firstname input { +.address-dialog .model-properties span.address-firstname input { width: 240px; } -span.address-lastname input { +.address-dialog .model-properties span.address-lastname input { width: 240px; } -span.address-street input { +.address-dialog .model-properties span.address-street input { width: 290px; } -li.address-country select { +.address-dialog .model-properties li.address-country select { width: 300px; } -li.address-state select { +.address-dialog .model-properties li.address-state select { width: 240px; } -span.address-city input { +.address-dialog .model-properties span.address-city input { width: 240px; } -span.address-zipcode input { +.address-dialog .model-properties span.address-zipcode input { width: 75px; } -span.address-phone input { +.address-dialog .model-properties span.address-phone input { width: 125px; } @@ -82,12 +82,20 @@ span.address-phone input { border: 1px solid #ddd; } -ul.default-table li.address-phone { - clear: none; +.address-dialog .model-properties ul.table.default-table { + min-width: 600px; +} + +.address-dialog .model-properties ul.default-table li div.table-label label { + width: 70px; } -ul.default-table li.address-phone label { - width: 50px; +.address-dialog .model-properties ul.default-table li.address-zipcode { + float: left; +} + +.address-dialog .model-properties ul.default-table li.address-phone { + clear: none; } .address-dialog .button { diff --git a/src/skins/admin/en/css/style.css b/src/skins/admin/en/css/style.css index 6f455ab61e..83b0fa25df 100644 --- a/src/skins/admin/en/css/style.css +++ b/src/skins/admin/en/css/style.css @@ -1639,6 +1639,7 @@ div.model-form-buttons { div.table-label { float: left; + padding-right: 35px; } .model-properties ul.table div.table-label label { @@ -1646,9 +1647,9 @@ div.table-label { } div.star { - float: right; width: 10px; padding: 12px 0px 5px 0px; + display: inline-block; } .table-label, @@ -1663,8 +1664,7 @@ div.star { } div.table-value { - float: right; - width: 80%; + display: inline-block; } div.table-value input[type="text"], diff --git a/src/skins/admin/en/form_field.tpl b/src/skins/admin/en/form_field.tpl index 26f3385734..c9c7c20f8c 100644 --- a/src/skins/admin/en/form_field.tpl +++ b/src/skins/admin/en/form_field.tpl @@ -15,6 +15,11 @@
    {end:} +{if:!getParam(#fieldOnly#)} +
    *
    +
     
    +{end:} +
    @@ -23,7 +28,5 @@
    {if:!getParam(#fieldOnly#)} -
    *
    -
     
    {end:} diff --git a/src/skins/default/en/address/style.css b/src/skins/default/en/address/style.css index 2c2eb8fcc0..f3b3b33136 100644 --- a/src/skins/default/en/address/style.css +++ b/src/skins/default/en/address/style.css @@ -272,6 +272,3 @@ ul.default-table li.address-phone { clear: none; } -ul.default-table li.address-phone label { - width: 50px; -} diff --git a/src/skins/default/en/checkout/controller.js b/src/skins/default/en/checkout/controller.js index 9d5544b65c..5bd5c8930b 100644 --- a/src/skins/default/en/checkout/controller.js +++ b/src/skins/default/en/checkout/controller.js @@ -805,7 +805,7 @@ ShippingAddressView.prototype.postprocess = function(isSuccess, initial) form.getElements().each( function() { var t = jQuery(this); - if (t.hasClass('field-zipcode') || t.hasClass('field-country') || t.hasClass('field-state')) { + if (t.hasClass('field-street') || t.hasClass('field-zipcode') || t.hasClass('field-country') || t.hasClass('field-state')) { this.markAsWatcher( function(element) { o.parentWidget.refreshSignificantShippingFields(element); diff --git a/src/skins/default/en/checkout/parts/address.plain.tpl b/src/skins/default/en/checkout/parts/address.plain.tpl index b9731d11b7..4d71bf9dec 100644 --- a/src/skins/default/en/checkout/parts/address.plain.tpl +++ b/src/skins/default/en/checkout/parts/address.plain.tpl @@ -8,6 +8,41 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ *} + +
    +
    + {foreach:getAddressFields(),fieldName,fieldData} +
    {getFieldValue(fieldName,address,1)}
    + {end:} +
    +
    + +{* +
      + +{foreach:getAddressFields(),fieldName,fieldData} + +
    • + +
        + +
      • {fieldData.label}:
      • + +
      • {getFieldValue(fieldName,address,1)}
      • + +
      • ,
      • + +
      + +
    • + +{end:} + +
    + +
    +*} +{*
    {address.name}
    @@ -17,3 +52,5 @@
    {t(#Phone#)}: {address.phone}
    +*} + diff --git a/src/skins/default/en/checkout/steps/shipping/address.tpl b/src/skins/default/en/checkout/steps/shipping/address.tpl index 461d480ea2..96add3a154 100644 --- a/src/skins/default/en/checkout/steps/shipping/address.tpl +++ b/src/skins/default/en/checkout/steps/shipping/address.tpl @@ -8,6 +8,10 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ *} +
      +
    • + +
    diff --git a/src/skins/default/en/checkout/steps/shipping/parts/address.address.tpl b/src/skins/default/en/checkout/steps/shipping/parts/address.address.tpl deleted file mode 100644 index f0fe061b57..0000000000 --- a/src/skins/default/en/checkout/steps/shipping/parts/address.address.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Shipping address : street - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.shipping.address", weight="20") - *} -
  • - - -
  • diff --git a/src/skins/default/en/checkout/steps/shipping/parts/address.city.tpl b/src/skins/default/en/checkout/steps/shipping/parts/address.city.tpl deleted file mode 100644 index b3a7b46da7..0000000000 --- a/src/skins/default/en/checkout/steps/shipping/parts/address.city.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Shipping address : city - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.shipping.address", weight="50") - *} -
  • - - -
  • diff --git a/src/skins/default/en/checkout/steps/shipping/parts/address.country.tpl b/src/skins/default/en/checkout/steps/shipping/parts/address.country.tpl deleted file mode 100644 index f2984db817..0000000000 --- a/src/skins/default/en/checkout/steps/shipping/parts/address.country.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Shipping address : country - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.shipping.address", weight="30") - *} -
  • - - -
  • diff --git a/src/skins/default/en/checkout/steps/shipping/parts/address.name.tpl b/src/skins/default/en/checkout/steps/shipping/parts/address.name.tpl deleted file mode 100644 index 42ebc21b6f..0000000000 --- a/src/skins/default/en/checkout/steps/shipping/parts/address.name.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Shipping address : name - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.shipping.address", weight="10") - *} -
  • - - -
  • diff --git a/src/skins/default/en/checkout/steps/shipping/parts/address.phone.tpl b/src/skins/default/en/checkout/steps/shipping/parts/address.phone.tpl deleted file mode 100644 index f657b59cf7..0000000000 --- a/src/skins/default/en/checkout/steps/shipping/parts/address.phone.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Shipping address : phone - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.shipping.address", weight="70") - *} -
  • - - -
  • diff --git a/src/skins/default/en/checkout/steps/shipping/parts/address.state.tpl b/src/skins/default/en/checkout/steps/shipping/parts/address.state.tpl deleted file mode 100644 index 05a4eb187c..0000000000 --- a/src/skins/default/en/checkout/steps/shipping/parts/address.state.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Shipping address : state - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.shipping.address", weight="40") - *} -
  • - - -
  • diff --git a/src/skins/default/en/checkout/steps/shipping/parts/address.zipcode.tpl b/src/skins/default/en/checkout/steps/shipping/parts/address.zipcode.tpl deleted file mode 100644 index 5832653d1e..0000000000 --- a/src/skins/default/en/checkout/steps/shipping/parts/address.zipcode.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Shipping address : zipcode - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.shipping.address", weight="60") - *} -
  • - - -
  • From a1c967e2de262c67cd0903d4481189a02b8a7b8f Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Mon, 1 Oct 2012 17:07:50 +0400 Subject: [PATCH 16/85] [!] PHP warning fixed --- src/classes/XLite/View/Model/Address/Address.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/XLite/View/Model/Address/Address.php b/src/classes/XLite/View/Model/Address/Address.php index 0c3ca3f0fb..81156f3870 100644 --- a/src/classes/XLite/View/Model/Address/Address.php +++ b/src/classes/XLite/View/Model/Address/Address.php @@ -327,7 +327,7 @@ protected function validateFields(array $data, $section) { $this->prepareDataToValidate($data); - parent::validateFields($data); + parent::validateFields($data, $section); } /** From a5cd5d1094dd5f3338af044c9103080bfec5122e Mon Sep 17 00:00:00 2001 From: skiv Date: Tue, 2 Oct 2012 15:08:53 +0400 Subject: [PATCH 17/85] Attributes --- .../XLite/Controller/Admin/Attribute.php | 8 +++++- .../Controller/Admin/AttributeGroups.php | 2 +- .../Input/Text/Base/Autocomplete.php | 2 +- .../View/FormField/Select/AttributeTypes.php | 16 ++++++++++++ src/classes/XLite/View/Model/Attribute.php | 4 ++- src/skins/admin/en/attribute_groups/list.tpl | 3 ++- src/skins/admin/en/attributes/script.js | 23 ++++++++++++++---- src/skins/admin/en/attributes/style.css | 5 ++-- .../admin/en/product/attributes/style.css | 15 +++++++++++- src/skins/default/en/css/lc.css | 11 +++++---- src/skins/default/en/images/dotted.png | Bin 188 -> 189 bytes 11 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/classes/XLite/Controller/Admin/Attribute.php b/src/classes/XLite/Controller/Admin/Attribute.php index e34dd29950..1b52cced9c 100644 --- a/src/classes/XLite/Controller/Admin/Attribute.php +++ b/src/classes/XLite/Controller/Admin/Attribute.php @@ -124,7 +124,13 @@ public function getTitle() */ protected function doActionUpdate() { - $this->setInternalRedirect(); + if ($this->getModelForm()->getModelObject()->getId()) { + $this->setSilenceClose(); + + } else { + $this->setInternalRedirect(); + } + $list = new \XLite\View\ItemsList\Model\AttributeOption; $list->processQuick(); diff --git a/src/classes/XLite/Controller/Admin/AttributeGroups.php b/src/classes/XLite/Controller/Admin/AttributeGroups.php index ab505f5394..989f32e9b4 100644 --- a/src/classes/XLite/Controller/Admin/AttributeGroups.php +++ b/src/classes/XLite/Controller/Admin/AttributeGroups.php @@ -82,7 +82,7 @@ public function getProductClass() */ protected function doActionUpdate() { - $this->setInternalRedirect(); + $this->setSilenceClose(); $list = new \XLite\View\ItemsList\Model\AttributeGroup; $list->processQuick(); } diff --git a/src/classes/XLite/View/FormField/Input/Text/Base/Autocomplete.php b/src/classes/XLite/View/FormField/Input/Text/Base/Autocomplete.php index aead0d936e..db3d938222 100644 --- a/src/classes/XLite/View/FormField/Input/Text/Base/Autocomplete.php +++ b/src/classes/XLite/View/FormField/Input/Text/Base/Autocomplete.php @@ -69,7 +69,7 @@ protected function assembleClasses(array $classes) } /** - * setCommonAttributes + * Set common attributes * * @param array $attrs Field attributes to prepare * diff --git a/src/classes/XLite/View/FormField/Select/AttributeTypes.php b/src/classes/XLite/View/FormField/Select/AttributeTypes.php index 37e9d57755..806746f36b 100644 --- a/src/classes/XLite/View/FormField/Select/AttributeTypes.php +++ b/src/classes/XLite/View/FormField/Select/AttributeTypes.php @@ -40,4 +40,20 @@ protected function getDefaultOptions() { return \XLite\Model\Attribute::getTypes(); } + + /** + * Set common attributes + * + * @param array $attrs Field attributes to prepare + * + * @return array + */ + protected function setCommonAttributes(array $attrs) + { + $attrs = parent::setCommonAttributes($attrs); + + $attrs['data-value'] = $this->getValue(); + + return $attrs; + } } diff --git a/src/classes/XLite/View/Model/Attribute.php b/src/classes/XLite/View/Model/Attribute.php index 019f925160..de570cf912 100644 --- a/src/classes/XLite/View/Model/Attribute.php +++ b/src/classes/XLite/View/Model/Attribute.php @@ -172,9 +172,11 @@ protected function getFormButtons() { $result = parent::getFormButtons(); + $label = $this->getModelObject()->getId() ? 'Save changes' : 'New attribute'; + $result['submit'] = new \XLite\View\Button\Submit( array( - \XLite\View\Button\AButton::PARAM_LABEL => 'Apply changes', + \XLite\View\Button\AButton::PARAM_LABEL => $label, \XLite\View\Button\AButton::PARAM_STYLE => 'action', ) ); diff --git a/src/skins/admin/en/attribute_groups/list.tpl b/src/skins/admin/en/attribute_groups/list.tpl index 141a4cc50d..f42c2db7af 100644 --- a/src/skins/admin/en/attribute_groups/list.tpl +++ b/src/skins/admin/en/attribute_groups/list.tpl @@ -12,6 +12,7 @@
    - +
    +
    {t(#Editing attribute groups on this page won't affect other product classes which use these groups. Removing a group doesn't delete attributes from the group, but makes them show up among other attributes having no associated groups.#)}
    diff --git a/src/skins/admin/en/attributes/script.js b/src/skins/admin/en/attributes/script.js index 8c8788d51a..02e5be99e8 100644 --- a/src/skins/admin/en/attributes/script.js +++ b/src/skins/admin/en/attributes/script.js @@ -13,6 +13,23 @@ var ppr = popup.postprocessRequest; popup.postprocessRequest = function(XMLHttpRequest, textStatus, data, isValid) { ppr.call(this, XMLHttpRequest, textStatus, data, isValid); TableItemsListQueue(); + + jQuery('.select-attributetypes select').change( + function () { + if (jQuery(this).data('value') == jQuery(this).val()) { + jQuery('.select-attributetypes .form-field-comment').hide(); + } else { + jQuery('.select-attributetypes .form-field-comment').show(); + } + } + ); +} + +var pprc = popup.postprocessRequestCallback; +popup.postprocessRequestCallback() = function() +{ + pprc.postprocessRequestCallback(); + popup.close(); } function popup_attribute_groups(product_class_id) { @@ -21,11 +38,7 @@ function popup_attribute_groups(product_class_id) { target: 'attribute_groups', product_class_id: product_class_id, widget: 'XLite\\View\\AttributeGroups' - }), - null, - function () { - self.location.reload(); - } + }) ); } diff --git a/src/skins/admin/en/attributes/style.css b/src/skins/admin/en/attributes/style.css index 1b75d2d0dd..93b04f8cf0 100644 --- a/src/skins/admin/en/attributes/style.css +++ b/src/skins/admin/en/attributes/style.css @@ -206,10 +206,11 @@ div.group table.list th.actions.left { } .ajax-container-loadable .select-attributetypes div.table-value .form-field-comment { - background: url("../images/icon_warning_round.png") no-repeat scroll 10px center transparent; - padding-left: 45px; + background: url("../images/icon_warning_round.png") no-repeat scroll 20px center transparent; + padding: 1px 0 0 50px; color: #456583; float: left; + display: none; } .ajax-container-loadable div.table-value .form-field-comment { diff --git a/src/skins/admin/en/product/attributes/style.css b/src/skins/admin/en/product/attributes/style.css index b09610620d..dd83fd1d3a 100644 --- a/src/skins/admin/en/product/attributes/style.css +++ b/src/skins/admin/en/product/attributes/style.css @@ -10,12 +10,13 @@ */ .tab-content h3 { + margin-top: 32px; color: #333; } .table-label label { color: #456583; - font-size: 16px; + font-size: 14px; } .table-value span.input-field-wrapper { @@ -38,3 +39,15 @@ width: auto; float: left; } + +.tab-content li { + margin-bottom: 8px; +} + +.table-value.checkbox label { + margin: 0; +} + +.table-label.checkbox { + float: right; +} diff --git a/src/skins/default/en/css/lc.css b/src/skins/default/en/css/lc.css index 050f31d0b4..1722182b57 100644 --- a/src/skins/default/en/css/lc.css +++ b/src/skins/default/en/css/lc.css @@ -1237,7 +1237,7 @@ div.product-details .continue-button-intend padding: 4px 0px; margin: 0px; background-image: none; - font-size: 16px; + font-size: 14px; } .product-details .extra-fields li strong @@ -1249,8 +1249,9 @@ div.product-details .continue-button-intend .product-details .extra-fields li h3 { - margin: 15px 0 0 0; + margin: 11px 0 0 0; color: #456583; + font-size: 16px; } .product-details .extra-fields li span @@ -1261,7 +1262,7 @@ div.product-details .continue-button-intend .product-details .extra-fields li div { - width: 300px; + width: 186px; display: inline-block; color: #7e7e7e; background: url(../images/dotted.png) repeat-x scroll 0 bottom transparent; @@ -1270,7 +1271,7 @@ div.product-details .continue-button-intend .product-details .extra-fields li ul li div { - width: 250px; + width: 166px; } .product-details .extra-fields li ul li @@ -1280,7 +1281,7 @@ div.product-details .continue-button-intend .product-details .extra-fields li ul { - margin: 0 0 0 50px; + margin: 0 0 0 20px; } .product-details .extra-fields ul { diff --git a/src/skins/default/en/images/dotted.png b/src/skins/default/en/images/dotted.png index aa09c98f42fec307b750912d05962b8c5c2f332d..e790c20f512ca7fb44d2c6405a9ab36ddaa1ec65 100644 GIT binary patch delta 96 zcmdnPxR+6}Gr-TCmrII^fq{Y7)59eQNHYU5I|mz(JiGJz%8810oLr2&Z0xfSt#F%| up`$6{>Eal|aXmQ!2yX1H{$9_vikX2ohS@N0=d*aACI(MeKbLh*2~7ZLX&RdV delta 95 zcmdnXxQ9`(Gr-TCmrII^fq{Y7)59eQNHYO38wVSZe5vklG*QuxlT(V%SR>$$^S+50 vIvT>BE{-7_*OO~LJvsUR_4W0}6Id9`G}(-9zuBk<)WhKE>gTe~DWM4fJ7XId From c7fe88eaeaf29d4987586d97344fa448730d1fe0 Mon Sep 17 00:00:00 2001 From: Maxim Shamaev Date: Wed, 3 Oct 2012 10:26:49 +0400 Subject: [PATCH 18/85] [*] Add .dev/macro/load-yaml.php --- .dev/macro/load-yaml.php | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100755 .dev/macro/load-yaml.php diff --git a/.dev/macro/load-yaml.php b/.dev/macro/load-yaml.php new file mode 100755 index 0000000000..4accec7793 --- /dev/null +++ b/.dev/macro/load-yaml.php @@ -0,0 +1,50 @@ +#!/usr/bin/env php + + * @copyright Copyright (c) 2010-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +require_once __DIR__ . '/core.php'; + +// get arguments +$path = macro_get_plain_argument(0); + +// Check arguments +macro_check_file_path($path); + +\XLite\Core\Database::getInstance()->loadFixturesFromYaml($path); + +die(0); + +/** + * Help + */ +function macro_help() +{ + return << Date: Wed, 3 Oct 2012 14:09:44 +0400 Subject: [PATCH 19/85] Attributes --- .../FormField/Input/Text/AttributeOption.php | 18 +--- .../FormField/Input/Text/Base/Combobox.php | 87 ++++++++++++++++++ .../Product/Details/Customer/Attributes.php | 46 +++++++++ .../en/form_field/input/text/autocomplete.js | 10 +- .../en/form_field/input/text/combobox.css | 27 ++++++ .../en/form_field/input/text/combobox.js | 29 ++++++ .../en/form_field/input/text/combobox.tpl | 16 ++++ src/skins/admin/en/images/arrows-select.png | Bin 0 -> 213 bytes src/skins/default/en/css/lc.css | 5 + .../en/product/details/parts/attribute.tpl | 6 +- 10 files changed, 215 insertions(+), 29 deletions(-) create mode 100644 src/classes/XLite/View/FormField/Input/Text/Base/Combobox.php create mode 100644 src/skins/admin/en/form_field/input/text/combobox.css create mode 100644 src/skins/admin/en/form_field/input/text/combobox.js create mode 100644 src/skins/admin/en/form_field/input/text/combobox.tpl create mode 100644 src/skins/admin/en/images/arrows-select.png diff --git a/src/classes/XLite/View/FormField/Input/Text/AttributeOption.php b/src/classes/XLite/View/FormField/Input/Text/AttributeOption.php index 3020e43e89..4659e2f575 100644 --- a/src/classes/XLite/View/FormField/Input/Text/AttributeOption.php +++ b/src/classes/XLite/View/FormField/Input/Text/AttributeOption.php @@ -29,7 +29,7 @@ * Atutribute option * */ -class AttributeOption extends \XLite\View\FormField\Input\Text\Base\Autocomplete +class AttributeOption extends \XLite\View\FormField\Input\Text\Base\Combobox { /** * Common params @@ -52,22 +52,6 @@ protected function defineWidgetParams() ); } - /** - * Assemble classes - * - * @param array $classes Classes - * - * @return array - */ - protected function assembleClasses(array $classes) - { - $classes = parent::assembleClasses($classes); - - $classes[] = 'combobox'; - - return $classes; - } - /** * Get URL * diff --git a/src/classes/XLite/View/FormField/Input/Text/Base/Combobox.php b/src/classes/XLite/View/FormField/Input/Text/Base/Combobox.php new file mode 100644 index 0000000000..0f91bec0b0 --- /dev/null +++ b/src/classes/XLite/View/FormField/Input/Text/Base/Combobox.php @@ -0,0 +1,87 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\FormField\Input\Text\Base; + +/** + * Combobox + * + */ +abstract class Combobox extends \XLite\View\FormField\Input\Text\Base\Autocomplete +{ + /** + * Get a list of CSS files required to display the widget properly + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = $this->getDir() . '/input/text/combobox.css'; + + return $list; + } + + /** + * Register JS files + * + * @return array + */ + public function getJSFiles() + { + $list = parent::getJSFiles(); + + $list[] = 'form_field/input/text/combobox.js'; + + return $list; + } + + /** + * Return field template + * + * @return string + */ + protected function getFieldTemplate() + { + return 'input/text/combobox.tpl'; + } + + /** + * Assemble classes + * + * @param array $classes Classes + * + * @return array + */ + protected function assembleClasses(array $classes) + { + $classes = parent::assembleClasses($classes); + + $classes[] = 'combobox'; + + return $classes; + } +} diff --git a/src/classes/XLite/View/Product/Details/Customer/Attributes.php b/src/classes/XLite/View/Product/Details/Customer/Attributes.php index c2c729a61f..df23766e7e 100644 --- a/src/classes/XLite/View/Product/Details/Customer/Attributes.php +++ b/src/classes/XLite/View/Product/Details/Customer/Attributes.php @@ -31,6 +31,41 @@ */ class Attributes extends \XLite\View\Product\Details\AAttributes { + /** + * Attributes + * + * @var array + */ + protected $attributes; + + /** + * Register CSS files + * + * @return array + */ + public function getAttrList() + { + if (is_null($this->attributes)) { + $this->attributes = array(); + foreach ($this->getAttributesList() as $a) { + $value = $a->getAttributeValue($this->getProduct(), true); + $class = strtolower($a->getTypes($a->getType())); + if (\XLite\Model\Attribute::TYPE_CHECKBOX == $a->getType()) { + $class .= ' ' . (static::t('yes') == $value ? 'checked' : 'no-checked'); + } + if ($value) { + $this->attributes[] = array( + 'name' => $a->getName(), + 'value' => $value, + 'class' => $class + ); + } + } + } + + return $this->attributes; + } + /** * Return widget default template * @@ -40,4 +75,15 @@ protected function getDefaultTemplate() { return 'product/details/parts/attribute.tpl'; } + + /** + * Check if widget is visible + * + * @return boolean + */ + protected function isVisible() + { + return parent::isVisible() + && $this->getAttrList(); + } } diff --git a/src/skins/admin/en/form_field/input/text/autocomplete.js b/src/skins/admin/en/form_field/input/text/autocomplete.js index ed805d4f7f..fce8bf8501 100644 --- a/src/skins/admin/en/form_field/input/text/autocomplete.js +++ b/src/skins/admin/en/form_field/input/text/autocomplete.js @@ -40,20 +40,12 @@ CommonForm.elementControllers.push( source: function(request, response) { input.autocompleteSource(request, response); }, - minLength: jQuery(this).hasClass('combobox') ? 0 : jQuery(this).data('min-length') || 2, + minLength: jQuery(this).data('min-length') || 2, }; } } jQuery(this).autocomplete(this.autocompleteAssembleOptions()); - - if (jQuery(this).hasClass('combobox')) { - jQuery(this).click( - function () { - jQuery(this).keydown(); - } - ); - } } } ); diff --git a/src/skins/admin/en/form_field/input/text/combobox.css b/src/skins/admin/en/form_field/input/text/combobox.css new file mode 100644 index 0000000000..0b8e97d25c --- /dev/null +++ b/src/skins/admin/en/form_field/input/text/combobox.css @@ -0,0 +1,27 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Combobox styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +input.combobox { + float: left; + padding-right: 21px; +} + +div.combobox-select { + background: transparent url(../images/arrows-select.png) center center no-repeat; + width: 21px; + height: 21px; + float: left; + display: inline; + position: relative; + top: 1px; + right: 22px; + cursor: pointer; +} diff --git a/src/skins/admin/en/form_field/input/text/combobox.js b/src/skins/admin/en/form_field/input/text/combobox.js new file mode 100644 index 0000000000..532b3e6f98 --- /dev/null +++ b/src/skins/admin/en/form_field/input/text/combobox.js @@ -0,0 +1,29 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Float field microcontroller + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +CommonForm.elementControllers.push( + { + pattern: '.input-field-wrapper div.combobox-select', + handler: function () { + + jQuery(this).click( + function () { + var input = jQuery(this).parent().find('input'); + var minLength = input.autocomplete('option', 'minLength'); + input.autocomplete('option', 'minLength', 0); + input.autocomplete('search', ''); + input.autocomplete('option', 'minLength', minLength); + input.focus(); + } + ); + } + } +); diff --git a/src/skins/admin/en/form_field/input/text/combobox.tpl b/src/skins/admin/en/form_field/input/text/combobox.tpl new file mode 100644 index 0000000000..3b1f000416 --- /dev/null +++ b/src/skins/admin/en/form_field/input/text/combobox.tpl @@ -0,0 +1,16 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Common input template + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + + {displayCommentedData(getCommentedData())} + +
    +
    diff --git a/src/skins/admin/en/images/arrows-select.png b/src/skins/admin/en/images/arrows-select.png new file mode 100644 index 0000000000000000000000000000000000000000..ef4fef9586c71a9a5952478308751da3420f91e5 GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^>>xG=8<0#rS+W&KF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?Eak7aXI#rie}sWmmz)2O`!Y!h357`~m`>Cjd&c@ZP-Oz+

    {getTitle()}

      {end:} -
    • -
      {a.getName()}
      - {a.getAttributeValue(product,#true#):nl2br} +
    • +
      {a.name}
      + {a.value:nl2br}
    • {if:getAttributeGroup()}
    From 5ab701aca016e9a3b6ae028f4e3a921aae9646eb Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Thu, 4 Oct 2012 15:25:41 +0400 Subject: [PATCH 20/85] [*] Address fields manage task. Checkout multiple changes. --- src/classes/XLite/Model/Profile.php | 17 ++- src/classes/XLite/View/AView.php | 1 - src/classes/XLite/View/Checkout.php | 13 +++ .../XLite/View/Checkout/AAddressBlock.php | 103 ++++++++++++++++++ .../XLite/View/Checkout/BillingAddress.php | 12 +- .../XLite/View/Checkout/ShippingAddress.php | 73 ++----------- src/classes/XLite/View/Checkout/Steps.php | 14 +++ .../View/Form/Checkout/UpdateProfile.php | 4 +- .../XLite/View/FormField/Select/Country.php | 8 +- src/skins/common/js/common.js | 4 + src/skins/default/en/checkout/checkout.css | 38 +++++++ src/skins/default/en/checkout/controller.js | 14 +-- .../en/checkout/parts/address.plain.tpl | 52 ++------- .../en/checkout/steps/payment/address.tpl | 11 ++ .../steps/payment/parts/address.address.tpl | 16 --- .../steps/payment/parts/address.city.tpl | 16 --- .../steps/payment/parts/address.country.tpl | 16 --- .../steps/payment/parts/address.name.tpl | 16 --- .../steps/payment/parts/address.phone.tpl | 16 --- .../steps/payment/parts/address.state.tpl | 16 --- .../steps/payment/parts/address.zipcode.tpl | 16 --- .../en/checkout/steps/shipping/address.tpl | 12 +- src/skins/default/en/css/lc.css | 13 ++- .../default/en/form_field/select_country.js | 3 - 24 files changed, 255 insertions(+), 249 deletions(-) create mode 100644 src/classes/XLite/View/Checkout/AAddressBlock.php delete mode 100644 src/skins/default/en/checkout/steps/payment/parts/address.address.tpl delete mode 100644 src/skins/default/en/checkout/steps/payment/parts/address.city.tpl delete mode 100644 src/skins/default/en/checkout/steps/payment/parts/address.country.tpl delete mode 100644 src/skins/default/en/checkout/steps/payment/parts/address.name.tpl delete mode 100644 src/skins/default/en/checkout/steps/payment/parts/address.phone.tpl delete mode 100644 src/skins/default/en/checkout/steps/payment/parts/address.state.tpl delete mode 100644 src/skins/default/en/checkout/steps/payment/parts/address.zipcode.tpl diff --git a/src/classes/XLite/Model/Profile.php b/src/classes/XLite/Model/Profile.php index 4d3b092ec4..9b27067a44 100644 --- a/src/classes/XLite/Model/Profile.php +++ b/src/classes/XLite/Model/Profile.php @@ -491,13 +491,10 @@ public function isSameAddress() $methodName = 'get' . \XLite\Core\Converter::getInstance()->convertToCamelCase($name); - if (method_exists($billingAddress, $methodName)) { - - // Compare field values of billing and shipping addresses - if ($billingAddress->$methodName() != $shippingAddress->$methodName()) { - $result = false; - break; - } + // Compare field values of billing and shipping addresses + if ($billingAddress->$methodName() != $shippingAddress->$methodName()) { + $result = false; + break; } } } @@ -548,9 +545,11 @@ public function cloneEntity() $newBillingAddress->update(); } - if (!$this->isSameAddress() && $this->getShippingAddress()) { + $shippingAddress = $this->getShippingAddress(); + + if (!$this->isSameAddress() && $shippingAddress) { - $newShippingAddress = $this->getShippingAddress()->cloneEntity(); + $newShippingAddress = $shippingAddress->cloneEntity(); $newShippingAddress->setProfile($newProfile); $newProfile->addAddresses($newShippingAddress); $newShippingAddress->update(); diff --git a/src/classes/XLite/View/AView.php b/src/classes/XLite/View/AView.php index 542e25a9de..4f728c3a98 100644 --- a/src/classes/XLite/View/AView.php +++ b/src/classes/XLite/View/AView.php @@ -1850,7 +1850,6 @@ public function getInvoiceLogo() protected function getAddressSectionData(\XLite\Model\Address $address) { $result = array(); - $repo = \XLite\Core\Database::getRepo('XLite\Model\AddressFieldValue'); foreach (\XLite\Core\Database::getRepo('XLite\Model\AddressField')->findAllEnabled() as $field) { diff --git a/src/classes/XLite/View/Checkout.php b/src/classes/XLite/View/Checkout.php index c747fd27ae..571addb1e2 100644 --- a/src/classes/XLite/View/Checkout.php +++ b/src/classes/XLite/View/Checkout.php @@ -53,6 +53,19 @@ public static function getAllowedTargets() return $result; } + /** + * Get a list of CSS files required to display the widget properly + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + $list[] = 'checkout/checkout.css'; + + return $list; + } + /** * Get a list of JS files required to display the widget properly * FIXME - decompose these files diff --git a/src/classes/XLite/View/Checkout/AAddressBlock.php b/src/classes/XLite/View/Checkout/AAddressBlock.php new file mode 100644 index 0000000000..539b2d36af --- /dev/null +++ b/src/classes/XLite/View/Checkout/AAddressBlock.php @@ -0,0 +1,103 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\Checkout; + +/** + * Address block info + * + */ +abstract class AAddressBlock extends \XLite\View\AView +{ + /** + * Get address info model + * + * @return \XLite\Model\Address + */ + abstract protected function getAddressInfo(); + + /** + * getFieldValue + * + * @param string $fieldName Field name + * @param boolean $processValue Process value flag OPTIONAL + * + * @return string + */ + public function getFieldValue($fieldName, $processValue = false) + { + $result = ''; + + $address = $this->getAddressInfo(); + + if (isset($address)) { + + $methodName = 'get' . \XLite\Core\Converter::getInstance()->convertToCamelCase($fieldName); + + // $methodName assembled from 'get' + camelized $fieldName + $result = $address->$methodName(); + + if ($result && false !== $processValue) { + + switch ($fieldName) { + + case 'state_id': + $result = $address->getState()->getState(); + break; + + case 'country_code': + $result = $address->getCountry()->getCountry(); + break; + + default: + + } + } + } + + return $result; + } + + /** + * Add CSS classes to the list of attributes + * + * @param string $fieldName Field service name + * @param array $fieldData Array of field properties (see getAddressFields() for the details) + * + * @return array + */ + public function getFieldAttributes($fieldName, $fieldData) + { + $classes = array('field-' . $fieldName); + + if ($fieldData[\XLite\View\Model\Address\Address::SCHEMA_REQUIRED]) { + $classes[] = 'field-required'; + } + + return array( + 'class' => implode(' ', $classes), + ); + } +} diff --git a/src/classes/XLite/View/Checkout/BillingAddress.php b/src/classes/XLite/View/Checkout/BillingAddress.php index b0b2f8cf27..d173c40991 100644 --- a/src/classes/XLite/View/Checkout/BillingAddress.php +++ b/src/classes/XLite/View/Checkout/BillingAddress.php @@ -29,7 +29,7 @@ * Billing address block * */ -class BillingAddress extends \XLite\View\AView +class BillingAddress extends \XLite\View\Checkout\AAddressBlock { /** * Modifier (cache) @@ -109,4 +109,14 @@ protected function getModifier() return $this->modifier; } + + /** + * Get address info model + * + * @return \XLite\Model\Address + */ + protected function getAddressInfo() + { + return $this->getSameAddress(); + } } diff --git a/src/classes/XLite/View/Checkout/ShippingAddress.php b/src/classes/XLite/View/Checkout/ShippingAddress.php index e143b2d793..5fff0348ae 100644 --- a/src/classes/XLite/View/Checkout/ShippingAddress.php +++ b/src/classes/XLite/View/Checkout/ShippingAddress.php @@ -29,7 +29,7 @@ * Shipping address block * */ -class ShippingAddress extends \XLite\View\AView +class ShippingAddress extends \XLite\View\Checkout\AAddressBlock { /** * Get shipping address @@ -70,13 +70,13 @@ public function getAddressFields() foreach (\XLite\Core\Database::getRepo('XLite\Model\AddressField')->findAllEnabled() as $field) { $result[$field->getServiceName()] = array( - \XLite\View\Model\Address\Address::SCHEMA_CLASS => $field->getSchemaClass(), - \XLite\View\Model\Address\Address::SCHEMA_LABEL => $field->getName(), - \XLite\View\Model\Address\Address::SCHEMA_REQUIRED => $field->getRequired(), - \XLite\View\Model\Address\Address::SCHEMA_MODEL_ATTRIBUTES => array( + \XLite\View\Model\Address\Address::SCHEMA_CLASS => $field->getSchemaClass(), + \XLite\View\Model\Address\Address::SCHEMA_LABEL => $field->getName(), + \XLite\View\Model\Address\Address::SCHEMA_REQUIRED => $field->getRequired(), + \XLite\View\Model\Address\Address::SCHEMA_MODEL_ATTRIBUTES => array( \XLite\View\FormField\Input\Base\String::PARAM_MAX_LENGTH => 'length', ), - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-' . $field->getServiceName(), + \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'address-' . $field->getServiceName(), ); } @@ -84,66 +84,13 @@ public function getAddressFields() } /** - * Add CSS classes to the list of attributes + * Get address info model * - * @param string $fieldName Field service name - * @param array $fieldData Array of field properties (see getAddressFields() for the details) - * - * @return array - */ - public function getFieldAttributes($fieldName, $fieldData) - { - $classes = array('field-' . $fieldName); - - if ($fieldData[\XLite\View\Model\Address\Address::SCHEMA_REQUIRED]) { - $classes[] = 'field-required'; - } - - return array( - 'class' => implode(' ', $classes), - ); - } - - /** - * getFieldValue - * - * @param string $fieldName Field name - * @param boolean $processValue Process value flag OPTIONAL - * - * @return string + * @return \XLite\Model\Address */ - public function getFieldValue($fieldName, $processValue = false) + protected function getAddressInfo() { - $result = ''; - - $address = $this->getShippingAddress(); - - if (isset($address)) { - - $methodName = 'get' . \XLite\Core\Converter::getInstance()->convertToCamelCase($fieldName); - - // $methodName assembled from 'get' + camelized $fieldName - $result = $address->$methodName(); - - if ($result && false !== $processValue) { - - switch ($fieldName) { - - case 'state_id': - $result = $address->getState()->getState(); - break; - - case 'country_code': - $result = $address->getCountry()->getCountry(); - break; - - default: - - } - } - } - - return $result; + return $this->getShippingAddress(); } /** diff --git a/src/classes/XLite/View/Checkout/Steps.php b/src/classes/XLite/View/Checkout/Steps.php index 2e3614bc18..dcbfc97c9a 100644 --- a/src/classes/XLite/View/Checkout/Steps.php +++ b/src/classes/XLite/View/Checkout/Steps.php @@ -54,6 +54,20 @@ class Steps extends \XLite\View\AView */ protected $currentStep; + + /** + * Register JS files + * + * @return array + */ + public function getJSFiles() + { + $list = parent::getJSFiles(); + + $list[] = 'form_field/select_country.js'; + + return $list; + } /** * Get steps diff --git a/src/classes/XLite/View/Form/Checkout/UpdateProfile.php b/src/classes/XLite/View/Form/Checkout/UpdateProfile.php index 430d3382e1..c74186f9ba 100644 --- a/src/classes/XLite/View/Form/Checkout/UpdateProfile.php +++ b/src/classes/XLite/View/Form/Checkout/UpdateProfile.php @@ -117,11 +117,11 @@ protected function getValidator() foreach ($addressFields as $fieldName => $fieldData) { if (!$isCountryStateAdded && in_array($fieldName, array('country', 'state'))) { - $shippingAddress->addPair(new \XLite\Core\Validator\Pair\CountryState()); + $billingAddress->addPair(new \XLite\Core\Validator\Pair\CountryState()); $isCountryStateAdded = true; } else { - $shippingAddress->addPair( + $billingAddress->addPair( $fieldName, new \XLite\Core\Validator\String($nonEmpty && $fieldData[\XLite\View\Model\Address\Address::SCHEMA_REQUIRED]), $mode diff --git a/src/classes/XLite/View/FormField/Select/Country.php b/src/classes/XLite/View/FormField/Select/Country.php index cb5b65eaab..bb26fd89dc 100644 --- a/src/classes/XLite/View/FormField/Select/Country.php +++ b/src/classes/XLite/View/FormField/Select/Country.php @@ -153,11 +153,11 @@ protected function getDefaultValue() */ protected function getInlineJSCode() { - return 'jQuery(document).ready(function() { ' - . 'stateSelectors[\'' . $this->getFieldId() . '\'] = new StateSelector(' + return $this->getWidget(array(), '\XLite\View\JS\StatesList')->getContent() . PHP_EOL + . 'jQuery(document).ready(function() { ' . PHP_EOL + . 'stateSelectors[\'' . $this->getFieldId() . '\'] = new StateSelector(' . PHP_EOL . '\'' . $this->getFieldId() . '\', ' . '\'' . $this->getParam(self::PARAM_STATE_SELECTOR_ID) . '\', ' - . '\'' . $this->getParam(self::PARAM_STATE_INPUT_ID) . '\'); });' . PHP_EOL - . $this->getWidget(array(), '\XLite\View\JS\StatesList')->getContent(); + . '\'' . $this->getParam(self::PARAM_STATE_INPUT_ID) . '\'); });' . PHP_EOL; } } diff --git a/src/skins/common/js/common.js b/src/skins/common/js/common.js index 18fb29144d..a10e21d280 100644 --- a/src/skins/common/js/common.js +++ b/src/skins/common/js/common.js @@ -502,3 +502,7 @@ function attachTooltip(elm, content) { } ); } + +var statesList = []; +var stateSelectors = []; + diff --git a/src/skins/default/en/checkout/checkout.css b/src/skins/default/en/checkout/checkout.css index eb61826c19..d73e671f55 100644 --- a/src/skins/default/en/checkout/checkout.css +++ b/src/skins/default/en/checkout/checkout.css @@ -19,3 +19,41 @@ color: #EE0000; padding-bottom: 25px; } + +.item-custom_state { + display: none; +} + +.address-text-label, + .address-text-comma +{ + display: none; +} + +ul.address-box > li { + padding: 0px 0px 2px 2px; + float: left; + clear: left; +} + +ul.address-box li ul li { + float: left; + clear: none; +} + +ul.address-box li.address-text-lastname, + ul.address-box li.address-text-firstname, + ul.address-box li.address-text-state_id, + ul.address-box li.address-text-zipcode +{ + clear: none; +} + +ul.address-box li.address-text-city .address-text-comma, + ul.address-box li.address-text-state_id .address-text-comma, + ul.address-box li.address-text-country_code .address-text-comma, + ul.address-box li.address-text-phone .address-text-label +{ + display: inherit; +} + diff --git a/src/skins/default/en/checkout/controller.js b/src/skins/default/en/checkout/controller.js index 5bd5c8930b..2426c54a3b 100644 --- a/src/skins/default/en/checkout/controller.js +++ b/src/skins/default/en/checkout/controller.js @@ -43,16 +43,16 @@ function CheckoutView(base) core.bind( 'updateCart', function(event, data) { - if (data.billingAddress && jQuery('.payment-step .same-address #same_address').length && !o.isLoadingStart) { + if (data.billingAddress && jQuery('#same_address').length && !o.isLoadingStart) { // Change same-address checkbox and reload billing address after change address into address book popup if ( - (data.billingAddress.same && 0 == jQuery('.payment-step .same-address #same_address:checked').length) - || (!data.billingAddress.same && 1 == jQuery('.payment-step .same-address #same_address:checked').length) + (data.billingAddress.same && 0 == jQuery('#same_address:checked').length) + || (!data.billingAddress.same && 1 == jQuery('#same_address:checked').length) ) { // Change from not-same-address to same-address or revert - var chk = jQuery('.payment-step .same-address #same_address').get(0); + var chk = jQuery('#same_address').get(0); if (chk) { chk.checked = !chk.checked; } @@ -320,7 +320,7 @@ CheckoutView.prototype.postprocess = function(isSuccess, initial) o.isLoadingStart = true; - return jQuery('.payment-step .same-address #same_address:checked', o.base).length + return jQuery('#same_address:checked').length ? !o.load() : !(jQuery('.payment-step.current .secondary form', o.base).submit() && o.shade()); } @@ -621,7 +621,7 @@ CheckoutView.prototype.refreshState = function() var paymentIsReady = (jQuery('ul.payments').length > 0) ? (1 == jQuery('ul.payments input:checked', this.base).length) : true; // Billing address is ready (completed) - isSameAddress = 1 == jQuery('.same-address #same_address:checked', this.base).length; + isSameAddress = 1 == jQuery('#same_address:checked').length; var billingAddressIsReady = isSameAddress || (0 < jQuery('form.billing-address ul.form :input', this.base).length && jQuery('form.billing-address', this.base).get(0).validate(true)); @@ -871,7 +871,7 @@ BillingAddressView.prototype.postprocess = function(isSuccess, initial) } ); - jQuery('.same-address #same_address', this.base).change( + jQuery('#same_address').change( function(event) { o.changeSameAddress = true; o.parentWidget.refreshState(); diff --git a/src/skins/default/en/checkout/parts/address.plain.tpl b/src/skins/default/en/checkout/parts/address.plain.tpl index 4d71bf9dec..130fa5a08a 100644 --- a/src/skins/default/en/checkout/parts/address.plain.tpl +++ b/src/skins/default/en/checkout/parts/address.plain.tpl @@ -9,48 +9,16 @@ * @link http://www.litecommerce.com/ *} -
    -
    - {foreach:getAddressFields(),fieldName,fieldData} -
    {getFieldValue(fieldName,address,1)}
    - {end:} -
    -
    - -{* -
      - -{foreach:getAddressFields(),fieldName,fieldData} - -
    • - -
        - -
      • {fieldData.label}:
      • - -
      • {getFieldValue(fieldName,address,1)}
      • - -
      • ,
      • - -
      - -
    • - -{end:} - +
        + {foreach:getAddressFields(),fieldName,fieldData} +
      • +
          +
        • {fieldData.label}:
        • +
        • {getFieldValue(fieldName,address,1)}
        • +
        • ,
        • +
        +
      • + {end:}
      -*} -{* -
      -
      {address.name}
      -
      - {address.street}
      - {address.city}, {address.state.state}, {address.zipcode}
      - {address.country.country}
      -
      -
      {t(#Phone#)}: {address.phone}
      -
      -*} - diff --git a/src/skins/default/en/checkout/steps/payment/address.tpl b/src/skins/default/en/checkout/steps/payment/address.tpl index f98034ce31..b548046f80 100644 --- a/src/skins/default/en/checkout/steps/payment/address.tpl +++ b/src/skins/default/en/checkout/steps/payment/address.tpl @@ -21,6 +21,17 @@ {else:}
        +
      • + +
      diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.address.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.address.tpl deleted file mode 100644 index 48fc84d54c..0000000000 --- a/src/skins/default/en/checkout/steps/payment/parts/address.address.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Billing address : street - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.payment.address", weight="20") - *} -
    • - - -
    • diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.city.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.city.tpl deleted file mode 100644 index a0d674f9ef..0000000000 --- a/src/skins/default/en/checkout/steps/payment/parts/address.city.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Billing address : city - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.payment.address", weight="50") - *} -
    • - - -
    • diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.country.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.country.tpl deleted file mode 100644 index e966ae05de..0000000000 --- a/src/skins/default/en/checkout/steps/payment/parts/address.country.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Billing address : country - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.payment.address", weight="30") - *} -
    • - - -
    • diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.name.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.name.tpl deleted file mode 100644 index 5d2f2b4022..0000000000 --- a/src/skins/default/en/checkout/steps/payment/parts/address.name.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Billing address : name - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.payment.address", weight="10") - *} -
    • - - -
    • diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.phone.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.phone.tpl deleted file mode 100644 index a27e08bb8b..0000000000 --- a/src/skins/default/en/checkout/steps/payment/parts/address.phone.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Billing address : phone - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.payment.address", weight="70") - *} -
    • - - -
    • diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.state.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.state.tpl deleted file mode 100644 index ec95a3fc6a..0000000000 --- a/src/skins/default/en/checkout/steps/payment/parts/address.state.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Billing address : state - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.payment.address", weight="40") - *} -
    • - - -
    • diff --git a/src/skins/default/en/checkout/steps/payment/parts/address.zipcode.tpl b/src/skins/default/en/checkout/steps/payment/parts/address.zipcode.tpl deleted file mode 100644 index c8f9d080ac..0000000000 --- a/src/skins/default/en/checkout/steps/payment/parts/address.zipcode.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * Billing address : zipcode - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - * - * @ListChild (list="checkout.payment.address", weight="60") - *} -
    • - - -
    • diff --git a/src/skins/default/en/checkout/steps/shipping/address.tpl b/src/skins/default/en/checkout/steps/shipping/address.tpl index 96add3a154..745ee33f6c 100644 --- a/src/skins/default/en/checkout/steps/shipping/address.tpl +++ b/src/skins/default/en/checkout/steps/shipping/address.tpl @@ -10,8 +10,16 @@ *}
        -
      • - +
      • +
      diff --git a/src/skins/default/en/css/lc.css b/src/skins/default/en/css/lc.css index 6da8c7fd59..0524c9b634 100644 --- a/src/skins/default/en/css/lc.css +++ b/src/skins/default/en/css/lc.css @@ -2351,6 +2351,7 @@ form.estimator .main, margin-top: 12px; margin-right: 4px; padding: 16px 20px; + height: 120px; } /* Step: order review */ @@ -2580,6 +2581,12 @@ form.estimator .main, } .select-address ul.addresses li { + background: none; + margin: 0px; + padding-left: 2px; +} + +.select-address ul.addresses > li { list-style: none; width: 278px; float: left; @@ -2596,11 +2603,11 @@ form.estimator .main, cursor: pointer; } -.select-address ul.addresses li.last { +.select-address ul.addresses > li.last { margin-right: 0px; } -.select-address ul.addresses li .shipping { +.select-address ul.addresses > li .shipping { position: absolute; right: 8px; bottom: 15px; @@ -2609,7 +2616,7 @@ form.estimator .main, height: 20px; } -.select-address ul.addresses li .billing { +.select-address ul.addresses > li .billing { position: absolute; right: 9px; bottom: 47px; diff --git a/src/skins/default/en/form_field/select_country.js b/src/skins/default/en/form_field/select_country.js index d4d86d9163..96db064508 100644 --- a/src/skins/default/en/form_field/select_country.js +++ b/src/skins/default/en/form_field/select_country.js @@ -9,9 +9,6 @@ * @link http://www.litecommerce.com/ */ -var statesList = []; -var stateSelectors = []; - function StateSelector(countrySelectorId, stateSelectorId, stateInputId) { this.countrySelectBox = jQuery('#' + countrySelectorId); From aa4d6aab2ab583a52876a4b130bc872e65100fba Mon Sep 17 00:00:00 2001 From: skiv Date: Fri, 5 Oct 2012 15:11:30 +0400 Subject: [PATCH 21/85] Attributes --- .../XLite/Controller/Admin/Attribute.php | 13 +++- .../Controller/Admin/AttributeGroups.php | 13 +++- .../XLite/Controller/Admin/Attributes.php | 4 +- src/classes/XLite/Model/Attribute.php | 12 ++++ .../AttributeValue/AttributeValueCheckbox.php | 2 +- .../AttributeValue/AttributeValueSelect.php | 6 +- src/classes/XLite/View/Attributes.php | 2 +- .../XLite/View/ItemsList/Model/AModel.php | 15 ++++- .../XLite/View/ItemsList/Model/Attribute.php | 2 +- .../View/Product/Details/Admin/Attributes.php | 4 +- .../Product/Details/Customer/Attributes.php | 24 +++++-- src/skins/admin/en/attribute_groups/list.tpl | 2 +- src/skins/admin/en/attributes/body.tpl | 9 ++- src/skins/admin/en/attributes/parts/type.tpl | 4 +- src/skins/admin/en/attributes/script.js | 66 ++++++++++--------- src/skins/admin/en/attributes/style.css | 4 ++ src/sql/xlite_data.yaml | 2 + 17 files changed, 127 insertions(+), 57 deletions(-) diff --git a/src/classes/XLite/Controller/Admin/Attribute.php b/src/classes/XLite/Controller/Admin/Attribute.php index 1b52cced9c..8c31b1db7c 100644 --- a/src/classes/XLite/Controller/Admin/Attribute.php +++ b/src/classes/XLite/Controller/Admin/Attribute.php @@ -59,7 +59,18 @@ class Attribute extends \XLite\Controller\Admin\AAdmin */ public function checkACL() { - return (parent::checkACL() || \XLite\Core\Auth::getInstance()->isPermissionAllowed('manage catalog')) + return parent::checkACL() + || \XLite\Core\Auth::getInstance()->isPermissionAllowed('manage catalog'); + } + + /** + * Check if current page is accessible + * + * @return boolean + */ + public function checkAccess() + { + return parent::checkAccess() && $this->getProductClass() && $this->isAJAX(); } diff --git a/src/classes/XLite/Controller/Admin/AttributeGroups.php b/src/classes/XLite/Controller/Admin/AttributeGroups.php index 989f32e9b4..52da3b5805 100644 --- a/src/classes/XLite/Controller/Admin/AttributeGroups.php +++ b/src/classes/XLite/Controller/Admin/AttributeGroups.php @@ -52,7 +52,18 @@ class AttributeGroups extends \XLite\Controller\Admin\AAdmin */ public function checkACL() { - return (parent::checkACL() || \XLite\Core\Auth::getInstance()->isPermissionAllowed('manage catalog')) + return parent::checkACL() + || \XLite\Core\Auth::getInstance()->isPermissionAllowed('manage catalog'); + } + + /** + * Check if current page is accessible + * + * @return boolean + */ + public function checkAccess() + { + return parent::checkAccess() && $this->getProductClass() && $this->isAJAX(); } diff --git a/src/classes/XLite/Controller/Admin/Attributes.php b/src/classes/XLite/Controller/Admin/Attributes.php index 82f6da3c86..d3ea8e11b2 100644 --- a/src/classes/XLite/Controller/Admin/Attributes.php +++ b/src/classes/XLite/Controller/Admin/Attributes.php @@ -103,8 +103,8 @@ protected function doActionUpdate() public function getTitle() { return $this->getProductClass() - ? \XLite\Core\Translation::getInstance()->lbl( - 'Attributes for "{{class}}" product class', + ? static::t( + 'Attributes for X product class', array( 'class' => $this->getProductClass()->getName() ) diff --git a/src/classes/XLite/Model/Attribute.php b/src/classes/XLite/Model/Attribute.php index 3040c936f8..d8f3a79457 100644 --- a/src/classes/XLite/Model/Attribute.php +++ b/src/classes/XLite/Model/Attribute.php @@ -279,6 +279,18 @@ public function getAttributeValueClass() . $this->getTypes($this->getType()); } + /** + * Return field comment + * + * @return string + */ + public function getFieldComment() + { + return self::TYPE_NUMBER == $this->getType() + ? $this->getUnit() + : ''; + } + /** * Set attribute value * diff --git a/src/classes/XLite/Model/AttributeValue/AttributeValueCheckbox.php b/src/classes/XLite/Model/AttributeValue/AttributeValueCheckbox.php index 560ea05954..e397ce46f8 100644 --- a/src/classes/XLite/Model/AttributeValue/AttributeValueCheckbox.php +++ b/src/classes/XLite/Model/AttributeValue/AttributeValueCheckbox.php @@ -46,5 +46,5 @@ class AttributeValueCheckbox extends \XLite\Model\AttributeValue\AAttributeValue * * @Column (type="boolean") */ - protected $value = 0; + protected $value = false; } diff --git a/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueSelect.php b/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueSelect.php index 8aa14c2804..6ce646d9e2 100644 --- a/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueSelect.php +++ b/src/classes/XLite/Model/Repo/AttributeValue/AttributeValueSelect.php @@ -43,20 +43,20 @@ class AttributeValueSelect extends \XLite\Model\Repo\AttributeValue\AAttributeVa */ protected function getHandlingSearchParams() { - return parent::getHandlingSearchParams() + array(static::SEARCH_ATTRIBUTE_OPTION); + return array_merge(parent::getHandlingSearchParams(), array(static::SEARCH_ATTRIBUTE_OPTION)); } /** * Prepare certain search condition * * @param \Doctrine\ORM\QueryBuilder $queryBuilder Query builder to prepare - * @param mixed $value Condition OPTIONAL + * @param mixed $value Condition * * @return void * @see ____func_see____ * @since 1.0.0 */ - protected function prepareCndAttributeOption(\Doctrine\ORM\QueryBuilder $queryBuilder, $value = null) + protected function prepareCndAttributeOption(\Doctrine\ORM\QueryBuilder $queryBuilder, $value) { if ($value) { $queryBuilder->andWhere('a.attribute_option = :attributeOption') diff --git a/src/classes/XLite/View/Attributes.php b/src/classes/XLite/View/Attributes.php index 0ac1100cd7..a0169d0c04 100644 --- a/src/classes/XLite/View/Attributes.php +++ b/src/classes/XLite/View/Attributes.php @@ -74,7 +74,6 @@ public function getJSFiles() { $list = parent::getJSFiles(); - $list[] = 'attributes/script.js'; $list[] = 'form_field/inline/controller.js'; $list[] = 'form_field/inline/input/text/position/move.js'; $list[] = 'form_field/js/text.js'; @@ -82,6 +81,7 @@ public function getJSFiles() $list[] = 'button/js/remove.js'; $list[] = 'items_list/items_list.js'; $list[] = 'items_list/model/table/controller.js'; + $list[] = 'attributes/script.js'; return $list; } diff --git a/src/classes/XLite/View/ItemsList/Model/AModel.php b/src/classes/XLite/View/ItemsList/Model/AModel.php index 970a77327e..1429acfcc0 100644 --- a/src/classes/XLite/View/ItemsList/Model/AModel.php +++ b/src/classes/XLite/View/ItemsList/Model/AModel.php @@ -495,13 +495,26 @@ protected function update() foreach ($this->getPageData() as $entity) { $entity->getRepository()->update($entity, array(), false); if ($this->isDefault()) { - $entity->setDefaultValue(isset($this->requestData['defaultValue']) && $this->requestData['defaultValue'] == $entity->getId()); + $entity->setDefaultValue($this->isDefaultEntity($entity)); } } return $count; } + /** + * Is default entity + * + * @param \XLite\Model\AEntity $entity Line + * + * @return boolean + */ + protected function isDefaultEntity(\XLite\Model\AEntity $entity) + { + return isset($this->requestData['defaultValue']) + && $this->requestData['defaultValue'] == $entity->getId(); + } + /** * Process errors * diff --git a/src/classes/XLite/View/ItemsList/Model/Attribute.php b/src/classes/XLite/View/ItemsList/Model/Attribute.php index d685a95a1b..f08b829571 100644 --- a/src/classes/XLite/View/ItemsList/Model/Attribute.php +++ b/src/classes/XLite/View/ItemsList/Model/Attribute.php @@ -54,7 +54,7 @@ protected function defineColumns() ), 'type' => array( static::COLUMN_NAME => $this->getAttributeGroup() - ? \XLite\Core\Translation::getInstance()->lbl( + ? static::t( '{{count}} attributes in group', array( 'count' => $this->getAttributeGroup()->getAttributesCount() diff --git a/src/classes/XLite/View/Product/Details/Admin/Attributes.php b/src/classes/XLite/View/Product/Details/Admin/Attributes.php index 6eb15297cd..44d271cf03 100644 --- a/src/classes/XLite/View/Product/Details/Admin/Attributes.php +++ b/src/classes/XLite/View/Product/Details/Admin/Attributes.php @@ -85,9 +85,7 @@ protected function getAttributesList($countOnly = false) 'maxHeight' => 100, 'rows' => 1, 'attribute' => $attribute, - 'comment' => \XLite\Model\Attribute::TYPE_NUMBER == $attribute->getType() - ? $attribute->getUnit() - : '', + 'comment' => $attribute->getFieldComment(), 'value' => $attribute->getAttributeValue($this->getProduct()) ), $attribute->getWidgetClass() diff --git a/src/classes/XLite/View/Product/Details/Customer/Attributes.php b/src/classes/XLite/View/Product/Details/Customer/Attributes.php index df23766e7e..a6f7cbeec7 100644 --- a/src/classes/XLite/View/Product/Details/Customer/Attributes.php +++ b/src/classes/XLite/View/Product/Details/Customer/Attributes.php @@ -49,15 +49,11 @@ public function getAttrList() $this->attributes = array(); foreach ($this->getAttributesList() as $a) { $value = $a->getAttributeValue($this->getProduct(), true); - $class = strtolower($a->getTypes($a->getType())); - if (\XLite\Model\Attribute::TYPE_CHECKBOX == $a->getType()) { - $class .= ' ' . (static::t('yes') == $value ? 'checked' : 'no-checked'); - } if ($value) { $this->attributes[] = array( 'name' => $a->getName(), 'value' => $value, - 'class' => $class + 'class' => $this->getFieldClass($a, $value) ); } } @@ -66,6 +62,24 @@ public function getAttrList() return $this->attributes; } + /** + * Return field class + * + * @param \XLite\Model\Attribute $attribute Attribute + * @param string $value Value + * + * @return string + */ + protected function getFieldClass(\XLite\Model\Attribute $attribute, $value) + { + $class = strtolower($a->getTypes($attribute->getType())); + if (\XLite\Model\Attribute::TYPE_CHECKBOX == $attribute->getType()) { + $class .= ' ' . (static::t('yes') == $value ? 'checked' : 'no-checked'); + } + + return $class; + } + /** * Return widget default template * diff --git a/src/skins/admin/en/attribute_groups/list.tpl b/src/skins/admin/en/attribute_groups/list.tpl index f42c2db7af..7192e584be 100644 --- a/src/skins/admin/en/attribute_groups/list.tpl +++ b/src/skins/admin/en/attribute_groups/list.tpl @@ -12,7 +12,7 @@
      - +
      {t(#Editing attribute groups on this page won't affect other product classes which use these groups. Removing a group doesn't delete attributes from the group, but makes them show up among other attributes having no associated groups.#)}
      diff --git a/src/skins/admin/en/attributes/body.tpl b/src/skins/admin/en/attributes/body.tpl index feb33ccfe8..0dc7ef5f1f 100644 --- a/src/skins/admin/en/attributes/body.tpl +++ b/src/skins/admin/en/attributes/body.tpl @@ -9,10 +9,9 @@ * @link http://www.litecommerce.com/ *} - - - -
      -
      +
      + + +
      diff --git a/src/skins/admin/en/attributes/parts/type.tpl b/src/skins/admin/en/attributes/parts/type.tpl index 3cc1c52f95..cef45323fd 100644 --- a/src/skins/admin/en/attributes/parts/type.tpl +++ b/src/skins/admin/en/attributes/parts/type.tpl @@ -9,5 +9,7 @@ * @link http://www.litecommerce.com/ *} - +
      + {t(entity.getTypes(entity.getType()))} +
      diff --git a/src/skins/admin/en/attributes/script.js b/src/skins/admin/en/attributes/script.js index 02e5be99e8..b26d04b4a0 100644 --- a/src/skins/admin/en/attributes/script.js +++ b/src/skins/admin/en/attributes/script.js @@ -25,34 +25,38 @@ popup.postprocessRequest = function(XMLHttpRequest, textStatus, data, isValid) { ); } -var pprc = popup.postprocessRequestCallback; -popup.postprocessRequestCallback() = function() -{ - pprc.postprocessRequestCallback(); - popup.close(); -} - -function popup_attribute_groups(product_class_id) { - return !popup.load( - URLHandler.buildURL({ - target: 'attribute_groups', - product_class_id: product_class_id, - widget: 'XLite\\View\\AttributeGroups' - }) - ); -} - -function popup_attribute(product_class_id, id) { - return !popup.load( - URLHandler.buildURL({ - target: 'attribute', - product_class_id: product_class_id, - id: id, - widget: 'XLite\\View\\Attribute' - }), - null, - function () { - self.location.reload(); - } - ); -} +jQuery().ready( + function () { + jQuery('button.manage-groups').click( + function () { + return !popup.load( + URLHandler.buildURL({ + target: 'attribute_groups', + product_class_id: jQuery(this).parent().data('class-id'), + widget: 'XLite\\View\\AttributeGroups' + }), + null, + function () { + self.location.reload(); + } + ); + } + ); + jQuery('button.new-attribute, button.edit-attribute').click( + function () { + return !popup.load( + URLHandler.buildURL({ + target: 'attribute', + product_class_id: jQuery(this).parent().data('class-id'), + id: jQuery(this).parent().data('id'), + widget: 'XLite\\View\\Attribute' + }), + null, + function () { + self.location.reload(); + } + ); + } + ); + } +); diff --git a/src/skins/admin/en/attributes/style.css b/src/skins/admin/en/attributes/style.css index 93b04f8cf0..c588d8032c 100644 --- a/src/skins/admin/en/attributes/style.css +++ b/src/skins/admin/en/attributes/style.css @@ -51,6 +51,10 @@ button.manage-groups span { padding: 2px 0 2px 25px; } +div.buttons { + margin-bottom: 25px; +} + div.group table.list th.actions.left { background: url("../images/icon_folder.png") no-repeat scroll center center transparent; } diff --git a/src/sql/xlite_data.yaml b/src/sql/xlite_data.yaml index 52b0851472..5a851a215a 100644 --- a/src/sql/xlite_data.yaml +++ b/src/sql/xlite_data.yaml @@ -491,6 +491,8 @@ XLite\Model\LanguageLabel: - { name: 'Payment method has been enabled successfully', translations: [{ code: en, label: 'Payment method has been enabled successfully' }] } - { name: 'Payment method has been disabled successfully', translations: [{ code: en, label: 'Payment method has been disabled successfully' }] } - { name: 'Payment method has been removed successfully', translations: [{ code: en, label: 'Payment method has been removed successfully' }] } + - { name: 'Attributes for X product clas', translations: [{ code: en, label: 'Attributes for "{{class}}" product class' }] } + - { name: 'X attributes in group', translations: [{ code: en, label: '{{count}} attributes in group' }] } XLite\Model\Membership: directives: { insert: true } - { orderby: 10, translations: [{ code: en, name: Gold }] } From 7d8ac0655f224344f6de84c956d8c09c97132aac Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Fri, 5 Oct 2012 16:45:39 +0400 Subject: [PATCH 22/85] [*] Country/State JS connection total refactoring. --- .../XLite/View/FormField/AFormField.php | 41 +++++++----- .../XLite/View/FormField/Select/Country.php | 28 +++++--- src/classes/XLite/View/JS/AJS.php | 34 ---------- src/classes/XLite/View/JS/StatesList.php | 53 --------------- src/skins/admin/en/button/js/add_address.js | 1 + .../admin/en/button/js/modify_address.js | 1 + src/skins/admin/en/form_field.tpl | 1 + .../admin/en/form_field/select_country.js | 15 +++-- src/skins/admin/en/js/states_list.tpl | 18 ----- src/skins/common/js/common.js | 19 ++++++ src/skins/common/js/php.js | 66 +++++++++++++++++++ src/skins/default/en/button/js/add_address.js | 1 + .../default/en/button/js/modify_address.js | 1 + src/skins/default/en/checkout/controller.js | 6 ++ src/skins/default/en/form_field.tpl | 5 +- .../default/en/form_field/select_country.js | 11 +++- src/skins/default/en/js/states_list.tpl | 18 ----- 17 files changed, 163 insertions(+), 156 deletions(-) delete mode 100644 src/classes/XLite/View/JS/AJS.php delete mode 100644 src/classes/XLite/View/JS/StatesList.php delete mode 100644 src/skins/admin/en/js/states_list.tpl delete mode 100644 src/skins/default/en/js/states_list.tpl diff --git a/src/classes/XLite/View/FormField/AFormField.php b/src/classes/XLite/View/FormField/AFormField.php index aa47ab9592..614483cbd4 100644 --- a/src/classes/XLite/View/FormField/AFormField.php +++ b/src/classes/XLite/View/FormField/AFormField.php @@ -81,8 +81,8 @@ abstract class AFormField extends \XLite\View\AView protected $isAllowedForCustomer = true; /** - * Error message - * + * Error message + * * @var string */ protected $errorMessage; @@ -271,12 +271,12 @@ protected function getValidityFlag() /** * Sanitize value - * + * * @return mixed */ protected function sanitize() { - return $this->getValue(); + return $this->getValue(); } /** @@ -318,10 +318,10 @@ protected function setCommonAttributes(array $attrs) } /** - * Assemble classes - * + * Assemble classes + * * @param array $classes Classes - * + * * @return array */ protected function assembleClasses(array $classes) @@ -335,8 +335,8 @@ protected function assembleClasses(array $classes) } /** - * Assemble validation rules - * + * Assemble validation rules + * * @return array */ protected function assembleValidationRules() @@ -399,6 +399,7 @@ protected function getAttributesCode() /** * Some JavaScript code to insert * + * @todo Remove it. Use getFormFieldJSData method instead. * @return string */ protected function getInlineJSCode() @@ -563,8 +564,8 @@ protected function isVisible() } /** - * Get default wrapper class - * + * Get default wrapper class + * * @return string */ protected function getDefaultWrapperClass() @@ -576,8 +577,8 @@ protected function getDefaultWrapperClass() } /** - * Get label container class - * + * Get label container class + * * @return string */ protected function getLabelContainerClass() @@ -586,12 +587,22 @@ protected function getLabelContainerClass() } /** - * Get value container class - * + * Get value container class + * * @return string */ protected function getValueContainerClass() { return 'table-value ' . $this->getFieldId() . '-value'; } + + /** + * Return some data for JS external scripts if it is needed. + * + * @return null|array + */ + protected function getFormFieldJSData() + { + return null; + } } diff --git a/src/classes/XLite/View/FormField/Select/Country.php b/src/classes/XLite/View/FormField/Select/Country.php index bb26fd89dc..f3ff73e4cb 100644 --- a/src/classes/XLite/View/FormField/Select/Country.php +++ b/src/classes/XLite/View/FormField/Select/Country.php @@ -147,17 +147,29 @@ protected function getDefaultValue() } /** - * Some JavaScript code to insert + * Return some data for JS external scripts if it is needed. + * + * @return null|array + */ + protected function getFormFieldJSData() + { + return array( + 'statesList' => \XLite\Core\Database::getRepo('XLite\Model\Country')->findCountriesStates(), + 'stateSelectors' => array( + 'fieldId' => $this->getFieldId(), + 'stateSelectorId' => $this->getParam(self::PARAM_STATE_SELECTOR_ID), + 'stateInputId' => $this->getParam(self::PARAM_STATE_INPUT_ID), + ), + ); + } + + /** + * Get value container class * * @return string */ - protected function getInlineJSCode() + protected function getValueContainerClass() { - return $this->getWidget(array(), '\XLite\View\JS\StatesList')->getContent() . PHP_EOL - . 'jQuery(document).ready(function() { ' . PHP_EOL - . 'stateSelectors[\'' . $this->getFieldId() . '\'] = new StateSelector(' . PHP_EOL - . '\'' . $this->getFieldId() . '\', ' - . '\'' . $this->getParam(self::PARAM_STATE_SELECTOR_ID) . '\', ' - . '\'' . $this->getParam(self::PARAM_STATE_INPUT_ID) . '\'); });' . PHP_EOL; + return parent::getValueContainerClass() . ' country-selector'; } } diff --git a/src/classes/XLite/View/JS/AJS.php b/src/classes/XLite/View/JS/AJS.php deleted file mode 100644 index f21566721c..0000000000 --- a/src/classes/XLite/View/JS/AJS.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - */ - -namespace XLite\View\JS; - -/** - * \XLite\View\JS\AJS - * - */ -abstract class AJS extends \XLite\View\AView -{ -} diff --git a/src/classes/XLite/View/JS/StatesList.php b/src/classes/XLite/View/JS/StatesList.php deleted file mode 100644 index 9902630092..0000000000 --- a/src/classes/XLite/View/JS/StatesList.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - */ - -namespace XLite\View\JS; - -/** - * \XLite\View\JS\StatesList - * - */ -class StatesList extends \XLite\View\JS\AJS -{ - /** - * getCountriesStates - * - * @return array - */ - protected function getCountriesStates() - { - return \XLite\Core\Database::getRepo('XLite\Model\Country')->findCountriesStates(); - } - - /** - * Return widget default template - * - * @return string - */ - protected function getDefaultTemplate() - { - return 'js/states_list.tpl'; - } -} diff --git a/src/skins/admin/en/button/js/add_address.js b/src/skins/admin/en/button/js/add_address.js index bb82bd8c63..4ec3e10e16 100644 --- a/src/skins/admin/en/button/js/add_address.js +++ b/src/skins/admin/en/button/js/add_address.js @@ -24,6 +24,7 @@ decorate( function (selector) { // Some autoloading could be added + UpdateStatesList(); } ); diff --git a/src/skins/admin/en/button/js/modify_address.js b/src/skins/admin/en/button/js/modify_address.js index 9bbfd7c44f..264c85293b 100644 --- a/src/skins/admin/en/button/js/modify_address.js +++ b/src/skins/admin/en/button/js/modify_address.js @@ -24,6 +24,7 @@ decorate( function (selector) { // Some autoloading could be added + UpdateStatesList(); } ); diff --git a/src/skins/admin/en/form_field.tpl b/src/skins/admin/en/form_field.tpl index c9c7c20f8c..05c285851c 100644 --- a/src/skins/admin/en/form_field.tpl +++ b/src/skins/admin/en/form_field.tpl @@ -24,6 +24,7 @@
      {t(getParam(#comment#)):r}
      + {if:getFormFieldJSData()}{displayCommentedData(getFormFieldJSData())}{end:} diff --git a/src/skins/admin/en/form_field/select_country.js b/src/skins/admin/en/form_field/select_country.js index cbd50d524b..68de1c59d7 100644 --- a/src/skins/admin/en/form_field/select_country.js +++ b/src/skins/admin/en/form_field/select_country.js @@ -9,9 +9,6 @@ * @link http://www.litecommerce.com/ */ -var statesList = []; -var stateSelectors = []; - function StateSelector(countrySelectorId, stateSelectorId, stateInputId) { var o = this; @@ -135,11 +132,13 @@ StateSelector.prototype.addStates = function(states) var s = this.stateSelectBox.get(0); var added = s.options.length; + var i = 0; if (states) { - for (var i = 0; i < states.length; i++) { - s.options[i + added] = new Option(states[i].state, states[i].id); - } + for (var key in states) { + s.options[i + added] = new Option(states[key], key); + i++; + } } if (this.stateSavedValue) { @@ -147,3 +146,7 @@ StateSelector.prototype.addStates = function(states) } } } + +jQuery(document).ready(function () { + UpdateStatesList(); +}); diff --git a/src/skins/admin/en/js/states_list.tpl b/src/skins/admin/en/js/states_list.tpl deleted file mode 100644 index 5c4395c9ed..0000000000 --- a/src/skins/admin/en/js/states_list.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * States lsit controller - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - *} -{foreach:getCountriesStates(),countryCode,data} - {if:data} - statesList['{countryCode}'] = []; - {foreach:data,stateId,state} - statesList['{countryCode}'][statesList['{countryCode}'].length] = { id: '{stateId}', state: '{state}' } - {end:} - {end:} -{end:} diff --git a/src/skins/common/js/common.js b/src/skins/common/js/common.js index a10e21d280..e8580ce133 100644 --- a/src/skins/common/js/common.js +++ b/src/skins/common/js/common.js @@ -503,6 +503,25 @@ function attachTooltip(elm, content) { ); } +/** + * State widget specific objects and methods (used in select_country.js ) + * @TODO : Move it to the one object after dynamic loading widgets JS implementation + */ var statesList = []; var stateSelectors = []; +function UpdateStatesList() +{ + var _stateSelectors; + + jQuery('.country-selector').each(function (index, elem) { + statesList = array_merge(statesList, core.getCommentedData(elem, 'statesList')); + _stateSelectors = core.getCommentedData(elem, 'stateSelectors'); + + stateSelectors[_stateSelectors.fieldId] = new StateSelector( + _stateSelectors.fieldId, + _stateSelectors.stateSelectorId, + _stateSelectors.stateInputId + ); + }); +} diff --git a/src/skins/common/js/php.js b/src/skins/common/js/php.js index 30419eca1c..78bf5888fe 100644 --- a/src/skins/common/js/php.js +++ b/src/skins/common/js/php.js @@ -527,3 +527,69 @@ function str_replace (search, replace, subject, count) { return sa ? s : s[0]; } +function array_merge () { + // Merges elements from passed arrays into one array + // + // version: 1109.2015 + // discuss at: http://phpjs.org/functions/array_merge + // + original by: Brett Zamir (http://brett-zamir.me) + // + bugfixed by: Nate + // + input by: josh + // + bugfixed by: Brett Zamir (http://brett-zamir.me) + // * example 1: arr1 = {"color": "red", 0: 2, 1: 4} + // * example 1: arr2 = {0: "a", 1: "b", "color": "green", "shape": "trapezoid", 2: 4} + // * example 1: array_merge(arr1, arr2) + // * returns 1: {"color": "green", 0: 2, 1: 4, 2: "a", 3: "b", "shape": "trapezoid", 4: 4} + // * example 2: arr1 = [] + // * example 2: arr2 = {1: "data"} + // * example 2: array_merge(arr1, arr2) + // * returns 2: {0: "data"} + var args = Array.prototype.slice.call(arguments), + argl = args.length, + arg, + retObj = {}, + k = '', + argil = 0, + j = 0, + i = 0, + ct = 0, + toStr = Object.prototype.toString, + retArr = true; + + for (i = 0; i < argl; i++) { + if (toStr.call(args[i]) !== '[object Array]') { + retArr = false; + break; + } + } + + if (retArr) { + retArr = []; + for (i = 0; i < argl; i++) { + retArr = retArr.concat(args[i]); + } + return retArr; + } + + for (i = 0, ct = 0; i < argl; i++) { + arg = args[i]; + if (toStr.call(arg) === '[object Array]') { + for (j = 0, argil = arg.length; j < argil; j++) { + retObj[ct++] = arg[j]; + } + } + else { + for (k in arg) { + if (arg.hasOwnProperty(k)) { + if (parseInt(k, 10) + '' === k) { + retObj[ct++] = arg[k]; + } + else { + retObj[k] = arg[k]; + } + } + } + } + } + return retObj; +} diff --git a/src/skins/default/en/button/js/add_address.js b/src/skins/default/en/button/js/add_address.js index bb82bd8c63..4ec3e10e16 100644 --- a/src/skins/default/en/button/js/add_address.js +++ b/src/skins/default/en/button/js/add_address.js @@ -24,6 +24,7 @@ decorate( function (selector) { // Some autoloading could be added + UpdateStatesList(); } ); diff --git a/src/skins/default/en/button/js/modify_address.js b/src/skins/default/en/button/js/modify_address.js index 6946f75b84..af9981e374 100644 --- a/src/skins/default/en/button/js/modify_address.js +++ b/src/skins/default/en/button/js/modify_address.js @@ -24,6 +24,7 @@ decorate( function (selector) { // Some autoloading could be added + UpdateStatesList(); } ); diff --git a/src/skins/default/en/checkout/controller.js b/src/skins/default/en/checkout/controller.js index 2426c54a3b..1800e19727 100644 --- a/src/skins/default/en/checkout/controller.js +++ b/src/skins/default/en/checkout/controller.js @@ -442,6 +442,8 @@ CheckoutView.prototype.postprocess = function(isSuccess, initial) } ); + UpdateStatesList(); + // Refresh state this.refreshState(); } @@ -890,6 +892,10 @@ BillingAddressView.prototype.postprocess = function(isSuccess, initial) if (!initial) { this.parentWidget.refreshState(); } + + if (this.parentWidget) { + UpdateStatesList(); + } } } diff --git a/src/skins/default/en/form_field.tpl b/src/skins/default/en/form_field.tpl index e7e3ff4161..d0862565b5 100644 --- a/src/skins/default/en/form_field.tpl +++ b/src/skins/default/en/form_field.tpl @@ -10,7 +10,7 @@ *} {if:!getParam(#fieldOnly#)} -
      +
      @@ -18,10 +18,11 @@
      {end:} -
      +
      {t(getParam(#comment#)):r}
      + {if:getFormFieldJSData()}{displayCommentedData(getFormFieldJSData())}{end:}
      diff --git a/src/skins/default/en/form_field/select_country.js b/src/skins/default/en/form_field/select_country.js index 96db064508..98104b6435 100644 --- a/src/skins/default/en/form_field/select_country.js +++ b/src/skins/default/en/form_field/select_country.js @@ -110,12 +110,19 @@ StateSelector.prototype.addStates = function(states) var s = this.stateSelectBox.get(0); var added = s.options.length; + var i = 0; if (states) { - for (var i = 0; i < states.length; i++) { - s.options[i + added] = new Option(states[i].state, states[i].id); + for (var key in states) { + s.options[i + added] = new Option(states[key], key); + i++; } } this.stateSelectBox.val(this.stateSavedValue); } + +jQuery(document).ready(function () { + UpdateStatesList(); +}); + diff --git a/src/skins/default/en/js/states_list.tpl b/src/skins/default/en/js/states_list.tpl deleted file mode 100644 index 9c53594c6b..0000000000 --- a/src/skins/default/en/js/states_list.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{* vim: set ts=2 sw=2 sts=2 et: *} - -{** - * ____file_title____ - * - * @author Creative Development LLC - * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link http://www.litecommerce.com/ - *} -{foreach:getCountriesStates(),countryCode,data} - {if:data} - statesList['{countryCode}'] = []; - {foreach:data,stateId,state} - statesList['{countryCode}'][statesList['{countryCode}'].length] = { id: '{stateId}', state: '{state}' } - {end:} - {end:} -{end:} From 9a903daab5d8fca5ca9e718412820900a9cc0abf Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Mon, 8 Oct 2012 15:16:17 +0400 Subject: [PATCH 23/85] [*] Address field feature changes for Estimate shipping. [*] Changes for non-additional fields: it is impossible now to change "Service name" for non-additional fields. --- .../View/ItemsList/Model/Address/Fields.php | 34 ++++++++++++++++++- src/classes/XLite/View/ShippingEstimate.php | 15 ++++++++ src/skins/admin/en/address/field/style.css | 5 +-- .../parts/address.country.tpl | 2 +- .../parts/address.state.tpl | 2 +- .../parts/address.zipcode.tpl | 2 +- 6 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php index 9a5a405f09..f78868e2c3 100644 --- a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php +++ b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php @@ -47,6 +47,7 @@ protected function defineColumns() 'serviceName' => array( static::COLUMN_NAME => static::t('Service name'), static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text', + static::COLUMN_TEMPLATE => 'items_list/model/table/field.tpl', static::COLUMN_PARAMS => array('required' => true), ), 'required' => array( @@ -172,6 +173,37 @@ protected function getEmptyListDir() */ protected function isAllowEntityRemove(\XLite\Model\AEntity $entity) { - return $entity->getAdditional() && parent::isAllowEntityRemove($entity); + return parent::isAllowEntityRemove($entity) && $entity->getAdditional(); + } + + /** + * Check if the column template is used for widget displaying + * + * @param array $column + * @param \XLite\Model\AEntity $entity + * + * @return boolean + */ + protected function isTemplateColumnVisible(array $column, \XLite\Model\AddresField $entity) + { + return 'serviceName' !== $column[static::COLUMN_CODE] + ? parent::isTemplateColumnVisible($column, $entity) + : !$entity->getAdditional(); + } + + + /** + * Check if the simple class is used for widget displaying + * + * @param array $column + * @param \XLite\Model\AEntity $entity + * + * @return boolean + */ + protected function isClassColumnVisible(array $column, \XLite\Model\AddresField $entity) + { + return 'serviceName' !== $column[static::COLUMN_CODE] + ? parent::isClassColumnVisible($column, $entity) + : $entity->getAdditional(); } } diff --git a/src/classes/XLite/View/ShippingEstimate.php b/src/classes/XLite/View/ShippingEstimate.php index bd31889988..f651a583c8 100644 --- a/src/classes/XLite/View/ShippingEstimate.php +++ b/src/classes/XLite/View/ShippingEstimate.php @@ -79,6 +79,21 @@ protected function getCountries() ->findByEnabled(true); } + /** + * Check if the enabled address field with the given name exists + * + * @param string $fieldName + * + * @return boolean + */ + protected function hasField($fieldName) + { + return (bool) \XLite\Core\Database::getRepo('XLite\Model\AddressField')->findOneBy(array( + 'serviceName' => $fieldName, + 'enabled' => true, + )); + } + /** * Get selected country code * diff --git a/src/skins/admin/en/address/field/style.css b/src/skins/admin/en/address/field/style.css index 490d90e474..05498678e0 100644 --- a/src/skins/admin/en/address/field/style.css +++ b/src/skins/admin/en/address/field/style.css @@ -9,5 +9,6 @@ * @link http://www.litecommerce.com/ */ - - \ No newline at end of file +div.model-properties ul.table div.table-label label { + width: 180px; +} \ No newline at end of file diff --git a/src/skins/default/en/shopping_cart/shipping_estimator/parts/address.country.tpl b/src/skins/default/en/shopping_cart/shipping_estimator/parts/address.country.tpl index 4a25d44c8f..61171ff9cb 100644 --- a/src/skins/default/en/shopping_cart/shipping_estimator/parts/address.country.tpl +++ b/src/skins/default/en/shopping_cart/shipping_estimator/parts/address.country.tpl @@ -10,7 +10,7 @@ * * @ListChild (list="shippingEstimator.address", weight="10") *} -
    • +
    • diff --git a/src/skins/default/en/shopping_cart/shipping_estimator/parts/address.state.tpl b/src/skins/default/en/shopping_cart/shipping_estimator/parts/address.state.tpl index 7f3ab54ff4..b1e8e03480 100644 --- a/src/skins/default/en/shopping_cart/shipping_estimator/parts/address.state.tpl +++ b/src/skins/default/en/shopping_cart/shipping_estimator/parts/address.state.tpl @@ -10,7 +10,7 @@ * * @ListChild (list="shippingEstimator.address", weight="20") *} -
    • +
    • diff --git a/src/skins/default/en/shopping_cart/shipping_estimator/parts/address.zipcode.tpl b/src/skins/default/en/shopping_cart/shipping_estimator/parts/address.zipcode.tpl index 1d1d82e300..5251190386 100644 --- a/src/skins/default/en/shopping_cart/shipping_estimator/parts/address.zipcode.tpl +++ b/src/skins/default/en/shopping_cart/shipping_estimator/parts/address.zipcode.tpl @@ -10,7 +10,7 @@ * * @ListChild (list="shippingEstimator.address", weight="30") *} -
    • +
    • From f86b2e6f58cf8fd01bb3a84b27025256dfd889b9 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Tue, 9 Oct 2012 11:41:20 +0400 Subject: [PATCH 24/85] [+] Upgrade hook is added for profile address fields feature changes. [*] Small code changes and refactoring. --- src/classes/XLite/Model/Base/Address.php | 9 --- .../View/ItemsList/Model/Address/Fields.php | 4 +- .../XLite/View/Model/Address/Address.php | 10 ---- src/upgrade/1.1/2/post_rebuild.php | 59 +++++++++++++++++++ src/upgrade/1.1/2/post_rebuild.yaml | 9 +++ src/upgrade/1.1/2/pre_upgrade.php | 50 ++++++++++++++++ 6 files changed, 120 insertions(+), 21 deletions(-) create mode 100644 src/upgrade/1.1/2/post_rebuild.php create mode 100644 src/upgrade/1.1/2/post_rebuild.yaml create mode 100644 src/upgrade/1.1/2/pre_upgrade.php diff --git a/src/classes/XLite/Model/Base/Address.php b/src/classes/XLite/Model/Base/Address.php index 4de176ab52..0d4dbae3e7 100644 --- a/src/classes/XLite/Model/Base/Address.php +++ b/src/classes/XLite/Model/Base/Address.php @@ -63,15 +63,6 @@ abstract class Address extends \XLite\Model\AEntity */ protected $state; - /** - * Custom state - * - * @var string - * - * @Column (type="string", length=255) - */ - protected $custom_state = ''; - /** * Country * diff --git a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php index f78868e2c3..f9b7be4f02 100644 --- a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php +++ b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php @@ -184,7 +184,7 @@ protected function isAllowEntityRemove(\XLite\Model\AEntity $entity) * * @return boolean */ - protected function isTemplateColumnVisible(array $column, \XLite\Model\AddresField $entity) + protected function isTemplateColumnVisible(array $column, \XLite\Model\AEntity $entity) { return 'serviceName' !== $column[static::COLUMN_CODE] ? parent::isTemplateColumnVisible($column, $entity) @@ -200,7 +200,7 @@ protected function isTemplateColumnVisible(array $column, \XLite\Model\AddresFie * * @return boolean */ - protected function isClassColumnVisible(array $column, \XLite\Model\AddresField $entity) + protected function isClassColumnVisible(array $column, \XLite\Model\AEntity $entity) { return 'serviceName' !== $column[static::COLUMN_CODE] ? parent::isClassColumnVisible($column, $entity) diff --git a/src/classes/XLite/View/Model/Address/Address.php b/src/classes/XLite/View/Model/Address/Address.php index 81156f3870..e9a7dd2444 100644 --- a/src/classes/XLite/View/Model/Address/Address.php +++ b/src/classes/XLite/View/Model/Address/Address.php @@ -234,16 +234,6 @@ protected function getModelObjectValue($name) return parent::getModelObjectValue($name); } - /** - * Some JavaScript code to insert - * - * @return string - */ - protected function getTopInlineJSCode() - { - return $this->getWidget(array(), '\XLite\View\JS\StatesList')->getContent(); - } - /** * Return text for the "Submit" button * diff --git a/src/upgrade/1.1/2/post_rebuild.php b/src/upgrade/1.1/2/post_rebuild.php new file mode 100644 index 0000000000..8ab60700ef --- /dev/null +++ b/src/upgrade/1.1/2/post_rebuild.php @@ -0,0 +1,59 @@ + + * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +return function() +{ + // Loading data to the database from yaml file + $yamlFile = __DIR__ . LC_DS . 'post_rebuild.yaml'; + + if (\Includes\Utils\FileManager::isFileReadable($yamlFile)) { + \XLite\Core\Database::getInstance()->loadFixturesFromYaml($yamlFile); + } + + // Import profile addresses from the temporary YAML file storage + $yamlProfileStorageFile = __DIR__ . LC_DS . 'temporary.storage.profiles.yaml'; + + foreach (\Includes\Utils\Operator::loadServiceYAML($yamlProfileStorageFile) as $address) { + + $_address = array(); + $_address['profile'] = \XLite\Core\Database::getRepo('XLite\Model\Profile')->find($address['profile_id']); + + $address['country'] = \XLite\Core\Database::getRepo('XLite\Model\Country')->findOneByCode($address['country_code']); + $address['state'] = \XLite\Core\Database::getRepo('XLite\Model\State')->find($address['state_id']); + + unset($address['profile_id'], $address['state_id'], $address['country_code']); + + $entity = new \XLite\Model\Address($_address); + + $entity->create(); + + $entity->map($address); + + \XLite\Core\Database::getEM()->flush($entity); + } + + \Includes\Utils\FileManager::deleteFile($yamlProfileStorageFile); + +}; diff --git a/src/upgrade/1.1/2/post_rebuild.yaml b/src/upgrade/1.1/2/post_rebuild.yaml new file mode 100644 index 0000000000..9d5ae32842 --- /dev/null +++ b/src/upgrade/1.1/2/post_rebuild.yaml @@ -0,0 +1,9 @@ +# vim: set ts=2 sw=2 sts=2 et: +# +# Data for core upgrading 1.1.1 -> 1.1.2 +# +# @author Creative Development LLC +# @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved +# @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +# @link http://www.litecommerce.com/ + diff --git a/src/upgrade/1.1/2/pre_upgrade.php b/src/upgrade/1.1/2/pre_upgrade.php new file mode 100644 index 0000000000..520ca4cc62 --- /dev/null +++ b/src/upgrade/1.1/2/pre_upgrade.php @@ -0,0 +1,50 @@ + + * @copyright Copyright (c) 2011 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +return function() +{ + // Store the profiles into the temporary YAML file + \Includes\Utils\Operator::saveServiceYAML( + __DIR__ . LC_DS . 'temporary.storage.profiles.yaml', + array_map( + function ($address) { + return array( + 'profile_id' => $address->getProfile()->getProfileId(), + 'title' => $address->getTitle(), + 'firstname' => $address->getFirstname(), + 'lastname' => $address->getLastname(), + 'phone' => $address->getPhone(), + 'street' => $address->getStreet(), + 'city' => $address->getCity(), + 'state_id' => $address->getState()->getStateId(), + 'custom_state' => $address->getCustomState(), + 'country_code' => $address->getCountry()->getCode(), + 'zipcode' => $address->getZipcode(), + ); + }, + \XLite\Core\Database::getRepo('XLite\Model\Address')->findAll() + ) + ); +}; From dc315cf46d347dfcdfb21a6749c6661ae31d44d2 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Tue, 9 Oct 2012 14:41:35 +0400 Subject: [PATCH 25/85] [!] Bug: Log library was loaded several times. --- src/classes/XLite/Upgrade/Cell.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/classes/XLite/Upgrade/Cell.php b/src/classes/XLite/Upgrade/Cell.php index 103a1ea887..62fc1f2f21 100644 --- a/src/classes/XLite/Upgrade/Cell.php +++ b/src/classes/XLite/Upgrade/Cell.php @@ -667,8 +667,8 @@ public function upgrade($isTestMode = true, array $filesToOverwrite = array()) } /** - * Preload libraries - * + * Preload libraries + * * @return void */ protected function preloadLibraries() @@ -677,8 +677,11 @@ protected function preloadLibraries() $dirIterator = new \RecursiveDirectoryIterator(LC_DIR_LIB); $iterator = new \RecursiveIteratorIterator($dirIterator, \RecursiveIteratorIterator::CHILD_FIRST); + $logLibDir = LC_DIR_LIB . 'Log' . LC_DS; + foreach ($iterator as $filePath => $fileObject) { - if (preg_match('/\.php$/Ss', $filePath)) { + if (preg_match('/\.php$/Ss', $filePath) && (false === stristr($filePath, $logLibDir))) { + require_once $filePath; } } From b3a48d00dc6e03dfae209aef78caeb463af9b1ce Mon Sep 17 00:00:00 2001 From: skiv Date: Thu, 11 Oct 2012 14:40:12 +0400 Subject: [PATCH 26/85] Attributes --- src/classes/XLite/View/ItemsList/Model/Attribute.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/XLite/View/ItemsList/Model/Attribute.php b/src/classes/XLite/View/ItemsList/Model/Attribute.php index f08b829571..c8888dccea 100644 --- a/src/classes/XLite/View/ItemsList/Model/Attribute.php +++ b/src/classes/XLite/View/ItemsList/Model/Attribute.php @@ -55,7 +55,7 @@ protected function defineColumns() 'type' => array( static::COLUMN_NAME => $this->getAttributeGroup() ? static::t( - '{{count}} attributes in group', + 'X attributes in group', array( 'count' => $this->getAttributeGroup()->getAttributesCount() ) From 490346741069dc53db9526a8ccaf443a58ca3ce6 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Thu, 11 Oct 2012 23:51:50 +0400 Subject: [PATCH 27/85] [*] Address fields refactoring. --- src/classes/XLite/Model/Address.php | 8 +++ src/classes/XLite/Model/Base/Address.php | 12 +---- src/classes/XLite/Model/Repo/AddressField.php | 20 +++++++ src/sql/demo/xlite_demo_orders.yaml | 4 +- src/sql/demo/xlite_demo_user.yaml | 54 ++++++++++++++++++- src/sql/demo/xlite_demo_user_admin.yaml | 33 +++++++++++- 6 files changed, 115 insertions(+), 16 deletions(-) diff --git a/src/classes/XLite/Model/Address.php b/src/classes/XLite/Model/Address.php index 1a830b5dc4..a6a9eb142b 100644 --- a/src/classes/XLite/Model/Address.php +++ b/src/classes/XLite/Model/Address.php @@ -47,6 +47,14 @@ class Address extends \XLite\Model\Base\PersonalAddress const SHIPPING = 's'; + /** + * Address fields collection + * + * @var \Doctrine\Common\Collections\ArrayCollection + * + * @OneToMany (targetEntity="XLite\Model\AddressFieldValue", mappedBy="address", cascade={"all"}) + */ + protected $addressFields; /** * Flag: is it a billing address diff --git a/src/classes/XLite/Model/Base/Address.php b/src/classes/XLite/Model/Base/Address.php index 0d4dbae3e7..4dc63d1bdd 100644 --- a/src/classes/XLite/Model/Base/Address.php +++ b/src/classes/XLite/Model/Base/Address.php @@ -120,6 +120,7 @@ public function getState() * @param mixed $state State object or state id or custom state name * * @return void + * @todo Refactor? */ public function setState($state) { @@ -129,25 +130,14 @@ public function setState($state) if ($state->getStateId()) { if (!$this->state || $this->state->getStateId() != $state->getStateId()) { $this->state = $state; - $this->setCustomState(''); } - } else { - $this->state = null; - - if ($state->getState()) { - $this->setCustomState($state->getState()); - } } - } elseif (is_string($state)) { - // Set custom state $this->state = null; - $this->setCustomState($state); - } } diff --git a/src/classes/XLite/Model/Repo/AddressField.php b/src/classes/XLite/Model/Repo/AddressField.php index 273f177583..50c5bb967d 100644 --- a/src/classes/XLite/Model/Repo/AddressField.php +++ b/src/classes/XLite/Model/Repo/AddressField.php @@ -107,6 +107,26 @@ public function findAllEnabled() return $this->search(new \XLite\Core\CommonCell(array('enabled' => true))); } + /** + * Find one by record + * + * @param array $data Record + * @param \XLite\Model\AEntity $parent Parent model OPTIONAL + * + * @return \XLite\Model\AEntity + */ + public function findOneByRecord(array $data, \XLite\Model\AEntity $parent = null) + { + if (isset($data['serviceName'])) { + $result = $this->findOneByServiceName($data['serviceName']); + + } else { + $result = parent::findOneByRecord($data, $parent); + } + + return $result; + } + /** * Return list of handling search params * diff --git a/src/sql/demo/xlite_demo_orders.yaml b/src/sql/demo/xlite_demo_orders.yaml index a51d139da4..90a30b939e 100644 --- a/src/sql/demo/xlite_demo_orders.yaml +++ b/src/sql/demo/xlite_demo_orders.yaml @@ -8,7 +8,7 @@ # @link http://www.litecommerce.com/ XLite\Model\Order: - - profile: { login: rnd_tester@rrf.ru, password: 084e0343a0486ff05530df6c705c8bb4, access_level: 0, status: E, cms_profile_id: 0, addresses: [{ is_billing: true, is_shipping: true, title: Mr., firstname: Admin, lastname: Admin, phone: '0123456789', street: '51 apt, 87 street', city: Edmond, state: { country_code: US, code: OK }, country: { code: US }, zipcode: '73003' }] } + - profile: { login: rnd_tester@rrf.ru, cms_profile_id: 0 } orig_profile: { login: rnd_tester@rrf.ru } total: 20.7599 subtotal: 17.99 @@ -37,7 +37,7 @@ XLite\Model\Order: description: Order placed - code: TRANSACTION description: "Payment transaction [method: Money Ordering, type: sale, amount: 17.99, status: Pending]" - - profile: { login: rnd_tester@rrf.ru, password: 084e0343a0486ff05530df6c705c8bb4, access_level: 0, status: E, cms_profile_id: 0, addresses: [{ is_billing: true, is_shipping: true, title: Mr., firstname: Admin, lastname: Admin, phone: '0123456789', street: '51 apt, 87 street', city: Edmond, state: { country_code: US, code: OK }, country: { code: US }, zipcode: '73003' }] } + - profile: { login: rnd_tester@rrf.ru, cms_profile_id: 0 } orig_profile: { login: rnd_tester@rrf.ru } total: 121.1137 subtotal: 116.91 diff --git a/src/sql/demo/xlite_demo_user.yaml b/src/sql/demo/xlite_demo_user.yaml index 910a892e87..82385fbf85 100644 --- a/src/sql/demo/xlite_demo_user.yaml +++ b/src/sql/demo/xlite_demo_user.yaml @@ -8,5 +8,55 @@ # @link http://www.litecommerce.com/ XLite\Model\Profile: -# - { login: rnd_tester@cdev.ru, password: eb0a191797624dd3a48fa681d3061212, access_level: 100, status: E, cms_profile_id: 1, cms_name: ____DRUPAL____, addresses: [{ is_billing: true, is_shipping: true, title: Mr., firstname: Admin, lastname: Admin, phone: '0123456789', street: '51 apt, 87 street', city: Edmond, state: { country_code: US, code: OK }, country: { code: US }, zipcode: '73003' }] } - - { login: rnd_tester@rrf.ru, password: 084e0343a0486ff05530df6c705c8bb4, status: E, cms_profile_id: 0, addresses: [{ is_billing: true, is_shipping: false, title: Mr., firstname: Guest, lastname: Guest, phone: '0123456789', street: '51 apt, 87 street', city: Edmond, state: { country_code: US, code: OK }, country: { code: US }, zipcode: '73003' }, { is_billing: false, is_shipping: true, title: Mr., firstname: Guest, lastname: Guest, phone: '9876543210', street: '12 apt, 34 street', city: 'New York', state: { country_code: US, code: OK }, country: { code: US }, zipcode: '10001' }] } + - login: rnd_tester@rrf.ru + password: 084e0343a0486ff05530df6c705c8bb4 + status: E + cms_profile_id: 0 + addresses: + - is_billing: true + is_shipping: false + state: { country_code: US, code: OK } + country: { code: US } + addressFields : + - addressField: { serviceName: title } + value : 'Mr.' + - addressField: { serviceName: firstname } + value: Guest + - addressField: { serviceName: lastname } + value: Guest + - addressField: { serviceName: phone } + value: '0123456789' + - addressField: { serviceName: street } + value: '51 apt, 87 street' + - addressField: { serviceName: city } + value: Edmond + - addressField: { serviceName: state_id } + value: 185 + - addressField: { serviceName: country_code } + value: US + - addressField: { serviceName: zipcode } + value: '73003' + - is_billing: false + is_shipping: true + state: { country_code: US, code: OK } + country: { code: US } + addressFields : + - addressField: { serviceName: title } + value : 'Mr.' + - addressField: { serviceName: firstname } + value: Guest + - addressField: { serviceName: lastname } + value: Guest + - addressField: { serviceName: phone } + value: '9876543210' + - addressField: { serviceName: street } + value: '12 apt, 34 street' + - addressField: { serviceName: city } + value: 'New York' + - addressField: { serviceName: state_id } + value: 185 + - addressField: { serviceName: country_code } + value: US + - addressField: { serviceName: zipcode } + value: '10001' + diff --git a/src/sql/demo/xlite_demo_user_admin.yaml b/src/sql/demo/xlite_demo_user_admin.yaml index ae6af813b5..24b95963c8 100644 --- a/src/sql/demo/xlite_demo_user_admin.yaml +++ b/src/sql/demo/xlite_demo_user_admin.yaml @@ -8,4 +8,35 @@ # @link http://www.litecommerce.com/ XLite\Model\Profile: - - { login: rnd_tester@cdev.ru, password: eb0a191797624dd3a48fa681d3061212, access_level: 100, status: E, cms_profile_id: 1, cms_name: ____DRUPAL____, addresses: [{ is_billing: true, is_shipping: true, title: Mr., firstname: Admin, lastname: Admin, phone: '0123456789', street: '51 apt, 87 street', city: Edmond, state: { country_code: US, code: OK }, country: { code: US }, zipcode: '73003' }], roles: [{ translations: [{ name: Administrator }] }] } + - login: rnd_tester@cdev.ru + password: eb0a191797624dd3a48fa681d3061212 + access_level: 100 + status: E + cms_profile_id: 1 + cms_name: ____DRUPAL____ + roles: [{ translations: [{ name: Administrator }] }] + addresses: + - is_billing: true + is_shipping: true + state: { country_code: US, code: OK } + country: { code: US } + addressFields : + - addressField: { serviceName: title } + value : 'Mr.' + - addressField: { serviceName: firstname } + value: Admin + - addressField: { serviceName: lastname } + value: Admin + - addressField: { serviceName: phone } + value: '0123456789' + - addressField: { serviceName: street } + value: '51 apt, 87 street' + - addressField: { serviceName: city } + value: Edmond + - addressField: { serviceName: state_id } + value: 185 + - addressField: { serviceName: country_code } + value: US + - addressField: { serviceName: zipcode } + value: '73003' + From 8553e8ac4d627741d837d867ea49f8fc1003fbc3 Mon Sep 17 00:00:00 2001 From: skiv Date: Mon, 15 Oct 2012 10:42:57 +0400 Subject: [PATCH 28/85] Attributes --- .../XLite/View/FormField/Select/AttributeGroups.php | 2 +- src/skins/admin/en/attributes/style.css | 9 +++++++++ .../en/form_field/inline/input/text/product-class.tpl | 2 +- src/sql/xlite_data.yaml | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/classes/XLite/View/FormField/Select/AttributeGroups.php b/src/classes/XLite/View/FormField/Select/AttributeGroups.php index fcb6d9716e..dadf0bc249 100644 --- a/src/classes/XLite/View/FormField/Select/AttributeGroups.php +++ b/src/classes/XLite/View/FormField/Select/AttributeGroups.php @@ -45,7 +45,7 @@ protected function getAttributeGroupsList() } foreach (\XLite\Core\Database::getRepo('\XLite\Model\AttributeGroup')->search($cnd) as $e) { - $list[$e->getId()] = $e->getName(); + $list[$e->getId()] = htmlspecialchars($e->getName()); } return $list; diff --git a/src/skins/admin/en/attributes/style.css b/src/skins/admin/en/attributes/style.css index c588d8032c..4f5f7087c9 100644 --- a/src/skins/admin/en/attributes/style.css +++ b/src/skins/admin/en/attributes/style.css @@ -171,6 +171,7 @@ div.group table.list th.actions.left { border-radius: 0; display: none; margin: 0 5px 0 0; + height: 26px; } .edit-mark .edit-attribute { display: inline; @@ -222,6 +223,10 @@ div.group table.list th.actions.left { font-size: 12px; } +.ajax-container-loadable div.table-value .input-field-wrapper { + float: left; +} + .ajax-container-loadable .star { display: none; } @@ -245,6 +250,10 @@ div.group table.list th.actions.left { float: left; } +.ajax-container-loadable li.edit-unit { + left: 180px; +} + .ajax-container-loadable div.note { color: #456583; text-align: center; diff --git a/src/skins/admin/en/form_field/inline/input/text/product-class.tpl b/src/skins/admin/en/form_field/inline/input/text/product-class.tpl index 5e49ab35d0..8cb033d9c4 100644 --- a/src/skins/admin/en/form_field/inline/input/text/product-class.tpl +++ b/src/skins/admin/en/form_field/inline/input/text/product-class.tpl @@ -9,5 +9,5 @@ * @link http://www.litecommerce.com/ *} -{getViewValue(singleField):h} +{getViewValue(singleField)} ({entity.getProductsCount()} {t(#products#)}) diff --git a/src/sql/xlite_data.yaml b/src/sql/xlite_data.yaml index 5a851a215a..d6b9181fd2 100644 --- a/src/sql/xlite_data.yaml +++ b/src/sql/xlite_data.yaml @@ -491,7 +491,7 @@ XLite\Model\LanguageLabel: - { name: 'Payment method has been enabled successfully', translations: [{ code: en, label: 'Payment method has been enabled successfully' }] } - { name: 'Payment method has been disabled successfully', translations: [{ code: en, label: 'Payment method has been disabled successfully' }] } - { name: 'Payment method has been removed successfully', translations: [{ code: en, label: 'Payment method has been removed successfully' }] } - - { name: 'Attributes for X product clas', translations: [{ code: en, label: 'Attributes for "{{class}}" product class' }] } + - { name: 'Attributes for X product class', translations: [{ code: en, label: 'Attributes for "{{class}}" product class' }] } - { name: 'X attributes in group', translations: [{ code: en, label: '{{count}} attributes in group' }] } XLite\Model\Membership: directives: { insert: true } From 727869e36c3002af22ce8ee1b2fba4379b51ccbe Mon Sep 17 00:00:00 2001 From: skiv Date: Mon, 15 Oct 2012 16:00:25 +0400 Subject: [PATCH 29/85] Attributes --- src/classes/XLite/Model/Repo/ProductClass.php | 10 ++++++---- src/skins/admin/en/attributes/style.css | 11 ++++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/classes/XLite/Model/Repo/ProductClass.php b/src/classes/XLite/Model/Repo/ProductClass.php index c82a7245be..c6f9dbb076 100644 --- a/src/classes/XLite/Model/Repo/ProductClass.php +++ b/src/classes/XLite/Model/Repo/ProductClass.php @@ -38,18 +38,20 @@ class ProductClass extends \XLite\Model\Repo\Base\I18n /** * Common search * - * @param \XLite\Core\CommonCell $cnd Search condition + * @param \XLite\Core\CommonCell $cnd Search condition OPTIONAL * @param boolean $countOnly Return items list or only its size OPTIONAL * * @return \Doctrine\ORM\PersistentCollection|integer */ - public function search(\XLite\Core\CommonCell $cnd, $countOnly = false) + public function search(\XLite\Core\CommonCell $cnd = null, $countOnly = false) { $queryBuilder = $this->createQueryBuilder('p'); $this->currentSearchCnd = $cnd; - foreach ($this->currentSearchCnd as $key => $value) { - $this->callSearchConditionHandler($value, $key, $queryBuilder, $countOnly); + if ($this->currentSearchCnd) { + foreach ($this->currentSearchCnd as $key => $value) { + $this->callSearchConditionHandler($value, $key, $queryBuilder, $countOnly); + } } return $countOnly diff --git a/src/skins/admin/en/attributes/style.css b/src/skins/admin/en/attributes/style.css index 4f5f7087c9..2050224884 100644 --- a/src/skins/admin/en/attributes/style.css +++ b/src/skins/admin/en/attributes/style.css @@ -284,6 +284,15 @@ div.group table.list th.actions.left { font-size: 14px; } -.ajax-container-loadable .main .view { +.ajax-container-loadable .items-list-table table.list tbody td.main .attributeoption-name .view { + max-width: 300px; +} + +.ajax-container-loadable .items-list-table table.list tbody td.main .view { position: relative; + max-width: 350px; +} + +.items-list-table table.list tbody td.main .view { + max-width: 500px; } From 9ac0bb1f46fb29f3fa0a98068fb2a9c312e6b71b Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Mon, 15 Oct 2012 16:07:07 +0400 Subject: [PATCH 30/85] [*] Address fields changes on the order pages. --- src/classes/XLite/Model/AddressField.php | 11 ++++ src/classes/XLite/View/AView.php | 2 +- .../invoice/parts/bottom.address.billing.tpl | 19 +++--- .../invoice/parts/bottom.address.shipping.tpl | 18 +++--- src/skins/admin/en/order/invoice/style.css | 50 +++++++++++++++- src/skins/admin/en/order/page/info.css | 1 + .../invoice/parts/bottom.address.billing.tpl | 20 +++---- .../invoice/parts/bottom.address.shipping.tpl | 19 +++--- src/skins/default/en/order/invoice/style.css | 58 +++++++++++++++++++ .../invoice/parts/bottom.address.billing.tpl | 19 +++--- .../invoice/parts/bottom.address.shipping.tpl | 18 +++--- src/skins/mail/en/order/invoice/style.css | 48 +++++++++++++++ 12 files changed, 210 insertions(+), 73 deletions(-) create mode 100644 src/skins/default/en/order/invoice/style.css diff --git a/src/classes/XLite/Model/AddressField.php b/src/classes/XLite/Model/AddressField.php index 8897f54e57..6bf6f166aa 100644 --- a/src/classes/XLite/Model/AddressField.php +++ b/src/classes/XLite/Model/AddressField.php @@ -124,4 +124,15 @@ class AddressField extends \XLite\Model\Base\I18n */ protected $position = 0; + + /** + * Return CSS classes for this field name entry + * + * @return string + */ + public function getCSSFieldName() + { + return 'address-' . $this->getServiceName() . ($this->getAdditional() ? ' field-additional' : ''); + } + } diff --git a/src/classes/XLite/View/AView.php b/src/classes/XLite/View/AView.php index 4f728c3a98..e8f58cb2e6 100644 --- a/src/classes/XLite/View/AView.php +++ b/src/classes/XLite/View/AView.php @@ -1857,7 +1857,7 @@ protected function getAddressSectionData(\XLite\Model\Address $address) if ($addressFieldValue) { $result[$field->getServiceName()] = array( - 'css_class' => 'address-' . $field->getServiceName(), + 'css_class' => $field->getCSSFieldName(), 'title' => $field->getName(), 'value' => $addressFieldValue, ); diff --git a/src/skins/admin/en/order/invoice/parts/bottom.address.billing.tpl b/src/skins/admin/en/order/invoice/parts/bottom.address.billing.tpl index 6786323c56..31b9126f13 100644 --- a/src/skins/admin/en/order/invoice/parts/bottom.address.billing.tpl +++ b/src/skins/admin/en/order/invoice/parts/bottom.address.billing.tpl @@ -12,19 +12,14 @@ *} {t(#Billing address#)} -

      - {order.profile.billing_address.title} {order.profile.billing_address.firstname} {order.profile.billing_address.lastname} -

      - -

      - {order.profile.billing_address.street}
      - {order.profile.billing_address.city}, {order.profile.billing_address.state.state}, {order.profile.billing_address.zipcode}
      - {order.profile.billing_address.country.country} -

      -

      - {t(#Phone#)}: {order.profile.billing_address.phone} -

      +
        +
      • + {t(field.title)}: + {field.value} + , +
      • +

      {t(#E-mail#)}: {order.profile.login} diff --git a/src/skins/admin/en/order/invoice/parts/bottom.address.shipping.tpl b/src/skins/admin/en/order/invoice/parts/bottom.address.shipping.tpl index a236824fee..6589e3b912 100644 --- a/src/skins/admin/en/order/invoice/parts/bottom.address.shipping.tpl +++ b/src/skins/admin/en/order/invoice/parts/bottom.address.shipping.tpl @@ -12,17 +12,13 @@ *} {t(#Shipping address#)} -

      - {order.profile.shipping_address.title} {order.profile.shipping_address.firstname} {order.profile.shipping_address.lastname} -

      -

      - {order.profile.shipping_address.street}
      - {order.profile.shipping_address.city}, {order.profile.shipping_address.state.state}, {order.profile.shipping_address.zipcode}
      - {order.profile.shipping_address.country.country} -

      +
        +
      • + {t(field.title)}: + {field.value} + , +
      • +
      -

      - {t(#Phone#)}: {order.profile.shipping_address.phone} -

      diff --git a/src/skins/admin/en/order/invoice/style.css b/src/skins/admin/en/order/invoice/style.css index 305e46f354..f7b4e7ceb8 100644 --- a/src/skins/admin/en/order/invoice/style.css +++ b/src/skins/admin/en/order/invoice/style.css @@ -258,9 +258,57 @@ text-align: center; } -.invoice-box .deleted-product-note +.invoice-box .deleted-product-note { color: #999; font-size: 12px; font-style: italic; } + + .addresses ul.address-section li { + background: none; + padding: 0px; + margin: 0px; + } + +.addresses ul.address-section { + padding-top: 12px; +} + +.addresses ul.address-section li.address-field { + padding-right: 4px; +} + +.addresses ul.address-section li.address-field.address-custom_state { + display: none; +} + +.addresses ul.address-section li.address-field span { + font-size: 14px; + line-height: 20px; + padding-top: 8px; +} + +ul.address-section li.address-field .address-title, + ul.address-section li.address-field .address-comma +{ + display: none; +} + +ul.address-section li.address-field.address-phone .address-title, + ul.address-section li.address-field.field-additional .address-title, + ul.address-section li.address-field.address-city .address-comma, + ul.address-section li.address-field.address-street .address-comma, + ul.address-section li.address-field.address-state .address-comma +{ + display: inline; +} + +ul.address-section li.address-field.address-title, + ul.address-section li.address-field.address-firstname, + ul.address-section li.address-field.address-city, + ul.address-section li.address-field.address-state +{ + float: left; +} + diff --git a/src/skins/admin/en/order/page/info.css b/src/skins/admin/en/order/page/info.css index 9907bbd013..2d4914b7c5 100644 --- a/src/skins/admin/en/order/page/info.css +++ b/src/skins/admin/en/order/page/info.css @@ -191,6 +191,7 @@ ul.address-section li.address-field .address-title, } ul.address-section li.address-field.address-phone .address-title, + ul.address-section li.address-field.field-additional .address-title, ul.address-section li.address-field.address-city .address-comma, ul.address-section li.address-field.address-street .address-comma, ul.address-section li.address-field.address-state .address-comma diff --git a/src/skins/default/en/order/invoice/parts/bottom.address.billing.tpl b/src/skins/default/en/order/invoice/parts/bottom.address.billing.tpl index 2e99cb49e3..ea0b08fd45 100644 --- a/src/skins/default/en/order/invoice/parts/bottom.address.billing.tpl +++ b/src/skins/default/en/order/invoice/parts/bottom.address.billing.tpl @@ -12,19 +12,13 @@ *} {t(#Billing address#)} -

      - {baddress.title} {baddress.firstname} {baddress.lastname} -

      - -

      - {baddress.street}
      - {baddress.city}, {baddress.state.state}, {baddress.zipcode}
      - {baddress.country.country} -

      - -

      - {t(#Phone#)}: {baddress.phone} -

      +
        +
      • + {t(field.title)}: + {field.value} + , +
      • +

      {t(#E-mail#)}: {order.profile.login} diff --git a/src/skins/default/en/order/invoice/parts/bottom.address.shipping.tpl b/src/skins/default/en/order/invoice/parts/bottom.address.shipping.tpl index 3c0a19ae9d..d1660e70ac 100644 --- a/src/skins/default/en/order/invoice/parts/bottom.address.shipping.tpl +++ b/src/skins/default/en/order/invoice/parts/bottom.address.shipping.tpl @@ -12,17 +12,12 @@ *} {t(#Shipping address#)} -

      - {saddress.title} {saddress.firstname} {saddress.lastname} -

      -

      - {saddress.street}
      - {saddress.city}, {saddress.state.state}, {saddress.zipcode}
      - {saddress.country.country} -

      - -

      - {t(#Phone#)}: {saddress.phone} -

      +
        +
      • + {t(field.title)}: + {field.value} + , +
      • +
      diff --git a/src/skins/default/en/order/invoice/style.css b/src/skins/default/en/order/invoice/style.css new file mode 100644 index 0000000000..07feba889e --- /dev/null +++ b/src/skins/default/en/order/invoice/style.css @@ -0,0 +1,58 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Invoice styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + + .addresses ul.address-section li { + background: none; + padding: 0px; + margin: 0px; + } + +.addresses ul.address-section { + padding-top: 12px; +} + +.addresses ul.address-section li.address-field { + padding-right: 4px; +} + +.addresses ul.address-section li.address-field.address-custom_state { + display: none; +} + +.addresses ul.address-section li.address-field span { + font-size: 14px; + line-height: 20px; + padding-top: 8px; +} + +ul.address-section li.address-field .address-title, + ul.address-section li.address-field .address-comma +{ + display: none; +} + +ul.address-section li.address-field.address-phone .address-title, + ul.address-section li.address-field.field-additional .address-title, + ul.address-section li.address-field.address-city .address-comma, + ul.address-section li.address-field.address-street .address-comma, + ul.address-section li.address-field.address-state .address-comma +{ + display: inline; +} + +ul.address-section li.address-field.address-title, + ul.address-section li.address-field.address-firstname, + ul.address-section li.address-field.address-city, + ul.address-section li.address-field.address-state +{ + float: left; +} + diff --git a/src/skins/mail/en/order/invoice/parts/bottom.address.billing.tpl b/src/skins/mail/en/order/invoice/parts/bottom.address.billing.tpl index b966a74949..d1ba772f96 100644 --- a/src/skins/mail/en/order/invoice/parts/bottom.address.billing.tpl +++ b/src/skins/mail/en/order/invoice/parts/bottom.address.billing.tpl @@ -12,19 +12,14 @@ *} {t(#Billing address#)} -

      - {order.profile.billing_address.title} {order.profile.billing_address.firstname:h} {order.profile.billing_address.lastname:h} -

      - -

      - {order.profile.billing_address.street:h}
      - {order.profile.billing_address.city:h}, {order.profile.billing_address.state.state:h}, {order.profile.billing_address.zipcode:h}
      - {order.profile.billing_address.country.country:h} -

      -

      - {t(#Phone#)}: {order.profile.billing_address.phone:h} -

      +
        +
      • + {t(field.title)}: + {field.value} + , +
      • +

      {t(#E-mail#)}: {order.profile.login:h} diff --git a/src/skins/mail/en/order/invoice/parts/bottom.address.shipping.tpl b/src/skins/mail/en/order/invoice/parts/bottom.address.shipping.tpl index ea309c8449..6589e3b912 100644 --- a/src/skins/mail/en/order/invoice/parts/bottom.address.shipping.tpl +++ b/src/skins/mail/en/order/invoice/parts/bottom.address.shipping.tpl @@ -12,17 +12,13 @@ *} {t(#Shipping address#)} -

      - {order.profile.shipping_address.title} {order.profile.shipping_address.firstname:h} {order.profile.shipping_address.lastname:h} -

      -

      - {order.profile.shipping_address.street:h}
      - {order.profile.shipping_address.city:h}, {order.profile.shipping_address.state.state:h}, {order.profile.shipping_address.zipcode:h}
      - {order.profile.shipping_address.country.country:h} -

      +
        +
      • + {t(field.title)}: + {field.value} + , +
      • +
      -

      - {t(#Phone#)}: {order.profile.shipping_address.phone:h} -

      diff --git a/src/skins/mail/en/order/invoice/style.css b/src/skins/mail/en/order/invoice/style.css index 3de124498a..2452050ea2 100644 --- a/src/skins/mail/en/order/invoice/style.css +++ b/src/skins/mail/en/order/invoice/style.css @@ -63,3 +63,51 @@ ul.invoice-totals li { padding: 3px 0; } + + .addresses ul.address-section li { + background: none; + padding: 0px; + margin: 0px; + } + +.addresses ul.address-section { + padding-top: 12px; +} + +.addresses ul.address-section li.address-field { + padding-right: 4px; +} + +.addresses ul.address-section li.address-field.address-custom_state { + display: none; +} + +.addresses ul.address-section li.address-field span { + font-size: 14px; + line-height: 20px; + padding-top: 8px; +} + +ul.address-section li.address-field .address-title, + ul.address-section li.address-field .address-comma +{ + display: none; +} + +ul.address-section li.address-field.address-phone .address-title, + ul.address-section li.address-field.field-additional .address-title, + ul.address-section li.address-field.address-city .address-comma, + ul.address-section li.address-field.address-street .address-comma, + ul.address-section li.address-field.address-state .address-comma +{ + display: inline; +} + +ul.address-section li.address-field.address-title, + ul.address-section li.address-field.address-firstname, + ul.address-section li.address-field.address-city, + ul.address-section li.address-field.address-state +{ + float: left; +} + From f91685ab89874ee53cd5b5528f1d9c0fa89b62fa Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Mon, 15 Oct 2012 16:51:17 +0400 Subject: [PATCH 31/85] [*] Custom state field could not change required state. --- .../XLite/View/ItemsList/Model/Address/Fields.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php index f9b7be4f02..8f7277bd05 100644 --- a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php +++ b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php @@ -186,6 +186,9 @@ protected function isAllowEntityRemove(\XLite\Model\AEntity $entity) */ protected function isTemplateColumnVisible(array $column, \XLite\Model\AEntity $entity) { + // Right now admin cannot directly edit serviceName values for additional fields + // and cannot change "Not required" state of "custom_state" field + // TODO: refactor it return 'serviceName' !== $column[static::COLUMN_CODE] ? parent::isTemplateColumnVisible($column, $entity) : !$entity->getAdditional(); @@ -202,8 +205,14 @@ protected function isTemplateColumnVisible(array $column, \XLite\Model\AEntity $ */ protected function isClassColumnVisible(array $column, \XLite\Model\AEntity $entity) { + // Right now admin cannot directly edit serviceName values for additional fields + // and cannot change "Not required" state of "custom_state" field + // TODO: refactor it return 'serviceName' !== $column[static::COLUMN_CODE] - ? parent::isClassColumnVisible($column, $entity) + ? (('custom_state' === $entity->getServiceName() && 'required' === $column[static::COLUMN_CODE]) + ? false + : parent::isClassColumnVisible($column, $entity) + ) : $entity->getAdditional(); } } From 344594119954b03feeddcd9dee5fd2e25235cc4f Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Mon, 15 Oct 2012 17:52:29 +0400 Subject: [PATCH 32/85] [*] Empty field value is not allowed now on the shipping settings form. --- src/classes/XLite/View/CountrySelect.php | 42 ++++++++++++------- .../XLite/View/FormField/Select/Country.php | 25 ++++++----- src/skins/admin/en/common/select_country.tpl | 2 +- src/skins/admin/en/shipping/settings.tpl | 2 +- 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/classes/XLite/View/CountrySelect.php b/src/classes/XLite/View/CountrySelect.php index e971c23128..da01be03f1 100644 --- a/src/classes/XLite/View/CountrySelect.php +++ b/src/classes/XLite/View/CountrySelect.php @@ -42,6 +42,7 @@ class CountrySelect extends \XLite\View\FormField const PARAM_COUNTRY = 'country'; const PARAM_FIELD_ID = 'fieldId'; const PARAM_CLASS_NAME = 'className'; + const PARAM_SELECT_ONE = 'selectOne'; const PARAM_ALLOW_LABEL_COUNTRY = 'allowLabelCountry'; @@ -65,12 +66,13 @@ protected function defineWidgetParams() parent::defineWidgetParams(); $this->widgetParams += array( - self::PARAM_ALL => new \XLite\Model\WidgetParam\Bool('All', false), - self::PARAM_FIELD_NAME => new \XLite\Model\WidgetParam\String('Field name', ''), - self::PARAM_FIELD_ID => new \XLite\Model\WidgetParam\String('Field ID', ''), - self::PARAM_CLASS_NAME => new \XLite\Model\WidgetParam\String('Class name', ''), - self::PARAM_COUNTRY => new \XLite\Model\WidgetParam\String('Value', ''), - self::PARAM_ALLOW_LABEL_COUNTRY => new \XLite\Model\WidgetParam\Bool('Allow label-based country selector', false), + static::PARAM_ALL => new \XLite\Model\WidgetParam\Bool('All', false), + static::PARAM_FIELD_NAME => new \XLite\Model\WidgetParam\String('Field name', ''), + static::PARAM_FIELD_ID => new \XLite\Model\WidgetParam\String('Field ID', ''), + static::PARAM_CLASS_NAME => new \XLite\Model\WidgetParam\String('Class name', ''), + static::PARAM_COUNTRY => new \XLite\Model\WidgetParam\String('Value', ''), + static::PARAM_SELECT_ONE => new \XLite\Model\WidgetParam\Bool('Select one value', false), + static::PARAM_ALLOW_LABEL_COUNTRY => new \XLite\Model\WidgetParam\Bool('Allow label-based country selector', false), ); } @@ -81,17 +83,17 @@ protected function defineWidgetParams() */ protected function isEnabledOnly() { - return !$this->getParam(self::PARAM_ALL); + return !$this->getParam(static::PARAM_ALL); } /** - * Get selected value - * + * Get selected value + * * @return string */ protected function getSelectedValue() { - return $this->getParam(self::PARAM_COUNTRY); + return $this->getParam(static::PARAM_COUNTRY); } /** @@ -103,7 +105,7 @@ protected function getSelectedValue() */ protected function isSelectedCountry($countryCode) { - $country = $this->getParam(self::PARAM_COUNTRY); + $country = $this->getParam(static::PARAM_COUNTRY); if ('' == $country) { $country = \XLite\Core\Config::getInstance()->General->default_country; @@ -126,18 +128,18 @@ protected function getCountries() /** * Check - country selector is label-based - * + * * @return boolean */ protected function isLabelBasedSelector() { - return $this->getParam(self::PARAM_ALLOW_LABEL_COUNTRY) + return $this->getParam(static::PARAM_ALLOW_LABEL_COUNTRY) && 1 == count($this->getCountries()); } /** - * Get one country - * + * Get one country + * * @return \XLite\Model\Country */ protected function getOneCountry() @@ -146,4 +148,14 @@ protected function getOneCountry() return reset($list); } + + /** + * Return if the select one value is available + * + * @return boolean + */ + protected function hasSelectOne() + { + return $this->getParam(static::PARAM_SELECT_ONE); + } } diff --git a/src/classes/XLite/View/FormField/Select/Country.php b/src/classes/XLite/View/FormField/Select/Country.php index f3ff73e4cb..22e307a2c5 100644 --- a/src/classes/XLite/View/FormField/Select/Country.php +++ b/src/classes/XLite/View/FormField/Select/Country.php @@ -37,6 +37,7 @@ class Country extends \XLite\View\FormField\Select\Regular const PARAM_ALL = 'all'; const PARAM_STATE_SELECTOR_ID = 'stateSelectorId'; const PARAM_STATE_INPUT_ID = 'stateInputId'; + const PARAM_SELECT_ONE = 'selectOne'; /** * Display only enabled countries @@ -54,7 +55,7 @@ class Country extends \XLite\View\FormField\Select\Regular */ public function __construct(array $params = array()) { - if (!empty($params[self::PARAM_ALL])) { + if (!empty($params[static::PARAM_ALL])) { $this->onlyEnabled = false; } @@ -85,8 +86,8 @@ public function getJSFiles() */ public function setStateSelectorIds($selectorId, $inputId) { - $this->getWidgetParams(self::PARAM_STATE_SELECTOR_ID)->setValue($selectorId); - $this->getWidgetParams(self::PARAM_STATE_INPUT_ID)->setValue($inputId); + $this->getWidgetParams(static::PARAM_STATE_SELECTOR_ID)->setValue($selectorId); + $this->getWidgetParams(static::PARAM_STATE_INPUT_ID)->setValue($inputId); } @@ -100,9 +101,10 @@ protected function defineWidgetParams() parent::defineWidgetParams(); $this->widgetParams += array( - self::PARAM_ALL => new \XLite\Model\WidgetParam\Bool('All', false), - self::PARAM_STATE_SELECTOR_ID => new \XLite\Model\WidgetParam\String('State select ID', null), - self::PARAM_STATE_INPUT_ID => new \XLite\Model\WidgetParam\String('State input ID', null), + static::PARAM_ALL => new \XLite\Model\WidgetParam\Bool('All', false), + static::PARAM_STATE_SELECTOR_ID => new \XLite\Model\WidgetParam\String('State select ID', null), + static::PARAM_STATE_INPUT_ID => new \XLite\Model\WidgetParam\String('State input ID', null), + static::PARAM_SELECT_ONE => new \XLite\Model\WidgetParam\Bool('All', true), ); } @@ -118,6 +120,7 @@ protected function getDefaultOptions() : \XLite\Core\Database::getRepo('XLite\Model\Country')->findAllCountries(); $options = array(); + foreach ($list as $country) { $options[$country->getCode()] = $country->getCountry(); } @@ -132,8 +135,10 @@ protected function getDefaultOptions() */ protected function getOptions() { - return array('' => 'Select one...') - + parent::getOptions(); + return $this->getParam(static::PARAM_SELECT_ONE) + ? array('' => 'Select one...') + + parent::getOptions() + : parent::getOptions(); } /** @@ -157,8 +162,8 @@ protected function getFormFieldJSData() 'statesList' => \XLite\Core\Database::getRepo('XLite\Model\Country')->findCountriesStates(), 'stateSelectors' => array( 'fieldId' => $this->getFieldId(), - 'stateSelectorId' => $this->getParam(self::PARAM_STATE_SELECTOR_ID), - 'stateInputId' => $this->getParam(self::PARAM_STATE_INPUT_ID), + 'stateSelectorId' => $this->getParam(static::PARAM_STATE_SELECTOR_ID), + 'stateInputId' => $this->getParam(static::PARAM_STATE_INPUT_ID), ), ); } diff --git a/src/skins/admin/en/common/select_country.tpl b/src/skins/admin/en/common/select_country.tpl index ff441a7456..62f0a4366d 100644 --- a/src/skins/admin/en/common/select_country.tpl +++ b/src/skins/admin/en/common/select_country.tpl @@ -9,6 +9,6 @@ * @link http://www.litecommerce.com/ *} diff --git a/src/skins/admin/en/shipping/settings.tpl b/src/skins/admin/en/shipping/settings.tpl index 1e439a9744..387c771a81 100644 --- a/src/skins/admin/en/shipping/settings.tpl +++ b/src/skins/admin/en/shipping/settings.tpl @@ -35,7 +35,7 @@ {end:} {if:option.type=#country#"} - + {end:} {if:option.type=#state#"} From 1cf0acfb9c8805c8f1dccef0535203410720bdd9 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Tue, 16 Oct 2012 12:48:25 +0400 Subject: [PATCH 33/85] [*] Small validation fix for service name field. --- src/classes/XLite/View/AView.php | 1 + .../FormField/Inline/Input/ServiceName.php | 54 +++++++++++++++++++ .../View/FormField/Input/Text/ServiceName.php | 47 ++++++++++++++++ .../View/ItemsList/Model/Address/Fields.php | 2 +- .../custom.validationEngine.js | 8 +++ 5 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 src/classes/XLite/View/FormField/Inline/Input/ServiceName.php create mode 100644 src/classes/XLite/View/FormField/Input/Text/ServiceName.php create mode 100644 src/skins/common/js/validationEngine/custom.validationEngine.js diff --git a/src/classes/XLite/View/AView.php b/src/classes/XLite/View/AView.php index e8f58cb2e6..6d8e417de3 100644 --- a/src/classes/XLite/View/AView.php +++ b/src/classes/XLite/View/AView.php @@ -610,6 +610,7 @@ protected function getCommonFiles() 'js/jquery.mousewheel.js', $this->getValidationEngineLanguageResource(), 'js/validationEngine/jquery.validationEngine.js', + 'js/validationEngine/custom.validationEngine.js', ), static::RESOURCE_CSS => array( 'ui/jquery-ui.css', diff --git a/src/classes/XLite/View/FormField/Inline/Input/ServiceName.php b/src/classes/XLite/View/FormField/Inline/Input/ServiceName.php new file mode 100644 index 0000000000..b5dae17bd4 --- /dev/null +++ b/src/classes/XLite/View/FormField/Inline/Input/ServiceName.php @@ -0,0 +1,54 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\FormField\Inline\Input; + +/** + * Service name field for address field + * + */ +class ServiceName extends \XLite\View\FormField\Inline\Input\Text +{ + /** + * Define form field + * + * @return string + */ + protected function defineFieldClass() + { + return 'XLite\View\FormField\Input\Text\ServiceName'; + } + + /** + * Get container class + * + * @return string + */ + protected function getContainerClass() + { + return parent::getContainerClass() . ' inline-service-name'; + } +} + diff --git a/src/classes/XLite/View/FormField/Input/Text/ServiceName.php b/src/classes/XLite/View/FormField/Input/Text/ServiceName.php new file mode 100644 index 0000000000..ff6936c1e0 --- /dev/null +++ b/src/classes/XLite/View/FormField/Input/Text/ServiceName.php @@ -0,0 +1,47 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\View\FormField\Input\Text; + +/** + * Service name for address fields items list + * + */ +class ServiceName extends \XLite\View\FormField\Input\Text +{ + /** + * Assemble validation rules + * + * @return array + */ + protected function assembleValidationRules() + { + $rules = parent::assembleValidationRules(); + + $rules[] = 'custom[onlySmallLetterNumberUnder]'; + + return $rules; + } +} diff --git a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php index 8f7277bd05..03d868597c 100644 --- a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php +++ b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php @@ -46,7 +46,7 @@ protected function defineColumns() ), 'serviceName' => array( static::COLUMN_NAME => static::t('Service name'), - static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text', + static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\ServiceName', static::COLUMN_TEMPLATE => 'items_list/model/table/field.tpl', static::COLUMN_PARAMS => array('required' => true), ), diff --git a/src/skins/common/js/validationEngine/custom.validationEngine.js b/src/skins/common/js/validationEngine/custom.validationEngine.js new file mode 100644 index 0000000000..26c93ca794 --- /dev/null +++ b/src/skins/common/js/validationEngine/custom.validationEngine.js @@ -0,0 +1,8 @@ +(function($){ + + $.validationEngineLanguage.allRules.onlySmallLetterNumberUnder = { + "regex": /^[a-z][0-9a-z_]+$/, + "alertText": "* Only small letter, digits and undescore sign are allowed" + }; + +})(jQuery); \ No newline at end of file From deb4acf26a06ad3cef2186e199f17039f9cbbeb1 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Tue, 16 Oct 2012 16:38:12 +0400 Subject: [PATCH 34/85] E:42290 [!] Bug: Removing address entry had been removed address fields. --- src/classes/XLite/Model/Address.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/XLite/Model/Address.php b/src/classes/XLite/Model/Address.php index a6a9eb142b..741dc402d7 100644 --- a/src/classes/XLite/Model/Address.php +++ b/src/classes/XLite/Model/Address.php @@ -52,7 +52,7 @@ class Address extends \XLite\Model\Base\PersonalAddress * * @var \Doctrine\Common\Collections\ArrayCollection * - * @OneToMany (targetEntity="XLite\Model\AddressFieldValue", mappedBy="address", cascade={"all"}) + * @OneToMany (targetEntity="XLite\Model\AddressFieldValue", mappedBy="address", cascade={"persist"}) */ protected $addressFields; From c58e3c149478e4f036eeff9fc00688c609602c62 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Tue, 16 Oct 2012 16:50:50 +0400 Subject: [PATCH 35/85] [*] Address field service name validation is added to the "Add address field" form. --- src/classes/XLite/View/Model/Address/Field.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/XLite/View/Model/Address/Field.php b/src/classes/XLite/View/Model/Address/Field.php index 3ccb0fcae5..5dd059d974 100644 --- a/src/classes/XLite/View/Model/Address/Field.php +++ b/src/classes/XLite/View/Model/Address/Field.php @@ -43,7 +43,7 @@ class Field extends \XLite\View\Model\AModel self::SCHEMA_REQUIRED => true, ), 'serviceName' => array( - self::SCHEMA_CLASS => 'XLite\View\FormField\Input\Text', + self::SCHEMA_CLASS => 'XLite\View\FormField\Input\Text\ServiceName', self::SCHEMA_LABEL => 'Service name of address field', self::SCHEMA_REQUIRED => true, ), From 0d9fc3f6f36fc769907e3cf3c97dc7b6ded9c665 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Tue, 16 Oct 2012 17:26:24 +0400 Subject: [PATCH 36/85] [*] Validation alerts hiding is added to popup window close functionality. --- src/skins/common/js/common.js | 6 ++++++ src/skins/common/js/core.popup.js | 3 +++ 2 files changed, 9 insertions(+) diff --git a/src/skins/common/js/common.js b/src/skins/common/js/common.js index e8580ce133..21b27b427e 100644 --- a/src/skins/common/js/common.js +++ b/src/skins/common/js/common.js @@ -1,3 +1,4 @@ + /* vim: set ts=2 sw=2 sts=2 et: */ /** @@ -154,6 +155,11 @@ function openDialog(selector, additionalOptions) overflow: 'visible' } ); + }, + close: function (event) { + jQuery('form', jQuery('.ui-dialog ' + selector)).each(function (index, elem) { + jQuery(elem).validationEngine('hide'); + }); } } diff --git a/src/skins/common/js/core.popup.js b/src/skins/common/js/core.popup.js index 63e6060f8f..8ed1776d49 100644 --- a/src/skins/common/js/core.popup.js +++ b/src/skins/common/js/core.popup.js @@ -307,6 +307,9 @@ popup.open = function(box) var o = this; jQuery('.blockMsg a.close-link').click( function(event) { + jQuery('form', jQuery(o)).each(function (index, elem) { + jQuery(elem).validationEngine('hide'); + }); o.close(); return false; } From 3fe3a67470dc80ac6e69722cf119db7738863f96 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Wed, 17 Oct 2012 11:09:26 +0400 Subject: [PATCH 37/85] [*] Required address fields checking is added. --- src/classes/XLite/Model/Address.php | 32 +++++-------------- src/classes/XLite/Model/Repo/AddressField.php | 27 ++++++++++++++++ 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/classes/XLite/Model/Address.php b/src/classes/XLite/Model/Address.php index 741dc402d7..824afeb8fc 100644 --- a/src/classes/XLite/Model/Address.php +++ b/src/classes/XLite/Model/Address.php @@ -167,17 +167,9 @@ public function getterProperty($property) * * @return array */ - public static function getBillingRequiredFields() + public function getBillingRequiredFields() { - return array( - 'firstname', - 'lastname', - 'street', - 'city', - 'zipcode', - 'state', - 'country', - ); + return \XLite\Core\Database::getRepo('XLite\Model\AddressField')->findRequiredFields(); } /** @@ -185,17 +177,9 @@ public static function getBillingRequiredFields() * * @return array */ - public static function getShippingRequiredFields() + public function getShippingRequiredFields() { - return array( - 'firstname', - 'lastname', - 'street', - 'city', - 'zipcode', - 'state', - 'country', - ); + return \XLite\Core\Database::getRepo('XLite\Model\AddressField')->findRequiredFields(); } /** @@ -245,12 +229,12 @@ public static function getDefaultFieldValue($fieldName) public function getRequiredFieldsByType($atype) { switch ($atype) { - case self::BILLING: - $list = static::getBillingRequiredFields(); + case static::BILLING: + $list = $this->getBillingRequiredFields(); break; - case self::SHIPPING: - $list = static::getShippingRequiredFields(); + case static::SHIPPING: + $list = $this->getShippingRequiredFields(); break; default: diff --git a/src/classes/XLite/Model/Repo/AddressField.php b/src/classes/XLite/Model/Repo/AddressField.php index 50c5bb967d..115d716d67 100644 --- a/src/classes/XLite/Model/Repo/AddressField.php +++ b/src/classes/XLite/Model/Repo/AddressField.php @@ -107,6 +107,33 @@ public function findAllEnabled() return $this->search(new \XLite\Core\CommonCell(array('enabled' => true))); } + /** + * Return address field service name value + * + * @param \XLite\Model\AddressField $field + * + * @return string + */ + public function getServiceName(\XLite\Model\AddressField $field) + { + return $field->getServiceName(); + } + + /** + * Get all enabled and required address fields + * + * @return \Doctrine\ORM\PersistentCollection|integer + */ + public function findRequiredFields() + { + return array_map(array($this, 'getServiceName'), $this->search( + new \XLite\Core\CommonCell(array( + 'enabled' => true, + 'required' => true, + ) + ))); + } + /** * Find one by record * From c22e053cd9d919bf7057813ee3cedd1e7ec160fc Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Wed, 17 Oct 2012 16:06:28 +0400 Subject: [PATCH 38/85] [*] Address fields table width changes. --- .../View/ItemsList/Model/Address/Fields.php | 14 ++++++++++++++ .../model/table/address_fields/style.css | 16 ++++++++++++++++ .../en/items_list/model/table/product/style.css | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/skins/admin/en/items_list/model/table/address_fields/style.css diff --git a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php index 03d868597c..e2751a6257 100644 --- a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php +++ b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php @@ -31,6 +31,20 @@ */ class Fields extends \XLite\View\ItemsList\Model\Table { + /** + * Get a list of CSS files + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = $this->getDir() . '/' . $this->getPageBodyDir() . '/address_fields/style.css'; + + return $list; + } + /** * Define columns structure * diff --git a/src/skins/admin/en/items_list/model/table/address_fields/style.css b/src/skins/admin/en/items_list/model/table/address_fields/style.css new file mode 100644 index 0000000000..5e126f2da0 --- /dev/null +++ b/src/skins/admin/en/items_list/model/table/address_fields/style.css @@ -0,0 +1,16 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Address fields list styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +.items-list-table table.list tbody.lines td .view, + .items-list-table table.list tbody.lines td .view * +{ + width: 300px; +} diff --git a/src/skins/admin/en/items_list/model/table/product/style.css b/src/skins/admin/en/items_list/model/table/product/style.css index 9ef0b68ab7..c1fcf8b2d0 100644 --- a/src/skins/admin/en/items_list/model/table/product/style.css +++ b/src/skins/admin/en/items_list/model/table/product/style.css @@ -1,7 +1,7 @@ /* vim: set ts=2 sw=2 sts=2 et: */ /** - * Product items lsit styles + * Product items list styles * * @author Creative Development LLC * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved From 7c8a6e94dd493ab272642c044245e0ff0481bee7 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Thu, 18 Oct 2012 14:14:38 +0400 Subject: [PATCH 39/85] [*] Address fields feature changes on the checkout. Required fields. --- .../XLite/Controller/Customer/Checkout.php | 6 +- src/classes/XLite/Model/Address.php | 44 +----------- src/classes/XLite/Model/Base/Address.php | 39 +++++++--- .../XLite/Model/Base/PersonalAddress.php | 11 --- src/classes/XLite/Model/Repo/Address.php | 71 ------------------- src/classes/XLite/Model/Repo/AddressField.php | 53 +++++++++++++- 6 files changed, 85 insertions(+), 139 deletions(-) diff --git a/src/classes/XLite/Controller/Customer/Checkout.php b/src/classes/XLite/Controller/Customer/Checkout.php index 7a3efb66d7..994fe5ea2c 100644 --- a/src/classes/XLite/Controller/Customer/Checkout.php +++ b/src/classes/XLite/Controller/Customer/Checkout.php @@ -181,7 +181,7 @@ protected function doActionCheckout() $this->redirect($this->buildURL('checkout')); } else { - // Register 'Place order' event in the order history + // Register 'Place order' event in the order history \XLite\Core\OrderHistory::getInstance()->registerPlaceOrder($this->getCart()->getOrderId()); // Make order payment step @@ -828,8 +828,8 @@ protected function prepareAddressData(array $data, $type = 'shipping') unset($data['save_as_new']); $requiredFields = 'shipping' == $type - ? \XLite\Model\Address::getShippingRequiredFields() - : \XLite\Model\Address::getBillingRequiredFields(); + ? \XLite\Core\Database::getRepo('XLite\Model\AddressField')->getShippingRequiredFields() + : \XLite\Core\Database::getRepo('XLite\Model\AddressField')->getBillingRequiredFields(); foreach ($requiredFields as $fieldName) { if (!isset($data[$fieldName]) && \XLite\Model\Address::getDefaultFieldValue($fieldName)) { diff --git a/src/classes/XLite/Model/Address.php b/src/classes/XLite/Model/Address.php index 824afeb8fc..27cca2fd98 100644 --- a/src/classes/XLite/Model/Address.php +++ b/src/classes/XLite/Model/Address.php @@ -162,26 +162,6 @@ public function getterProperty($property) return $result; } - /** - * Get billing address-specified required fields - * - * @return array - */ - public function getBillingRequiredFields() - { - return \XLite\Core\Database::getRepo('XLite\Model\AddressField')->findRequiredFields(); - } - - /** - * Get shipping address-specified required fields - * - * @return array - */ - public function getShippingRequiredFields() - { - return \XLite\Core\Database::getRepo('XLite\Model\AddressField')->findRequiredFields(); - } - /** * Get default value for the field * @@ -230,11 +210,11 @@ public function getRequiredFieldsByType($atype) { switch ($atype) { case static::BILLING: - $list = $this->getBillingRequiredFields(); + $list = \XLite\Core\Database::getRepo('XLite\Model\AddressField')->getBillingRequiredFields(); break; case static::SHIPPING: - $list = $this->getShippingRequiredFields(); + $list = \XLite\Core\Database::getRepo('XLite\Model\AddressField')->getShippingRequiredFields(); break; default: @@ -278,24 +258,4 @@ public function cloneEntity() return $entity; } - - - /** - * Check if address has duplicates - * - * @return boolean - */ - protected function checkAddress() - { - $result = parent::checkAddress(); - - $sameAddress = $this->getRepository()->findSameAddress($this); - - if ($sameAddress) { - \XLite\Core\TopMessage::addWarning('Address was not saved as other address with specified fields is already exists.'); - $result = false; - } - - return $result; - } } diff --git a/src/classes/XLite/Model/Base/Address.php b/src/classes/XLite/Model/Base/Address.php index 4dc63d1bdd..4bfecfb31e 100644 --- a/src/classes/XLite/Model/Base/Address.php +++ b/src/classes/XLite/Model/Base/Address.php @@ -78,20 +78,11 @@ abstract class Address extends \XLite\Model\AEntity * * @return array(string) */ - public static function getAddressFields() + public function getAddressFields() { - return array( - 'phone', - 'street', - 'city', - 'zipcode', - 'state_id', - 'custom_state', - 'country_code', - ); + return \XLite\Core\Database::getRepo('XLite\Model\AddressField')->findEnabledFields(); } - /** * Get state * @@ -114,6 +105,32 @@ public function getState() return $state; } + /** + * Set country + * + * @param integer $countryCode Country code + */ + public function setCountryCode($countryCode) + { + $this->setterProperty('country_code', $countryCode); + + $this->setCountry(\XLite\Core\Database::getRepo('XLite\Model\Country')->findOneBy(array('code' => $countryCode))); + } + + /** + * Set state + * + * @param integer $state State id + * + * @return void + */ + public function setStateId($stateId) + { + $this->setterProperty('state_id', $stateId); + + $this->setState(\XLite\Core\Database::getRepo('XLite\Model\State')->find($stateId)); + } + /** * Set state * diff --git a/src/classes/XLite/Model/Base/PersonalAddress.php b/src/classes/XLite/Model/Base/PersonalAddress.php index 9c514678c9..8b0dfa4d38 100644 --- a/src/classes/XLite/Model/Base/PersonalAddress.php +++ b/src/classes/XLite/Model/Base/PersonalAddress.php @@ -33,17 +33,6 @@ */ abstract class PersonalAddress extends \XLite\Model\Base\Address { - /** - * Get address fields list - * - * @return array(string) - */ - public static function getAddressFields() - { - return array_merge(array('firstname', 'lastname'), parent::getAddressFields()); - } - - /** * Get full name * diff --git a/src/classes/XLite/Model/Repo/Address.php b/src/classes/XLite/Model/Repo/Address.php index 63fc7c8777..a35ce07d86 100644 --- a/src/classes/XLite/Model/Repo/Address.php +++ b/src/classes/XLite/Model/Repo/Address.php @@ -57,16 +57,6 @@ public function findAllCities() return $cities; } - /** - * Find address with same properties as specified address has - * - * @return \XLite\Model\Address - */ - public function findSameAddress($address) - { - return $address ? $this->defineFindSameAddressQuery($address)->getSingleResult() : null; - } - /** * defineFindAllCities * @@ -80,67 +70,6 @@ protected function defineFindAllCities() ->addOrderBy('a.city'); } - /** - * defineFindSameAddressQuery - * - * @return \Doctrine\ORM\QueryBuilder - */ - protected function defineFindSameAddressQuery($address) - { - $params = array(); - - $qb = $this->createQueryBuilder(); - - $qb ->innerJoin('a.profile', 'p') - ->andWhere('p.profile_id = :profile_id'); - - $params['profile_id'] = $address->getProfile()->getProfileId(); - - if ($address->getAddressId()) { - $qb->andWhere($qb->expr()->not('a.address_id = :address_id')); - $params['address_id'] = $address->getAddressId(); - } - - $fields = $address->getAddressFields(); - - foreach ($fields as $field) { - - if ('state_id' == $field) { - - if ($address->getStateId()) { - $qb->innerJoin('a.state', 's') - ->andWhere('s.state_id = :state_id'); - $params[$field] = $address->getStateId(); - - } else { - $qb->leftJoin('a.state', 's') - ->andWhere('s.state_id IS NULL'); - } - - } elseif ('country_code' == $field) { - $qb->innerJoin('a.country', 'c') - ->andWhere('c.code = :country_code'); - $params[$field] = $address->getCountryCode(); - - } else { - - $methodName = 'get' . \XLite\Core\Converter::getInstance()->convertToCamelCase($field); - - if (method_exists($address, $methodName)) { - - $qb->andWhere(sprintf('a.%s = :%s', $field, $field)); - - // Assign value from address - $params[$field] = $address->$methodName(); - } - } - } - - $qb->setParameters($params); - - return $qb; - } - /** * Get detailed foreign keys * diff --git a/src/classes/XLite/Model/Repo/AddressField.php b/src/classes/XLite/Model/Repo/AddressField.php index 115d716d67..d75ca8c09f 100644 --- a/src/classes/XLite/Model/Repo/AddressField.php +++ b/src/classes/XLite/Model/Repo/AddressField.php @@ -119,10 +119,30 @@ public function getServiceName(\XLite\Model\AddressField $field) return $field->getServiceName(); } + /** + * Get billing address-specified required fields + * + * @return array + */ + public function getBillingRequiredFields() + { + return $this->findRequiredFields(); + } + + /** + * Get shipping address-specified required fields + * + * @return array + */ + public function getShippingRequiredFields() + { + return $this->findRequiredFields(); + } + /** * Get all enabled and required address fields * - * @return \Doctrine\ORM\PersistentCollection|integer + * @return array */ public function findRequiredFields() { @@ -134,6 +154,20 @@ public function findRequiredFields() ))); } + /** + * Get all enabled and required address fields + * + * @return array + */ + public function findEnabledFields() + { + return array_map(array($this, 'getServiceName'), $this->search( + new \XLite\Core\CommonCell(array( + 'enabled' => true, + ) + ))); + } + /** * Find one by record * @@ -163,6 +197,7 @@ protected function getHandlingSearchParams() { return array( 'enabled', + 'required', ); } @@ -212,4 +247,20 @@ protected function prepareCndEnabled(\Doctrine\ORM\QueryBuilder $queryBuilder, $ ->andWhere($this->getMainAlias($queryBuilder) . '.enabled = :enabled_value') ->setParameter('enabled_value', $value); } + + /** + * Prepare query builder for required status search + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder + * @param boolean $value + * @param boolean $countOnly + * + * @return void + */ + protected function prepareCndRequired(\Doctrine\ORM\QueryBuilder $queryBuilder, $value, $countOnly) + { + $queryBuilder + ->andWhere($this->getMainAlias($queryBuilder) . '.required = :required_value') + ->setParameter('required_value', $value); + } } From 842a3713cc4971e12e0d8247f3e2b66eb5bbb2a2 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Fri, 19 Oct 2012 17:37:33 +0400 Subject: [PATCH 40/85] [*] Search functionality changes for address fields feature. [*] Several code changes for address fields feature. --- src/classes/XLite/Model/Repo/Profile.php | 66 +++++++++++++++---- .../View/ItemsList/Model/Address/Fields.php | 13 ++++ .../XLite/View/ItemsList/Model/Table.php | 12 ++++ .../items_list/model/table/parts/switcher.tpl | 2 +- .../default/en/form_field/select_country.tpl | 2 +- .../default/en/form_field/select_state.tpl | 2 +- 6 files changed, 80 insertions(+), 17 deletions(-) diff --git a/src/classes/XLite/Model/Repo/Profile.php b/src/classes/XLite/Model/Repo/Profile.php index f80d59e98c..5ddb07c14d 100644 --- a/src/classes/XLite/Model/Repo/Profile.php +++ b/src/classes/XLite/Model/Repo/Profile.php @@ -318,8 +318,8 @@ protected function callSearchConditionHandler($value, $key, \Doctrine\ORM\QueryB protected function getNameSubstringSearchFields() { return array( - 'CONCAT(CONCAT(addresses.firstname, \' \'), addresses.lastname)', - 'CONCAT(CONCAT(addresses.lastname, \' \'), addresses.firstname)', + 'CONCAT(CONCAT(field_value_firstname.value, \' \'), field_value_lastname.value)', + 'CONCAT(CONCAT(field_value_lastname.value, \' \'), field_value_firstname.value)', 'p.login' ); } @@ -332,10 +332,10 @@ protected function getNameSubstringSearchFields() protected function getAddressSubstringSearchFields() { return array( - 'addresses.street', - 'addresses.custom_state', - 'addresses.city', - 'addresses.zipcode', + 'street', + 'custom_state', + 'city', + 'zipcode', ); } @@ -372,6 +372,45 @@ protected function prepareCndCommon(\Doctrine\ORM\QueryBuilder $queryBuilder, $v } } + /** + * Prepare field search query + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder + * @param type $fieldName + */ + protected function prepareField(\Doctrine\ORM\QueryBuilder $queryBuilder, $fieldName) + { + $queryBuilder->leftJoin( + 'addresses.addressFields', + 'field_value_' . $fieldName + )->leftJoin( + 'field_value_' . $fieldName . '.addressField', + 'field_' . $fieldName, + \Doctrine\ORM\Query\Expr\Join::WITH, + 'field_' . $fieldName . '.serviceName = :' . $fieldName + )->setParameter($fieldName, $fieldName); + } + + /** + * Prepare field search query + * + * @param \Doctrine\ORM\QueryBuilder $queryBuilder + * @param type $value + * @param type $fieldName + */ + protected function prepareCommonField(\Doctrine\ORM\QueryBuilder $queryBuilder, $value, $fieldName, $exactCmp = true) + { + if ($value) { + $this->prepareField($queryBuilder, $fieldName); + + $queryBuilder->andWhere( + $exactCmp + ? 'field_value_' . $fieldName . '.value = :field_value_' . $fieldName + : 'field_value_' . $fieldName . '.value LIKE :field_value_' . $fieldName + )->setParameter('field_value_' . $fieldName, $exactCmp ? $value : '%' . $value . '%'); + } + } + /** * prepareCndProfileId * @@ -526,6 +565,9 @@ protected function prepareCndPattern(\Doctrine\ORM\QueryBuilder $queryBuilder, $ if (!empty($value)) { $cnd = new \Doctrine\ORM\Query\Expr\Orx(); + $this->prepareField($queryBuilder, 'firstname'); + $this->prepareField($queryBuilder, 'lastname'); + foreach ($this->getNameSubstringSearchFields() as $field) { $cnd->add($field . ' LIKE :pattern'); } @@ -546,7 +588,7 @@ protected function prepareCndPattern(\Doctrine\ORM\QueryBuilder $queryBuilder, $ */ protected function prepareCndPhone(\Doctrine\ORM\QueryBuilder $queryBuilder, $value) { - $this->prepareCndCommon($queryBuilder, $value, 'phone', false, 'addresses'); + $this->prepareCommonField($queryBuilder, $value, 'name', false); } /** @@ -585,7 +627,7 @@ protected function prepareCndState(\Doctrine\ORM\QueryBuilder $queryBuilder, $va */ protected function prepareCndCustomState(\Doctrine\ORM\QueryBuilder $queryBuilder, $value) { - $this->prepareCndCommon($queryBuilder, $value, 'custom_state', true, 'addresses'); + $this->prepareCommonField($queryBuilder, $value, 'custom_state'); } /** @@ -599,15 +641,11 @@ protected function prepareCndCustomState(\Doctrine\ORM\QueryBuilder $queryBuilde protected function prepareCndAddress(\Doctrine\ORM\QueryBuilder $queryBuilder, $value) { if (!empty($value)) { - $cnd = new \Doctrine\ORM\Query\Expr\Orx(); foreach ($this->getAddressSubstringSearchFields() as $field) { - $cnd->add($field . ' LIKE :addressPattern'); - } - $queryBuilder - ->andWhere($cnd) - ->setParameter('addressPattern', '%' . $value . '%'); + $this->prepareCommonField($queryBuilder, $value, $field, false); + } } } diff --git a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php index e2751a6257..30cc39d8f9 100644 --- a/src/classes/XLite/View/ItemsList/Model/Address/Fields.php +++ b/src/classes/XLite/View/ItemsList/Model/Address/Fields.php @@ -190,6 +190,19 @@ protected function isAllowEntityRemove(\XLite\Model\AEntity $entity) return parent::isAllowEntityRemove($entity) && $entity->getAdditional(); } + /** + * Check - switch entity or not + * + * @param \XLite\Model\AEntity $entity Entity + * + * @return boolean + */ + protected function isAllowEntitySwitch(\XLite\Model\AEntity $entity) + { + // Custom state is not allowed to switch off + return parent::isAllowEntitySwitch($entity) && 'custom_state' !== $entity->getServiceName(); + } + /** * Check if the column template is used for widget displaying * diff --git a/src/classes/XLite/View/ItemsList/Model/Table.php b/src/classes/XLite/View/ItemsList/Model/Table.php index 538b829bfa..3d371c4e9a 100644 --- a/src/classes/XLite/View/ItemsList/Model/Table.php +++ b/src/classes/XLite/View/ItemsList/Model/Table.php @@ -638,6 +638,18 @@ protected function isAllowEntityRemove(\XLite\Model\AEntity $entity) return true; } + /** + * Check - switch entity or not + * + * @param \XLite\Model\AEntity $entity Entity + * + * @return boolean + */ + protected function isAllowEntitySwitch(\XLite\Model\AEntity $entity) + { + return (bool)$this->getSwitcherField(); + } + // }}} // {{{ Inherited methods diff --git a/src/skins/admin/en/items_list/model/table/parts/switcher.tpl b/src/skins/admin/en/items_list/model/table/parts/switcher.tpl index fab680e88a..78651b1dde 100644 --- a/src/skins/admin/en/items_list/model/table/parts/switcher.tpl +++ b/src/skins/admin/en/items_list/model/table/parts/switcher.tpl @@ -9,4 +9,4 @@ * @link http://www.litecommerce.com/ *} - + diff --git a/src/skins/default/en/form_field/select_country.tpl b/src/skins/default/en/form_field/select_country.tpl index cc915650dc..69d31384ed 100644 --- a/src/skins/default/en/form_field/select_country.tpl +++ b/src/skins/default/en/form_field/select_country.tpl @@ -10,5 +10,5 @@ *} diff --git a/src/skins/default/en/form_field/select_state.tpl b/src/skins/default/en/form_field/select_state.tpl index 2bd4c1bc57..589166a7ba 100644 --- a/src/skins/default/en/form_field/select_state.tpl +++ b/src/skins/default/en/form_field/select_state.tpl @@ -12,5 +12,5 @@ From da42fbd9791a4d266b479ce9e44328deec96eff5 Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Fri, 19 Oct 2012 17:50:06 +0400 Subject: [PATCH 41/85] E:0042305 [!] Payment method: moduleEnabled property of method didn't change when related to the method module was disabled or enabled. Fixed. (hotfix) --- .../XLite/Model/Repo/Payment/Method.php | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/classes/XLite/Model/Repo/Payment/Method.php b/src/classes/XLite/Model/Repo/Payment/Method.php index ff290f637a..e96e227c96 100644 --- a/src/classes/XLite/Model/Repo/Payment/Method.php +++ b/src/classes/XLite/Model/Repo/Payment/Method.php @@ -137,7 +137,7 @@ public function search(\XLite\Core\CommonCell $cnd, $countOnly = false) return $countOnly ? $this->searchCount($queryBuilder) - : $this->searchResult($queryBuilder); + : $this->correctSearchResult($this->searchResult($queryBuilder), $cnd->P_MODULE_ENABLED); } /** @@ -166,6 +166,35 @@ public function searchResult(\Doctrine\ORM\QueryBuilder $qb) return $qb->getResult(); } + /** + * Correct the list of payment methods + * FIXME: this should be moved to the module hooks + * + * @param array $methods List of payment methods + * @param boolean $moduleEnabledFlag True if list should contain methods of enabled modules + * + * @return array + */ + protected function correctSearchResult($methods, $moduleEnabledFlag) + { + if ($methods) { + foreach ($methods as $k => $method) { + if ($method->getModuleName()) { + $isReallyModuleEnabled = (bool)$method->getProcessor(); + if ($method->getModuleEnabled() != $isReallyModuleEnabled) { + $method->setModuleEnabled($isReallyModuleEnabled); + $this->update($method); + if ($moduleEnabledFlag && !$isReallyModuleEnabled || !$moduleEnabledFlag && $isReallyModuleEnabled) { + unset($methods[$k]); + } + } + } + } + } + + return $methods; + } + /** * Call corresponded method to handle a search condition * From 972a3a2cbee89f3a9a268cfe63443d14238a7412 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Sat, 20 Oct 2012 00:20:42 +0400 Subject: [PATCH 42/85] [*] Address pattern search changes. --- src/classes/XLite/Model/Repo/Profile.php | 29 +++++------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/src/classes/XLite/Model/Repo/Profile.php b/src/classes/XLite/Model/Repo/Profile.php index 5ddb07c14d..cbe815d571 100644 --- a/src/classes/XLite/Model/Repo/Profile.php +++ b/src/classes/XLite/Model/Repo/Profile.php @@ -324,21 +324,6 @@ protected function getNameSubstringSearchFields() ); } - /** - * List of fields to use in search by substring - * - * @return array - */ - protected function getAddressSubstringSearchFields() - { - return array( - 'street', - 'custom_state', - 'city', - 'zipcode', - ); - } - /** * prepareCndCommon * @@ -435,13 +420,10 @@ protected function prepareCndProfileId(\Doctrine\ORM\QueryBuilder $queryBuilder, protected function prepareCndOrderId(\Doctrine\ORM\QueryBuilder $queryBuilder, $value) { if ($value) { - $queryBuilder->innerJoin('p.order', 'porder') ->andWhere('porder.order_id = :orderId') ->setParameter('orderId', $value); - } else { - $queryBuilder->andWhere('p.order is null'); } } @@ -641,11 +623,12 @@ protected function prepareCndCustomState(\Doctrine\ORM\QueryBuilder $queryBuilde protected function prepareCndAddress(\Doctrine\ORM\QueryBuilder $queryBuilder, $value) { if (!empty($value)) { - - foreach ($this->getAddressSubstringSearchFields() as $field) { - - $this->prepareCommonField($queryBuilder, $value, $field, false); - } + $queryBuilder->leftJoin( + 'addresses.addressFields', + 'field_value_address_pattern' + ) + ->andWhere('field_value_address_pattern.value LIKE :addressPattern') + ->setParameter('addressPattern', '%' . $value . '%'); } } From 4d37f5a0611a46e807860af5265948651a874048 Mon Sep 17 00:00:00 2001 From: skiv Date: Mon, 22 Oct 2012 18:29:01 +0400 Subject: [PATCH 43/85] Product comparison --- .../ProductComparison/Core/CMSConnector.php | 45 ++++++++ .../Module/CDev/ProductComparison/Main.php | 84 +++++++++++++++ .../View/ProductComparison.php | 99 ++++++++++++++++++ .../CDev/ProductComparison/install.yaml | 12 +++ .../CDev/ProductComparison/scales_icon.png | Bin 0 -> 785 bytes .../CDev/ProductComparison/sidebar/body.tpl | 16 +++ .../CDev/ProductComparison/sidebar/script.js | 69 ++++++++++++ 7 files changed, 325 insertions(+) create mode 100644 src/classes/XLite/Module/CDev/ProductComparison/Core/CMSConnector.php create mode 100644 src/classes/XLite/Module/CDev/ProductComparison/Main.php create mode 100644 src/classes/XLite/Module/CDev/ProductComparison/View/ProductComparison.php create mode 100644 src/classes/XLite/Module/CDev/ProductComparison/install.yaml create mode 100644 src/skins/default/en/modules/CDev/ProductComparison/scales_icon.png create mode 100644 src/skins/default/en/modules/CDev/ProductComparison/sidebar/body.tpl create mode 100644 src/skins/default/en/modules/CDev/ProductComparison/sidebar/script.js diff --git a/src/classes/XLite/Module/CDev/ProductComparison/Core/CMSConnector.php b/src/classes/XLite/Module/CDev/ProductComparison/Core/CMSConnector.php new file mode 100644 index 0000000000..43ac0e51dd --- /dev/null +++ b/src/classes/XLite/Module/CDev/ProductComparison/Core/CMSConnector.php @@ -0,0 +1,45 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Module\CDev\ProductComparison\Core; + +/** + * CMSConnector class + * + */ +abstract class CMSConnector extends \XLite\Core\CMSConnector implements \XLite\Base\IDecorator +{ + /** + * Constructor + * + * @return void + */ + protected function __construct() + { + parent::__construct(); + + $this->widgetsList['\XLite\Module\CDev\ProductComparison\View\ProductComparison'] = 'Product comparison list'; + } +} diff --git a/src/classes/XLite/Module/CDev/ProductComparison/Main.php b/src/classes/XLite/Module/CDev/ProductComparison/Main.php new file mode 100644 index 0000000000..b7585d71fa --- /dev/null +++ b/src/classes/XLite/Module/CDev/ProductComparison/Main.php @@ -0,0 +1,84 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Module\CDev\ProductComparison; + +/** + * Product comparison module main class + * + */ +abstract class Main extends \XLite\Module\AModule +{ + /** + * Author name + * + * @return string + */ + public static function getAuthorName() + { + return 'Creative Development LLC'; + } + + /** + * Module version + * + * @return string + */ + public static function getMajorVersion() + { + return '1.1'; + } + + /** + * Module version + * + * @return string + */ + public static function getMinorVersion() + { + return '0'; + } + + /** + * Module name + * + * @return string + */ + public static function getModuleName() + { + return 'Product Comparison'; + } + + /** + * Module description + * + * @return string + */ + public static function getDescription() + { + return 'Allows customers to compare products.'; + } + +} diff --git a/src/classes/XLite/Module/CDev/ProductComparison/View/ProductComparison.php b/src/classes/XLite/Module/CDev/ProductComparison/View/ProductComparison.php new file mode 100644 index 0000000000..06431bcad1 --- /dev/null +++ b/src/classes/XLite/Module/CDev/ProductComparison/View/ProductComparison.php @@ -0,0 +1,99 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Module\CDev\ProductComparison\View; + +/** + * Product comparison widget + * + * + * @ListChild (list="sidebar.first", zone="customer", weight="120") + */ +class ProductComparison extends \XLite\View\SideBarBox +{ + + /** + * Register JS files + * + * @return array + */ + public function getJSFiles() + { + $list = parent::getJSFiles(); + + $list[] = $this->getDir() . '/script.js'; + + return $list; + } + + /** + * Get title + * + * @return string + */ + protected function getHead() + { + return static::t( + 'Compare X products', + array( + 'count' => 2 + ) + ); + } + + /** + * Register CSS files + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = $this->getDir() . '/style.css'; + + return $list; + } + + /** + * Get widget templates directory + * + * @return string + */ + protected function getDir() + { + return 'modules/CDev/ProductComparison/sidebar'; + } + + /** + * Return default template + * + * @return string + */ + protected function getDefaultTemplate() + { + return $this->getDir() . '/body.tpl'; + } +} diff --git a/src/classes/XLite/Module/CDev/ProductComparison/install.yaml b/src/classes/XLite/Module/CDev/ProductComparison/install.yaml new file mode 100644 index 0000000000..e5fb29837f --- /dev/null +++ b/src/classes/XLite/Module/CDev/ProductComparison/install.yaml @@ -0,0 +1,12 @@ +# vim: set ts=2 sw=2 sts=2 et: +# +# Fixtures +# +# @author Creative Development LLC +# @copyright Copyright (c) 2012 Creative Development LLC . All rights reserved +# @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +# @link http://www.litecommerce.com/ + +XLite\Model\LanguageLabel: + - { name: 'Compare X products', translations: [{ code: en, label: 'Compare {{count}} products' }] } + - { name: 'X products selected', translations: [{ code: en, label: '{{count}} products selected' }] } diff --git a/src/skins/default/en/modules/CDev/ProductComparison/scales_icon.png b/src/skins/default/en/modules/CDev/ProductComparison/scales_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a54c9f0d5387405a4b352b91778ce27e4b92ca7 GIT binary patch literal 785 zcmV+s1Md8ZP)tiWK{_ zFA_iInr!PDR|umK(hr@&X>QI2^5-sBF&-UFY5 zo8addp)Lh{&<@7ApcABq2p-Qm40Uh|ya*NzFM~Dk4Oyejjyn(TFaklLIq)jOW^o5x z1j{@Oi?mtHfD82H6_Ux5Om>gCvFI=dn}I{%BJz=8E&GJdf{*zBo?VebmGohba|QRo z*+D{|nCx;usOGWjhzK?q#y+762mDeK`&Oi!xg8~@ugN(YTMXx}kX**QW>DXX)PfQv zsBwmKG+$#?4+OS0BbGv#n@a?{!S2>QnEgVQhm5xt%et zYyIX{soLFK2P@$1j66wx-eu%R=1zh)LOU8&s{6B2b;-I0Rs)IE?W#J$HPd&C$6nhi zJYfG}r7GKdkY?kt36Dct*$4WNL3Lh0ALMd2l*6a0@1?R2^x+0dV%Na0?EKDlT{#=0 z-Qg!Vq53m@4D*?2dRBWOc7AS^YHVFM&KKJjkzc?=d`U)?>OU^@TYv!of$m)*s^!E+ P00000NkvXXu0mjf$@6g0 literal 0 HcmV?d00001 diff --git a/src/skins/default/en/modules/CDev/ProductComparison/sidebar/body.tpl b/src/skins/default/en/modules/CDev/ProductComparison/sidebar/body.tpl new file mode 100644 index 0000000000..a129f28d0d --- /dev/null +++ b/src/skins/default/en/modules/CDev/ProductComparison/sidebar/body.tpl @@ -0,0 +1,16 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Body + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} +
      +
      +

      {t(getHead())}

      + {t(#Clear list#)} +
      +
      diff --git a/src/skins/default/en/modules/CDev/ProductComparison/sidebar/script.js b/src/skins/default/en/modules/CDev/ProductComparison/sidebar/script.js new file mode 100644 index 0000000000..3ba5de5f1a --- /dev/null +++ b/src/skins/default/en/modules/CDev/ProductComparison/sidebar/script.js @@ -0,0 +1,69 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Product comparison + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +/** + * Widget + */ +function ProductComparisonView(base) +{ + this.callSupermethod('constructor', arguments); + var o = this; + core.bind( + 'updateComparisonList', + function(event, data) { + o.load(); + } + ); +} + +extend(ProductComparisonView, ALoadable); + +ProductComparisonView.autoload = function(){ + new ProductComparisonView(jQuery('.product-comparison')); +}; + +// No shade widget +ProductComparisonView.prototype.shadeWidget = false; + +// Widget target +ProductComparisonView.prototype.widgetTarget = 'main'; + +// Widget class name +ProductComparisonView.prototype.widgetClass = '\\XLite\\Module\\CDev\\ProductComparison\\View\\ProductComparison'; + +// Body handler is binded or not +ProductComparisonView.prototype.bodyHandlerBinded = false; + +// Clear list +ProductComparisonView.prototype.clearList = function() +{ + this.load({action: 'clear'}); + + return false; +} + +// Postprocess widget +ProductComparisonView.prototype.postprocess = function(isSuccess) +{ + this.callSupermethod('postprocess', arguments); + + if (isSuccess) { + var o = this; + + jQuery('.clear-list').click( + function() { + return o.clearList(); + } + ); + } +} + +core.autoload(ProductComparisonView); From d825f80e97aceb29158b5cbf21c97aeee39f1a29 Mon Sep 17 00:00:00 2001 From: skiv Date: Tue, 23 Oct 2012 11:36:05 +0400 Subject: [PATCH 44/85] Product comparison --- .../Controller/Customer/ProductComparison.php | 72 ++++++++++++++ .../View/AddToCompare/AAddToCompare.php | 95 +++++++++++++++++++ .../View/AddToCompare/Products.php | 45 +++++++++ .../View/ProductComparison.php | 2 +- .../compare/products/body.tpl | 12 +++ .../compare/products/script.js | 71 ++++++++++++++ .../CDev/ProductComparison/compare/script.js | 15 +++ .../CDev/ProductComparison/sidebar/body.tpl | 2 +- .../CDev/ProductComparison/sidebar/script.js | 2 +- 9 files changed, 313 insertions(+), 3 deletions(-) create mode 100644 src/classes/XLite/Module/CDev/ProductComparison/Controller/Customer/ProductComparison.php create mode 100644 src/classes/XLite/Module/CDev/ProductComparison/View/AddToCompare/AAddToCompare.php create mode 100644 src/classes/XLite/Module/CDev/ProductComparison/View/AddToCompare/Products.php create mode 100644 src/skins/default/en/modules/CDev/ProductComparison/compare/products/body.tpl create mode 100644 src/skins/default/en/modules/CDev/ProductComparison/compare/products/script.js create mode 100644 src/skins/default/en/modules/CDev/ProductComparison/compare/script.js diff --git a/src/classes/XLite/Module/CDev/ProductComparison/Controller/Customer/ProductComparison.php b/src/classes/XLite/Module/CDev/ProductComparison/Controller/Customer/ProductComparison.php new file mode 100644 index 0000000000..ec293ada12 --- /dev/null +++ b/src/classes/XLite/Module/CDev/ProductComparison/Controller/Customer/ProductComparison.php @@ -0,0 +1,72 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Module\CDev\ProductComparison\Controller\Customer; + +/** + * Product comparison + * + */ +class ProductComparison extends \XLite\Controller\Customer\ACustomer +{ + /** + * Controller parameters + * + * @var array + */ + protected $params = array('target'); + + /** + * Product comparison delete + * + * @return void + */ + protected function doActionDelete() + { + $id = \XLite\Core\Request::getInstance()->product_id; + \XLite\Core\Event::updateProductComparison( + array( + 'productId' => $id, + 'action' => 'delete' + ) + ); + } + + /** + * Product comparison add + * + * @return void + */ + protected function doActionAdd() + { + $id = \XLite\Core\Request::getInstance()->product_id; + \XLite\Core\Event::updateProductComparison( + array( + 'productId' => $id, + 'action' => 'add' + ) + ); + } +} diff --git a/src/classes/XLite/Module/CDev/ProductComparison/View/AddToCompare/AAddToCompare.php b/src/classes/XLite/Module/CDev/ProductComparison/View/AddToCompare/AAddToCompare.php new file mode 100644 index 0000000000..d3848ce770 --- /dev/null +++ b/src/classes/XLite/Module/CDev/ProductComparison/View/AddToCompare/AAddToCompare.php @@ -0,0 +1,95 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Module\CDev\ProductComparison\View\AddToCompare; + +/** + * Add to compare widget + * + * + */ +abstract class AAddToCompare extends \XLite\View\Container +{ + /** + * Checkbox id + * + * @var string + */ + protected $checkboxId; + + /** + * Get checkbox id + * + * @return string + */ + public function getCheckboxId() + { + if (!isset($this->checkboxId)) { + $this->checkboxId = 'product' . rand(); + }; + + return $this->checkboxId; + } + + /** + * Register JS files + * + * @return array + */ + public function getJSFiles() + { + $list = parent::getJSFiles(); + + $list[] = $this->getDir() . '/script.js'; + $list[] = 'modules/CDev/ProductComparison/compare/script.js'; + + return $list; + } + + /** + * Register CSS files + * + * @return array + */ + public function getCSSFiles() + { + $list = parent::getCSSFiles(); + + $list[] = $this->getDir() . '/style.css'; + $list[] = 'modules/CDev/ProductComparison/compare/style.css'; + + return $list; + } + + /** + * Return default template + * + * @return string + */ + protected function getDefaultTemplate() + { + return $this->getDir() . '/body.tpl'; + } +} diff --git a/src/classes/XLite/Module/CDev/ProductComparison/View/AddToCompare/Products.php b/src/classes/XLite/Module/CDev/ProductComparison/View/AddToCompare/Products.php new file mode 100644 index 0000000000..c3742f4aaf --- /dev/null +++ b/src/classes/XLite/Module/CDev/ProductComparison/View/AddToCompare/Products.php @@ -0,0 +1,45 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Module\CDev\ProductComparison\View\AddToCompare; + +/** + * Add to compare widget + * + * + * @ListChild (list="itemsList.product.grid.customer.info", zone="customer", weight="120") + */ +class Products extends \XLite\Module\CDev\ProductComparison\View\AddToCompare\AAddToCompare +{ + /** + * Get widget templates directory + * + * @return string + */ + protected function getDir() + { + return 'modules/CDev/ProductComparison/compare/products'; + } +} diff --git a/src/classes/XLite/Module/CDev/ProductComparison/View/ProductComparison.php b/src/classes/XLite/Module/CDev/ProductComparison/View/ProductComparison.php index 06431bcad1..9e4fb905c1 100644 --- a/src/classes/XLite/Module/CDev/ProductComparison/View/ProductComparison.php +++ b/src/classes/XLite/Module/CDev/ProductComparison/View/ProductComparison.php @@ -58,7 +58,7 @@ protected function getHead() return static::t( 'Compare X products', array( - 'count' => 2 + 'count' => date('h:i:s', time()) ) ); } diff --git a/src/skins/default/en/modules/CDev/ProductComparison/compare/products/body.tpl b/src/skins/default/en/modules/CDev/ProductComparison/compare/products/body.tpl new file mode 100644 index 0000000000..efacc3dc47 --- /dev/null +++ b/src/skins/default/en/modules/CDev/ProductComparison/compare/products/body.tpl @@ -0,0 +1,12 @@ +{* vim: set ts=2 sw=2 sts=2 et: *} + +{** + * Body + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + *} + + diff --git a/src/skins/default/en/modules/CDev/ProductComparison/compare/products/script.js b/src/skins/default/en/modules/CDev/ProductComparison/compare/products/script.js new file mode 100644 index 0000000000..fc20163da9 --- /dev/null +++ b/src/skins/default/en/modules/CDev/ProductComparison/compare/products/script.js @@ -0,0 +1,71 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Product comparison + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +core.bind( + 'load', + function() { + decorate( + 'ProductsListView', + 'postprocess', + function(isSuccess, initial) + { + arguments.callee.previousMethod.apply(this, arguments); + + if (isSuccess) { + + var o = this; + + jQuery('.add-to-compare').not('.binded').each( + function() { + var pr = jQuery(this); + pr.change( + function() { + pr.attr('disabled', 'disabled'); + var action = pr.attr('checked') ? 'add' : 'delete'; + core.post( + URLHandler.buildURL( + { + target: 'product_comparison', + action: action + } + ), + function(){}, + { + target: 'product_comparison', + action: action, + product_id: pr.data('id') + }, + { + rpc: true + } + ); + } + ); + core.bind('updateProductComparison', + function(event, data) { + if (data.productId == pr.data('id')) { + pr.removeAttr('disabled'); + if (data.action == 'add') { + pr.attr('checked', 'checked'); + + } else { + pr.removeAttr('checked'); + } + } + } + ); + } + ).addClass('binded'); + } + } + ); + } +); diff --git a/src/skins/default/en/modules/CDev/ProductComparison/compare/script.js b/src/skins/default/en/modules/CDev/ProductComparison/compare/script.js new file mode 100644 index 0000000000..6c76fba7cc --- /dev/null +++ b/src/skins/default/en/modules/CDev/ProductComparison/compare/script.js @@ -0,0 +1,15 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Product comparison + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +function addToCompare(id) +{ + alert(id); +} diff --git a/src/skins/default/en/modules/CDev/ProductComparison/sidebar/body.tpl b/src/skins/default/en/modules/CDev/ProductComparison/sidebar/body.tpl index a129f28d0d..fc26c2283c 100644 --- a/src/skins/default/en/modules/CDev/ProductComparison/sidebar/body.tpl +++ b/src/skins/default/en/modules/CDev/ProductComparison/sidebar/body.tpl @@ -11,6 +11,6 @@ diff --git a/src/skins/default/en/modules/CDev/ProductComparison/sidebar/script.js b/src/skins/default/en/modules/CDev/ProductComparison/sidebar/script.js index 3ba5de5f1a..11d6437294 100644 --- a/src/skins/default/en/modules/CDev/ProductComparison/sidebar/script.js +++ b/src/skins/default/en/modules/CDev/ProductComparison/sidebar/script.js @@ -17,7 +17,7 @@ function ProductComparisonView(base) this.callSupermethod('constructor', arguments); var o = this; core.bind( - 'updateComparisonList', + 'updateProductComparison', function(event, data) { o.load(); } From cad71b7c712bd1aaf54b9e5b3c7dcd240fc271fd Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Tue, 23 Oct 2012 15:28:05 +0400 Subject: [PATCH 45/85] [*] Minor refactoring in Core/Marketplace.php --- src/classes/XLite/Core/Marketplace.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/classes/XLite/Core/Marketplace.php b/src/classes/XLite/Core/Marketplace.php index 1348ac42de..c23a373745 100644 --- a/src/classes/XLite/Core/Marketplace.php +++ b/src/classes/XLite/Core/Marketplace.php @@ -524,6 +524,8 @@ protected function prepareResponseForGetAddonsAction(array $data) 'isSystem' => (bool) $this->getField($module, static::FIELD_IS_SYSTEM), ); + $result[$key] = array_merge($result[$key], $this->adjustResponseItemForGetAddonsAction($module)); + } else { // :TODO: add logging here @@ -533,6 +535,18 @@ protected function prepareResponseForGetAddonsAction(array $data) return $result; } + /** + * Adjust result array item for get_addons action + * + * @param array $module + * + * @return array + */ + protected function adjustResponseItemForGetAddonsAction($module) + { + return array(); + } + // }}} // {{{ "Get addon pack" request From 6adc38679772e1e2f73155e9100ffe081ae8ae2e Mon Sep 17 00:00:00 2001 From: Vladimir Semenov Date: Wed, 24 Oct 2012 18:11:04 +0400 Subject: [PATCH 46/85] [*] Paypal module: Corrected pattern for checking error message 10486 to redirect customer back to Paypal server after failed payment (Express Checkout) --- .../CDev/Paypal/Model/Payment/Processor/ExpressCheckout.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/XLite/Module/CDev/Paypal/Model/Payment/Processor/ExpressCheckout.php b/src/classes/XLite/Module/CDev/Paypal/Model/Payment/Processor/ExpressCheckout.php index 22d0054d7a..d48b199bbf 100644 --- a/src/classes/XLite/Module/CDev/Paypal/Model/Payment/Processor/ExpressCheckout.php +++ b/src/classes/XLite/Module/CDev/Paypal/Model/Payment/Processor/ExpressCheckout.php @@ -419,7 +419,7 @@ protected function doExpressCheckoutPayment() $status = self::PENDING; } - } elseif (preg_match('/^10486/', $responseData['RESPMSG'])) { + } elseif (preg_match('/^Generic processor error: 10486/', $responseData['RESPMSG'])) { $this->retryExpressCheckout(\XLite\Core\Session::getInstance()->ec_token); } else { From 310bd2d332917f290de1fe1f8cb666ab95a9d956 Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Thu, 1 Nov 2012 11:10:07 +0400 Subject: [PATCH 47/85] [!] Percent shipping markup field has wrong type - decimal(4,2). Fixed: changed to decimal(14,2) --- src/classes/XLite/Model/Shipping/Markup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/XLite/Model/Shipping/Markup.php b/src/classes/XLite/Model/Shipping/Markup.php index 6877eb705d..f2dbfc1be9 100644 --- a/src/classes/XLite/Model/Shipping/Markup.php +++ b/src/classes/XLite/Model/Shipping/Markup.php @@ -124,7 +124,7 @@ class Markup extends \XLite\Model\AEntity * * @var float * - * @Column (type="decimal", precision=4, scale=2) + * @Column (type="decimal", precision=14, scale=2) */ protected $markup_percent = 0; From 901bccd62bf1fb668cbff6e5fa9de16567f80d2f Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Thu, 1 Nov 2012 12:30:11 +0400 Subject: [PATCH 48/85] E:0042336 [*] Admin did not get any warnings if payment method does not support the current store currency and is not available for customers. Fixed (added warning on the payment list) --- src/classes/XLite/Model/Payment/Base/Processor.php | 14 ++++++++++++++ src/classes/XLite/Module/CDev/Paypal/Main.php | 14 ++++++++++---- .../CDev/Paypal/View/Button/ButtonsSeparator.php | 4 ++-- .../CDev/Paypal/View/Button/ExpressCheckout.php | 4 ++-- .../payment/methods/parts/action.right.tpl | 3 +++ 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/classes/XLite/Model/Payment/Base/Processor.php b/src/classes/XLite/Model/Payment/Base/Processor.php index fec03bbf9f..fa48ba31fd 100644 --- a/src/classes/XLite/Model/Payment/Base/Processor.php +++ b/src/classes/XLite/Model/Payment/Base/Processor.php @@ -234,6 +234,20 @@ public function isConfigured(\XLite\Model\Payment\Method $method) return true; } + /** + * Return true if payment method supports currency defined in store + * + * @param \XLite\Model\Payment\Method $method Payment method + * + * @return boolean + */ + public function isCurrencyApplicable(\XLite\Model\Payment\Method $method) + { + $currencies = $this->getAllowedCurrencies($method); + + return !$currencies || in_array(\XLite::getInstance()->getCurrency()->getCode(), $currencies); + } + /** * Check - payment processor is applicable for specified order or not * diff --git a/src/classes/XLite/Module/CDev/Paypal/Main.php b/src/classes/XLite/Module/CDev/Paypal/Main.php index c3fe7e2bf7..ed3879b8cf 100644 --- a/src/classes/XLite/Module/CDev/Paypal/Main.php +++ b/src/classes/XLite/Module/CDev/Paypal/Main.php @@ -136,11 +136,13 @@ public static function addLog($message = null, $data = null) * * @return boolean */ - public static function isExpressCheckoutEnabled() + public static function isExpressCheckoutEnabled($order = null) { static $result; - if (!isset($result)) { + $index = isset($order) ? 1 : 0; + + if (!isset($result[$index])) { $paymentMethod = \XLite\Core\Database::getRepo('XLite\Model\Payment\Method') ->findOneBy( array( @@ -148,10 +150,14 @@ public static function isExpressCheckoutEnabled() 'enabled' => true ) ); - $result = !empty($paymentMethod) && $paymentMethod->isEnabled(); + $result[$index] = !empty($paymentMethod) && $paymentMethod->isEnabled(); + + if ($order) { + $result[$index] = $paymentMethod->getProcessor()->isApplicable($order, $paymentMethod); + } } - return $result; + return $result[$index]; } /** diff --git a/src/classes/XLite/Module/CDev/Paypal/View/Button/ButtonsSeparator.php b/src/classes/XLite/Module/CDev/Paypal/View/Button/ButtonsSeparator.php index ecd007f0d5..0f7126f8af 100644 --- a/src/classes/XLite/Module/CDev/Paypal/View/Button/ButtonsSeparator.php +++ b/src/classes/XLite/Module/CDev/Paypal/View/Button/ButtonsSeparator.php @@ -42,8 +42,8 @@ class ButtonsSeparator extends \XLite\View\Button\ButtonsSeparator protected function isVisible() { return parent::isVisible() - && \XLite\Module\CDev\Paypal\Main::isExpressCheckoutEnabled() && $this->getCart() - && (0 < $this->getCart()->getTotal()); + && (0 < $this->getCart()->getTotal()) + && \XLite\Module\CDev\Paypal\Main::isExpressCheckoutEnabled($this->getCart()); } } diff --git a/src/classes/XLite/Module/CDev/Paypal/View/Button/ExpressCheckout.php b/src/classes/XLite/Module/CDev/Paypal/View/Button/ExpressCheckout.php index e0f49abaef..55399c08e1 100644 --- a/src/classes/XLite/Module/CDev/Paypal/View/Button/ExpressCheckout.php +++ b/src/classes/XLite/Module/CDev/Paypal/View/Button/ExpressCheckout.php @@ -64,9 +64,9 @@ protected function getTemplate() protected function isVisible() { return parent::isVisible() - && \XLite\Module\CDev\Paypal\Main::isExpressCheckoutEnabled() && $this->getCart() - && (0 < $this->getCart()->getTotal()); + && (0 < $this->getCart()->getTotal()) + && \XLite\Module\CDev\Paypal\Main::isExpressCheckoutEnabled($this->getCart()); } /** diff --git a/src/skins/admin/en/items_list/payment/methods/parts/action.right.tpl b/src/skins/admin/en/items_list/payment/methods/parts/action.right.tpl index a26222a077..0953c0ba4e 100644 --- a/src/skins/admin/en/items_list/payment/methods/parts/action.right.tpl +++ b/src/skins/admin/en/items_list/payment/methods/parts/action.right.tpl @@ -20,6 +20,9 @@ {if:method.getWarningNote()}
      {method.getWarningNote()}
      + {elseif:!method.isCurrencyApplicable()} + +
      {t(#This method does not support the current store currency and is not available for customers#)}
      {elseif:method.isTestMode()}
      {t(#This method is in test mode#)}
      From 273e730b1cbc0e821953ba3cf8939ba77a703a9f Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Thu, 1 Nov 2012 14:18:04 +0400 Subject: [PATCH 49/85] E:0042289 [*] DrupalConnector module: Option General->products_per_page added to the list of disabled options --- .../XLite/Module/CDev/DrupalConnector/Model/Repo/Config.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/classes/XLite/Module/CDev/DrupalConnector/Model/Repo/Config.php b/src/classes/XLite/Module/CDev/DrupalConnector/Model/Repo/Config.php index e6a0d6aed2..6c70d1ef85 100644 --- a/src/classes/XLite/Module/CDev/DrupalConnector/Model/Repo/Config.php +++ b/src/classes/XLite/Module/CDev/DrupalConnector/Model/Repo/Config.php @@ -46,5 +46,6 @@ public function __construct(\Doctrine\ORM\EntityManager $em, \Doctrine\ORM\Mappi $this->disableOption('General', 'operation_presentation'); $this->disableOption('General', 'shop_closed'); $this->disableOption('General', 'subcategories_look'); + $this->disableOption('General', 'products_per_page'); } } From 4b73bc743c2a302d9cc9acfbab2c549a2f4efb52 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Thu, 1 Nov 2012 14:25:18 +0400 Subject: [PATCH 50/85] [!] E:42335 Bug: ID was not unique on the marketplace page. --- src/skins/admin/en/modules_manager/license/body.tpl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/skins/admin/en/modules_manager/license/body.tpl b/src/skins/admin/en/modules_manager/license/body.tpl index 9a30702cc3..7db47424b6 100644 --- a/src/skins/admin/en/modules_manager/license/body.tpl +++ b/src/skins/admin/en/modules_manager/license/body.tpl @@ -40,8 +40,10 @@
      - - +
      From 5c8a20bc6e03efa2a58fb31e8c506f07dea2f9f7 Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Thu, 1 Nov 2012 19:14:44 +0400 Subject: [PATCH 51/85] E:0042184 [!] Import products issue: import routime breaks with internal error if CSV-file contains products with same cleanURLs. Fixed. --- .../XLite/Controller/Admin/ImportExport.php | 32 ++++++++++++++++++- src/classes/XLite/Model/Repo/Product.php | 30 +++++++++++++++++ src/sql/xlite_data.yaml | 2 ++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/classes/XLite/Controller/Admin/ImportExport.php b/src/classes/XLite/Controller/Admin/ImportExport.php index 29a42105d3..2dc0119025 100644 --- a/src/classes/XLite/Controller/Admin/ImportExport.php +++ b/src/classes/XLite/Controller/Admin/ImportExport.php @@ -85,6 +85,14 @@ class ImportExport extends \XLite\Controller\Admin\AAdmin */ protected $importCell; + /** + * Clean URLs cache + * + * @var array + */ + protected $cleanURLs = array(); + + /** * Check ACL permissions * @@ -739,6 +747,8 @@ protected function startImportStep() } } } + + $this->cleanURLs = \XLite\Core\Database::getRepo('XLite\Model\Product')->findAllCleanURLs(); } /** @@ -1028,7 +1038,27 @@ protected function importCleanURL(\XLite\Model\Product $product, $data) $product->setCleanURL(null); } else { - $product->setCleanURL($data); + + if (isset($this->cleanURLs[$data]) && (empty($this->cleanURLs[$data]) || intval($product->getProductId()) != $this->cleanURLs[$data])) { + + // Add log message + $this->logImportWarning( + static::t( + 'Duplicated clean URL: X', + array('value' => $data) + ), + $this->importCell['position'], + 'cleanURL', + $data, + $product + ); + + $product->setCleanURL(null); + + } else { + $product->setCleanURL($data); + $this->cleanURLs[$data] = 0; + } } } diff --git a/src/classes/XLite/Model/Repo/Product.php b/src/classes/XLite/Model/Repo/Product.php index 47e482d895..9f18dd135c 100644 --- a/src/classes/XLite/Model/Repo/Product.php +++ b/src/classes/XLite/Model/Repo/Product.php @@ -80,6 +80,36 @@ class Product extends \XLite\Model\Repo\Base\I18n implements \XLite\Base\IREST ); + /** + * Get the list of all clean URLS + * + * @return array + */ + public function findAllCleanURLs() + { + $result = array(); + + $products = $this->defineAllCleanURLsQuery()->getArrayResult(); + + foreach($products as $row) { + $result[$row['cleanURL']] = $row['product_id']; + } + + return $result; + } + + /** + * Define the Doctrine query + * + * @return \Doctrine\ORM\QueryBuilder + */ + protected function defineAllCleanURLsQuery() + { + return $this->createPureQueryBuilder() + ->select('p.product_id') + ->addSelect('p.cleanURL'); + } + /** * Common search * diff --git a/src/sql/xlite_data.yaml b/src/sql/xlite_data.yaml index 52b0851472..3383c12b3b 100644 --- a/src/sql/xlite_data.yaml +++ b/src/sql/xlite_data.yaml @@ -491,6 +491,8 @@ XLite\Model\LanguageLabel: - { name: 'Payment method has been enabled successfully', translations: [{ code: en, label: 'Payment method has been enabled successfully' }] } - { name: 'Payment method has been disabled successfully', translations: [{ code: en, label: 'Payment method has been disabled successfully' }] } - { name: 'Payment method has been removed successfully', translations: [{ code: en, label: 'Payment method has been removed successfully' }] } + - { name: 'Duplicated clean URL: X', translations: [{ code: en, label: 'Duplicated clean URL: {{value}}' }] } + XLite\Model\Membership: directives: { insert: true } - { orderby: 10, translations: [{ code: en, name: Gold }] } From 3cbbcc13638673d44887aaaca88deae85aa2332e Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Fri, 2 Nov 2012 14:11:08 +0400 Subject: [PATCH 52/85] E:42186 [!] Button tags had wrong content. --- src/skins/admin/en/button/js/remove.js | 9 ++++----- src/skins/admin/en/button/remove.tpl | 9 +++++---- src/skins/admin/en/items_list/model/style.css | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/skins/admin/en/button/js/remove.js b/src/skins/admin/en/button/js/remove.js index f4eeea1bc8..b1cc68a1d0 100644 --- a/src/skins/admin/en/button/js/remove.js +++ b/src/skins/admin/en/button/js/remove.js @@ -11,21 +11,20 @@ CommonForm.elementControllers.push( { - pattern: '.line .actions button.remove', + pattern: '.line .actions .remove-wrapper', handler: function () { - var inp = jQuery('input', this); - var btn = jQuery(this); + var inp = jQuery('input', this).eq(0); + var btn = jQuery('button.remove', this); var cell = btn.parents('.line').eq(0); btn.click( function () { if (inp.attr('checked')) { inp.removeAttr('checked'); - } else { inp.attr('checked', 'checked'); - inp.get(0).setAttribute('checked', 'checked'); } + inp.change(); } ); diff --git a/src/skins/admin/en/button/remove.tpl b/src/skins/admin/en/button/remove.tpl index 8073282629..2c781ca8a1 100644 --- a/src/skins/admin/en/button/remove.tpl +++ b/src/skins/admin/en/button/remove.tpl @@ -8,8 +8,9 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ *} - - - - +
      diff --git a/src/skins/admin/en/items_list/model/style.css b/src/skins/admin/en/items_list/model/style.css index 46c45f5179..7e8c0a47e6 100644 --- a/src/skins/admin/en/items_list/model/style.css +++ b/src/skins/admin/en/items_list/model/style.css @@ -9,7 +9,7 @@ * @link http://www.litecommerce.com/ */ -.items-list button.remove input { +.items-list .remove-wrapper input { display: none; } From 1e39b5a56f6462373038ac80aca3cd3862494239 Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Tue, 6 Nov 2012 12:13:08 +0400 Subject: [PATCH 53/85] E:0042349 [!] Paypal module: PHP error on add-to-cart event if payment_method still unknown. Fixed. --- src/classes/XLite/Module/CDev/Paypal/Main.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/classes/XLite/Module/CDev/Paypal/Main.php b/src/classes/XLite/Module/CDev/Paypal/Main.php index ed3879b8cf..292002f9b4 100644 --- a/src/classes/XLite/Module/CDev/Paypal/Main.php +++ b/src/classes/XLite/Module/CDev/Paypal/Main.php @@ -133,7 +133,9 @@ public static function addLog($message = null, $data = null) /** * Returns true if ExpressCheckout payment is enabled - * + * + * @param \XLite\Model\Cart $order Cart object OPTIONAL + * * @return boolean */ public static function isExpressCheckoutEnabled($order = null) @@ -152,7 +154,7 @@ public static function isExpressCheckoutEnabled($order = null) ); $result[$index] = !empty($paymentMethod) && $paymentMethod->isEnabled(); - if ($order) { + if ($order && $result[$index]) { $result[$index] = $paymentMethod->getProcessor()->isApplicable($order, $paymentMethod); } } From a0064c14a8d346c66f82d84b39df488c9336f5be Mon Sep 17 00:00:00 2001 From: skiv Date: Tue, 6 Nov 2012 16:02:13 +0400 Subject: [PATCH 54/85] Product comparison --- .../Controller/Customer/ProductComparison.php | 24 +++- .../CDev/ProductComparison/Core/Data.php | 109 ++++++++++++++++++ .../View/AddToCompare/AAddToCompare.php | 34 +++++- .../View/ProductComparison.php | 2 +- .../compare/products/body.tpl | 14 ++- .../compare/products/script.js | 27 ++++- .../compare/products/style.css | 80 +++++++++++++ 7 files changed, 280 insertions(+), 10 deletions(-) create mode 100644 src/classes/XLite/Module/CDev/ProductComparison/Core/Data.php create mode 100644 src/skins/default/en/modules/CDev/ProductComparison/compare/products/style.css diff --git a/src/classes/XLite/Module/CDev/ProductComparison/Controller/Customer/ProductComparison.php b/src/classes/XLite/Module/CDev/ProductComparison/Controller/Customer/ProductComparison.php index ec293ada12..77c79cbd38 100644 --- a/src/classes/XLite/Module/CDev/ProductComparison/Controller/Customer/ProductComparison.php +++ b/src/classes/XLite/Module/CDev/ProductComparison/Controller/Customer/ProductComparison.php @@ -46,10 +46,12 @@ class ProductComparison extends \XLite\Controller\Customer\ACustomer protected function doActionDelete() { $id = \XLite\Core\Request::getInstance()->product_id; + \XLite\Module\CDev\ProductComparison\Core\Data::getInstance()->deleteProductId($id); \XLite\Core\Event::updateProductComparison( array( 'productId' => $id, - 'action' => 'delete' + 'action' => 'delete', + 'title' => $this->getTitle() ) ); } @@ -62,11 +64,29 @@ protected function doActionDelete() protected function doActionAdd() { $id = \XLite\Core\Request::getInstance()->product_id; + \XLite\Module\CDev\ProductComparison\Core\Data::getInstance()->addProductId($id); \XLite\Core\Event::updateProductComparison( array( 'productId' => $id, - 'action' => 'add' + 'action' => 'add', + 'title' => $this->getTitle() ) ); } + + /** + * Get title + * + * @return string + */ + public function getTitle() + { + return static::t( + 'X products selected', + array( + 'count' => \XLite\Module\CDev\ProductComparison\Core\Data::getInstance()->getProductsCount() + ) + ); + } + } diff --git a/src/classes/XLite/Module/CDev/ProductComparison/Core/Data.php b/src/classes/XLite/Module/CDev/ProductComparison/Core/Data.php new file mode 100644 index 0000000000..6c9b546b4b --- /dev/null +++ b/src/classes/XLite/Module/CDev/ProductComparison/Core/Data.php @@ -0,0 +1,109 @@ + + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ + +namespace XLite\Module\CDev\ProductComparison\Core; + +/** + * Data class + * + */ +class Data extends \XLite\Base\Singleton +{ + /** + * Products count + * + * @var integer + */ + protected $productsCount; + + /** + * Product ids + * + * @var array + */ + protected $productIds; + + /** + * Get products count + * + * @return integer + */ + public function getProductsCount() + { + if (!isset($this->productsCount)) { + $this->productsCount = count($this->getProductIds()); + } + + return $this->productsCount; + } + + /** + * Add product id + * + * @param integer $productId Product id + * + * @return void + */ + public function addProductId($productId) + { + $ids = $this->getProductIds(); + $ids[$productId] = $productId; + $this->productIds = $ids; + \XLite\Core\Session::getInstance()->productComparisonIds = $ids; + } + + /** + * Delete product id + * + * @param integer $productId Product id + * + * @return void + */ + public function deleteProductId($productId) + { + $ids = $this->getProductIds(); + if (isset($ids[$productId])) { + unset($ids[$productId]); + } + $this->productIds = $ids; + \XLite\Core\Session::getInstance()->productComparisonIds = $ids; + } + + /** + * Get product ids + * + * @return array + */ + protected function getProductIds() + { + if (!isset($this->productIds)) { + $this->productIds = \XLite\Core\Session::getInstance()->productComparisonIds; + } + + return is_array($this->productIds) + ? $this->productIds + : array(); + } +} diff --git a/src/classes/XLite/Module/CDev/ProductComparison/View/AddToCompare/AAddToCompare.php b/src/classes/XLite/Module/CDev/ProductComparison/View/AddToCompare/AAddToCompare.php index d3848ce770..d4a7ea9bc1 100644 --- a/src/classes/XLite/Module/CDev/ProductComparison/View/AddToCompare/AAddToCompare.php +++ b/src/classes/XLite/Module/CDev/ProductComparison/View/AddToCompare/AAddToCompare.php @@ -39,16 +39,29 @@ abstract class AAddToCompare extends \XLite\View\Container */ protected $checkboxId; + /** + * Product id + * + * @var string + */ + protected $productId; + /** * Get checkbox id * + * @param integer $productId Product id + * * @return string */ - public function getCheckboxId() + public function getCheckboxId($productId) { - if (!isset($this->checkboxId)) { - $this->checkboxId = 'product' . rand(); + if ( + !isset($this->checkboxId) + || $productId != $this->productId + ) { + $this->checkboxId = 'product' . rand() . $productId; }; + $this->productId = $productId; return $this->checkboxId; } @@ -92,4 +105,19 @@ protected function getDefaultTemplate() { return $this->getDir() . '/body.tpl'; } + + /** + * Get title + * + * @return string + */ + public function getTitle() + { + return static::t( + 'X products selected', + array( + 'count' => \XLite\Module\CDev\ProductComparison\Core\Data::getInstance()->getProductsCount() + ) + ); + } } diff --git a/src/classes/XLite/Module/CDev/ProductComparison/View/ProductComparison.php b/src/classes/XLite/Module/CDev/ProductComparison/View/ProductComparison.php index 9e4fb905c1..fa862cff71 100644 --- a/src/classes/XLite/Module/CDev/ProductComparison/View/ProductComparison.php +++ b/src/classes/XLite/Module/CDev/ProductComparison/View/ProductComparison.php @@ -58,7 +58,7 @@ protected function getHead() return static::t( 'Compare X products', array( - 'count' => date('h:i:s', time()) + 'count' => \XLite\Module\CDev\ProductComparison\Core\Data::getInstance()->getProductsCount() ) ); } diff --git a/src/skins/default/en/modules/CDev/ProductComparison/compare/products/body.tpl b/src/skins/default/en/modules/CDev/ProductComparison/compare/products/body.tpl index efacc3dc47..679c9bcdc8 100644 --- a/src/skins/default/en/modules/CDev/ProductComparison/compare/products/body.tpl +++ b/src/skins/default/en/modules/CDev/ProductComparison/compare/products/body.tpl @@ -8,5 +8,15 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ *} - - +
      +
      +
      + + +
      +
      + {getTitle()} + +
      +
      +
      diff --git a/src/skins/default/en/modules/CDev/ProductComparison/compare/products/script.js b/src/skins/default/en/modules/CDev/ProductComparison/compare/products/script.js index fc20163da9..858eeeeec8 100644 --- a/src/skins/default/en/modules/CDev/ProductComparison/compare/products/script.js +++ b/src/skins/default/en/modules/CDev/ProductComparison/compare/products/script.js @@ -22,8 +22,30 @@ core.bind( if (isSuccess) { var o = this; + + jQuery('div.product').mouseover( + function() { + jQuery(this).addClass('compare'); + } + ).mouseout( + function() { + jQuery(this).removeClass('compare'); + } + ); + + jQuery('div.compare-checkbox').mouseover( + function() { + jQuery(this).parent().addClass('visible'); + } + ); + + jQuery('div.compare-popup').mouseleave( + function() { + jQuery(this).removeClass('visible'); + } + ); - jQuery('.add-to-compare').not('.binded').each( + jQuery('.compare-checkbox input').not('.binded').each( function() { var pr = jQuery(this); pr.change( @@ -58,8 +80,9 @@ core.bind( } else { pr.removeAttr('checked'); - } + } } + pr.parent().parent().find('.compare-products-selected').text(data.title); } ); } diff --git a/src/skins/default/en/modules/CDev/ProductComparison/compare/products/style.css b/src/skins/default/en/modules/CDev/ProductComparison/compare/products/style.css new file mode 100644 index 0000000000..4ca93fc004 --- /dev/null +++ b/src/skins/default/en/modules/CDev/ProductComparison/compare/products/style.css @@ -0,0 +1,80 @@ +/* vim: set ts=2 sw=2 sts=2 et: */ + +/** + * Styles + * + * @author Creative Development LLC + * @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link http://www.litecommerce.com/ + */ +div.add-to-compare { + display: none; + width: 100%; + text-align: center; + position: absolute; + top: 170px; + left: 0; +} + +div.add-to-compare div.compare-popup { + margin: 0 30px; + top: 1px; + position: relative; +} + +div.add-to-compare div.compare-popup.visible { + margin: 0 29px; + top: 0; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + border: solid 1px #bbc7d2; + box-shadow: 2px 2px 3px #bbc7d2; + -moz-box-shadow: 2px 2px 3px #bbc7d2; + -webkit-box-shadow: 2px 2px 3px #bbc7d2; + background-color: #fff; +} + +div.add-to-compare div.compare-checkbox { + margin: 10px 30px; + position: relative; + top: 0; + padding: 2px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + border: solid 1px #d7e1e8; + background-color: #eaf6fe; +} + +div.add-to-compare div.compare-checkbox label { + font-size: 12px; + color: #446482; +} + +div.add-to-compare div.compare-button { + display: none; + margin: 10px 0; + background-color: #fff; + color: #2c5fa6; + font-size: 14px; +} + +div.add-to-compare div.compare-popup.visible div.compare-button { + display: block; +} + +div.product.compare div.add-to-compare { + display: block; +} + +div.compare-button button { + margin: 10px 0 5px 0; + padding: 6px 6px; +} + +div.compare-button button span { + background: url(../../scales_icon.png) no-repeat 4px top transparent; + padding: 4px 4px 4px 36px; +} From 9aec2dfe104caed92b22284b5b365285bb942e57 Mon Sep 17 00:00:00 2001 From: skiv Date: Tue, 6 Nov 2012 16:06:20 +0400 Subject: [PATCH 55/85] Attributes --- src/classes/XLite/View/Attributes.php | 2 ++ src/classes/XLite/View/ItemsList/Model/Attribute.php | 10 ++++++++++ .../XLite/View/ItemsList/Model/AttributeGroup.php | 10 ++++++++++ .../XLite/View/ItemsList/Model/AttributeOption.php | 10 ++++++++++ .../XLite/View/Product/Details/Customer/Attributes.php | 2 +- 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/classes/XLite/View/Attributes.php b/src/classes/XLite/View/Attributes.php index a0169d0c04..b5ac95e0c1 100644 --- a/src/classes/XLite/View/Attributes.php +++ b/src/classes/XLite/View/Attributes.php @@ -61,6 +61,7 @@ public function getCSSFiles() $list[] = 'items_list/items_list.css'; $list[] = 'items_list/model/style.css'; $list[] = 'items_list/model/table/style.css'; + $list[] = 'form_field/inline/input/text.css'; return $list; } @@ -82,6 +83,7 @@ public function getJSFiles() $list[] = 'items_list/items_list.js'; $list[] = 'items_list/model/table/controller.js'; $list[] = 'attributes/script.js'; + $list[] = 'form_field/inline/input/text.js'; return $list; } diff --git a/src/classes/XLite/View/ItemsList/Model/Attribute.php b/src/classes/XLite/View/ItemsList/Model/Attribute.php index c8888dccea..88685999a7 100644 --- a/src/classes/XLite/View/ItemsList/Model/Attribute.php +++ b/src/classes/XLite/View/ItemsList/Model/Attribute.php @@ -165,6 +165,16 @@ protected function isVisible() || 0 < $this->getItemsCount(); } + /** + * Check - pager box is visible or not + * + * @return boolean + */ + protected function isPagerVisible() + { + return false; + } + // }}} /** diff --git a/src/classes/XLite/View/ItemsList/Model/AttributeGroup.php b/src/classes/XLite/View/ItemsList/Model/AttributeGroup.php index b4ac05e786..949f702f23 100644 --- a/src/classes/XLite/View/ItemsList/Model/AttributeGroup.php +++ b/src/classes/XLite/View/ItemsList/Model/AttributeGroup.php @@ -159,6 +159,16 @@ protected function createEntity() return $entity; } + /** + * Check - pager box is visible or not + * + * @return boolean + */ + protected function isPagerVisible() + { + return false; + } + // {{{ Search /** diff --git a/src/classes/XLite/View/ItemsList/Model/AttributeOption.php b/src/classes/XLite/View/ItemsList/Model/AttributeOption.php index 8808ca5cf2..572cb00eb3 100644 --- a/src/classes/XLite/View/ItemsList/Model/AttributeOption.php +++ b/src/classes/XLite/View/ItemsList/Model/AttributeOption.php @@ -159,6 +159,16 @@ protected function createEntity() return $entity; } + /** + * Check - pager box is visible or not + * + * @return boolean + */ + protected function isPagerVisible() + { + return false; + } + // {{{ Search /** diff --git a/src/classes/XLite/View/Product/Details/Customer/Attributes.php b/src/classes/XLite/View/Product/Details/Customer/Attributes.php index a6f7cbeec7..942efd4f8a 100644 --- a/src/classes/XLite/View/Product/Details/Customer/Attributes.php +++ b/src/classes/XLite/View/Product/Details/Customer/Attributes.php @@ -72,7 +72,7 @@ public function getAttrList() */ protected function getFieldClass(\XLite\Model\Attribute $attribute, $value) { - $class = strtolower($a->getTypes($attribute->getType())); + $class = strtolower($attribute->getTypes($attribute->getType())); if (\XLite\Model\Attribute::TYPE_CHECKBOX == $attribute->getType()) { $class .= ' ' . (static::t('yes') == $value ? 'checked' : 'no-checked'); } From 73195d29682b294fedc9ee669ecb8dfad595c44a Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Wed, 7 Nov 2012 12:37:15 +0400 Subject: [PATCH 56/85] [!] Bug: Transparency attribute was not on the appropriate element. --- src/skins/admin/en/items_list/model/table/style.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/skins/admin/en/items_list/model/table/style.css b/src/skins/admin/en/items_list/model/table/style.css index 4c9076de11..120058ffe9 100644 --- a/src/skins/admin/en/items_list/model/table/style.css +++ b/src/skins/admin/en/items_list/model/table/style.css @@ -169,8 +169,9 @@ color: #d91a1a; } -.items-list-table table.list tbody tr.line.remove-mark { - opacity: .3; +.items-list-table table.list tbody tr.line.remove-mark * { + opacity: .7; + filter: alpha(opacity=70); } .items-list-table table.list tbody .inline-field .field { From 9110c321508fe2d98f5d7c860ba5b16aa3fd95b4 Mon Sep 17 00:00:00 2001 From: skiv Date: Wed, 7 Nov 2012 14:13:59 +0400 Subject: [PATCH 57/85] Attributes --- src/skins/admin/en/form_field/input/text/combobox.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/skins/admin/en/form_field/input/text/combobox.css b/src/skins/admin/en/form_field/input/text/combobox.css index 0b8e97d25c..0144459090 100644 --- a/src/skins/admin/en/form_field/input/text/combobox.css +++ b/src/skins/admin/en/form_field/input/text/combobox.css @@ -15,7 +15,7 @@ input.combobox { } div.combobox-select { - background: transparent url(../images/arrows-select.png) center center no-repeat; + background: transparent url(../../../images/arrows-select.png) center center no-repeat; width: 21px; height: 21px; float: left; From 580371718d54f251b9be3e45070180bebc5b7e10 Mon Sep 17 00:00:00 2001 From: skiv Date: Wed, 7 Nov 2012 14:40:10 +0400 Subject: [PATCH 58/85] Attributes --- src/classes/XLite/Model/Attribute.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/classes/XLite/Model/Attribute.php b/src/classes/XLite/Model/Attribute.php index d8f3a79457..eced1feccb 100644 --- a/src/classes/XLite/Model/Attribute.php +++ b/src/classes/XLite/Model/Attribute.php @@ -121,7 +121,7 @@ class Attribute extends \XLite\Model\Base\I18n * * @Column (type="fixedstring", length=1) */ - protected $type = self::TYPE_NUMBER; + protected $type = self::TYPE_TEXT; /** * Constructor @@ -157,8 +157,8 @@ public function getProductsCount() public static function getTypes($type = null) { $list = array( - self::TYPE_NUMBER => 'Number', self::TYPE_TEXT => 'Text', + self::TYPE_NUMBER => 'Number', self::TYPE_CHECKBOX => 'Checkbox', self::TYPE_SELECT => 'Select', ); @@ -234,9 +234,16 @@ public function setDefaultValue($value) */ public function getDefaultValue() { - return self::TYPE_CHECKBOX == $this->type - ? (boolean)$this->defaultValue - : $this->defaultValue; + $value = $this->defaultValue; + if (self::TYPE_NUMBER == $this->type) { + $value = (float)$value; + + } elseif (self::TYPE_CHECKBOX == $this->type) { + $value = (boolean)$value; + + } + + return $value; } /** From f1a95bde1cafc92914159269ee17e9423bbb6210 Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Wed, 7 Nov 2012 15:30:58 +0400 Subject: [PATCH 59/85] E:0042271 [*] Phone orderig payment method is enabled by default --- src/sql/xlite_data.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/xlite_data.yaml b/src/sql/xlite_data.yaml index 3383c12b3b..f09df8799c 100644 --- a/src/sql/xlite_data.yaml +++ b/src/sql/xlite_data.yaml @@ -684,7 +684,7 @@ XLite\Model\Language: XLite\Model\Payment\Method: directives: { insert: true } - { service_name: PurchaseOrder, class: 'Model\Payment\Processor\PurchaseOrder', added: true, orderby: 20, translations: [{ code: en, name: 'Purchase Order' }] } - - { service_name: PhoneOrdering, class: 'Model\Payment\Processor\Offline', added: true, orderby: 30, translations: [{ code: en, name: 'Phone Ordering', description: 'Phone: (555) 555-5555' }] } + - { service_name: PhoneOrdering, class: 'Model\Payment\Processor\Offline', added: true, enabled: true, orderby: 30, translations: [{ code: en, name: 'Phone Ordering', description: 'Phone: (555) 555-5555' }] } - { service_name: FaxOrdering, class: 'Model\Payment\Processor\Offline', added: true, orderby: 40, translations: [{ code: en, name: 'Fax Ordering', description: 'Fax: (555) 555-5555' }] } - { service_name: MoneyOrdering, class: 'Model\Payment\Processor\Offline', added: true, orderby: 50, translations: [{ code: en, name: 'Money Order', description: 'US Banks Only' }] } - { service_name: Echeck, class: 'Model\Payment\Processor\Check', added: true, orderby: 60, translations: [{ code: en, name: Check, description: 'Check payment' }] } From 049cfe45446bd74b94f212a59953aadb1342b4bb Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Wed, 7 Nov 2012 18:17:16 +0400 Subject: [PATCH 60/85] E:0042371 [!] Bug: e parameter didn't affected getValue() method in XLite\View\FormField\Input\Text\Float widget. Fixed. --- .../XLite/View/FormField/Input/Text/Float.php | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/classes/XLite/View/FormField/Input/Text/Float.php b/src/classes/XLite/View/FormField/Input/Text/Float.php index 54df94d686..d42e1c3fce 100644 --- a/src/classes/XLite/View/FormField/Input/Text/Float.php +++ b/src/classes/XLite/View/FormField/Input/Text/Float.php @@ -50,6 +50,16 @@ public function getJSFiles() return $list; } + /** + * Get value + * + * @return float + */ + public function getValue() + { + return $this->sanitizeFloat(parent::getValue()); + } + /** * Define widget params * @@ -71,7 +81,17 @@ protected function defineWidgetParams() */ protected function sanitize() { - return round(doubleval(parent::sanitize()), $this->getParam(self::PARAM_E)); + return $this->sanitizeFloat(parent::sanitize()); + } + + /** + * Sanitize value + * + * @return mixed + */ + protected function sanitizeFloat($value) + { + return round(doubleval($value), $this->getParam(self::PARAM_E)); } /** From ff51e819eb71e977e0b455edbc17ccad61e2098e Mon Sep 17 00:00:00 2001 From: skiv Date: Thu, 8 Nov 2012 11:17:15 +0400 Subject: [PATCH 61/85] Attributes --- src/classes/XLite/Controller/Admin/Product.php | 4 ++-- src/classes/XLite/Model/Attribute.php | 1 + src/classes/XLite/Model/Product.php | 17 +++++++++++++++++ .../Product/Details/Customer/Attributes.php | 2 +- .../Product/Details/Customer/Page/APage.php | 2 +- src/skins/admin/en/attributes/body.tpl | 4 ++++ src/skins/admin/en/product/attributes.tpl | 2 +- src/skins/default/en/css/lc.css | 5 +++-- 8 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/classes/XLite/Controller/Admin/Product.php b/src/classes/XLite/Controller/Admin/Product.php index cfe7a1d316..3e358db26c 100644 --- a/src/classes/XLite/Controller/Admin/Product.php +++ b/src/classes/XLite/Controller/Admin/Product.php @@ -99,7 +99,7 @@ public function getPages() if (!$this->isNew()) { $list['images'] = 'Product images'; $list['inventory'] = 'Inventory tracking'; - if ($this->getProduct()->getClasses()->count()) { + if ($this->getProduct()->getAttributesCount()) { $list['attributes'] = 'Attributes'; } } @@ -121,7 +121,7 @@ protected function getPageTemplates() if (!$this->isNew()) { $list['images'] = 'product/product_images.tpl'; $list['inventory'] = 'product/inventory.tpl'; - if ($this->getProduct()->getClasses()->count()) { + if ($this->getProduct()->getAttributesCount()) { $list['attributes'] = 'product/attributes.tpl'; } } diff --git a/src/classes/XLite/Model/Attribute.php b/src/classes/XLite/Model/Attribute.php index eced1feccb..a6b4e69102 100644 --- a/src/classes/XLite/Model/Attribute.php +++ b/src/classes/XLite/Model/Attribute.php @@ -320,6 +320,7 @@ public function setAttributeValue(\XLite\Model\Product $product, $value) } if (self::TYPE_SELECT == $this->getType()) { + $value = trim($value); if ($value) { $attributeOption = \XLite\Core\Database::getRepo('XLite\Model\AttributeOption') ->findOneByNameAndAttribute($value, $this); diff --git a/src/classes/XLite/Model/Product.php b/src/classes/XLite/Model/Product.php index 300a93a878..9b5ee7891d 100644 --- a/src/classes/XLite/Model/Product.php +++ b/src/classes/XLite/Model/Product.php @@ -616,4 +616,21 @@ protected function getLink($categoryId = null) return $result; } + + /** + * Return number of attributes associated with this product + * + * @return integer + */ + public function getAttributesCount() + { + $count = 0; + if ($this->getClasses()) { + foreach ($this->getClasses() as $class) { + $count += $class->getAttributesCount(); + } + } + + return $count; + } } diff --git a/src/classes/XLite/View/Product/Details/Customer/Attributes.php b/src/classes/XLite/View/Product/Details/Customer/Attributes.php index 942efd4f8a..2862d34869 100644 --- a/src/classes/XLite/View/Product/Details/Customer/Attributes.php +++ b/src/classes/XLite/View/Product/Details/Customer/Attributes.php @@ -52,7 +52,7 @@ public function getAttrList() if ($value) { $this->attributes[] = array( 'name' => $a->getName(), - 'value' => $value, + 'value' => htmlentities($value), 'class' => $this->getFieldClass($a, $value) ); } diff --git a/src/classes/XLite/View/Product/Details/Customer/Page/APage.php b/src/classes/XLite/View/Product/Details/Customer/Page/APage.php index 8d34cf76a8..6c5b1c925f 100644 --- a/src/classes/XLite/View/Product/Details/Customer/Page/APage.php +++ b/src/classes/XLite/View/Product/Details/Customer/Page/APage.php @@ -137,7 +137,7 @@ protected function defineTabs() if ( $this->getProduct()->getAttrSepTab() - && $this->getProduct()->getClasses() + && $this->getProduct()->getAttributesCount() ) { $list['Specification'] = array( 'list' => 'product.details.page.tab.attributes' diff --git a/src/skins/admin/en/attributes/body.tpl b/src/skins/admin/en/attributes/body.tpl index 0dc7ef5f1f..0cc4d265a6 100644 --- a/src/skins/admin/en/attributes/body.tpl +++ b/src/skins/admin/en/attributes/body.tpl @@ -14,4 +14,8 @@
      +{if:productClass.getAttributesCount()} +{else:} +{t(#No attributes are defined for the product class yet.#)} +{end:} diff --git a/src/skins/admin/en/product/attributes.tpl b/src/skins/admin/en/product/attributes.tpl index a92cda8309..344c59e7d7 100644 --- a/src/skins/admin/en/product/attributes.tpl +++ b/src/skins/admin/en/product/attributes.tpl @@ -26,6 +26,6 @@
      - +
      diff --git a/src/skins/default/en/css/lc.css b/src/skins/default/en/css/lc.css index b27b7567dd..7c180e7906 100644 --- a/src/skins/default/en/css/lc.css +++ b/src/skins/default/en/css/lc.css @@ -1258,6 +1258,7 @@ div.product-details .continue-button-intend { display: inline-block; color: #1f1f1f; + vertical-align: bottom; } .product-details .extra-fields li span.checkbox.no-checked @@ -1267,7 +1268,7 @@ div.product-details .continue-button-intend .product-details .extra-fields li div { - width: 186px; + width: 246px; display: inline-block; color: #7e7e7e; background: url(../images/dotted.png) repeat-x scroll 0 bottom transparent; @@ -1276,7 +1277,7 @@ div.product-details .continue-button-intend .product-details .extra-fields li ul li div { - width: 166px; + width: 226px; } .product-details .extra-fields li ul li From bcfffb4cbf6acd636bdd4ec5efe6e03c531faa46 Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Thu, 8 Nov 2012 14:20:55 +0400 Subject: [PATCH 62/85] E:0042350 [!] SalesTax module: tax is not calculated on shipping cost. Fixed. --- .../SalesTax/Logic/Order/Modifier/Tax.php | 33 +++++++++++++++++-- .../Module/CDev/SalesTax/Model/Tax/Rate.php | 23 ++++++++++++- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/classes/XLite/Module/CDev/SalesTax/Logic/Order/Modifier/Tax.php b/src/classes/XLite/Module/CDev/SalesTax/Logic/Order/Modifier/Tax.php index 375f8f0e04..203b344dbd 100644 --- a/src/classes/XLite/Module/CDev/SalesTax/Logic/Order/Modifier/Tax.php +++ b/src/classes/XLite/Module/CDev/SalesTax/Logic/Order/Modifier/Tax.php @@ -67,7 +67,7 @@ public function canApply() public function calculate() { $zones = $this->getZonesList(); - $memebrship = $this->getMembership(); + $membership = $this->getMembership(); foreach ($this->getTaxes() as $tax) { $previousItems = array(); @@ -75,11 +75,12 @@ public function calculate() $cost = 0; $ratesExists = false; - foreach ($tax->getFilteredRates($zones, $memebrship) as $rate) { + foreach ($tax->getFilteredRates($zones, $membership) as $rate) { $ratesExists = true; $productClass = $rate->getProductClass() ?: null; if (!in_array($productClass, $previousClasses)) { + // Get tax cost for products in the cart with specified product class $items = $this->getTaxableItems($productClass, $previousItems); if ($items) { foreach ($items as $item) { @@ -88,6 +89,9 @@ public function calculate() $cost += $rate->calculate($items); } + // Add shipping tax cost + $cost += $rate->calculateShippingTax($this->getTaxableShippingCost($productClass)); + $previousClasses[] = $productClass; } } @@ -103,6 +107,31 @@ public function calculate() } } + /** + * Get taxable shipping cost + * + * @param \XLite\Model\ProductClass $class Product class object + * + * @return float + */ + protected function getTaxableShippingCost($class) + { + $result = 0; + + $modifier = $this->order->getModifier(\XLite\Model\Base\Surcharge::TYPE_SHIPPING, 'SHIPPING'); + + if ($modifier && $modifier->getSelectedRate() && $modifier->getSelectedRate()->getMethod()) { + + $rate = $modifier->getSelectedRate(); + + if (!$class || ($class && $rate->getMethod()->getClasses()->contains($class))) { + $result = $rate->getTaxableBasis(); + } + } + + return $result; + } + /** * Get taxes * diff --git a/src/classes/XLite/Module/CDev/SalesTax/Model/Tax/Rate.php b/src/classes/XLite/Module/CDev/SalesTax/Model/Tax/Rate.php index a141542d93..8bb447fa7f 100644 --- a/src/classes/XLite/Module/CDev/SalesTax/Model/Tax/Rate.php +++ b/src/classes/XLite/Module/CDev/SalesTax/Model/Tax/Rate.php @@ -179,7 +179,7 @@ public function setMembership(\XLite\Model\Membership $membership = null) * * @param array $items Items * - * @return array + * @return float */ public function calculate(array $items) { @@ -194,6 +194,27 @@ public function calculate(array $items) return $cost; } + /** + * Calculate shipping tax cost + * + * @param float $shippingCost Shipping cost + * + * @return float + */ + public function calculateShippingTax($shippingCost) + { + $cost = 0; + + if ($shippingCost) { + $cost = $this->getType() == static::TYPE_PERCENT + ? $shippingCost * $this->getValue() / 100 + : $this->getValue(); + } + + return $cost; + } + + /** * Get basis * From 5cabb8b44dd6a63038e7234b6c308c1cc38f236b Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Thu, 8 Nov 2012 17:14:30 +0400 Subject: [PATCH 63/85] [*] Small design changes. --- src/skins/admin/en/payment/configuration/style.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/skins/admin/en/payment/configuration/style.css b/src/skins/admin/en/payment/configuration/style.css index a68154edd8..7120585baf 100644 --- a/src/skins/admin/en/payment/configuration/style.css +++ b/src/skins/admin/en/payment/configuration/style.css @@ -336,6 +336,10 @@ background-color: #f4f4f4; } +.add-payment-box .alternative-methods .body .body-box { + border: solid 1px #c2cbd2; +} + .add-payment-box .body .body-item.selected { display: block; } From ec9eeb061567c396bae9adcf10fb8e045786ac08 Mon Sep 17 00:00:00 2001 From: skiv Date: Thu, 8 Nov 2012 17:44:19 +0400 Subject: [PATCH 64/85] Attributes --- src/classes/XLite/View/Attributes.php | 11 +++++++++++ src/skins/admin/en/attributes/body.tpl | 2 +- src/skins/admin/en/product/attributes/style.css | 4 ++++ src/skins/default/en/css/lc.css | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/classes/XLite/View/Attributes.php b/src/classes/XLite/View/Attributes.php index b5ac95e0c1..38aea8bcdd 100644 --- a/src/classes/XLite/View/Attributes.php +++ b/src/classes/XLite/View/Attributes.php @@ -122,4 +122,15 @@ protected function isSearchVisible() return 0 < \XLite\Core\Database::getRepo('XLite\Model\Attribute')->count(); } + /** + * Check - list box is visible or not + * + * @return boolean + */ + protected function isListVisible() + { + return $this->getProductClass()->getAttributesCount() + || $this->getProductClass()->getAttributeGroups()->count(); + } + } diff --git a/src/skins/admin/en/attributes/body.tpl b/src/skins/admin/en/attributes/body.tpl index 0cc4d265a6..f55463e21e 100644 --- a/src/skins/admin/en/attributes/body.tpl +++ b/src/skins/admin/en/attributes/body.tpl @@ -14,7 +14,7 @@ -{if:productClass.getAttributesCount()} +{if:isListVisible()} {else:} {t(#No attributes are defined for the product class yet.#)} diff --git a/src/skins/admin/en/product/attributes/style.css b/src/skins/admin/en/product/attributes/style.css index dd83fd1d3a..0df36ef121 100644 --- a/src/skins/admin/en/product/attributes/style.css +++ b/src/skins/admin/en/product/attributes/style.css @@ -51,3 +51,7 @@ .table-label.checkbox { float: right; } + +.table-value .main-button { + line-height: 14px; +} diff --git a/src/skins/default/en/css/lc.css b/src/skins/default/en/css/lc.css index 7c180e7906..0bb83b1ac7 100644 --- a/src/skins/default/en/css/lc.css +++ b/src/skins/default/en/css/lc.css @@ -1259,6 +1259,7 @@ div.product-details .continue-button-intend display: inline-block; color: #1f1f1f; vertical-align: bottom; + max-width: 700px; } .product-details .extra-fields li span.checkbox.no-checked From 1ec9628b9d0352f4b326aa4a41cd0767c06c806f Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Thu, 8 Nov 2012 23:56:41 +0400 Subject: [PATCH 65/85] E:0042241 [!] Tests on PaypalWPS module corrected --- .dev/tests/Classes/Module/CDev/PaypalWPS/Main.php | 6 +++--- .../CDev/PaypalWPS/Model/Payment/Processor/PaypalWPS.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.dev/tests/Classes/Module/CDev/PaypalWPS/Main.php b/.dev/tests/Classes/Module/CDev/PaypalWPS/Main.php index 8502633b25..d0be32a1af 100644 --- a/.dev/tests/Classes/Module/CDev/PaypalWPS/Main.php +++ b/.dev/tests/Classes/Module/CDev/PaypalWPS/Main.php @@ -30,19 +30,19 @@ class XLite_Tests_Module_CDev_PaypalWPS_Main extends XLite_Tests_TestCase public function testGetModuleName() { $main = $this->getMain(); - $this->assertEquals('Paypal Website Payments Standard', $main::getModuleName(), 'Wrong module name'); + $this->assertEquals('PayPal (outside of the US)', $main::getModuleName(), 'Wrong module name'); } public function testGetDescription() { $main = $this->getMain(); - $this->assertEquals('Enables taking credit card payments for your online store via Paypal (Website Payments Standard).', $main::getDescription(), 'Wrong description'); + $this->assertEquals('Enables taking credit card payments for your online store via PayPal (Website Payments Standard).', $main::getDescription(), 'Wrong description'); } public function testGetVersion() { $main = $this->getMain(); - $this->assertEquals('1.1.0', $main::getVersion(), 'Wrong version'); + $this->assertEquals('1.1.1', $main::getVersion(), 'Wrong version'); } public function testShowSettingsForm() diff --git a/.dev/tests/Classes/Module/CDev/PaypalWPS/Model/Payment/Processor/PaypalWPS.php b/.dev/tests/Classes/Module/CDev/PaypalWPS/Model/Payment/Processor/PaypalWPS.php index c3515d114a..f67efe6367 100644 --- a/.dev/tests/Classes/Module/CDev/PaypalWPS/Model/Payment/Processor/PaypalWPS.php +++ b/.dev/tests/Classes/Module/CDev/PaypalWPS/Model/Payment/Processor/PaypalWPS.php @@ -146,7 +146,7 @@ public function testGetSettingsWidget() $order = $this->getTestOrder(); $p = $order->getPaymentMethod()->getProcessor(); - $this->assertEquals('modules/CDev/PaypalWPS/config.tpl', $p->getSettingsWidget(), 'check settings widget'); + $this->assertEquals('\\XLite\\Module\\CDev\\PaypalWPS\\View\\PaypalSettings', $p->getSettingsWidget(), 'check settings widget'); } public function testIsConfigured() From d6b1024c8b827153178d3b07a29fe1ba0d982ccc Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Fri, 9 Nov 2012 01:05:59 +0400 Subject: [PATCH 66/85] E:0042386 [!] Tests updated (SQL dump Repo/sql/module/setup.sql is corrected) --- .../Classes/Model/Repo/sql/module/setup.sql | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/.dev/tests/Classes/Model/Repo/sql/module/setup.sql b/.dev/tests/Classes/Model/Repo/sql/module/setup.sql index 4f624f69a3..37c5c7d371 100644 --- a/.dev/tests/Classes/Model/Repo/sql/module/setup.sql +++ b/.dev/tests/Classes/Model/Repo/sql/module/setup.sql @@ -1,26 +1,26 @@ DELETE FROM `xlite_modules`; -INSERT INTO `xlite_modules` VALUES (1,'AustraliaPost','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Australia Post','Creative Development LLC','This module introduces Australia Post real-time shipping cost calculations','','','','a:0:{}',0); -INSERT INTO `xlite_modules` VALUES (2,'AuthorizeNet','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Authorize.Net SIM','Creative Development LLC','Authorize.Net SIM (Server Integration Method) credit card payment processor','','','','a:0:{}',0); -INSERT INTO `xlite_modules` VALUES (3,'Bestsellers','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Bestsellers','Creative Development LLC','This module enables bestsellers list','','','','a:0:{}',0); -INSERT INTO `xlite_modules` VALUES (4,'DrupalConnector','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Drupal Connector','Creative Development LLC','Integration with the Drupal CMS','','','','a:0:{}',0); -INSERT INTO `xlite_modules` VALUES (5,'Demo','CDev',0,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Demo mode','Creative Development LLC','Demo mode','','','','a:0:{}',0); -INSERT INTO `xlite_modules` VALUES (6,'FeaturedProducts','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Featured Products','Creative Development LLC','This module enables featured products list','','','','a:0:{}',0); -INSERT INTO `xlite_modules` VALUES (7,'GoogleAnalytics','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Google Analytics','Creative Development LLC','This module enables Google Analytics tracking','','','','a:0:{}',0); -INSERT INTO `xlite_modules` VALUES (8,'JoomlaConnector','CDev',0,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Joomla Connector','Creative Development LLC','Integration with the Joomla CMS','','','','a:0:{}',0); -INSERT INTO `xlite_modules` VALUES (9,'ProductOptions','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Product Options','Creative Development LLC','Support for product options, enabling you to provide customers with a choice of product variants','','','','a:0:{}',0); -INSERT INTO `xlite_modules` VALUES (10,'Quantum','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Quantum','Creative Development LLC','QuantumGateway integration (QGWdatabase Engine API)','','','','a:0:{}',0); -INSERT INTO `xlite_modules` VALUES (11,'Taxes','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Taxes','Creative Development LLC','This module enables taxes','','','','a:0:{}',0); -INSERT INTO `xlite_modules` VALUES (12,'TinyMCE','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'TinyMCE integration','Creative Development LLC','This module integrates TinyMCE WYSIWYG editor into LC widgets. Textarea widgets involved','','','','a:0:{}',0); -INSERT INTO `xlite_modules` VALUES (13,'AustraliaPost','CDev',0,0,0,'4.5000',23,76,'0.00','USD','1.0','1',1306461783,53248,'Australia Post','Creative Development LLC','This module introduces Australia Post real-time shipping cost calculations','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:0:{}',1); -INSERT INTO `xlite_modules` VALUES (14,'AustraliaPost','CDev',0,0,0,'4.5000',23,76,'0.00','USD','1.2','1',1306462072,53760,'Australia Post','Creative Development LLC','This module introduces Australia Post real-time shipping cost calculations','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:0:{}',1); -INSERT INTO `xlite_modules` VALUES (15,'DrupalConnector','CDev',0,0,0,'5.0000',98,421,'0.00','USD','1.0','1',1306461906,245248,'Drupal Connector','Creative Development LLC','Integration with the Drupal CMS','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:0:{}',1); -INSERT INTO `xlite_modules` VALUES (16,'DrupalConnector','CDev',0,0,0,'5.0000',98,421,'0.00','USD','1.2','1',1306462006,245248,'Drupal Connector','Creative Development LLC','Integration with the Drupal CMS','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:0:{}',1); -INSERT INTO `xlite_modules` VALUES (17,'Bestsellers','CDev',0,0,0,'0.0000',1,25,'10.00','USD','1.0','0',1306442013,27648,'Bestsellers','Creative Development LLC','This module enables bestsellers list','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:0:{}',1); -INSERT INTO `xlite_modules` VALUES (18,'Module1','Test',0,0,0,'2.4000',45,74,'0.00','USD','0.3','0',1301465349,6144,'Test module 1 (from marketplace)','Test author','[v0.3.0] Test module 1 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','http://www.example.com','','a:0:{}',1); -INSERT INTO `xlite_modules` VALUES (19,'Module2','Test',0,0,0,'5.0000',1,9,'0.00','USD','1.2','0',1301465356,0,'Test module 2 (from marketplace)','Test author','[v1.2.0] Test module 2 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:0:{}',1); -INSERT INTO `xlite_modules` VALUES (20,'Module3','Test',0,0,0,'3.0000',7,46,'0.00','USD','1.0','0',1301465361,6144,'Test module 3 (from marketplace)','Test author','[v1.0.0] Test module 3 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:2:{i:0;s:12:\"Test\\Module1\";i:1;s:12:\"Test\\Module2\";}',1); -INSERT INTO `xlite_modules` VALUES (21,'Module4','Test',0,0,0,'0.9000',23,50,'0.00','USD','1.0','0',1301465365,5632,'Test module 4 (from marketplace)','Test author','[v1.0.0] Test module 4 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','http://www.example.com','','a:0:{}',1); -INSERT INTO `xlite_modules` VALUES (22,'Module5','Test',0,0,0,'2.9000',36,1,'27.00','USD','1.0','7',1301465365,0,'Test module 5 (from marketplace)','Test author','[v1.0.7] Test module 5 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','http://www.example.com','','a:0:{}',1); -INSERT INTO `xlite_modules` VALUES (23,'Module6','Test',0,0,0,'0.7000',112,1,'35.05','USD','1.0','4',1301465365,0,'Test module 6 (from marketplace)','Test author','[v1.0.4] Test module 6 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','http://www.example.com','','a:0:{}',1); -INSERT INTO `xlite_modules` VALUES (24,'Module7','Test',0,0,0,'4.1000',6,1,'77.30','USD','1.0','2',1301465365,0,'Test module 7 (from marketplace)','Test author','[v1.0.2] Test module 7 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','http://www.example.com','','a:0:{}',1); +INSERT INTO `xlite_modules` VALUES (1,'AustraliaPost','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Australia Post','Creative Development LLC','This module introduces Australia Post real-time shipping cost calculations','','','','a:0:{}',0,0); +INSERT INTO `xlite_modules` VALUES (2,'AuthorizeNet','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Authorize.Net SIM','Creative Development LLC','Authorize.Net SIM (Server Integration Method) credit card payment processor','','','','a:0:{}',0,0); +INSERT INTO `xlite_modules` VALUES (3,'Bestsellers','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Bestsellers','Creative Development LLC','This module enables bestsellers list','','','','a:0:{}',0,0); +INSERT INTO `xlite_modules` VALUES (4,'DrupalConnector','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Drupal Connector','Creative Development LLC','Integration with the Drupal CMS','','','','a:0:{}',0,0); +INSERT INTO `xlite_modules` VALUES (5,'Demo','CDev',0,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Demo mode','Creative Development LLC','Demo mode','','','','a:0:{}',0,0); +INSERT INTO `xlite_modules` VALUES (6,'FeaturedProducts','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Featured Products','Creative Development LLC','This module enables featured products list','','','','a:0:{}',0,0); +INSERT INTO `xlite_modules` VALUES (7,'GoogleAnalytics','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Google Analytics','Creative Development LLC','This module enables Google Analytics tracking','','','','a:0:{}',0,0); +INSERT INTO `xlite_modules` VALUES (8,'JoomlaConnector','CDev',0,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Joomla Connector','Creative Development LLC','Integration with the Joomla CMS','','','','a:0:{}',0,0); +INSERT INTO `xlite_modules` VALUES (9,'ProductOptions','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Product Options','Creative Development LLC','Support for product options, enabling you to provide customers with a choice of product variants','','','','a:0:{}',0,0); +INSERT INTO `xlite_modules` VALUES (10,'Quantum','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Quantum','Creative Development LLC','QuantumGateway integration (QGWdatabase Engine API)','','','','a:0:{}',0,0); +INSERT INTO `xlite_modules` VALUES (11,'Taxes','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'Taxes','Creative Development LLC','This module enables taxes','','','','a:0:{}',0,0); +INSERT INTO `xlite_modules` VALUES (12,'TinyMCE','CDev',1,1,1307925045,'0.0000',0,0,'0.00','USD','1.0','0',0,0,'TinyMCE integration','Creative Development LLC','This module integrates TinyMCE WYSIWYG editor into LC widgets. Textarea widgets involved','','','','a:0:{}',0,0); +INSERT INTO `xlite_modules` VALUES (13,'AustraliaPost','CDev',0,0,0,'4.5000',23,76,'0.00','USD','1.0','1',1306461783,53248,'Australia Post','Creative Development LLC','This module introduces Australia Post real-time shipping cost calculations','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:0:{}',1,0); +INSERT INTO `xlite_modules` VALUES (14,'AustraliaPost','CDev',0,0,0,'4.5000',23,76,'0.00','USD','1.2','1',1306462072,53760,'Australia Post','Creative Development LLC','This module introduces Australia Post real-time shipping cost calculations','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:0:{}',1,0); +INSERT INTO `xlite_modules` VALUES (15,'DrupalConnector','CDev',0,0,0,'5.0000',98,421,'0.00','USD','1.0','1',1306461906,245248,'Drupal Connector','Creative Development LLC','Integration with the Drupal CMS','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:0:{}',1,0); +INSERT INTO `xlite_modules` VALUES (16,'DrupalConnector','CDev',0,0,0,'5.0000',98,421,'0.00','USD','1.2','1',1306462006,245248,'Drupal Connector','Creative Development LLC','Integration with the Drupal CMS','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:0:{}',1,0); +INSERT INTO `xlite_modules` VALUES (17,'Bestsellers','CDev',0,0,0,'0.0000',1,25,'10.00','USD','1.0','0',1306442013,27648,'Bestsellers','Creative Development LLC','This module enables bestsellers list','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:0:{}',1,0); +INSERT INTO `xlite_modules` VALUES (18,'Module1','Test',0,0,0,'2.4000',45,74,'0.00','USD','0.3','0',1301465349,6144,'Test module 1 (from marketplace)','Test author','[v0.3.0] Test module 1 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','http://www.example.com','','a:0:{}',1,0); +INSERT INTO `xlite_modules` VALUES (19,'Module2','Test',0,0,0,'5.0000',1,9,'0.00','USD','1.2','0',1301465356,0,'Test module 2 (from marketplace)','Test author','[v1.2.0] Test module 2 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:0:{}',1,0); +INSERT INTO `xlite_modules` VALUES (20,'Module3','Test',0,0,0,'3.0000',7,46,'0.00','USD','1.0','0',1301465361,6144,'Test module 3 (from marketplace)','Test author','[v1.0.0] Test module 3 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','','','a:2:{i:0;s:12:\"Test\\Module1\";i:1;s:12:\"Test\\Module2\";}',1,0); +INSERT INTO `xlite_modules` VALUES (21,'Module4','Test',0,0,0,'0.9000',23,50,'0.00','USD','1.0','0',1301465365,5632,'Test module 4 (from marketplace)','Test author','[v1.0.0] Test module 4 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','http://www.example.com','','a:0:{}',1,0); +INSERT INTO `xlite_modules` VALUES (22,'Module5','Test',0,0,0,'2.9000',36,1,'27.00','USD','1.0','7',1301465365,0,'Test module 5 (from marketplace)','Test author','[v1.0.7] Test module 5 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','http://www.example.com','','a:0:{}',1,0); +INSERT INTO `xlite_modules` VALUES (23,'Module6','Test',0,0,0,'0.7000',112,1,'35.05','USD','1.0','4',1301465365,0,'Test module 6 (from marketplace)','Test author','[v1.0.4] Test module 6 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','http://www.example.com','','a:0:{}',1,0); +INSERT INTO `xlite_modules` VALUES (24,'Module7','Test',0,0,0,'4.1000',6,1,'77.30','USD','1.0','2',1301465365,0,'Test module 7 (from marketplace)','Test author','[v1.0.2] Test module 7 description','http://xcart2-530.crtdev.local/~vvs/site/sites/default/files/addons/default_icon.png','http://www.example.com','','a:0:{}',1,0); From 27a292d55720778a1a08a2d745523c3c9f79fc32 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Fri, 9 Nov 2012 23:33:51 +0400 Subject: [PATCH 67/85] [*] Address fields default values are added. --- .../Controller/Admin/ShippingSettings.php | 5 +- src/classes/XLite/Model/Address.php | 4 +- src/classes/XLite/Model/Base/Address.php | 54 ++++++++++++++++++- src/classes/XLite/Model/Config.php | 10 ++++ .../XLite/View/Checkout/AAddressBlock.php | 3 ++ 5 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/classes/XLite/Controller/Admin/ShippingSettings.php b/src/classes/XLite/Controller/Admin/ShippingSettings.php index b525b97c22..03b85fad9c 100644 --- a/src/classes/XLite/Controller/Admin/ShippingSettings.php +++ b/src/classes/XLite/Controller/Admin/ShippingSettings.php @@ -60,8 +60,7 @@ public function getTitle() public function doActionUpdate() { $postedData = \XLite\Core\Request::getInstance()->getData(); - $options = \XLite\Core\Database::getRepo('\XLite\Model\Config') - ->findBy(array('category' => $this->getOptionsCategory())); + $options = \XLite\Core\Database::getRepo('\XLite\Model\Config')->findBy(array('category' => $this->getOptionsCategory())); $isUpdated = false; foreach ($options as $key => $option) { @@ -105,6 +104,6 @@ public function getStateById($stateId) */ protected function getOptionsCategory() { - return 'Shipping'; + return \XLite\Model\Config::SHIPPING_CATEGORY; } } diff --git a/src/classes/XLite/Model/Address.php b/src/classes/XLite/Model/Address.php index 27cca2fd98..152283a403 100644 --- a/src/classes/XLite/Model/Address.php +++ b/src/classes/XLite/Model/Address.php @@ -155,7 +155,9 @@ public function getterProperty($property) 'addressField' => $addressField->getId(), )); - $result = $addressFieldValue ? $addressFieldValue->getValue() : ''; + $result = $addressFieldValue + ? $addressFieldValue->getValue() + : static::getDefaultFieldPlainValue($property); } } diff --git a/src/classes/XLite/Model/Base/Address.php b/src/classes/XLite/Model/Base/Address.php index 4bfecfb31e..c28a56b2aa 100644 --- a/src/classes/XLite/Model/Base/Address.php +++ b/src/classes/XLite/Model/Base/Address.php @@ -165,7 +165,9 @@ public function setState($state) */ public function getStateId() { - return $this->getState() ? $this->getState()->getStateId() : null; + return $this->getState() + ? ($this->getState()->getStateId() ?: static::getDefaultFieldPlainValue('state_id')) + : static::getDefaultFieldPlainValue('state_id'); } /** @@ -175,7 +177,9 @@ public function getStateId() */ public function getCountryCode() { - return $this->getCountry() ? $this->getCountry()->getCode() : null; + return $this->getCountry() + ? ($this->getCountry()->getCode() ?: static::getDefaultFieldPlainValue('country_code')) + : static::getDefaultFieldPlainValue('country_code'); } /** @@ -198,6 +202,52 @@ public function getStateName() return $this->getState()->getState(); } + /** + * Return default field value + * + * @param string $fieldName Field name + * + * @return string + */ + public static function getDefaultFieldPlainValue($fieldName) + { + $field = \XLite\Core\Database::getRepo('\XLite\Model\Config') + ->findOneBy(array( + 'category' => \XLite\Model\Config::SHIPPING_CATEGORY, + 'name' => static::getDefaultFieldName($fieldName) + )); + + return $field ? $field->getValue() : ''; + } + + /** + * Return name of the address field in the default shipping category of the settings + * + * @param string $fieldName + * + * @return string + */ + protected static function getDefaultFieldName($fieldName) + { + $result = \XLite\Model\Config::SHIPPING_VALUES_PREFIX; + + switch ($fieldName) { + case 'country_code': + $result .= 'country'; + break; + + case 'state_id': + $result .= 'state'; + break; + + default: + $result .= $fieldName; + break; + } + + return $result; + } + /** * Get required fields by address type * diff --git a/src/classes/XLite/Model/Config.php b/src/classes/XLite/Model/Config.php index 3b0ed06e4a..463e36065a 100644 --- a/src/classes/XLite/Model/Config.php +++ b/src/classes/XLite/Model/Config.php @@ -42,6 +42,16 @@ */ class Config extends \XLite\Model\Base\I18n { + /** + * Name for the Shipping category options + */ + const SHIPPING_CATEGORY = 'Shipping'; + + /** + * Prefix for the shipping values + */ + const SHIPPING_VALUES_PREFIX = 'anonymous_'; + /** * Option unique name * diff --git a/src/classes/XLite/View/Checkout/AAddressBlock.php b/src/classes/XLite/View/Checkout/AAddressBlock.php index 539b2d36af..5de8233d73 100644 --- a/src/classes/XLite/View/Checkout/AAddressBlock.php +++ b/src/classes/XLite/View/Checkout/AAddressBlock.php @@ -75,6 +75,9 @@ public function getFieldValue($fieldName, $processValue = false) } } + } else { + + $result = \XLite\Model\Address::getDefaultFieldPlainValue($fieldName); } return $result; From b24b99cdb6c2395285575dbe12fcd5af0134a8af Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Mon, 12 Nov 2012 18:08:42 +0400 Subject: [PATCH 68/85] [!] Bug: Street address line had no default value. --- src/classes/XLite/Controller/Admin/AddonsListInstalled.php | 4 +++- src/classes/XLite/Model/Base/Address.php | 4 ++++ src/classes/XLite/View/Checkout/AAddressBlock.php | 2 +- src/upgrade/1.1/{2 => 3}/post_rebuild.php | 0 src/upgrade/1.1/{2 => 3}/post_rebuild.yaml | 0 src/upgrade/1.1/{2 => 3}/pre_upgrade.php | 0 6 files changed, 8 insertions(+), 2 deletions(-) rename src/upgrade/1.1/{2 => 3}/post_rebuild.php (100%) rename src/upgrade/1.1/{2 => 3}/post_rebuild.yaml (100%) rename src/upgrade/1.1/{2 => 3}/pre_upgrade.php (100%) diff --git a/src/classes/XLite/Controller/Admin/AddonsListInstalled.php b/src/classes/XLite/Controller/Admin/AddonsListInstalled.php index 484c44dc77..8d6f83dd61 100644 --- a/src/classes/XLite/Controller/Admin/AddonsListInstalled.php +++ b/src/classes/XLite/Controller/Admin/AddonsListInstalled.php @@ -87,6 +87,8 @@ protected function getModules($cellName) /** * Enable module + * + * @todo TO REMOVE? * * @return void */ @@ -173,7 +175,7 @@ protected function doActionUninstall() // Disable this and depended modules \Includes\Utils\ModulesManager::disableModule($module->getActualName()); \Includes\Utils\ModulesManager::removeModuleFromDisabledStructure($module->getActualName()); - + // Remove from DB \XLite\Core\Database::getRepo('\XLite\Model\Module')->delete($module); diff --git a/src/classes/XLite/Model/Base/Address.php b/src/classes/XLite/Model/Base/Address.php index c28a56b2aa..d938ec27c1 100644 --- a/src/classes/XLite/Model/Base/Address.php +++ b/src/classes/XLite/Model/Base/Address.php @@ -240,6 +240,10 @@ protected static function getDefaultFieldName($fieldName) $result .= 'state'; break; + case 'street': + $result .= 'address'; + break; + default: $result .= $fieldName; break; diff --git a/src/classes/XLite/View/Checkout/AAddressBlock.php b/src/classes/XLite/View/Checkout/AAddressBlock.php index 5de8233d73..fbfdee3ab2 100644 --- a/src/classes/XLite/View/Checkout/AAddressBlock.php +++ b/src/classes/XLite/View/Checkout/AAddressBlock.php @@ -63,7 +63,7 @@ public function getFieldValue($fieldName, $processValue = false) switch ($fieldName) { - case 'state_id': + case 'state_id': $result = $address->getState()->getState(); break; diff --git a/src/upgrade/1.1/2/post_rebuild.php b/src/upgrade/1.1/3/post_rebuild.php similarity index 100% rename from src/upgrade/1.1/2/post_rebuild.php rename to src/upgrade/1.1/3/post_rebuild.php diff --git a/src/upgrade/1.1/2/post_rebuild.yaml b/src/upgrade/1.1/3/post_rebuild.yaml similarity index 100% rename from src/upgrade/1.1/2/post_rebuild.yaml rename to src/upgrade/1.1/3/post_rebuild.yaml diff --git a/src/upgrade/1.1/2/pre_upgrade.php b/src/upgrade/1.1/3/pre_upgrade.php similarity index 100% rename from src/upgrade/1.1/2/pre_upgrade.php rename to src/upgrade/1.1/3/pre_upgrade.php From 2a1c515ffed861ca447f51a14fbd5e2251c4a5a2 Mon Sep 17 00:00:00 2001 From: skiv Date: Mon, 12 Nov 2012 18:29:01 +0400 Subject: [PATCH 69/85] Attributes --- src/skins/admin/en/attributes/parts/type.tpl | 2 +- src/skins/admin/en/attributes/script.js | 4 ++- src/skins/admin/en/attributes/style.css | 34 ++++++++++++-------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/skins/admin/en/attributes/parts/type.tpl b/src/skins/admin/en/attributes/parts/type.tpl index cef45323fd..5c9ce926cf 100644 --- a/src/skins/admin/en/attributes/parts/type.tpl +++ b/src/skins/admin/en/attributes/parts/type.tpl @@ -10,6 +10,6 @@ *}
      - +{t(#Edit attribute#)} {t(entity.getTypes(entity.getType()))}
      diff --git a/src/skins/admin/en/attributes/script.js b/src/skins/admin/en/attributes/script.js index b26d04b4a0..21d734be60 100644 --- a/src/skins/admin/en/attributes/script.js +++ b/src/skins/admin/en/attributes/script.js @@ -23,6 +23,8 @@ popup.postprocessRequest = function(XMLHttpRequest, textStatus, data, isValid) { } } ); + + jQuery('.ajax-container-loadable form.attribute', this.base).commonController('submitOnlyChanged', false); } jQuery().ready( @@ -42,7 +44,7 @@ jQuery().ready( ); } ); - jQuery('button.new-attribute, button.edit-attribute').click( + jQuery('button.new-attribute, a.edit-attribute').click( function () { return !popup.load( URLHandler.buildURL({ diff --git a/src/skins/admin/en/attributes/style.css b/src/skins/admin/en/attributes/style.css index 2050224884..7fc78d5098 100644 --- a/src/skins/admin/en/attributes/style.css +++ b/src/skins/admin/en/attributes/style.css @@ -165,27 +165,33 @@ div.group table.list th.actions.left { } .edit-attribute { - background: url("../images/tri_right_button.png") no-repeat scroll right top transparent; - padding: 0 11px 0 0; - border: none; - border-radius: 0; + background: url("../images/tri_right_button.png") no-repeat right top transparent; + padding-right: 13px; display: none; - margin: 0 5px 0 0; - height: 26px; + line-height: 26px; } .edit-mark .edit-attribute { - display: inline; + display: inline-block; } .edit-attribute span { - background-color: #eff9fe; - border: 1px solid #CADCE8; - border-bottom-left-radius: 3px; - border-right: 0 none; + -moz-top-left-border-radius: 3px; + -moz-bottom-left-border-radius: 3px; + -webkit-top-left-border-radius: 3px; + -webkit-bottom-left-border-radius: 3px; border-top-left-radius: 3px; - padding: 5px 0 5px 10px; - background-color: #EFF8FE; - color: #154E9C; + border-bottom-left-radius: 3px; + padding-left: 10px; line-height: 24px; + background-color: #eff8fe; + color: #154e9c; + border: 1px solid #cadce8; + border-right: 0 none; + display: inline-block; +} + +.items-list-table table.list tbody.lines td .edit-attribute, +.items-list-table table.list tbody.lines td .edit-attribute span { + vertical-align: top; } .ajax-container-loadable .model-properties ul.table div.table-label label { From a33274a3347b444a9039eaebda152ef3b82178a9 Mon Sep 17 00:00:00 2001 From: skiv Date: Tue, 13 Nov 2012 15:05:44 +0400 Subject: [PATCH 70/85] Attributes --- src/classes/XLite/View/Model/Attribute.php | 10 +++++----- src/skins/admin/en/attributes/script.js | 2 ++ src/skins/admin/en/attributes/style.css | 8 +++++++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/classes/XLite/View/Model/Attribute.php b/src/classes/XLite/View/Model/Attribute.php index de570cf912..aaf36f86e6 100644 --- a/src/classes/XLite/View/Model/Attribute.php +++ b/src/classes/XLite/View/Model/Attribute.php @@ -72,9 +72,7 @@ public function getModelId() protected function getFormFieldsForSectionDefault() { if ($this->getModelObject()->getId()) { - if ($this->getModelObject()->getAttributeValuesCount()) { - $this->schemaDefault['type'][self::SCHEMA_COMMENT] = 'There are products using this attribute!'; - } + $this->schemaDefault['type'][self::SCHEMA_COMMENT] = 'Before editing attriubutes specific for the chosen type you should save the changes'; if ( \XLite\Model\Attribute::TYPE_NUMBER == $this->getModelObject()->getType() @@ -83,14 +81,14 @@ protected function getFormFieldsForSectionDefault() self::SCHEMA_CLASS => 'XLite\View\FormField\Select\Decimals', self::SCHEMA_LABEL => 'Decimals', self::SCHEMA_REQUIRED => false, - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'edit-decimals', + \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'edit-decimals custom-field', ); $this->schemaDefault['unit'] = array( self::SCHEMA_CLASS => 'XLite\View\FormField\Input\Text', self::SCHEMA_LABEL => 'Unit', self::SCHEMA_REQUIRED => false, self::SCHEMA_COMMENT => '(suffix)', - \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'edit-unit', + \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'edit-unit custom-field', ); } @@ -105,6 +103,7 @@ protected function getFormFieldsForSectionDefault() self::SCHEMA_REQUIRED => false, 'rows' => 1, 'maxHeight' => 100, + \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'custom-field', ); } @@ -116,6 +115,7 @@ protected function getFormFieldsForSectionDefault() self::SCHEMA_LABEL => 'Allowed attribute values and default one', self::SCHEMA_REQUIRED => false, \XLite\View\FormField\ItemsList::PARAM_LIST_CLASS => 'XLite\View\ItemsList\Model\AttributeOption', + \XLite\View\FormField\AFormField::PARAM_WRAPPER_CLASS => 'custom-field', ); } } diff --git a/src/skins/admin/en/attributes/script.js b/src/skins/admin/en/attributes/script.js index 21d734be60..63e28a03c7 100644 --- a/src/skins/admin/en/attributes/script.js +++ b/src/skins/admin/en/attributes/script.js @@ -18,8 +18,10 @@ popup.postprocessRequest = function(XMLHttpRequest, textStatus, data, isValid) { function () { if (jQuery(this).data('value') == jQuery(this).val()) { jQuery('.select-attributetypes .form-field-comment').hide(); + jQuery('li.custom-field').show(); } else { jQuery('.select-attributetypes .form-field-comment').show(); + jQuery('li.custom-field').hide(); } } ); diff --git a/src/skins/admin/en/attributes/style.css b/src/skins/admin/en/attributes/style.css index 7fc78d5098..ae9fa75125 100644 --- a/src/skins/admin/en/attributes/style.css +++ b/src/skins/admin/en/attributes/style.css @@ -206,6 +206,10 @@ div.group table.list th.actions.left { float: left; } +.ajax-container-loadable .model-properties div.table-value.values-value { + width: 400px; +} + .ajax-container-loadable div.button.submit { text-align: center; } @@ -218,10 +222,12 @@ div.group table.list th.actions.left { .ajax-container-loadable .select-attributetypes div.table-value .form-field-comment { background: url("../images/icon_warning_round.png") no-repeat scroll 20px center transparent; - padding: 1px 0 0 50px; + padding-left: 50px; color: #456583; float: left; display: none; + line-height: 12px; + max-width: 300px; } .ajax-container-loadable div.table-value .form-field-comment { From 798dd579d9ffab920d38d62992a2b7dd83f73127 Mon Sep 17 00:00:00 2001 From: skiv Date: Tue, 13 Nov 2012 15:32:32 +0400 Subject: [PATCH 71/85] Attributes --- src/classes/XLite/View/Model/Attribute.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/XLite/View/Model/Attribute.php b/src/classes/XLite/View/Model/Attribute.php index aaf36f86e6..b0cfb3e547 100644 --- a/src/classes/XLite/View/Model/Attribute.php +++ b/src/classes/XLite/View/Model/Attribute.php @@ -172,7 +172,7 @@ protected function getFormButtons() { $result = parent::getFormButtons(); - $label = $this->getModelObject()->getId() ? 'Save changes' : 'New attribute'; + $label = $this->getModelObject()->getId() ? 'Save changes' : 'Next'; $result['submit'] = new \XLite\View\Button\Submit( array( From f38824cbafe11e3d1b1b11bbf4762a294b588086 Mon Sep 17 00:00:00 2001 From: skiv Date: Tue, 13 Nov 2012 16:52:28 +0400 Subject: [PATCH 72/85] Attributes --- src/classes/XLite/Model/Attribute.php | 17 +++++++++++++++++ src/classes/XLite/View/Model/Attribute.php | 4 ++++ src/skins/admin/en/attributes/style.css | 10 ++++++---- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/classes/XLite/Model/Attribute.php b/src/classes/XLite/Model/Attribute.php index a6b4e69102..0a9ed22a40 100644 --- a/src/classes/XLite/Model/Attribute.php +++ b/src/classes/XLite/Model/Attribute.php @@ -168,6 +168,20 @@ public static function getTypes($type = null) : $list; } + /** + * Return values associated with this attribute + * + * @return mixed + */ + public function getAttributeValues() + { + $cnd = new \XLite\Core\CommonCell; + $cnd->attribute = $this; + + return \XLite\Core\Database::getRepo($this->getAttributeValueClass()) + ->search($cnd); + } + /** * Return number of values associated with this attribute * @@ -202,6 +216,9 @@ public function setType($type) foreach ($this->getAttributeOptions() as $option) { \XLite\Core\Database::getEM()->remove($option); } + foreach ($this->getAttributeValues() as $value) { + \XLite\Core\Database::getEM()->remove($value); + } } $this->type = $type; } diff --git a/src/classes/XLite/View/Model/Attribute.php b/src/classes/XLite/View/Model/Attribute.php index b0cfb3e547..2237404fb1 100644 --- a/src/classes/XLite/View/Model/Attribute.php +++ b/src/classes/XLite/View/Model/Attribute.php @@ -73,6 +73,10 @@ protected function getFormFieldsForSectionDefault() { if ($this->getModelObject()->getId()) { $this->schemaDefault['type'][self::SCHEMA_COMMENT] = 'Before editing attriubutes specific for the chosen type you should save the changes'; + + if ($this->getModelObject()->getAttributeValuesCount()) { + $this->schemaDefault['type'][self::SCHEMA_COMMENT] .= '
      There are products using this attribute!'; + } if ( \XLite\Model\Attribute::TYPE_NUMBER == $this->getModelObject()->getType() diff --git a/src/skins/admin/en/attributes/style.css b/src/skins/admin/en/attributes/style.css index ae9fa75125..d6a6d9020f 100644 --- a/src/skins/admin/en/attributes/style.css +++ b/src/skins/admin/en/attributes/style.css @@ -204,6 +204,7 @@ div.group table.list th.actions.left { width: auto; margin-left: 10px; float: left; + max-width: 440px; } .ajax-container-loadable .model-properties div.table-value.values-value { @@ -221,13 +222,14 @@ div.group table.list th.actions.left { } .ajax-container-loadable .select-attributetypes div.table-value .form-field-comment { - background: url("../images/icon_warning_round.png") no-repeat scroll 20px center transparent; - padding-left: 50px; + background: url("../images/icon_warning_round.png") no-repeat scroll 0px center transparent; + padding-left: 30px; color: #456583; float: left; display: none; - line-height: 12px; - max-width: 300px; + line-height: 14px; + width: 360px; + margin-top: 25px; } .ajax-container-loadable div.table-value .form-field-comment { From f6726b1d4ba1661f1fa84ddf2a5d063ceaee7130 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Tue, 13 Nov 2012 23:10:22 +0400 Subject: [PATCH 73/85] [!] Bug: Wrong directory was used for the temporary file storing event. --- src/upgrade/1.1/3/post_rebuild.php | 2 +- src/upgrade/1.1/3/post_rebuild.yaml | 2 +- src/upgrade/1.1/3/pre_upgrade.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/upgrade/1.1/3/post_rebuild.php b/src/upgrade/1.1/3/post_rebuild.php index 8ab60700ef..9200a44724 100644 --- a/src/upgrade/1.1/3/post_rebuild.php +++ b/src/upgrade/1.1/3/post_rebuild.php @@ -26,7 +26,7 @@ return function() { // Loading data to the database from yaml file - $yamlFile = __DIR__ . LC_DS . 'post_rebuild.yaml'; + $yamlFile = LC_DIR_TMP . 'post_rebuild.yaml'; if (\Includes\Utils\FileManager::isFileReadable($yamlFile)) { \XLite\Core\Database::getInstance()->loadFixturesFromYaml($yamlFile); diff --git a/src/upgrade/1.1/3/post_rebuild.yaml b/src/upgrade/1.1/3/post_rebuild.yaml index 9d5ae32842..8563fd87d7 100644 --- a/src/upgrade/1.1/3/post_rebuild.yaml +++ b/src/upgrade/1.1/3/post_rebuild.yaml @@ -1,6 +1,6 @@ # vim: set ts=2 sw=2 sts=2 et: # -# Data for core upgrading 1.1.1 -> 1.1.2 +# Data for core upgrading 1.1.1 -> 1.1.3 # # @author Creative Development LLC # @copyright Copyright (c) 2011-2012 Creative Development LLC . All rights reserved diff --git a/src/upgrade/1.1/3/pre_upgrade.php b/src/upgrade/1.1/3/pre_upgrade.php index 520ca4cc62..f32eae3e27 100644 --- a/src/upgrade/1.1/3/pre_upgrade.php +++ b/src/upgrade/1.1/3/pre_upgrade.php @@ -27,7 +27,7 @@ { // Store the profiles into the temporary YAML file \Includes\Utils\Operator::saveServiceYAML( - __DIR__ . LC_DS . 'temporary.storage.profiles.yaml', + LC_DIR_TMP . 'temporary.storage.profiles.yaml', array_map( function ($address) { return array( From 7e659cc147ddfbeedfa8973b655a586f08606001 Mon Sep 17 00:00:00 2001 From: Maxim Mukhin Date: Wed, 14 Nov 2012 11:25:31 +0400 Subject: [PATCH 74/85] [!] Bug: Wrong file path was used. --- src/upgrade/1.1/3/post_rebuild.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/upgrade/1.1/3/post_rebuild.php b/src/upgrade/1.1/3/post_rebuild.php index 9200a44724..dcba732e8d 100644 --- a/src/upgrade/1.1/3/post_rebuild.php +++ b/src/upgrade/1.1/3/post_rebuild.php @@ -26,14 +26,14 @@ return function() { // Loading data to the database from yaml file - $yamlFile = LC_DIR_TMP . 'post_rebuild.yaml'; + $yamlFile = __DIR__ . LC_DS . 'post_rebuild.yaml'; if (\Includes\Utils\FileManager::isFileReadable($yamlFile)) { \XLite\Core\Database::getInstance()->loadFixturesFromYaml($yamlFile); } // Import profile addresses from the temporary YAML file storage - $yamlProfileStorageFile = __DIR__ . LC_DS . 'temporary.storage.profiles.yaml'; + $yamlProfileStorageFile = LC_DIR_TMP . 'temporary.storage.profiles.yaml'; foreach (\Includes\Utils\Operator::loadServiceYAML($yamlProfileStorageFile) as $address) { From e1e3975f2568d29ac87d3251027055852f7c690e Mon Sep 17 00:00:00 2001 From: Sergei Fundaev Date: Wed, 14 Nov 2012 13:36:48 +0400 Subject: [PATCH 75/85] [*] post_rebuild hook has been corrected. --- src/upgrade/1.1/3/post_rebuild.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/upgrade/1.1/3/post_rebuild.yaml b/src/upgrade/1.1/3/post_rebuild.yaml index 8563fd87d7..bf02df15db 100644 --- a/src/upgrade/1.1/3/post_rebuild.yaml +++ b/src/upgrade/1.1/3/post_rebuild.yaml @@ -7,3 +7,14 @@ # @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) # @link http://www.litecommerce.com/ +XLite\Model\AddressField: + - { serviceName: title, additional: false, required: false, translations: [{ code: en, name: Title }], schemaClass: \XLite\View\FormField\Select\Title } + - { serviceName: firstname, additional: false, required: true, translations: [{ code: en, name: First name }] } + - { serviceName: lastname, additional: false, required: true, translations: [{ code: en, name: Last name }] } + - { serviceName: street, additional: false, required: true, translations: [{ code: en, name: Address }] } + - { serviceName: city, additional: false, required: true, translations: [{ code: en, name: City }] } + - { serviceName: country_code, additional: false, required: true, translations: [{ code: en, name: Country }], schemaClass: \XLite\View\FormField\Select\Country, viewGetterName: country_name } + - { serviceName: state_id, additional: false, required: true, translations: [{ code: en, name: State }], schemaClass: \XLite\View\FormField\Select\State, viewGetterName: state_name } + - { serviceName: custom_state, additional: false, required: false, translations: [{ code: en, name: State }], viewGetterName: state_name } + - { serviceName: zipcode, additional: false, required: true, translations: [{ code: en, name: Zip code }] } + - { serviceName: phone, additional: false, required: true, translations: [{ code: en, name: Phone }] } From 9670692359384df5aceca455435811e3cfe0fe72 Mon Sep 17 00:00:00 2001 From: Sergei Fundaev Date: Wed, 14 Nov 2012 14:45:39 +0400 Subject: [PATCH 76/85] [*] post_rebuild hook corrected --- src/upgrade/1.1/3/post_rebuild.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/upgrade/1.1/3/post_rebuild.php b/src/upgrade/1.1/3/post_rebuild.php index dcba732e8d..deff2a1e93 100644 --- a/src/upgrade/1.1/3/post_rebuild.php +++ b/src/upgrade/1.1/3/post_rebuild.php @@ -37,15 +37,13 @@ foreach (\Includes\Utils\Operator::loadServiceYAML($yamlProfileStorageFile) as $address) { - $_address = array(); - $_address['profile'] = \XLite\Core\Database::getRepo('XLite\Model\Profile')->find($address['profile_id']); - + $address['profile'] = \XLite\Core\Database::getRepo('XLite\Model\Profile')->find($address['profile_id']); $address['country'] = \XLite\Core\Database::getRepo('XLite\Model\Country')->findOneByCode($address['country_code']); $address['state'] = \XLite\Core\Database::getRepo('XLite\Model\State')->find($address['state_id']); unset($address['profile_id'], $address['state_id'], $address['country_code']); - $entity = new \XLite\Model\Address($_address); + $entity = new \XLite\Model\Address($address); $entity->create(); From 7d2eb3536b929a1c56a00d2bd58cff5babc8b0f1 Mon Sep 17 00:00:00 2001 From: Sergei Fundaev Date: Wed, 14 Nov 2012 15:53:56 +0400 Subject: [PATCH 77/85] [*] upgrade hook: LC_DIR_TMP -> LC_DIR_VAR --- src/upgrade/1.1/3/post_rebuild.php | 2 +- src/upgrade/1.1/3/pre_upgrade.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/upgrade/1.1/3/post_rebuild.php b/src/upgrade/1.1/3/post_rebuild.php index deff2a1e93..f6bbee8252 100644 --- a/src/upgrade/1.1/3/post_rebuild.php +++ b/src/upgrade/1.1/3/post_rebuild.php @@ -33,7 +33,7 @@ } // Import profile addresses from the temporary YAML file storage - $yamlProfileStorageFile = LC_DIR_TMP . 'temporary.storage.profiles.yaml'; + $yamlProfileStorageFile = LC_DIR_VAR . 'temporary.storage.profiles.yaml'; foreach (\Includes\Utils\Operator::loadServiceYAML($yamlProfileStorageFile) as $address) { diff --git a/src/upgrade/1.1/3/pre_upgrade.php b/src/upgrade/1.1/3/pre_upgrade.php index f32eae3e27..604be8ee6d 100644 --- a/src/upgrade/1.1/3/pre_upgrade.php +++ b/src/upgrade/1.1/3/pre_upgrade.php @@ -27,7 +27,7 @@ { // Store the profiles into the temporary YAML file \Includes\Utils\Operator::saveServiceYAML( - LC_DIR_TMP . 'temporary.storage.profiles.yaml', + LC_DIR_VAR . 'temporary.storage.profiles.yaml', array_map( function ($address) { return array( From b32d782162ab1d0db8667826493e8db34927a324 Mon Sep 17 00:00:00 2001 From: Sergei Fundaev Date: Wed, 14 Nov 2012 16:49:41 +0400 Subject: [PATCH 78/85] [*] Address fields: upgrade hook has been corrected. --- src/upgrade/1.1/3/post_rebuild.php | 19 +++++++++++-------- src/upgrade/1.1/3/pre_upgrade.php | 1 + 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/upgrade/1.1/3/post_rebuild.php b/src/upgrade/1.1/3/post_rebuild.php index f6bbee8252..5805e4f22c 100644 --- a/src/upgrade/1.1/3/post_rebuild.php +++ b/src/upgrade/1.1/3/post_rebuild.php @@ -37,18 +37,21 @@ foreach (\Includes\Utils\Operator::loadServiceYAML($yamlProfileStorageFile) as $address) { - $address['profile'] = \XLite\Core\Database::getRepo('XLite\Model\Profile')->find($address['profile_id']); - $address['country'] = \XLite\Core\Database::getRepo('XLite\Model\Country')->findOneByCode($address['country_code']); - $address['state'] = \XLite\Core\Database::getRepo('XLite\Model\State')->find($address['state_id']); + $entity = \XLite\Core\Database::getRepo('XLite\Model\Address') + ->findOneBy(array( + 'address_id' => $address['address_id'], + 'profile' => $address['profile_id'], + ) + ); - unset($address['profile_id'], $address['state_id'], $address['country_code']); - - $entity = new \XLite\Model\Address($address); - - $entity->create(); + $entity->setProfile(\XLite\Core\Database::getRepo('XLite\Model\Profile')->find($address['profile_id'])); + $entity->setCountry(\XLite\Core\Database::getRepo('XLite\Model\Country')->findOneByCode($address['country_code'])); + $entity->setState(\XLite\Core\Database::getRepo('XLite\Model\State')->find($address['state_id'])); + unset($address['profile_id'], $address['state_id'], $address['country_code']); $entity->map($address); + $entity->update(); \XLite\Core\Database::getEM()->flush($entity); } diff --git a/src/upgrade/1.1/3/pre_upgrade.php b/src/upgrade/1.1/3/pre_upgrade.php index 604be8ee6d..ac30172f36 100644 --- a/src/upgrade/1.1/3/pre_upgrade.php +++ b/src/upgrade/1.1/3/pre_upgrade.php @@ -31,6 +31,7 @@ array_map( function ($address) { return array( + 'address_id' => $address->getAddressId(), 'profile_id' => $address->getProfile()->getProfileId(), 'title' => $address->getTitle(), 'firstname' => $address->getFirstname(), From 643013b42a52e93b75836a9a55c222e02971aa9a Mon Sep 17 00:00:00 2001 From: skiv Date: Wed, 14 Nov 2012 18:01:04 +0400 Subject: [PATCH 79/85] Attributes --- src/classes/XLite/Model/Attribute.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/classes/XLite/Model/Attribute.php b/src/classes/XLite/Model/Attribute.php index 0a9ed22a40..94667fa049 100644 --- a/src/classes/XLite/Model/Attribute.php +++ b/src/classes/XLite/Model/Attribute.php @@ -211,6 +211,7 @@ public function setType($type) if ( $this->type && $type != $this->type + && $this->getId() ) { $this->setDefaultValue($this->defaultValue); foreach ($this->getAttributeOptions() as $option) { From cfa4f79c0d7c8ec6d81b1d32deaaa8cee390757b Mon Sep 17 00:00:00 2001 From: Vladimir Semyonov Date: Wed, 14 Nov 2012 21:57:08 +0400 Subject: [PATCH 80/85] E:0042148 [*] Order invoice templates for email newsletter have been corrected. --- src/classes/XLite/Core/Mailer.php | 45 +++++++++++++------ src/skins/mail/en/order/invoice/body.tpl | 8 +++- .../invoice/parts/bottom.methods.payment.tpl | 1 + .../invoice/parts/bottom.methods.shipping.tpl | 1 + .../mail/en/order/invoice/parts/bottom.tpl | 2 +- .../mail/en/order/invoice/parts/footer.tpl | 4 ++ .../mail/en/order/invoice/parts/head.tpl | 2 +- .../mail/en/order/invoice/parts/item.name.tpl | 4 +- .../en/order/invoice/parts/item.price.tpl | 2 +- .../mail/en/order/invoice/parts/item.qty.tpl | 2 +- .../en/order/invoice/parts/item.total.tpl | 2 +- .../mail/en/order/invoice/parts/items.tpl | 12 ++--- .../order/invoice/parts/totals.modifiers.tpl | 4 +- .../order/invoice/parts/totals.subtotal.tpl | 4 +- .../en/order/invoice/parts/totals.total.tpl | 6 +-- .../mail/en/order/invoice/parts/totals.tpl | 6 ++- src/skins/mail/en/order_processed/body.tpl | 1 + 17 files changed, 70 insertions(+), 36 deletions(-) diff --git a/src/classes/XLite/Core/Mailer.php b/src/classes/XLite/Core/Mailer.php index f45619b1ce..89be875c78 100644 --- a/src/classes/XLite/Core/Mailer.php +++ b/src/classes/XLite/Core/Mailer.php @@ -255,7 +255,10 @@ public static function sendOrderCreatedCustomer(\XLite\Model\Order $order) static::compose( \XLite\Core\Config::getInstance()->Company->orders_department, $order->getProfile()->getLogin(), - 'order_created' + 'order_created', + array(), + true, + \XLite::MAIL_INTERFACE ); \XLite\Core\OrderHistory::getInstance()->registerCustomerEmailSent($order->getOrderId()); @@ -275,7 +278,10 @@ public static function sendOrderCreatedAdmin(\XLite\Model\Order $order) static::compose( \XLite\Core\Config::getInstance()->Company->site_administrator, \XLite\Core\Config::getInstance()->Company->orders_department, - 'order_created_admin' + 'order_created_admin', + array(), + true, + \XLite::MAIL_INTERFACE ); \XLite\Core\OrderHistory::getInstance()->registerAdminEmailSent($order->getOrderId()); @@ -315,7 +321,10 @@ public static function sendProcessOrderAdmin(\XLite\Model\Order $order) static::compose( \XLite\Core\Config::getInstance()->Company->site_administrator, \XLite\Core\Config::getInstance()->Company->orders_department, - 'order_processed' + 'order_processed', + array(), + true, + \XLite::MAIL_INTERFACE ); \XLite\Core\OrderHistory::getInstance()->registerAdminEmailSent($order->getOrderId()); @@ -336,7 +345,10 @@ public static function sendProcessOrderCustomer(\XLite\Model\Order $order) static::compose( \XLite\Core\Config::getInstance()->Company->site_administrator, $order->getProfile()->getLogin(), - 'order_processed' + 'order_processed', + array(), + true, + \XLite::MAIL_INTERFACE ); \XLite\Core\OrderHistory::getInstance()->registerCustomerEmailSent($order->getOrderId()); @@ -377,7 +389,10 @@ public static function sendFailedOrderAdmin(\XLite\Model\Order $order) static::compose( \XLite\Core\Config::getInstance()->Company->site_administrator, \XLite\Core\Config::getInstance()->Company->orders_department, - 'order_failed' + 'order_failed', + array(), + true, + \XLite::MAIL_INTERFACE ); \XLite\Core\OrderHistory::getInstance()->registerAdminEmailSent($order->getOrderId()); @@ -398,7 +413,10 @@ public static function sendFailedOrderCustomer(\XLite\Model\Order $order) static::compose( \XLite\Core\Config::getInstance()->Company->orders_department, $order->getProfile()->getLogin(), - 'order_failed' + 'order_failed', + array(), + true, + \XLite::MAIL_INTERFACE ); \XLite\Core\OrderHistory::getInstance()->registerCustomerEmailSent($order->getOrderId()); @@ -507,17 +525,18 @@ protected static function register($name, $value = '') /** * Compose and send wrapper for \XLite\View\Mailer::compose() * - * @param string $from ____param_comment____ - * @param string $to ____param_comment____ - * @param string $dir ____param_comment____ - * @param array $customHeaders ____param_comment____ OPTIONAL - * @param boolean $doSend ____param_comment____ OPTIONAL + * @param string $from Email FROM + * @param string $to Email TO + * @param string $dir Directory where mail templates are located + * @param array $customHeaders Array of custom mail headers OPTIONAL + * @param boolean $doSend Flag: if true - send email immediately OPTIONAL + * @param string $mailInterface Intarface to compile mail templates (skin name: customer, admin or mail) OPTIONAL * * @return void */ - protected static function compose($from, $to, $dir, $customHeaders = array(), $doSend = true) + protected static function compose($from, $to, $dir, $customHeaders = array(), $doSend = true, $mailInterface = \XLite::CUSTOMER_INTERFACE) { - static::getMailer()->compose($from, $to, $dir, $customHeaders, static::$mailInterface); + static::getMailer()->compose($from, $to, $dir, $customHeaders, $mailInterface); if ($doSend) { diff --git a/src/skins/mail/en/order/invoice/body.tpl b/src/skins/mail/en/order/invoice/body.tpl index 4b0af4c78c..3f14fb9cb9 100644 --- a/src/skins/mail/en/order/invoice/body.tpl +++ b/src/skins/mail/en/order/invoice/body.tpl @@ -8,6 +8,10 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link http://www.litecommerce.com/ *} -
      + + + + +
      - +
      diff --git a/src/skins/mail/en/order/invoice/parts/bottom.methods.payment.tpl b/src/skins/mail/en/order/invoice/parts/bottom.methods.payment.tpl index 6f1303f924..9de1cc26bb 100644 --- a/src/skins/mail/en/order/invoice/parts/bottom.methods.payment.tpl +++ b/src/skins/mail/en/order/invoice/parts/bottom.methods.payment.tpl @@ -11,6 +11,7 @@ * @ListChild (list="invoice.bottom.methods", weight="20") *} +
      {t(#Payment method#)}: {foreach:order.getVisiblePaymentMethods(),m} {m.getName():h}
      diff --git a/src/skins/mail/en/order/invoice/parts/bottom.methods.shipping.tpl b/src/skins/mail/en/order/invoice/parts/bottom.methods.shipping.tpl index 78b2700635..a0c6b23b93 100644 --- a/src/skins/mail/en/order/invoice/parts/bottom.methods.shipping.tpl +++ b/src/skins/mail/en/order/invoice/parts/bottom.methods.shipping.tpl @@ -11,6 +11,7 @@ * @ListChild (list="invoice.bottom.methods", weight="10") *} +
      {t(#Shipping method#)}: {shippingModifier.method.getName():h} diff --git a/src/skins/mail/en/order/invoice/parts/bottom.tpl b/src/skins/mail/en/order/invoice/parts/bottom.tpl index 0acf8339c1..9b4f41da17 100644 --- a/src/skins/mail/en/order/invoice/parts/bottom.tpl +++ b/src/skins/mail/en/order/invoice/parts/bottom.tpl @@ -10,7 +10,7 @@ * * @ListChild (list="invoice.base", weight="50") *} - +
      {w.display()} diff --git a/src/skins/mail/en/order/invoice/parts/footer.tpl b/src/skins/mail/en/order/invoice/parts/footer.tpl index 1fdfa41fce..6d504e98e6 100644 --- a/src/skins/mail/en/order/invoice/parts/footer.tpl +++ b/src/skins/mail/en/order/invoice/parts/footer.tpl @@ -10,4 +10,8 @@ * * @ListChild (list="invoice.base", weight="60") *} + +
      +
      +
      {t(#Thank you for your order FOOTER#):h}
      diff --git a/src/skins/mail/en/order/invoice/parts/head.tpl b/src/skins/mail/en/order/invoice/parts/head.tpl index c25cd3e61a..ac3cf2fdc2 100644 --- a/src/skins/mail/en/order/invoice/parts/head.tpl +++ b/src/skins/mail/en/order/invoice/parts/head.tpl @@ -10,7 +10,7 @@ * * @ListChild (list="invoice.base", weight="10") *} -
      +
      diff --git a/src/skins/mail/en/order/invoice/parts/item.name.tpl b/src/skins/mail/en/order/invoice/parts/item.name.tpl index 07bd0eb5c4..2b0b83bc25 100644 --- a/src/skins/mail/en/order/invoice/parts/item.name.tpl +++ b/src/skins/mail/en/order/invoice/parts/item.name.tpl @@ -10,8 +10,8 @@ * * @ListChild (list="invoice.item", weight="10") *} - + diff --git a/src/skins/mail/en/order/invoice/parts/item.qty.tpl b/src/skins/mail/en/order/invoice/parts/item.qty.tpl index 9a1c7ba3b5..967abc0a57 100644 --- a/src/skins/mail/en/order/invoice/parts/item.qty.tpl +++ b/src/skins/mail/en/order/invoice/parts/item.qty.tpl @@ -10,4 +10,4 @@ * * @ListChild (list="invoice.subitem", weight="20") *} - + diff --git a/src/skins/mail/en/order/invoice/parts/item.total.tpl b/src/skins/mail/en/order/invoice/parts/item.total.tpl index f8757be129..182fec2369 100644 --- a/src/skins/mail/en/order/invoice/parts/item.total.tpl +++ b/src/skins/mail/en/order/invoice/parts/item.total.tpl @@ -10,4 +10,4 @@ * * @ListChild (list="invoice.item", weight="40") *} - + diff --git a/src/skins/mail/en/order/invoice/parts/items.tpl b/src/skins/mail/en/order/invoice/parts/items.tpl index 80268154d7..40a48b513a 100644 --- a/src/skins/mail/en/order/invoice/parts/items.tpl +++ b/src/skins/mail/en/order/invoice/parts/items.tpl @@ -10,16 +10,16 @@ * * @ListChild (list="invoice.base", weight="30") *} -
      - {item.getName()} + + {item.getName()}
      diff --git a/src/skins/mail/en/order/invoice/parts/item.price.tpl b/src/skins/mail/en/order/invoice/parts/item.price.tpl index ff9bd44c9c..7de714713c 100644 --- a/src/skins/mail/en/order/invoice/parts/item.price.tpl +++ b/src/skins/mail/en/order/invoice/parts/item.price.tpl @@ -10,4 +10,4 @@ * * @ListChild (list="invoice.subitem", weight="30") *} -
      {formatPrice(item.getNetPrice(),order.getCurrency())}{formatPrice(item.getNetPrice(),order.getCurrency())}{item.getAmount()}{item.getAmount()}{formatPrice(item.getTotal(),order.getCurrency())}{formatPrice(item.getTotal(),order.getCurrency())}
      +
      - + - + - + {foreach:order.getItems(),index,item} @@ -29,8 +29,8 @@ - - + + {end:} diff --git a/src/skins/mail/en/order/invoice/parts/totals.modifiers.tpl b/src/skins/mail/en/order/invoice/parts/totals.modifiers.tpl index 02da02aeba..43dc18ef00 100644 --- a/src/skins/mail/en/order/invoice/parts/totals.modifiers.tpl +++ b/src/skins/mail/en/order/invoice/parts/totals.modifiers.tpl @@ -11,13 +11,13 @@ * @ListChild (list="invoice.base.totals", weight="200") *} - + {if:surcharge.count=#1#} {else:} {end:} - + - + diff --git a/src/skins/mail/en/order/invoice/parts/totals.total.tpl b/src/skins/mail/en/order/invoice/parts/totals.total.tpl index 6b71e5d763..cf91e95029 100644 --- a/src/skins/mail/en/order/invoice/parts/totals.total.tpl +++ b/src/skins/mail/en/order/invoice/parts/totals.total.tpl @@ -10,7 +10,7 @@ * * @ListChild (list="invoice.base.totals", weight="300") *} - - - + + + diff --git a/src/skins/mail/en/order/invoice/parts/totals.tpl b/src/skins/mail/en/order/invoice/parts/totals.tpl index 8edfeb0a65..9c5531736e 100644 --- a/src/skins/mail/en/order/invoice/parts/totals.tpl +++ b/src/skins/mail/en/order/invoice/parts/totals.tpl @@ -10,6 +10,10 @@ * * @ListChild (list="invoice.base", weight="40") *} -
      {surcharge.lastName}:{surcharge.name}: + {if:surcharge.available} {formatPrice(surcharge.cost,order.getCurrency())} {else:} diff --git a/src/skins/mail/en/order/invoice/parts/totals.subtotal.tpl b/src/skins/mail/en/order/invoice/parts/totals.subtotal.tpl index 68d9ccf809..b476228d47 100644 --- a/src/skins/mail/en/order/invoice/parts/totals.subtotal.tpl +++ b/src/skins/mail/en/order/invoice/parts/totals.subtotal.tpl @@ -10,7 +10,7 @@ * * @ListChild (list="invoice.base.totals", weight="100") *} -
      {t(#Subtotal#)}:{formatPrice(order.getSubtotal(),order.getCurrency())}{formatPrice(order.getSubtotal(),order.getCurrency())}
      {t(#Grand total#)}:{formatPrice(order.getTotal(),order.getCurrency())}
      {t(#Grand total#)}:{formatPrice(order.getTotal(),order.getCurrency())}
      + +
      +{t(#Totals#)} +
      +
      diff --git a/src/skins/mail/en/order_processed/body.tpl b/src/skins/mail/en/order_processed/body.tpl index 5207cf5d75..0ea186d9f9 100644 --- a/src/skins/mail/en/order_processed/body.tpl +++ b/src/skins/mail/en/order_processed/body.tpl @@ -13,6 +13,7 @@ {t(#Dear X#,_ARRAY_(#firstname#^order.profile.billing_address.firstname,#lastname#^order.profile.billing_address.lastname)):h}

      {t(#Your order has been processed#,_ARRAY_(#id#^order.order_id)):h} {t(#Thank you for your order FOOTER#):h} +


      From 7efe1ac265b70034b085b4432e36eb2c43d17136 Mon Sep 17 00:00:00 2001 From: skiv Date: Thu, 15 Nov 2012 16:08:00 +0400 Subject: [PATCH 81/85] Attributes --- src/classes/XLite/View/Model/Attribute.php | 7 +++++-- src/skins/admin/en/attributes/style.css | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/classes/XLite/View/Model/Attribute.php b/src/classes/XLite/View/Model/Attribute.php index 2237404fb1..57e3a35c80 100644 --- a/src/classes/XLite/View/Model/Attribute.php +++ b/src/classes/XLite/View/Model/Attribute.php @@ -74,8 +74,11 @@ protected function getFormFieldsForSectionDefault() if ($this->getModelObject()->getId()) { $this->schemaDefault['type'][self::SCHEMA_COMMENT] = 'Before editing attriubutes specific for the chosen type you should save the changes'; - if ($this->getModelObject()->getAttributeValuesCount()) { - $this->schemaDefault['type'][self::SCHEMA_COMMENT] .= '
      There are products using this attribute!'; + if ( + $this->getModelObject()->getAttributeValuesCount() + || $this->getModelObject()->getProductClass()->getProductsCount() + ) { + $this->schemaDefault['type'][self::SCHEMA_COMMENT] .= '

      Changing the type of a product attribute after having defined values for this attribute for some products will result in losing the defined attribute values'; } if ( diff --git a/src/skins/admin/en/attributes/style.css b/src/skins/admin/en/attributes/style.css index d6a6d9020f..0036ccd427 100644 --- a/src/skins/admin/en/attributes/style.css +++ b/src/skins/admin/en/attributes/style.css @@ -222,7 +222,7 @@ div.group table.list th.actions.left { } .ajax-container-loadable .select-attributetypes div.table-value .form-field-comment { - background: url("../images/icon_warning_round.png") no-repeat scroll 0px center transparent; + background: url("../images/icon_warning_round.png") no-repeat scroll 0 0 transparent; padding-left: 30px; color: #456583; float: left; @@ -273,6 +273,7 @@ div.group table.list th.actions.left { text-align: center; width: 440px; margin-top: 10px; + padding: 0 30px; } .ajax-container-loadable .model-form-buttons { From eb1d2a3a5eb99a50a59969f93a8a3cab867ddcf8 Mon Sep 17 00:00:00 2001 From: Vladimir Semenov Date: Fri, 16 Nov 2012 10:27:12 +0400 Subject: [PATCH 82/85] [!] Minor fix in Model/Payment/Method.php --- src/classes/XLite/Model/Payment/Method.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/XLite/Model/Payment/Method.php b/src/classes/XLite/Model/Payment/Method.php index 7f58db4b10..b65ae76337 100644 --- a/src/classes/XLite/Model/Payment/Method.php +++ b/src/classes/XLite/Model/Payment/Method.php @@ -338,7 +338,7 @@ public function getWarningNote() { $message = null; - if (!$this->getProcessor()->isConfigured($this)) { + if ($this->getProcessor() && !$this->getProcessor()->isConfigured($this)) { $message = static::t('The method is not configured and can\'t be used'); } From cf279357217d5718884607382add98b42d97d68b Mon Sep 17 00:00:00 2001 From: Sergei Fundaev Date: Fri, 16 Nov 2012 13:09:04 +0400 Subject: [PATCH 83/85] [!] Cyrillic symbols in attributes values were displayed wrong. --- src/classes/XLite/View/Product/Details/Customer/Attributes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/XLite/View/Product/Details/Customer/Attributes.php b/src/classes/XLite/View/Product/Details/Customer/Attributes.php index 2862d34869..d5b1b9dbf8 100644 --- a/src/classes/XLite/View/Product/Details/Customer/Attributes.php +++ b/src/classes/XLite/View/Product/Details/Customer/Attributes.php @@ -52,7 +52,7 @@ public function getAttrList() if ($value) { $this->attributes[] = array( 'name' => $a->getName(), - 'value' => htmlentities($value), + 'value' => htmlspecialchars($value), 'class' => $this->getFieldClass($a, $value) ); } From 8649bc3a45700410cfb0e2c8635a43277ce753c1 Mon Sep 17 00:00:00 2001 From: Vladimir Semenov Date: Fri, 16 Nov 2012 13:44:04 +0400 Subject: [PATCH 84/85] [*] Added hidden URL to clear marketplace cache --- .../XLite/Controller/Admin/AddonsListMarketplace.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/classes/XLite/Controller/Admin/AddonsListMarketplace.php b/src/classes/XLite/Controller/Admin/AddonsListMarketplace.php index 9744bd06b8..fe557c10ee 100644 --- a/src/classes/XLite/Controller/Admin/AddonsListMarketplace.php +++ b/src/classes/XLite/Controller/Admin/AddonsListMarketplace.php @@ -40,4 +40,16 @@ public function getTitle() { return 'Modules Marketplace'; } + + /** + * Clear marketplace cache + * + * @return void + */ + protected function doActionClearCache() + { + \XLite\Core\Marketplace::getInstance()->clearActionCache(\XLite\Core\Marketplace::ACTION_GET_ADDONS_LIST); + + $this->setReturnURL($this->buildURL('addons_list_marketplace')); + } } From d1488ab488c8211dec93e17df9a1076f53b74b68 Mon Sep 17 00:00:00 2001 From: Sergei Fundaev Date: Fri, 16 Nov 2012 17:57:03 +0400 Subject: [PATCH 85/85] [*] Attributes: oops. --- src/skins/admin/en/attribute/select.tpl | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/skins/admin/en/attribute/select.tpl diff --git a/src/skins/admin/en/attribute/select.tpl b/src/skins/admin/en/attribute/select.tpl deleted file mode 100644 index d862b5e04b..0000000000 --- a/src/skins/admin/en/attribute/select.tpl +++ /dev/null @@ -1 +0,0 @@ -sdfsdfsdfds