diff --git a/CHANGELOG.md b/CHANGELOG.md index 67c355bcc7bd8b2d1b450ebc8240d3e19e9b4cf6..ddcbc8c2cc06bbddf7a7a8c694645f0ea1e309b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +0.74.0-beta7 +============= +* Framework improvements + * Exceptions are caught and logged before reaching the Phrase::__toString() method + * Refactored controller actions in the Checkout area + * Refactored controller actions in the Tax area + * Implemented new look & feel for the Edit Order page (View/Edit Order) + * Replaced the end-to-end test for Onepage Checkout with online shipment methods with the scenario test +* Fixed bugs + * Fixed an issue where a success message was absent when adding a product with options from Wishlist to Shopping Cart + * Fixed an issue where an exception was thrown when trying to sort Customer Groups by Tax Class + * Fixed an issue where the background color changed to the “on focus†state when clicking the Admin Menu logo + * Fixed an issue with Mini Shopping Cart containing extra empty space +* GitHub issues + * [#1173] (https://github.com/magento/magento2/pull/1173) -- Change to HttpClient4 from Java client; fix regex issues + * [#1185] (https://github.com/magento/magento2/pull/1185) -- Error message for duplicated phrases not allowed in Generator.php + * [#1199] (https://github.com/magento/magento2/pull/1199) -- Add Event for sales_order_state_change_before during Order->saveState() + * [#1201] (https://github.com/magento/magento2/pull/1101) -- Add customer_validate event + * [#1202] (https://github.com/magento/magento2/pull/1102) -- Email sending events + 0.74.0-beta6 ============= * Framework improvements diff --git a/app/code/Magento/AdminNotification/composer.json b/app/code/Magento/AdminNotification/composer.json index 354ef5fe45ea35de94ce81c1970bbb98e1a889ab..f458a240d3166d604a83b026cf38c06e32ed6247 100644 --- a/app/code/Magento/AdminNotification/composer.json +++ b/app/code/Magento/AdminNotification/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "lib-libxml": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/AdminNotification/view/adminhtml/templates/toolbar_entry.phtml b/app/code/Magento/AdminNotification/view/adminhtml/templates/toolbar_entry.phtml index 4eb8992290adff8b14a85fc98e0f1b7b944a812c..e020a661d4d917d2e61ef793ab0c76bdb2eda699 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/templates/toolbar_entry.phtml +++ b/app/code/Magento/AdminNotification/view/adminhtml/templates/toolbar_entry.phtml @@ -14,12 +14,12 @@ ?> <div data-mage-init='{"toolbarEntry": {}}' - class="notifications-wrapper" + class="notifications-wrapper admin__action-dropdown-wrap" data-notification-count="<?php echo $notificationCount; ?>"> <?php if ($notificationCount > 0) : ?> <a href="<?php echo $block->getUrl('adminhtml/notification/index'); ?>" - class="notifications-action" + class="notifications-action admin__action-dropdown" data-mage-init='{"dropdown":{}}' title="<?php echo __('Notifications'); ?>" data-toggle="dropdown"> @@ -28,7 +28,7 @@ </span> </a> <ul - class="notifications-list" + class="admin__action-dropdown-menu" data-mark-as-read-url="<?php echo $block->getUrl('adminhtml/notification/ajaxMarkAsRead'); ?>"> <?php foreach ($block->getLatestUnreadNotifications() as $notification) : ?> <?php /** @var $notification \Magento\AdminNotification\Model\Inbox*/ ?> @@ -76,7 +76,7 @@ </ul> <?php else : ?> <a - class="notifications-action" + class="notifications-action admin__action-dropdown" href="<?php echo $block->getUrl('adminhtml/notification/index'); ?>" title="<?php echo __('Notifications'); ?>"> </a> diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/toolbar_entry.js b/app/code/Magento/AdminNotification/view/adminhtml/web/toolbar_entry.js index 43e4869cdf52625f864894e028715f0bc6de40d7..7eb99c590fb4a66a814a18698258bb1b3993e784 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/toolbar_entry.js +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/toolbar_entry.js @@ -11,7 +11,7 @@ define([ // Mark notification as read via AJAX call var markNotificationAsRead = function (notificationId) { - var requestUrl = $('.notifications-wrapper .notifications-list').attr('data-mark-as-read-url'); + var requestUrl = $('.notifications-wrapper .admin__action-dropdown-menu').attr('data-mark-as-read-url'); $.ajax({ url: requestUrl, type: 'POST', @@ -33,7 +33,7 @@ define([ if (notificationCount == 0) { // Change appearance of the bubble and its behavior when the last notification is removed - $('.notifications-wrapper .notifications-list').remove(); + $('.notifications-wrapper .admin__action-dropdown-menu').remove(); var notificationIcon = $('.notifications-wrapper .notifications-icon'); notificationIcon.removeAttr('data-toggle'); notificationIcon.off('click.dropdown'); @@ -45,7 +45,7 @@ define([ } $('.notifications-entry-last .notifications-counter').text(notificationCount); // Modify caption of the 'See All' link - var actionElement = $('.notifications-wrapper .notifications-list .last .action-more'); + var actionElement = $('.notifications-wrapper .admin__action-dropdown-menu .last .action-more'); actionElement.text(actionElement.text().replace(/\d+/, notificationCount)); } }, @@ -65,7 +65,7 @@ define([ }; // Show notification description when corresponding item is clicked - $('.notifications-wrapper .notifications-list .notifications-entry').on('click.showNotification', function (event) { + $('.notifications-wrapper .admin__action-dropdown-menu .notifications-entry').on('click.showNotification', function (event) { // hide notification dropdown $('.notifications-wrapper .notifications-icon').trigger('click.dropdown'); diff --git a/app/code/Magento/Authorization/composer.json b/app/code/Magento/Authorization/composer.json index 22341f8d0b4d16e93ce92006994cd36e1fbedb58..7e752b8409c4e92ccb1114620a761fdb81d5f50e 100644 --- a/app/code/Magento/Authorization/composer.json +++ b/app/code/Magento/Authorization/composer.json @@ -3,12 +3,12 @@ "description": "Authorization module provides access to Magento ACL functionality.", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-backend": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-backend": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Backend/Block/Menu.php b/app/code/Magento/Backend/Block/Menu.php index 6eaed8e5b16344608d8b4672b933ca2b013c284d..55ad3f2cbca00cec0f08004c0a0db5867727d769 100644 --- a/app/code/Magento/Backend/Block/Menu.php +++ b/app/code/Magento/Backend/Block/Menu.php @@ -419,7 +419,7 @@ class Menu extends \Magento\Backend\Block\Template if ($level == 0 && $limit) { $colStops = $this->_columnBrake($menuItem->getChildren(), $limit); $output .= '<strong class="submenu-title">' . $this->_getAnchorLabel($menuItem) . '</strong>'; - $output .= '<a href="#" class="submenu-close _close" data-role="close-submenu"></a>'; + $output .= '<a href="#" class="action-close _close" data-role="close-submenu"></a>'; } $output .= $this->renderNavigation($menuItem->getChildren(), $level + 1, $limit, $colStops); diff --git a/app/code/Magento/Backend/Block/Widget/Grid.php b/app/code/Magento/Backend/Block/Widget/Grid.php index 0e0ac51f859950b32f695e7014a04de1a7ce4684..1d33dc18146219f8fe4cb68d00b03a1aefa0ebad 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid.php +++ b/app/code/Magento/Backend/Block/Widget/Grid.php @@ -391,6 +391,10 @@ class Grid extends \Magento\Backend\Block\Widget */ protected function _prepareGrid() { + $this->_eventManager->dispatch( + 'backend_block_widget_grid_prepare_grid_before', + ['grid' => $this, 'collection' => $this->getCollection()] + ); if ($this->getChildBlock('grid.massaction') && $this->getChildBlock('grid.massaction')->isAvailable()) { $this->getChildBlock('grid.massaction')->prepareMassactionColumn(); } @@ -433,6 +437,10 @@ class Grid extends \Magento\Backend\Block\Widget 'Magento\Backend\Block\Widget\Button' )->setData( ['label' => __('Reset Filter'), 'onclick' => $this->getJsObjectName() . '.resetFilter()', 'class' => 'action-reset'] + )->setDataAttribute( + [ + 'action' => 'grid-filter-reset' + ] ) ); $this->setChild( @@ -445,6 +453,10 @@ class Grid extends \Magento\Backend\Block\Widget 'onclick' => $this->getJsObjectName() . '.doFilter()', 'class' => 'task', ] + )->setDataAttribute( + [ + 'action' => 'grid-filter-apply' + ] ) ); } diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Extended.php b/app/code/Magento/Backend/Block/Widget/Grid/Extended.php index cafd687c9da150d6c0d56c7e0649645a24923e51..516c3eaae5040e655ac5bf02c7b2871a9208a394 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid/Extended.php +++ b/app/code/Magento/Backend/Block/Widget/Grid/Extended.php @@ -208,6 +208,10 @@ class Extended extends \Magento\Backend\Block\Widget\Grid implements \Magento\Ba 'onclick' => $this->getJsObjectName() . '.resetFilter()', 'class' => 'action-reset' ] + )->setDataAttribute( + [ + 'action' => 'grid-filter-reset' + ] ) ); $this->setChild( @@ -218,6 +222,10 @@ class Extended extends \Magento\Backend\Block\Widget\Grid implements \Magento\Ba 'onclick' => $this->getJsObjectName() . '.doFilter()', 'class' => 'task', ] + )->setDataAttribute( + [ + 'action' => 'grid-filter-apply' + ] ) ); return parent::_prepareLayout(); diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json index d229a7feb44b54367af4b052d1c43bc2a8f7e517..d304a64899593b2b01303dd3e431a9c59fb47fbc 100644 --- a/app/code/Magento/Backend/composer.json +++ b/app/code/Magento/Backend/composer.json @@ -3,27 +3,27 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-developer": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-cron": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/module-reports": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-user": "0.74.0-beta6", - "magento/module-backup": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-translation": "0.74.0-beta6", - "magento/module-require-js": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-developer": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-cron": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/module-reports": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-user": "0.74.0-beta7", + "magento/module-backup": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-translation": "0.74.0-beta7", + "magento/module-require-js": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Backend/view/adminhtml/templates/admin/login.phtml b/app/code/Magento/Backend/view/adminhtml/templates/admin/login.phtml index 1d1cb81fd064a8dce77e3e6b76b8675672293118..12d8f0b32e94d50d64a55d9b687b84492af28c20 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/admin/login.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/admin/login.phtml @@ -7,6 +7,7 @@ // @codingStandardsIgnoreFile ?> + <form method="post" action="" id="login-form" data-mage-init='{"form": {}, "validation": {}}' autocomplete="off"> <fieldset class="admin__fieldset"> <legend class="admin__legend"><span><?php echo __('Welcome, please sign in') ?></span></legend><br/> @@ -14,15 +15,33 @@ <div class="admin__field _required field-username"> <label for="username" class="admin__field-label"><span><?php echo __('Username') ?></span></label> <div class="admin__field-control"> - <input type="text" id="username" name="login[username]" autofocus value="" data-validate="{required:true}" class="admin__control-text" placeholder="<?php echo __('user name') ?>" /> + <input + id="username" + class="admin__control-text" + type="text" + name="login[username]" + autofocus + value="" + data-validate="{required:true}" + placeholder="<?php echo __('user name') ?>"/> </div> </div> <div class="admin__field _required field-password"> <label for="login" class="admin__field-label"><span><?php echo __('Password') ?></span></label> <div class="admin__field-control"> <!-- This is a dummy hidden field to trick firefox from auto filling the password --> - <input type="text" class="admin__control-dummy" name="dummy" id="dummy" /> - <input type="password" id="login" name="login[password]" data-validate="{required:true}" class="admin__control-text" value="" placeholder="<?php echo __('password') ?>" /> + <input + id="dummy" + class="admin__control-dummy" + type="text" + name="dummy"/> + <input + id="login" + class="admin__control-text" + type="password" + name="login[password]" + data-validate="{required:true}" + value="" placeholder="<?php echo __('password') ?>" /> </div> </div> <?php echo $block->getChildHtml('form.additional.info'); ?> diff --git a/app/code/Magento/Backend/view/adminhtml/templates/page/header.phtml b/app/code/Magento/Backend/view/adminhtml/templates/page/header.phtml index 6e90069f9ee6c87bfcc4119b16c78d46ecfd3583..8b60043de0f8d49b63f65ab771eef3a065fcfec6 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/page/header.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/page/header.phtml @@ -21,18 +21,18 @@ </a> <?php break; ?> <?php case 'user': ?> - <div class="admin-user"> + <div class="admin-user admin__action-dropdown-wrap"> <a href="<?php echo $block->getUrl('adminhtml/system_account/index') ?>" - class="admin-user-account" + class="admin__action-dropdown" title="<?php echo $block->escapeHtml(__('My Account')) ?>" data-mage-init='{"dropdown":{}}' data-toggle="dropdown"> - <span class="admin-user-account-text-wrapper"> + <span class="admin__action-dropdown-text"> <span class="admin-user-account-text"><?php echo $block->escapeHtml($block->getUser()->getUsername()); ?></span> </span> </a> - <ul class="admin-user-menu"> + <ul class="admin__action-dropdown-menu"> <?php if ($block->getAuthorization()->isAllowed('Magento_Backend::myaccount')): ?> <li> <a diff --git a/app/code/Magento/Backup/composer.json b/app/code/Magento/Backup/composer.json index f7f9a0371534346f0bc39f7d7087a12200428386..e562c51a28780fef47745fed5db8c70162f3417a 100644 --- a/app/code/Magento/Backup/composer.json +++ b/app/code/Magento/Backup/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-cron": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-cron": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json index a16b4ad6d56cfb1002fae21f984ace5e9a5ea588..07f3110b0c936a3d3a3cdfac5dcf640aaf6b7c1e 100644 --- a/app/code/Magento/Bundle/composer.json +++ b/app/code/Magento/Bundle/composer.json @@ -3,28 +3,28 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-catalog-rule": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/module-gift-message": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-catalog-rule": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/module-gift-message": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-webapi": "0.74.0-beta6" + "magento/module-webapi": "0.74.0-beta7" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CacheInvalidate/composer.json b/app/code/Magento/CacheInvalidate/composer.json index 4e1062c5a74902db562b9e2c7ed010ff9ab5bdfa..31eb21d58f55a24acfd34f0b5ca9623adead22f0 100644 --- a/app/code/Magento/CacheInvalidate/composer.json +++ b/app/code/Magento/CacheInvalidate/composer.json @@ -3,12 +3,12 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-page-cache": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-page-cache": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Captcha/composer.json b/app/code/Magento/Captcha/composer.json index dee103fd89226bade4029e318d5b99fd03bf2b30..d1ee6a69a432e98b832400e6b8bd3143bb7531cb 100644 --- a/app/code/Magento/Captcha/composer.json +++ b/app/code/Magento/Captcha/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml index d862e010441d261c1f906fc79dc8f28a9db1de57..d8811b0a29338951f610ca182a481d368745f3de 100644 --- a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml +++ b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml @@ -11,9 +11,16 @@ <?php /* @var $block \Magento\Captcha\Block\Captcha\DefaultCaptcha */ ?> <?php $captcha = $block->getCaptchaModel() ?> <div class="admin__field _required"> - <label for="captcha" class="admin__field-label"><span><?php echo __('Please enter the letters from the image') ?></span></label> + <label for="captcha" class="admin__field-label"> + <span><?php echo __('Please enter the letters from the image') ?></span> + </label> <div class="admin__field-control"> - <input type="text" name="<?php echo \Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE ?>[<?php echo $block->getFormId()?>]" id="captcha" data-validate="{required:true}" class="admin__control-text"/> + <input + id="captcha" + class="admin__control-text" + type="text" + name="<?php echo \Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE ?>[<?php echo $block->getFormId()?>]" + data-validate="{required:true}"/> <?php if ($captcha->isCaseSensitive()) :?> <div class="admin__field-note"> <span><?php echo __('<strong>Attention</strong>: Captcha is case sensitive.') ?></span> @@ -22,8 +29,16 @@ </div> </div> <div class="admin__field field-captcha"> - <img id="captcha-reload" class="captcha-reload" src="<?php echo $block->getViewFileUrl('Magento_Captcha::reload.png') ?>" alt="<?php echo __('Reload captcha') ?>"/> - <img id="<?php echo $block->getFormId() ?>" width="<?php echo $block->getImgWidth() ?>" height="<?php echo $block->getImgHeight() ?>" src="<?php echo $captcha->getImgSrc() ?>" /> + <img + id="captcha-reload" + class="captcha-reload" + src="<?php echo $block->getViewFileUrl('Magento_Captcha::reload.png') ?>" + alt="<?php echo __('Reload captcha') ?>"/> + <img + id="<?php echo $block->getFormId() ?>" + width="<?php echo $block->getImgWidth() ?>" + height="<?php echo $block->getImgHeight() ?>" + src="<?php echo $captcha->getImgSrc() ?>" /> </div> <script> require(["prototype", "mage/captcha"], function(){ diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json index 16e53d937b9199bb77a3828853871a6e287d4060..9aba73d735b3ff1caee1b2a7840d0a37037bb935 100644 --- a/app/code/Magento/Catalog/composer.json +++ b/app/code/Magento/Catalog/composer.json @@ -3,37 +3,37 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-cms": "0.74.0-beta6", - "magento/module-indexer": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-log": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-widget": "0.74.0-beta6", - "magento/module-wishlist": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/module-msrp": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-catalog-rule": "0.74.0-beta6", - "magento/module-product-alert": "0.74.0-beta6", - "magento/module-url-rewrite": "0.74.0-beta6", - "magento/module-catalog-url-rewrite": "0.74.0-beta6", - "magento/module-page-cache": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-cms": "0.74.0-beta7", + "magento/module-indexer": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-log": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-widget": "0.74.0-beta7", + "magento/module-wishlist": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/module-msrp": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-catalog-rule": "0.74.0-beta7", + "magento/module-product-alert": "0.74.0-beta7", + "magento/module-url-rewrite": "0.74.0-beta7", + "magento/module-catalog-url-rewrite": "0.74.0-beta7", + "magento/module-page-cache": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-cookie": "0.74.0-beta6" + "magento/module-cookie": "0.74.0-beta7" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product.js index df3cc6b9694987e9e382d8e348db0fd2f95d9915..ec4e6efab5be63b5539f5a25ab5c449cebe1a04b 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product.js @@ -3,14 +3,18 @@ * See COPYING.txt for license details. */ require([ - "jquery", - "prototype" -], function(jQuery){ + 'jquery' +], function ($) { + 'use strict'; window.Product = {}; + function byId(id) { + return document.getElementById(id); + } + function toogleFieldEditMode(toogleIdentifier, fieldContainer) { - if ($(toogleIdentifier).checked) { + if (byId(toogleIdentifier).checked) { enableFieldEditMode(fieldContainer); } else { disableFieldEditMode(fieldContainer); @@ -18,47 +22,53 @@ require([ } function disableFieldEditMode(fieldContainer) { - $(fieldContainer).disabled = true; - if ($(fieldContainer + '_hidden')) { - $(fieldContainer + '_hidden').disabled = true; + byId(fieldContainer).disabled = true; + + if (byId(fieldContainer + '_hidden')) { + byId(fieldContainer + '_hidden').disabled = true; } } function enableFieldEditMode(fieldContainer) { - $(fieldContainer).disabled = false; - if ($(fieldContainer + '_hidden')) { - $(fieldContainer + '_hidden').disabled = false; + byId(fieldContainer).disabled = false; + + if (byId(fieldContainer + '_hidden')) { + byId(fieldContainer + '_hidden').disabled = false; } } function onCompleteDisableInited() { - jQuery.each(jQuery('[data-disable]'), function () { - var item = jQuery(this).data('disable'); + $.each($('[data-disable]'), function () { + var item = $(this).data('disable'); disableFieldEditMode(item); }); } function onUrlkeyChanged(urlKey) { - urlKey = $(urlKey); - var hidden = urlKey.next('input[type=hidden]'); - var chbx = urlKey.next('input[type=checkbox]'); + urlKey = byId(urlKey); + var hidden = $(urlKey).next('input[type=hidden]')[0]; + var chbx = $(urlKey).next('input[type=checkbox]')[0]; var oldValue = chbx.value; - chbx.disabled = (oldValue == urlKey.value); + + chbx.disabled = (oldValue === urlKey.value); hidden.disabled = chbx.disabled; } function onCustomUseParentChanged(element) { - var useParent = (element.value == 1) ? true : false; - element.up(2).select('input', 'select', 'textarea').each(function (el) { - if (element.id != el.id) { + var useParent = (element.value === 1) ? true : false, + parent = $(element).parent().parent(); + + parent.find('input, select, textarea').each(function (i, el) { + if (element.id !== el.id) { el.disabled = useParent; } }); - element.up(2).select('img').each(function (el) { + + parent.find('img').each(function (i, el) { if (useParent) { - el.hide(); + $(el).hide(); } else { - el.show(); + $(el).show(); } }); } @@ -67,5 +77,5 @@ require([ window.onUrlkeyChanged = onUrlkeyChanged; window.toogleFieldEditMode = toogleFieldEditMode; - Event.observe(window, 'load', onCompleteDisableInited); -}); \ No newline at end of file + $(window).load(onCompleteDisableInited); +}); diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json index ee8f34355558e63ab22dc08089041e4bdc99c3a4..83d1e2e075da3a7a18b94418bb619feb0d8f86ad 100644 --- a/app/code/Magento/CatalogImportExport/composer.json +++ b/app/code/Magento/CatalogImportExport/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-import-export": "0.74.0-beta6", - "magento/module-indexer": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-import-export": "0.74.0-beta7", + "magento/module-indexer": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "ext-ctype": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json index 129c2285172ca06dabdd98cb51dcc1a6ba9fdad7..b7209d2df90f07c288bdaa1eca809222777c6678 100644 --- a/app/code/Magento/CatalogInventory/composer.json +++ b/app/code/Magento/CatalogInventory/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-indexer": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-indexer": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json index 321bbcd7334b631b6f630452474b2ae25f5a265c..b3192cfcc8459c4f74fa8c68076c255add2719b3 100644 --- a/app/code/Magento/CatalogRule/composer.json +++ b/app/code/Magento/CatalogRule/composer.json @@ -3,19 +3,19 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-rule": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-indexer": "0.74.0-beta6", - "magento/module-import-export": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-rule": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-indexer": "0.74.0-beta7", + "magento/module-import-export": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json index d9f2822e173203097515ba797209fdbb4a4c8a64..39e60cdc03a9c5e15623e4744e874cb04360f601 100644 --- a/app/code/Magento/CatalogSearch/composer.json +++ b/app/code/Magento/CatalogSearch/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-search": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-indexer": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-search": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-indexer": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json index 2488990a45e7570de05a47be2802787cb2fe1395..2e9cc77143f5017b3fc59b6257edd8789592fcef 100644 --- a/app/code/Magento/CatalogUrlRewrite/composer.json +++ b/app/code/Magento/CatalogUrlRewrite/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-backend": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-catalog-import-export": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-import-export": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-url-rewrite": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-backend": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-catalog-import-export": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-import-export": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-url-rewrite": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogWidget/composer.json b/app/code/Magento/CatalogWidget/composer.json index e92c896cb1a574e1aa912d5cc378bb8c70aead25..6600bf5ff65cec1c7f2915dcceb4d5812048bcdb 100644 --- a/app/code/Magento/CatalogWidget/composer.json +++ b/app/code/Magento/CatalogWidget/composer.json @@ -3,19 +3,19 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-widget": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-rule": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-wishlist": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-widget": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-rule": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-wishlist": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Centinel/composer.json b/app/code/Magento/Centinel/composer.json index 584771858a87c0b5d497fd4ff33d11d890b28892..fba6a6e8c1b5af2c4b3f933e8ca57cd319447f4f 100644 --- a/app/code/Magento/Centinel/composer.json +++ b/app/code/Magento/Centinel/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php b/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php index 04141e448fec992be6bc53f0afa82b41d6dedd2d..7249f26f18540c606d9716bbc55b17ef2312adc8 100644 --- a/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php +++ b/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php @@ -5,6 +5,7 @@ */ namespace Magento\Checkout\Controller\Onepage; +use Magento\Framework\Object; use Magento\Framework\Exception\PaymentException; class SaveOrder extends \Magento\Checkout\Controller\Onepage @@ -26,16 +27,17 @@ class SaveOrder extends \Magento\Checkout\Controller\Onepage return $this->_ajaxRedirectResponse(); } - $result = []; + $result = new Object(); try { $agreementsValidator = $this->_objectManager->get('Magento\Checkout\Model\Agreements\AgreementsValidator'); if (!$agreementsValidator->isValid(array_keys($this->getRequest()->getPost('agreement', [])))) { - $result['success'] = false; - $result['error'] = true; - $result['error_messages'] = __( - 'Please agree to all the terms and conditions before placing the order.' + $result->setData('success', false); + $result->setData('error', true); + $result->setData( + 'error_messages', + __('Please agree to all the terms and conditions before placing the order.') ); - return $this->resultJsonFactory->create()->setData($result); + return $this->resultJsonFactory->create()->setData($result->getData()); } $data = $this->getRequest()->getPost('payment', []); @@ -54,25 +56,34 @@ class SaveOrder extends \Magento\Checkout\Controller\Onepage $this->getOnepage()->saveOrder(); $redirectUrl = $this->getOnepage()->getCheckout()->getRedirectUrl(); - $result['success'] = true; - $result['error'] = false; + $result->setData('success', true); + $result->setData('error', false); } catch (PaymentException $e) { $message = $e->getMessage(); if (!empty($message)) { - $result['error_messages'] = $message; + $result->setData('error_messages', $message); } - $result['goto_section'] = 'payment'; - $result['update_section'] = ['name' => 'payment-method', 'html' => $this->_getPaymentMethodsHtml()]; + $result->setData('goto_section', 'payment'); + $result->setData( + 'update_section', + [ + 'name' => 'payment-method', + 'html' => $this->_getPaymentMethodsHtml() + ] + ); } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e); $this->_objectManager->get('Magento\Checkout\Helper\Data') ->sendPaymentFailedEmail($this->getOnepage()->getQuote(), $e->getMessage()); - $result['success'] = false; - $result['error'] = true; - $result['error_messages'] = $e->getMessage(); + $result->setData( + 'success', + false + ); + $result->setData('error', true); + $result->setData('error_messages', $e->getMessage()); $gotoSection = $this->getOnepage()->getCheckout()->getGotoSection(); if ($gotoSection) { - $result['goto_section'] = $gotoSection; + $result->setData('goto_section', $gotoSection); $this->getOnepage()->getCheckout()->setGotoSection(null); } @@ -80,10 +91,13 @@ class SaveOrder extends \Magento\Checkout\Controller\Onepage if ($updateSection) { if (isset($this->_sectionUpdateFunctions[$updateSection])) { $updateSectionFunction = $this->_sectionUpdateFunctions[$updateSection]; - $result['update_section'] = [ - 'name' => $updateSection, - 'html' => $this->{$updateSectionFunction}(), - ]; + $result->setData( + 'update_section', + [ + 'name' => $updateSection, + 'html' => $this->{$updateSectionFunction}(), + ] + ); } $this->getOnepage()->getCheckout()->setUpdateSection(null); } @@ -91,18 +105,29 @@ class SaveOrder extends \Magento\Checkout\Controller\Onepage $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e); $this->_objectManager->get('Magento\Checkout\Helper\Data') ->sendPaymentFailedEmail($this->getOnepage()->getQuote(), $e->getMessage()); - $result['success'] = false; - $result['error'] = true; - $result['error_messages'] = __('Something went wrong processing your order. Please try again later.'); + $result->setData('success', false); + $result->setData('error', true); + $result->setData( + 'error_messages', + __('Something went wrong processing your order. Please try again later.') + ); } /** * when there is redirect to third party, we don't want to save order yet. * we will save the order in return action. */ if (isset($redirectUrl)) { - $result['redirect'] = $redirectUrl; + $result->setData('redirect', $redirectUrl); } - return $this->resultJsonFactory->create()->setData($result); + $this->_eventManager->dispatch( + 'checkout_controller_onepage_saveOrder', + [ + 'result' => $result, + 'action' => $this + ] + ); + + return $this->resultJsonFactory->create()->setData($result->getData()); } } diff --git a/app/code/Magento/Checkout/Test/Unit/Controller/Onepage/SaveOrderTest.php b/app/code/Magento/Checkout/Test/Unit/Controller/Onepage/SaveOrderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..cef6ff863cc8d50289d6d12c92e9bfc4421f07e6 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Unit/Controller/Onepage/SaveOrderTest.php @@ -0,0 +1,322 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Checkout\Test\Unit\Controller\Onepage; + +use Magento\Checkout\Controller\Onepage\SaveOrder; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +/** + * Class SaveOrderTest + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class SaveOrderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var SaveOrder + */ + protected $controller; + + /** + * @var \Magento\Framework\Data\Form\FormKey\Validator|\PHPUnit_Framework_MockObject_MockObject + */ + protected $formKeyValidatorMock; + + /** + * @var \Magento\Framework\App\Action\Context|\PHPUnit_Framework_MockObject_MockObject + */ + protected $contextMock; + + /** + * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $requestMock; + + /** + * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $responseMock; + + /** + * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $objectManagerMock; + + /** + * @var \Magento\Framework\Controller\Result\RedirectFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $resultRedirectFactoryMock; + + /** + * @var \Magento\Framework\Controller\Result\RawFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $resultRawFactoryMock; + + /** + * @var \Magento\Framework\Controller\Result\JsonFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $resultJsonFactoryMock; + + /** + * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $eventManagerMock; + + /** + * @var \Magento\Checkout\Model\Type\Onepage|\PHPUnit_Framework_MockObject_MockObject + */ + protected $onepageMock; + + /** + * @var \Magento\Checkout\Model\Agreements\AgreementsValidator|\PHPUnit_Framework_MockObject_MockObject + */ + protected $agreementsValidatorMock; + + /** + * @var \Magento\Quote\Model\Quote|\PHPUnit_Framework_MockObject_MockObject + */ + protected $quoteMock; + + /** + * Set up + * + * @return void + */ + protected function setUp() + { + $helper = new ObjectManager($this); + + $contextMock = $this->getMockBuilder('Magento\Framework\App\Action\Context') + ->disableOriginalConstructor() + ->getMock(); + $this->requestMock = $this->getMockBuilder('Magento\Framework\App\RequestInterface') + ->disableOriginalConstructor() + ->setMethods(['getPost']) + ->getMockForAbstractClass(); + $this->responseMock = $this->getMockBuilder('Magento\Framework\App\ResponseInterface') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->objectManagerMock = $this->getMockBuilder('Magento\Framework\ObjectManagerInterface') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->formKeyValidatorMock = $this->getMockBuilder('Magento\Framework\Data\Form\FormKey\Validator') + ->disableOriginalConstructor() + ->getMock(); + $this->resultRedirectFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\Result\RedirectFactory') + ->disableOriginalConstructor() + ->getMock(); + $this->resultRawFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\Result\RawFactory') + ->disableOriginalConstructor() + ->getMock(); + $this->resultJsonFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\Result\JsonFactory') + ->disableOriginalConstructor() + ->getMock(); + $this->eventManagerMock = $this->getMockBuilder('Magento\Framework\Event\ManagerInterface') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->onepageMock = $this->getMockBuilder('Magento\Checkout\Model\Type\Onepage') + ->disableOriginalConstructor() + ->getMock(); + $this->agreementsValidatorMock = $this->getMockBuilder('Magento\Checkout\Model\Agreements\AgreementsValidator') + ->disableOriginalConstructor() + ->getMock(); + $this->quoteMock = $this->getMockBuilder('Magento\Quote\Model\Quote') + ->disableOriginalConstructor() + ->getMock(); + + $contextMock->expects($this->once()) + ->method('getRequest') + ->willReturn($this->requestMock); + $contextMock->expects($this->once()) + ->method('getResponse') + ->willReturn($this->responseMock); + $contextMock->expects($this->once()) + ->method('getObjectManager') + ->willReturn($this->objectManagerMock); + $contextMock->expects($this->once()) + ->method('getResultRedirectFactory') + ->willReturn($this->resultRedirectFactoryMock); + $contextMock->expects($this->once()) + ->method('getEventManager') + ->willReturn($this->eventManagerMock); + + $this->controller = $helper->getObject( + 'Magento\Checkout\Controller\Onepage\SaveOrder', + [ + 'context' => $contextMock, + 'formKeyValidator' => $this->formKeyValidatorMock, + 'resultRawFactory' => $this->resultRawFactoryMock, + 'resultJsonFactory' => $this->resultJsonFactoryMock, + ] + ); + } + + /** + * Test method execution _expireAjax (call hasItems === false) + * + * @return void + */ + protected function expireAjaxFlowHasItemsFalse() + { + $this->onepageMock->expects($this->atLeastOnce()) + ->method('getQuote') + ->willReturn($this->quoteMock); + + $this->quoteMock->expects($this->once()) + ->method('hasItems') + ->willReturn(false); + $this->quoteMock->expects($this->never()) + ->method('getHasError') + ->willReturn(true); + $this->quoteMock->expects($this->never()) + ->method('validateMinimumAmount') + ->willReturn(false); + + $this->requestMock->expects($this->never()) + ->method('getActionName'); + } + + /** + * Test for execute method + * + * @return void + */ + public function testExecuteWithSuccessOrderSave() + { + $testData = $this->getExecuteWithSuccessOrderSaveTestData(); + + + $redirectMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Redirect') + ->disableOriginalConstructor() + ->getMock(); + $paymentMock = $this->getMockBuilder('Magento\Quote\Model\Quote\Payment') + ->disableOriginalConstructor() + ->getMock(); + $checkoutMock = $this->getMockBuilder('Magento\Checkout\Model\Session') + ->disableOriginalConstructor() + ->setMethods(['getRedirectUrl']) + ->getMock(); + $resultJsonMock = $this->getMockBuilder('Magento\Framework\Controller\Result\Json') + ->disableOriginalConstructor() + ->getMock(); + + $redirectMock->expects($this->never()) + ->method('setPath') + ->with('*/*/') + ->willReturn('redirect'); + + $this->formKeyValidatorMock->expects($this->once()) + ->method('validate') + ->with($this->requestMock) + ->willReturn(true); + + $this->resultRedirectFactoryMock->expects($this->never()) + ->method('create') + ->willReturn($redirectMock); + + $this->objectManagerMock->expects($this->atLeastOnce()) + ->method('get') + ->willReturnMap($testData['objectManager.get']); + + // call _expireAjax method + $this->expireAjaxFlowHasItemsFalse(); + + $this->requestMock->expects($this->atLeastOnce()) + ->method('getPost') + ->willReturnMap($testData['request.getPost']); + + $this->agreementsValidatorMock->expects($this->once()) + ->method('isValid') + ->with($testData['agreementsValidator.isValid']) + ->willReturn(true); + + $this->quoteMock->expects($this->atLeastOnce()) + ->method('getPayment') + ->willReturn($paymentMock); + + $paymentMock->expects($this->once()) + ->method('setQuote') + ->with($this->quoteMock); + $paymentMock->expects($this->once()) + ->method('importData') + ->with($testData['payment.importData']); + + $this->onepageMock->expects($this->once()) + ->method('saveOrder'); + $this->onepageMock->expects($this->once()) + ->method('getCheckout') + ->willReturn($checkoutMock); + + $checkoutMock->expects($this->once()) + ->method('getRedirectUrl') + ->willReturn(null); + + $this->eventManagerMock->expects($this->once()) + ->method('dispatch') + ->withConsecutive( + $this->equalTo('checkout_controller_onepage_saveOrder'), + $this->countOf(2) + ); + + $this->resultJsonFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($resultJsonMock); + + $resultJsonMock->expects($this->once()) + ->method('setData') + ->with($testData['resultJson.setData']) + ->willReturnSelf(); + + $this->assertEquals($resultJsonMock, $this->controller->execute()); + } + + /** + * Get data for test testExecuteWithSuccessOrderSave + * + * @return array + */ + protected function getExecuteWithSuccessOrderSaveTestData() + { + $data = [ + 'payment-key-1' => 'payment-value-1', + 'checks' => [ + \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_CHECKOUT, + \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_COUNTRY, + \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_CURRENCY, + \Magento\Payment\Model\Method\AbstractMethod::CHECK_ORDER_TOTAL_MIN_MAX, + \Magento\Payment\Model\Method\AbstractMethod::CHECK_ZERO_TOTAL, + ] + ]; + $testKey = 'test-key-1'; + + return [ + 'resultJson.setData' => [ + 'success' => 1, + 'error' => false + ], + 'request.getPost' => [ + [ + 'agreement', + [], + [ + $testKey => 'test-value-1' + ] + ], + [ + 'payment', + [], + $data + ], + ], + 'payment.importData' => $data, + 'agreementsValidator.isValid' => [$testKey], + 'objectManager.get' => [ + ['Magento\Checkout\Model\Type\Onepage', $this->onepageMock], + ['Magento\Checkout\Model\Agreements\AgreementsValidator', $this->agreementsValidatorMock], + ] + ]; + } +} diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json index 266290632764108d9de90c7d0d6a60a447173e5e..8d4be858de464bba4a902109399ecb0da8c843c6 100644 --- a/app/code/Magento/Checkout/composer.json +++ b/app/code/Magento/Checkout/composer.json @@ -3,32 +3,32 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-payment": "0.74.0-beta6", - "magento/module-shipping": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-gift-message": "0.74.0-beta6", - "magento/module-wishlist": "0.74.0-beta6", - "magento/module-page-cache": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/module-msrp": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-ui": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-payment": "0.74.0-beta7", + "magento/module-shipping": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-gift-message": "0.74.0-beta7", + "magento/module-wishlist": "0.74.0-beta7", + "magento/module-page-cache": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/module-msrp": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-ui": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-cookie": "0.74.0-beta6" + "magento/module-cookie": "0.74.0-beta7" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CheckoutAgreements/composer.json b/app/code/Magento/CheckoutAgreements/composer.json index 4693f5b11aa25b57cde6a425594a965b1355de7f..4d3341593e7fd0dce401014d7bac7ab32909f36f 100644 --- a/app/code/Magento/CheckoutAgreements/composer.json +++ b/app/code/Magento/CheckoutAgreements/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Cms/Controller/Adminhtml/AbstractMassDelete.php b/app/code/Magento/Cms/Controller/Adminhtml/AbstractMassDelete.php index defddb18779229876ae60ca59e9b40491885aedf..68cf470787c9c520135bf878c674abd922414aae 100755 --- a/app/code/Magento/Cms/Controller/Adminhtml/AbstractMassDelete.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/AbstractMassDelete.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ @@ -21,7 +20,7 @@ class AbstractMassDelete extends \Magento\Backend\App\Action /** * Redirect url */ - const REDIRECT_URL = '*/*/index'; + const REDIRECT_URL = '*/*/'; /** * Resource collection @@ -45,17 +44,17 @@ class AbstractMassDelete extends \Magento\Backend\App\Action */ public function execute() { - $data = $this->getRequest()->getParam('massaction', '[]'); - $data = json_decode($data, true); + $selected = $this->getRequest()->getParam('selected'); + $excluded = $this->getRequest()->getParam('excluded'); - if (isset($data['all_selected']) && $data['all_selected'] === true) { - if (!empty($data['excluded'])) { - $this->excludedDelete($data['excluded']); + if (isset($excluded)) { + if (!empty($excluded)) { + $this->excludedDelete($excluded); } else { $this->deleteAll(); } - } elseif (!empty($data['selected'])) { - $this->selectedDelete($data['selected']); + } elseif (!empty($selected)) { + $this->selectedDelete($selected); } else { $this->messageManager->addError(__('Please select item(s).')); } diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php index a87024f3ea1e622f46e7f1d540e5f9081932bcaf..b255b784a1ac9358e53238425db74b889432eb99 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ diff --git a/app/code/Magento/Cms/Model/Block/DataProvider.php b/app/code/Magento/Cms/Model/Block/DataProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..71994a060b0812b0997fc3c4b026e5ae2b3c206c --- /dev/null +++ b/app/code/Magento/Cms/Model/Block/DataProvider.php @@ -0,0 +1,221 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Cms\Model\Block; + +use Magento\Cms\Model\Resource\Block\Collection; +use Magento\Cms\Model\Resource\Block\CollectionFactory; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; + +/** + * Class DataProvider + */ +class DataProvider implements DataProviderInterface +{ + /** + * @var string + */ + protected $primaryFieldName; + + /** + * @var string + */ + protected $requestFieldName; + + /** + * @var CollectionFactory + */ + protected $collectionFactory; + + /** + * @var Collection + */ + protected $collection; + + /** + * Provider configuration data + * + * @var array + */ + protected $data = []; + + /** + * @param string $primaryFieldName + * @param string $requestFieldName + * @param CollectionFactory $collectionFactory + * @param array $meta + * @param array $data + */ + public function __construct( + $primaryFieldName, + $requestFieldName, + CollectionFactory $collectionFactory, + array $meta = [], + array $data = [] + ) { + $this->primaryFieldName = $primaryFieldName; + $this->requestFieldName = $requestFieldName; + $this->collection = $collectionFactory->create(); + $this->meta = $meta; + $this->data = $data; + } + + /** + * @return array + */ + public function getMeta() + { + return $this->meta; + } + + /** + * @param string $fieldSetName + * @param string $fieldName + * @return array + */ + public function getFieldMetaInfo($fieldSetName, $fieldName) + { + return isset($this->meta[$fieldSetName]['fields'][$fieldName]) + ? $this->meta[$fieldSetName]['fields'][$fieldName] + : []; + } + + /** + * Get data + * + * @return array + */ + public function getData() + { + return $this->collection->toArray(); + } + + /** + * Get field name in request + * + * @return string + */ + public function getRequestFieldName() + { + return $this->requestFieldName; + } + + /** + * Get primary field name + * + * @return string + */ + public function getPrimaryFieldName() + { + return $this->primaryFieldName; + } + + /** + * @inheritdoc + */ + public function addFilter($field, $condition = null) + { + $this->collection->addFieldToFilter($field, $condition); + } + + /** + * Add field to select + * + * @param string|array $field + * @param string|null $alias + * @return void + */ + public function addField($field, $alias = null) + { + $this->collection->addFieldToSelect($field, $alias); + } + + /** + * Add ORDER BY to the end or to the beginning + * + * @param string $field + * @param string $direction + * @return void + */ + public function addOrder($field, $direction) + { + $this->collection->addOrder($field, $direction); + } + + /** + * Set Query limit + * + * @param int $offset + * @param int $size + * @return void + */ + public function setLimit($offset, $size) + { + $this->collection->setPageSize($size); + $this->collection->setCurPage($offset); + } + + /** + * Removes field from select + * + * @param string|null $field + * @param bool $isAlias Alias identifier + * @return void + */ + public function removeField($field, $isAlias = false) + { + $this->collection->removeFieldFromSelect($field, $isAlias); + } + + /** + * Removes all fields from select + * + * @return void + */ + public function removeAllFields() + { + $this->collection->removeAllFieldsFromSelect(); + } + + /** + * Retrieve count of loaded items + * + * @return int + */ + public function count() + { + return $this->collection->count(); + } + + /** + * Get config data + * + * @return mixed + */ + public function getConfigData() + { + return isset($this->data['config']) ? $this->data['config'] : []; + } + + /** + * Set data + * + * @param mixed $config + * @return void + */ + public function setConfigData($config) + { + $this->data['config'] = $config; + } + + /** + * @param string $fieldSetName + * @return array + */ + public function getFieldsMetaInfo($fieldSetName) + { + return isset($this->meta[$fieldSetName]['fields']) ? $this->meta[$fieldSetName]['fields'] : []; + } +} diff --git a/app/code/Magento/Cms/Model/Page/DataProvider.php b/app/code/Magento/Cms/Model/Page/DataProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..4797ffbe28c84f086f2a45cb8b084db9ccd2389b --- /dev/null +++ b/app/code/Magento/Cms/Model/Page/DataProvider.php @@ -0,0 +1,228 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Cms\Model\Page; + +use Magento\Cms\Model\Resource\Page\Collection; +use Magento\Cms\Model\Resource\Page\CollectionFactory; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; + +/** + * Class DataProvider + */ +class DataProvider implements DataProviderInterface +{ + /** + * @var string + */ + protected $primaryFieldName; + + /** + * @var string + */ + protected $requestFieldName; + + /** + * @var CollectionFactory + */ + protected $collectionFactory; + + /** + * @var Collection + */ + protected $collection; + + /** + * @var array + */ + protected $meta = []; + + /** + * Provider configuration data + * + * @var array + */ + protected $data = []; + + /** + * @param string $primaryFieldName + * @param string $requestFieldName + * @param CollectionFactory $collectionFactory + * @param array $meta + * @param array $data + */ + public function __construct( + $primaryFieldName, + $requestFieldName, + CollectionFactory $collectionFactory, + array $meta = [], + array $data = [] + ) { + $this->primaryFieldName = $primaryFieldName; + $this->requestFieldName = $requestFieldName; + + $this->collection = $collectionFactory->create(); + $this->collection->setFirstStoreFlag(true); + $this->meta = $meta; + $this->data = $data; + } + + /** + * @return array + */ + public function getMeta() + { + return $this->meta; + } + + /** + * Get data + * + * @return array + */ + public function getData() + { + return $this->collection->toArray(); + } + + /** + * @param string $fieldSetName + * @param string $fieldName + * @return array + */ + public function getFieldMetaInfo($fieldSetName, $fieldName) + { + return isset($this->meta[$fieldSetName]['fields'][$fieldName]) + ? $this->meta[$fieldSetName]['fields'][$fieldName] + : []; + } + + /** + * Get field name in request + * + * @return string + */ + public function getRequestFieldName() + { + return $this->requestFieldName; + } + + /** + * Get primary field name + * + * @return string + */ + public function getPrimaryFieldName() + { + return $this->primaryFieldName; + } + + /** + * @inheritdoc + */ + public function addFilter($field, $condition = null) + { + $this->collection->addFieldToFilter($field, $condition); + } + + /** + * Add field to select + * + * @param string|array $field + * @param string|null $alias + * @return void + */ + public function addField($field, $alias = null) + { + $this->collection->addFieldToSelect($field, $alias); + } + + /** + * self::setOrder() alias + * + * @param string $field + * @param string $direction + * @return void + */ + public function addOrder($field, $direction) + { + $this->collection->addOrder($field, $direction); + } + + /** + * Set Query limit + * + * @param int $offset + * @param int $size + * @return void + */ + public function setLimit($offset, $size) + { + $this->collection->setPageSize($size); + $this->collection->setCurPage($offset); + } + + /** + * Removes field from select + * + * @param string|null $field + * @param bool $isAlias Alias identifier + * @return void + */ + public function removeField($field, $isAlias = false) + { + $this->collection->removeFieldFromSelect($field, $isAlias); + } + + /** + * Removes all fields from select + * + * @return void + */ + public function removeAllFields() + { + $this->collection->removeAllFieldsFromSelect(); + } + + /** + * Retrieve count of loaded items + * + * @return int + */ + public function count() + { + return $this->collection->count(); + } + + /** + * Get config data + * + * @return mixed + */ + public function getConfigData() + { + return isset($this->data['config']) ? $this->data['config'] : []; + } + + /** + * Set data + * + * @param mixed $config + * @return void + */ + public function setConfigData($config) + { + $this->data['config'] = $config; + } + + /** + * @param string $fieldSetName + * @return array + */ + public function getFieldsMetaInfo($fieldSetName) + { + return isset($this->meta[$fieldSetName]['fields']) ? $this->meta[$fieldSetName]['fields'] : []; + } +} diff --git a/app/code/Magento/Cms/Ui/DataProvider/Page/Options/IsActive.php b/app/code/Magento/Cms/Model/Page/Source/IsActive.php similarity index 57% rename from app/code/Magento/Cms/Ui/DataProvider/Page/Options/IsActive.php rename to app/code/Magento/Cms/Model/Page/Source/IsActive.php index 4934fc0297f229360d249ee23fe43dda37be7599..7c9d153e5a5a5d8cb363e4830c8e096f82cb92d3 100644 --- a/app/code/Magento/Cms/Ui/DataProvider/Page/Options/IsActive.php +++ b/app/code/Magento/Cms/Model/Page/Source/IsActive.php @@ -3,14 +3,14 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Cms\Ui\DataProvider\Page\Options; +namespace Magento\Cms\Model\Page\Source; -use Magento\Ui\Component\Listing\OptionsInterface; +use Magento\Framework\Data\OptionSourceInterface; /** * Class IsActive */ -class IsActive implements OptionsInterface +class IsActive implements OptionSourceInterface { /** * @var \Magento\Cms\Model\Page @@ -30,19 +30,18 @@ class IsActive implements OptionsInterface /** * Get options * - * @param array $options * @return array */ - public function getOptions(array $options = []) + public function toOptionArray() { - $newOptions = $this->cmsPage->getAvailableStatuses(); - foreach ($newOptions as $key => $value) { - $newOptions[$key] = [ + $options = []; + $availableOptions = $this->cmsPage->getAvailableStatuses(); + foreach ($availableOptions as $key => $value) { + $options[$key] = [ 'label' => $value, 'value' => $key, ]; } - - return array_merge_recursive($newOptions, $options); + return $options; } } diff --git a/app/code/Magento/Cms/Ui/DataProvider/Page/Options/PageLayout.php b/app/code/Magento/Cms/Model/Page/Source/PageLayout.php similarity index 55% rename from app/code/Magento/Cms/Ui/DataProvider/Page/Options/PageLayout.php rename to app/code/Magento/Cms/Model/Page/Source/PageLayout.php index 7a053e0fd3948891f3fa1d10aa5e690d586aecf6..32e8878dbe5b277ea401f09a6098cddeae4eeef8 100644 --- a/app/code/Magento/Cms/Ui/DataProvider/Page/Options/PageLayout.php +++ b/app/code/Magento/Cms/Model/Page/Source/PageLayout.php @@ -3,21 +3,26 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Cms\Ui\DataProvider\Page\Options; +namespace Magento\Cms\Model\Page\Source; +use Magento\Framework\Data\OptionSourceInterface; use Magento\Framework\View\Model\PageLayout\Config\BuilderInterface; -use Magento\Ui\Component\Listing\OptionsInterface; /** * Class PageLayout */ -class PageLayout implements OptionsInterface +class PageLayout implements OptionSourceInterface { /** * @var \Magento\Framework\View\Model\PageLayout\Config\BuilderInterface */ protected $pageLayoutBuilder; + /** + * @var array + */ + protected $options; + /** * Constructor * @@ -31,19 +36,23 @@ class PageLayout implements OptionsInterface /** * Get options * - * @param array $options * @return array */ - public function getOptions(array $options = []) + public function toOptionArray() { - $newOptions = $this->pageLayoutBuilder->getPageLayoutsConfig()->getOptions(); - foreach ($newOptions as $key => $value) { - $newOptions[$key] = [ + if ($this->options !== null) { + return $this->options; + } + $options = []; + $configOptions = $this->pageLayoutBuilder->getPageLayoutsConfig()->getOptions(); + foreach ($configOptions as $key => $value) { + $options[$key] = [ 'label' => $value, 'value' => $key, ]; } + $this->options = $options; - return array_merge_recursive($newOptions, $options); + return $this->options; } } diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php new file mode 100644 index 0000000000000000000000000000000000000000..ecdf19a805f4cda93e6528a07b47cde1c2b97e14 --- /dev/null +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Cms\Ui\Component\Listing\Column; + +use Magento\Framework\UrlInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Ui\Component\Listing\Columns\Column; + +/** + * Class BlockActions + */ +class BlockActions extends Column +{ + /** + * Url path + */ + const URL_PATH = 'cms/block/edit'; + + /** + * @var UrlInterface + */ + protected $urlBuilder; + + /** + * Constructor + * + * @param ContextInterface $context + * @param UiComponentFactory $uiComponentFactory + * @param UrlInterface $urlBuilder + * @param array $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + UiComponentFactory $uiComponentFactory, + UrlInterface $urlBuilder, + array $components = [], + array $data = [] + ) { + $this->urlBuilder = $urlBuilder; + parent::__construct($context, $uiComponentFactory, $components, $data); + } + + /** + * @param array $items + * @return array + */ + public function prepareItems(array & $items) + { + foreach ($items as & $item) { + if (isset($item['block_id'])) { + $item[$this->getData('name')] = [ + 'edit' => [ + 'href' => $this->urlBuilder->getUrl(static::URL_PATH, ['block_id' => $item['block_id']]), + 'label' => __('Edit'), + ] + ]; + } + } + return $items; + } +} diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php new file mode 100644 index 0000000000000000000000000000000000000000..2a8140c0923cf2ac52304dc6ad67f8a2240e773a --- /dev/null +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Cms\Ui\Component\Listing\Column; + +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Ui\Component\Listing\Columns\Column; +use Magento\Cms\Block\Adminhtml\Page\Grid\Renderer\Action\UrlBuilder; +use Magento\Framework\UrlInterface; + +/** + * Class PageActions + */ +class PageActions extends Column +{ + /** + * Url path + */ + const URL_PATH = 'cms/page/edit'; + + /** + * @var UrlBuilder + */ + protected $actionUrlBuilder; + + /** + * @var UrlInterface + */ + protected $urlBuilder; + + + /** + * Constructor + * + * @param ContextInterface $context + * @param UiComponentFactory $uiComponentFactory + * @param UrlBuilder $actionUrlBuilder + * @param UrlInterface $urlBuilder + * @param array $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + UiComponentFactory $uiComponentFactory, + UrlBuilder $actionUrlBuilder, + UrlInterface $urlBuilder, + array $components = [], + array $data = [] + ) { + $this->urlBuilder = $urlBuilder; + $this->actionUrlBuilder = $actionUrlBuilder; + parent::__construct($context, $uiComponentFactory, $components, $data); + } + + /** + * @param array $items + * @return array + */ + public function prepareItems(array & $items) + { + foreach ($items as & $item) { + if (isset($item['page_id'])) { + $item[$this->getData('name')]['edit'] = [ + 'href' => $this->urlBuilder->getUrl(static::URL_PATH, ['page_id' => $item['page_id']]), + 'label' => __('Edit'), + 'hidden' => true + ]; + } + if (isset($item['identifier'])) { + $item[$this->getData('name')]['preview'] = [ + 'href' => $this->actionUrlBuilder->getUrl( + $item['identifier'], + isset($item['_first_store_id']) ? $item['_first_store_id'] : null, + isset($item['store_code']) ? $item['store_code'] : null + ), + 'label' => __('Preview') + ]; + } + } + + return $items; + } +} diff --git a/app/code/Magento/Cms/composer.json b/app/code/Magento/Cms/composer.json index 9ee9de410e132ace5520da29bfb9f6edc89fb4c7..9b0c037e3e12103a5985b9972867b36512e3c63c 100644 --- a/app/code/Magento/Cms/composer.json +++ b/app/code/Magento/Cms/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/module-widget": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-email": "0.74.0-beta6", - "magento/module-ui": "0.74.0-beta6", - "magento/module-variable": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/module-widget": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-email": "0.74.0-beta7", + "magento/module-ui": "0.74.0-beta7", + "magento/module-variable": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_index.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_index.xml index 2e9d8a6ea0b25b06093db7dfb319d280866d1fac..dbdf185d5083e02bd98847af6d282fc1f0de91b3 100644 --- a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_index.xml +++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_index.xml @@ -8,7 +8,8 @@ <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> - <ui_component name="cms_block_listing" component="listing"/> + <uiComponent name="cms_block_listing"/> </referenceContainer> + <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way --> </body> </page> diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_listing.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_listing.xml index 6f1975adb97cd11e5032ed1b455183ac0a653f31..22788b865327bc82bdaa19f196bcbb469bdaeea1 100644 --- a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_listing.xml +++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_listing.xml @@ -92,14 +92,6 @@ </item> </item> </argument> - <argument name="row_data_provider" xsi:type="array"> - <item name="actions" xsi:type="array"> - <item name="class" xsi:type="string">Magento\Cms\Ui\DataProvider\Block\Row\Actions</item> - </item> - <item name="store_id" xsi:type="array"> - <item name="class" xsi:type="string">Magento\Store\Ui\DataProvider\Row</item> - </item> - </argument> </arguments> </referenceBlock> <referenceBlock name="sorting"> diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_index.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_index.xml index a63fe9f63f08d305c5595171900176096473e033..b5fbe5373d4f837ce76412ae4d417d182eae26d9 100644 --- a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_index.xml +++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_index.xml @@ -6,9 +6,10 @@ */ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> + <update handle="styles"/> <body> <referenceContainer name="content"> - <ui_component name="cms_page_listing" component="listing"/> + <uiComponent name="cms_page_listing"/> </referenceContainer> </body> </page> diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_listing.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_listing.xml index bebf23cacd86b98d4f7e4f6c3af734c4cba77515..55a8f042883487aa8d6e88524a7e6cbf1ebe6bf6 100644 --- a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_listing.xml +++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_listing.xml @@ -89,14 +89,6 @@ </item> </item> </argument> - <argument name="row_data_provider" xsi:type="array"> - <item name="actions" xsi:type="array"> - <item name="class" xsi:type="string">Magento\Cms\Ui\DataProvider\Page\Row\Actions</item> - </item> - <item name="store_id" xsi:type="array"> - <item name="class" xsi:type="string">Magento\Store\Ui\DataProvider\Row</item> - </item> - </argument> </arguments> </referenceBlock> <referenceBlock name="massactions"> diff --git a/app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_listing.xml b/app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_listing.xml new file mode 100644 index 0000000000000000000000000000000000000000..da8c5b01d5ea6cd2ff079669e6404ab400fa8dad --- /dev/null +++ b/app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_listing.xml @@ -0,0 +1,383 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Ui/etc/ui_configuration.xsd"> + <argument name="context" xsi:type="configurableObject"> + <argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\Context</argument> + <argument name="namespace" xsi:type="string">cms_block_listing</argument> + </argument> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="provider" xsi:type="string">cms_block_listing.cms_block_listing_data_source</item> + </item> + <item name="deps" xsi:type="string">cms_block_listing.cms_block_listing_data_source</item> + </item> + <item name="spinner" xsi:type="string">cms_block_columns</item> + <item name="buttons" xsi:type="array"> + <item name="add" xsi:type="array"> + <item name="name" xsi:type="string">add</item> + <item name="label" xsi:type="string" translate="true">Add New Block</item> + <item name="class" xsi:type="string">primary</item> + <item name="url" xsi:type="string">*/*/new</item> + </item> + </item> + </argument> + <container name="listing_top"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="template" xsi:type="string">ui/grid/toolbar</item> + </item> + </argument> + <container name="default_view"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/view</item> + <item name="displayArea" xsi:type="string">dataGridActions</item> + </item> + </argument> + </container> + <container name="columns_controls"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item> + <item name="displayArea" xsi:type="string">dataGridActions</item> + </item> + </argument> + </container> + <filters name="listing_filters"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="displayArea" xsi:type="string">dataGridFilters</item> + <item name="dataScope" xsi:type="string">params.filters</item> + </item> + </argument> + <filterRange name="block_id"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">block_id</item> + <item name="label" xsi:type="string" translate="true">ID</item> + </item> + </argument> + <filterInput name="from"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">from</item> + <item name="label" xsi:type="string" translate="true">from</item> + <item name="placeholder" xsi:type="string" translate="true">From</item> + </item> + </argument> + </filterInput> + <filterInput name="to"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">to</item> + <item name="label" xsi:type="string" translate="true">to</item> + <item name="placeholder" xsi:type="string" translate="true">To</item> + </item> + </argument> + </filterInput> + </filterRange> + <filterInput name="title"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">title</item> + <item name="label" xsi:type="string" translate="true">Title</item> + </item> + </argument> + </filterInput> + <filterInput name="identifier"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">identifier</item> + <item name="label" xsi:type="string" translate="true">Identifier</item> + </item> + </argument> + </filterInput> + <filterSelect name="store_id"> + <argument name="optionsProvider" xsi:type="configurableObject"> + <argument name="class" xsi:type="string">Magento\Store\Ui\Component\Listing\Column\Store\Options</argument> + </argument> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="caption" xsi:type="string" translate="true">Select...</item> + <item name="dataScope" xsi:type="string">store_id</item> + <item name="label" xsi:type="string" translate="true">Store View</item> + </item> + </argument> + </filterSelect> + <filterSelect name="is_active"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="caption" xsi:type="string" translate="true">Select...</item> + <item name="label" xsi:type="string" translate="true">Status</item> + <item name="dataScope" xsi:type="string">is_active</item> + <item name="options" xsi:type="array"> + <item name="disable" xsi:type="array"> + <item name="value" xsi:type="string">0</item> + <item name="label" xsi:type="string" translate="true">Disabled</item> + </item> + <item name="enable" xsi:type="array"> + <item name="value" xsi:type="string">1</item> + <item name="label" xsi:type="string" translate="true">Enabled</item> + </item> + </item> + </item> + </argument> + </filterSelect> + <filterRange name="creation_time" class="Magento\Ui\Component\Filters\Type\DateRange"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">creation_time</item> + <item name="label" xsi:type="string" translate="true">Created</item> + </item> + </argument> + <filterDate name="from"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">from</item> + <item name="label" xsi:type="string" translate="true">From</item> + <item name="placeholder" xsi:type="string" translate="true">From</item> + </item> + </argument> + </filterDate> + <filterDate name="to"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">to</item> + <item name="label" xsi:type="string" translate="true">To</item> + <item name="placeholder" xsi:type="string" translate="true">To</item> + </item> + </argument> + </filterDate> + </filterRange> + <filterRange name="update_time" class="Magento\Ui\Component\Filters\Type\DateRange"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">update_time</item> + <item name="label" xsi:type="string" translate="true">Modified</item> + </item> + </argument> + <filterDate name="from"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">from</item> + <item name="label" xsi:type="string" translate="true">From</item> + <item name="placeholder" xsi:type="string" translate="true">From</item> + </item> + </argument> + </filterDate> + <filterDate name="to"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">to</item> + <item name="label" xsi:type="string" translate="true">To</item> + <item name="placeholder" xsi:type="string" translate="true">To</item> + </item> + </argument> + </filterDate> + </filterRange> + </filters> + <massaction name="listing_massaction"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="displayArea" xsi:type="string">bottom</item> + <item name="actions" xsi:type="array"> + <item name="delete" xsi:type="array"> + <item name="confirm" xsi:type="string" translate="true">Are you sure you want to perform this action?</item> + <item name="type" xsi:type="string">delete</item> + <item name="label" xsi:type="string" translate="true">Delete</item> + <item name="url" xsi:type="string">cms/block/massDelete</item> + </item> + </item> + <item name="indexField" xsi:type="string">block_id</item> + </item> + </argument> + </massaction> + <paging name="listing_paging"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="displayArea" xsi:type="string">bottom</item> + <item name="options" xsi:type="array"> + <item name="20" xsi:type="array"> + <item name="value" xsi:type="number">20</item> + <item name="label" xsi:type="string" translate="true">20</item> + </item> + <item name="30" xsi:type="array"> + <item name="value" xsi:type="number">30</item> + <item name="label" xsi:type="string" translate="true">30</item> + </item> + <item name="50" xsi:type="array"> + <item name="value" xsi:type="number">50</item> + <item name="label" xsi:type="string" translate="true">50</item> + </item> + <item name="100" xsi:type="array"> + <item name="value" xsi:type="number">100</item> + <item name="label" xsi:type="string" translate="true">100</item> + </item> + <item name="200" xsi:type="array"> + <item name="value" xsi:type="number">200</item> + <item name="label" xsi:type="string" translate="true">200</item> + </item> + </item> + </item> + </argument> + </paging> + </container> + <dataSource name="cms_block_listing_data_source"> + <argument name="dataProvider" xsi:type="configurableObject"> + <argument name="class" xsi:type="string">Magento\Cms\Model\Block\DataProvider</argument> + <argument name="primaryFieldName" xsi:type="string">block_id</argument> + <argument name="requestFieldName" xsi:type="string">id</argument> + <argument name="meta" xsi:type="array"> + <item name="cms_page" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="label" xsi:type="string" translate="true">CMS Page</item> + </item> + </item> + </argument> + </argument> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item> + </item> + <item name="config" xsi:type="array"> + <item name="update_url" xsi:type="string">mui/index/render</item> + </item> + </argument> + </dataSource> + <columns name="cms_block_columns"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="childDefaults" xsi:type="array"> + <item name="actionField" xsi:type="string">actions</item> + <item name="clickAction" xsi:type="string">edit</item> + <item name="appendTo" xsi:type="string">cms_block_listing.cms_block_listing.listing_top.columns_controls</item> + </item> + </item> + </argument> + <column name="ids" class="Magento\Ui\Component\MassAction\Columns\Column"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/multiselect</item> + </item> + <item name="config" xsi:type="array"> + <item name="indexField" xsi:type="string">block_id</item> + <item name="appendTo" xsi:type="boolean">false</item> + </item> + </argument> + </column> + <column name="block_id"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="sorting" xsi:type="string">asc</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">ID</item> + </item> + </argument> + </column> + <column name="title"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Title</item> + </item> + </argument> + </column> + <column name="identifier"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Identifier</item> + </item> + </argument> + </column> + <column name="store_id" class="Magento\Store\Ui\Component\Listing\Column\Store"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item> + </item> + <item name="config" xsi:type="array"> + <item name="sortable" xsi:type="boolean">false</item> + <item name="dataType" xsi:type="string">text</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Store View</item> + </item> + </argument> + </column> + <column name="is_active"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item> + </item> + <item name="options" xsi:type="array"> + <item name="disable" xsi:type="array"> + <item name="value" xsi:type="string">0</item> + <item name="label" xsi:type="string" translate="true">Disabled</item> + </item> + <item name="enable" xsi:type="array"> + <item name="value" xsi:type="string">1</item> + <item name="label" xsi:type="string" translate="true">Enabled</item> + </item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">select</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Status</item> + </item> + </argument> + </column> + <column name="creation_time"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">date</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Created</item> + </item> + </argument> + </column> + <column name="update_time"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">date</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Modified</item> + </item> + </argument> + </column> + <column name="actions" class="Magento\Cms\Ui\Component\Listing\Column\BlockActions"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">actions</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Action</item> + <item name="data_type" xsi:type="string">actions</item> + <item name="filterable" xsi:type="boolean">false</item> + <item name="sortable" xsi:type="boolean">false</item> + </item> + </argument> + </column> + </columns> +</listing> diff --git a/app/code/Magento/Cms/view/adminhtml/ui_component/cms_page_listing.xml b/app/code/Magento/Cms/view/adminhtml/ui_component/cms_page_listing.xml new file mode 100644 index 0000000000000000000000000000000000000000..3e67e0ef1235c458b18a948d2a369db408b1a698 --- /dev/null +++ b/app/code/Magento/Cms/view/adminhtml/ui_component/cms_page_listing.xml @@ -0,0 +1,399 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Ui/etc/ui_configuration.xsd"> + <argument name="context" xsi:type="configurableObject"> + <argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\Context</argument> + <argument name="namespace" xsi:type="string">cms_page_listing</argument> + </argument> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="provider" xsi:type="string">cms_page_listing.cms_page_listing_data_source</item> + </item> + <item name="deps" xsi:type="string">cms_page_listing.cms_page_listing_data_source</item> + </item> + <item name="spinner" xsi:type="string">cms_page_columns</item> + <item name="buttons" xsi:type="array"> + <item name="add" xsi:type="array"> + <item name="name" xsi:type="string">add</item> + <item name="label" xsi:type="string" translate="true">Add New Page</item> + <item name="class" xsi:type="string">primary</item> + <item name="url" xsi:type="string">*/*/new</item> + </item> + </item> + </argument> + <dataSource name="cms_page_listing_data_source"> + <argument name="dataProvider" xsi:type="configurableObject"> + <argument name="class" xsi:type="string">Magento\Cms\Model\Page\DataProvider</argument> + <argument name="primaryFieldName" xsi:type="string">block_id</argument> + <argument name="requestFieldName" xsi:type="string">id</argument> + <argument name="meta" xsi:type="array"> + <item name="cms_block" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="label" xsi:type="string" translate="true">CMS Block</item> + </item> + </item> + </argument> + </argument> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item> + </item> + <item name="config" xsi:type="array"> + <item name="update_url" xsi:type="string">mui/index/render</item> + </item> + </argument> + </dataSource> + <container name="listing_top"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="template" xsi:type="string">ui/grid/toolbar</item> + </item> + </argument> + <container name="default_view"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/view</item> + <item name="displayArea" xsi:type="string">dataGridActions</item> + </item> + </argument> + </container> + <container name="columns_controls"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item> + <item name="displayArea" xsi:type="string">dataGridActions</item> + </item> + </argument> + </container> + <filters name="listing_filters"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="displayArea" xsi:type="string">dataGridFilters</item> + <item name="dataScope" xsi:type="string">params.filters</item> + </item> + </argument> + <filterRange name="page_id"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">page_id</item> + <item name="label" xsi:type="string" translate="true">ID</item> + </item> + </argument> + <filterInput name="from"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">from</item> + <item name="label" xsi:type="string" translate="true">from</item> + <item name="placeholder" xsi:type="string" translate="true">From</item> + </item> + </argument> + </filterInput> + <filterInput name="to"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">to</item> + <item name="label" xsi:type="string" translate="true">to</item> + <item name="placeholder" xsi:type="string" translate="true">To</item> + </item> + </argument> + </filterInput> + </filterRange> + <filterInput name="title"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">title</item> + <item name="label" xsi:type="string" translate="true">Title</item> + </item> + </argument> + </filterInput> + <filterInput name="identifier"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">identifier</item> + <item name="label" xsi:type="string" translate="true">URL Key</item> + </item> + </argument> + </filterInput> + <filterSelect name="page_layout"> + <argument name="optionsProvider" xsi:type="configurableObject"> + <argument name="class" xsi:type="string">Magento\Cms\Model\Page\Source\PageLayout</argument> + </argument> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">page_layout</item> + <item name="label" xsi:type="string" translate="true">Layout</item> + <item name="caption" xsi:type="string" translate="true">Select...</item> + </item> + </argument> + </filterSelect> + <filterSelect name="store_id"> + <argument name="optionsProvider" xsi:type="configurableObject"> + <argument name="class" xsi:type="string">Magento\Store\Ui\Component\Listing\Column\Store\Options</argument> + </argument> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">store_id</item> + <item name="caption" xsi:type="string" translate="true">Select...</item> + <item name="label" xsi:type="string" translate="true">Store View</item> + </item> + </argument> + </filterSelect> + <filterSelect name="is_active"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">is_active</item> + <item name="label" xsi:type="string" translate="true">Status</item> + <item name="caption" xsi:type="string" translate="true">Select...</item> + <item name="options" xsi:type="array"> + <item name="disable" xsi:type="array"> + <item name="value" xsi:type="string">0</item> + <item name="label" xsi:type="string" translate="true">Disabled</item> + </item> + <item name="enable" xsi:type="array"> + <item name="value" xsi:type="string">1</item> + <item name="label" xsi:type="string" translate="true">Enabled</item> + </item> + </item> + </item> + </argument> + </filterSelect> + <filterRange name="creation_time" class="Magento\Ui\Component\Filters\Type\DateRange"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">creation_time</item> + <item name="label" xsi:type="string" translate="true">Created</item> + </item> + </argument> + <filterDate name="from"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">from</item> + <item name="label" xsi:type="string" translate="true">from</item> + <item name="placeholder" xsi:type="string" translate="true">From</item> + </item> + </argument> + </filterDate> + <filterDate name="to"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">to</item> + <item name="label" xsi:type="string" translate="true">to</item> + <item name="placeholder" xsi:type="string" translate="true">To</item> + </item> + </argument> + </filterDate> + </filterRange> + <filterRange name="update_time" class="Magento\Ui\Component\Filters\Type\DateRange"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">update_time</item> + <item name="label" xsi:type="string" translate="true">Modified</item> + </item> + </argument> + <filterDate name="from"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">from</item> + <item name="label" xsi:type="string" translate="true">from</item> + <item name="placeholder" xsi:type="string" translate="true">From</item> + </item> + </argument> + </filterDate> + <filterDate name="to"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">to</item> + <item name="label" xsi:type="string" translate="true">to</item> + <item name="placeholder" xsi:type="string" translate="true">To</item> + </item> + </argument> + </filterDate> + </filterRange> + </filters> + <massaction name="listing_massaction"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="displayArea" xsi:type="string">bottom</item> + <item name="actions" xsi:type="array"> + <item name="delete" xsi:type="array"> + <item name="confirm" xsi:type="string" translate="true">Delete selected items?</item> + <item name="type" xsi:type="string">delete</item> + <item name="label" xsi:type="string" translate="true">Delete</item> + <item name="url" xsi:type="string">cms/page/massDelete</item> + </item> + </item> + <item name="indexField" xsi:type="string">page_id</item> + </item> + </argument> + </massaction> + <paging name="listing_paging"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="displayArea" xsi:type="string">bottom</item> + <item name="options" xsi:type="array"> + <item name="20" xsi:type="array"> + <item name="value" xsi:type="number">20</item> + <item name="label" xsi:type="string" translate="true">20</item> + </item> + <item name="30" xsi:type="array"> + <item name="value" xsi:type="number">30</item> + <item name="label" xsi:type="string" translate="true">30</item> + </item> + <item name="50" xsi:type="array"> + <item name="value" xsi:type="number">50</item> + <item name="label" xsi:type="string" translate="true">50</item> + </item> + <item name="100" xsi:type="array"> + <item name="value" xsi:type="number">100</item> + <item name="label" xsi:type="string" translate="true">100</item> + </item> + <item name="200" xsi:type="array"> + <item name="value" xsi:type="number">200</item> + <item name="label" xsi:type="string" translate="true">200</item> + </item> + </item> + </item> + </argument> + </paging> + </container> + <columns name="cms_page_columns"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="childDefaults" xsi:type="array"> + <item name="actionField" xsi:type="string">actions</item> + <item name="clickAction" xsi:type="string">edit</item> + <item name="appendTo" xsi:type="string">cms_page_listing.cms_page_listing.listing_top.columns_controls</item> + </item> + </item> + </argument> + <column name="ids" class="Magento\Ui\Component\MassAction\Columns\Column"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/multiselect</item> + </item> + <item name="config" xsi:type="array"> + <item name="indexField" xsi:type="string">page_id</item> + <item name="appendTo" xsi:type="string"></item> + </item> + </argument> + </column> + <column name="page_id"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="sorting" xsi:type="string">asc</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">ID</item> + </item> + </argument> + </column> + <column name="title"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Title</item> + </item> + </argument> + </column> + <column name="identifier"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">URL Key</item> + </item> + </argument> + </column> + <column name="page_layout"> + <argument name="data" xsi:type="array"> + <item name="options" xsi:type="object">Magento\Cms\Model\Page\Source\PageLayout</item> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">select</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Layout</item> + </item> + </argument> + </column> + <column name="store_id" class="Magento\Store\Ui\Component\Listing\Column\Store"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/sortable</item> + </item> + <item name="config" xsi:type="array"> + <item name="sortable" xsi:type="boolean">false</item> + <item name="dataType" xsi:type="string">text</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Store View</item> + </item> + </argument> + </column> + <column name="is_active"> + <argument name="data" xsi:type="array"> + <item name="options" xsi:type="object">Magento\Cms\Model\Page\Source\IsActive</item> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">select</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Status</item> + </item> + </argument> + </column> + <column name="creation_time"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">date</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Created</item> + </item> + </argument> + </column> + <column name="update_time"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">date</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Modified</item> + </item> + </argument> + </column> + <column name="actions" class="Magento\Cms\Ui\Component\Listing\Column\PageActions"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">actions</item> + <item name="align" xsi:type="string">left</item> + <item name="label" xsi:type="string" translate="true">Action</item> + <item name="data_type" xsi:type="string">actions</item> + <item name="filterable" xsi:type="boolean">false</item> + <item name="sortable" xsi:type="boolean">false</item> + </item> + </argument> + </column> + </columns> +</listing> diff --git a/app/code/Magento/CmsUrlRewrite/composer.json b/app/code/Magento/CmsUrlRewrite/composer.json index 06f0e19df1fb840dd3dde3e6028ab68dda347b3a..6723b56a38eefe51d91034c726c045e014d25550 100644 --- a/app/code/Magento/CmsUrlRewrite/composer.json +++ b/app/code/Magento/CmsUrlRewrite/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-cms": "0.74.0-beta6", - "magento/module-url-rewrite": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-cms": "0.74.0-beta7", + "magento/module-url-rewrite": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Config/composer.json b/app/code/Magento/Config/composer.json index 04e2fbc1e741c134694fdd2579fc618a3bf132c4..339caeb7101710a9d1ac410ab6749ff8e3b8c5d3 100644 --- a/app/code/Magento/Config/composer.json +++ b/app/code/Magento/Config/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-cron": "0.74.0-beta6", - "magento/module-email": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-cron": "0.74.0-beta7", + "magento/module-email": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/ConfigurableImportExport/composer.json b/app/code/Magento/ConfigurableImportExport/composer.json index d504ebf2a76d16c9f183cd6419774e822571e6c3..3476dfec4a07b222c02e69cb4dd2909fcabafb35 100644 --- a/app/code/Magento/ConfigurableImportExport/composer.json +++ b/app/code/Magento/ConfigurableImportExport/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-catalog-import-export": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-import-export": "0.74.0-beta6", - "magento/module-configurable-product": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-catalog-import-export": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-import-export": "0.74.0-beta7", + "magento/module-configurable-product": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json index 507ee995f908bde44cc3f29647133573e35de89c..e39bfede226336143aab79ade959eb6ccfb71b39 100644 --- a/app/code/Magento/ConfigurableProduct/composer.json +++ b/app/code/Magento/ConfigurableProduct/composer.json @@ -3,26 +3,26 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-catalog-rule": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-catalog-rule": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-webapi": "0.74.0-beta6" + "magento/module-webapi": "0.74.0-beta7" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Contact/composer.json b/app/code/Magento/Contact/composer.json index d2e5971064d0752a9053de71ef835fa13f07b6db..3918d730162140a6d4a43c0d3f867d04160a7da7 100644 --- a/app/code/Magento/Contact/composer.json +++ b/app/code/Magento/Contact/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-cms": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-cms": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Cookie/composer.json b/app/code/Magento/Cookie/composer.json index d3d5ef16f597b19653d8a69ff3e597bca16d30bf..e9fbc65e8fe32e9286593292ffb40f6f2c373af3 100644 --- a/app/code/Magento/Cookie/composer.json +++ b/app/code/Magento/Cookie/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.4.11|~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-backend": "0.74.0-beta6" + "magento/module-backend": "0.74.0-beta7" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Cron/composer.json b/app/code/Magento/Cron/composer.json index 02fe4b2ed4e83bb3de474176d18e622266e9552d..a1fbef449d8300e48de58421c67bd96cd716ea89 100644 --- a/app/code/Magento/Cron/composer.json +++ b/app/code/Magento/Cron/composer.json @@ -3,13 +3,13 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CurrencySymbol/composer.json b/app/code/Magento/CurrencySymbol/composer.json index 4ef0b1acf67493b6de9ff927c58ba3ad8ae97166..6f862fbf51bd05c47a100f58df52d9d7580bb902 100644 --- a/app/code/Magento/CurrencySymbol/composer.json +++ b/app/code/Magento/CurrencySymbol/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-page-cache": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-page-cache": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/BackButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/BackButton.php index ee99e417ad351ce4007b26d8119a590a5c7daa38..20d5ffa53787e68ab33e50a594401856af4dcec5 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/BackButton.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/BackButton.php @@ -5,11 +5,10 @@ */ namespace Magento\Customer\Block\Adminhtml\Edit; -use Magento\Ui\Component\Control\ButtonProviderInterface; +use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; /** * Class BackButton - * @package Magento\Customer\Block\Adminhtml\Edit */ class BackButton extends GenericButton implements ButtonProviderInterface { @@ -20,7 +19,7 @@ class BackButton extends GenericButton implements ButtonProviderInterface { return [ 'label' => __('Back'), - 'on_click' => 'setLocation(\'' . $this->getBackUrl() . '\')', + 'on_click' => sprintf("location.href = '%s';", $this->getBackUrl()), 'class' => 'back', 'sort_order' => 10 ]; diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/DeleteButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/DeleteButton.php index 00966848b9b3177db7df9b0e8c6605d4c9f35013..c2961ece3dd4b6938635711b7836721cc243886e 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/DeleteButton.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/DeleteButton.php @@ -6,7 +6,7 @@ namespace Magento\Customer\Block\Adminhtml\Edit; use Magento\Customer\Api\AccountManagementInterface; -use Magento\Ui\Component\Control\ButtonProviderInterface; +use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; /** * Class DeleteButton diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/InvalidateTokenButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/InvalidateTokenButton.php index 7b02478d44516a095d203c1b5a31f6a73a1952bc..a3744a1e8b2c3d08dc3e5729edd0dc849401b84a 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/InvalidateTokenButton.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/InvalidateTokenButton.php @@ -5,7 +5,7 @@ */ namespace Magento\Customer\Block\Adminhtml\Edit; -use Magento\Ui\Component\Control\ButtonProviderInterface; +use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; /** * Class InvalidateTokenButton diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/OrderButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/OrderButton.php index 4b402caf146e2112786a254f797cb3ecd1341be2..0edfd379f6517bb9a979c157ca530f3118119084 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/OrderButton.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/OrderButton.php @@ -5,11 +5,10 @@ */ namespace Magento\Customer\Block\Adminhtml\Edit; -use Magento\Ui\Component\Control\ButtonProviderInterface; +use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; /** * Class OrderButton - * @package Magento\Customer\Block\Adminhtml\Edit */ class OrderButton extends GenericButton implements ButtonProviderInterface { @@ -42,7 +41,7 @@ class OrderButton extends GenericButton implements ButtonProviderInterface if ($customerId && $this->authorization->isAllowed('Magento_Sales::create')) { $data = [ 'label' => __('Create Order'), - 'on_click' => 'setLocation(\'' . $this->getCreateOrderUrl() . '\')', + 'on_click' => sprintf("location.href = '%s';", $this->getCreateOrderUrl()), 'class' => 'add', 'sort_order' => 40, ]; diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetButton.php index 81e2d5845910886742c0f0f85d26c4b6bb9cbf18..8581974c55b8d8472502b5552d7562d4e9ee96ec 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetButton.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetButton.php @@ -5,11 +5,10 @@ */ namespace Magento\Customer\Block\Adminhtml\Edit; -use Magento\Ui\Component\Control\ButtonProviderInterface; +use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; /** * Class ResetButton - * @package Magento\Customer\Block\Adminhtml\Edit */ class ResetButton implements ButtonProviderInterface { @@ -21,7 +20,7 @@ class ResetButton implements ButtonProviderInterface return [ 'label' => __('Reset'), 'class' => 'reset', - 'on_click' => 'setLocation(window.location.href)', + 'on_click' => 'location.reload();', 'sort_order' => 30 ]; } diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php index ff377711a9b506dd5c6061f36a8151bf333dbd6a..f2894efd0bd0ba816b4d627a48b703948d0a355a 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php @@ -5,11 +5,10 @@ */ namespace Magento\Customer\Block\Adminhtml\Edit; -use Magento\Ui\Component\Control\ButtonProviderInterface; +use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; /** * Class ResetPasswordButton - * @package Magento\Customer\Block\Adminhtml\Edit */ class ResetPasswordButton extends GenericButton implements ButtonProviderInterface { @@ -24,7 +23,7 @@ class ResetPasswordButton extends GenericButton implements ButtonProviderInterfa $data = [ 'label' => __('Reset Password'), 'class' => 'reset reset-password', - 'on_click' => 'setLocation(\'' . $this->getResetPasswordUrl() . '\')', + 'on_click' => sprintf("location.href = '%s';", $this->getResetPasswordUrl()), 'sort_order' => 40, ]; } diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveAndContinueButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveAndContinueButton.php index f3113b1503ab1896f6bb82e030525640dea77a5c..44b9d328b252e848acfb58c6a8ecd4f37e35c1e1 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveAndContinueButton.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveAndContinueButton.php @@ -6,11 +6,10 @@ namespace Magento\Customer\Block\Adminhtml\Edit; use Magento\Customer\Api\AccountManagementInterface; -use Magento\Ui\Component\Control\ButtonProviderInterface; +use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; /** * Class SaveAndContinueButton - * @package Magento\Customer\Block\Adminhtml\Edit */ class SaveAndContinueButton extends GenericButton implements ButtonProviderInterface { diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveButton.php index b52302c73c90a619723dd57cb8552cb555a892c5..33f0bdada2941a33f6a5e38b3ec6ad99a425c8a6 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveButton.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/SaveButton.php @@ -6,7 +6,7 @@ namespace Magento\Customer\Block\Adminhtml\Edit; use Magento\Customer\Api\AccountManagementInterface; -use Magento\Ui\Component\Control\ButtonProviderInterface; +use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; /** * Class SaveButton diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php index 4a6743eddfabfa5ea5e4edc92c88aa13e8d40e7c..08919f7401d9007c97a89ad793161063ae4ca1cb 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php @@ -27,7 +27,7 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index protected function _extractCustomerData() { $customerData = []; - if ($this->getRequest()->getPost('account')) { + if ($this->getRequest()->getPost('customer')) { $serviceAttributes = [ CustomerInterface::DEFAULT_BILLING, CustomerInterface::DEFAULT_SHIPPING, @@ -40,7 +40,7 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index 'adminhtml_customer', \Magento\Customer\Api\CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, $serviceAttributes, - 'account' + 'customer' ); } @@ -113,7 +113,7 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index $extractedCustomerData[CustomerInterface::DEFAULT_BILLING] = null; $extractedCustomerData[CustomerInterface::DEFAULT_SHIPPING] = null; foreach ($addressIdList as $addressId) { - $scope = sprintf('account/customer_address/%s', $addressId); + $scope = sprintf('address/%s', $addressId); $addressData = $this->_extractData( $this->getRequest(), 'adminhtml_customer_address', @@ -151,10 +151,9 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index */ protected function _extractCustomerAddressData(array & $extractedCustomerData) { - $customerData = $this->getRequest()->getPost('account'); - $addresses = isset($customerData['customer_address']) ? $customerData['customer_address'] : []; + $addresses = $this->getRequest()->getPost('address'); $result = []; - if ($addresses) { + if (is_array($addresses)) { if (isset($addresses['_template_'])) { unset($addresses['_template_']); } @@ -177,8 +176,10 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index public function execute() { $returnToEdit = false; - $customerId = (int)$this->getRequest()->getParam('id'); $originalRequestData = $this->getRequest()->getPostValue(); + $customerId = isset($originalRequestData['customer']['entity_id']) + ? $originalRequestData['customer']['entity_id'] + : null; if ($originalRequestData) { try { // optional fields might be set in request for future processing by observers in other modules diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Validate.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Validate.php index 3986551d78389058e3f503511c7bf9d621ee66f5..b701d653dc030d2436527e924c5761f369e9da99 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Validate.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Validate.php @@ -37,7 +37,7 @@ class Validate extends \Magento\Customer\Controller\Adminhtml\Index ); $customerForm->setInvisibleIgnored(true); - $data = $customerForm->extractData($this->getRequest(), 'account'); + $data = $customerForm->extractData($this->getRequest(), 'customer'); if ($customer->getWebsiteId()) { unset($data['website_id']); @@ -74,8 +74,7 @@ class Validate extends \Magento\Customer\Controller\Adminhtml\Index */ protected function _validateCustomerAddress($response) { - $customerData = $this->getRequest()->getParam('account'); - $addresses = isset($customerData['customer_address']) ? $customerData['customer_address'] : []; + $addresses = $this->getRequest()->getPost('address'); if (!is_array($addresses)) { return; } @@ -86,7 +85,7 @@ class Validate extends \Magento\Customer\Controller\Adminhtml\Index $addressForm = $this->_formFactory->create('customer_address', 'adminhtml_customer_address'); - $requestScope = sprintf('account/customer_address/%s', $index); + $requestScope = sprintf('address/%s', $index); $formData = $addressForm->extractData($this->getRequest(), $requestScope); $errors = $addressForm->validateData($formData); diff --git a/app/code/Magento/Customer/Model/Customer.php b/app/code/Magento/Customer/Model/Customer.php index d6792e7d47c2a33d77b8b6991754a7dad31c3e56..c65cda9e51bbae8fa77d7f89b0bb440a7fb121f7 100644 --- a/app/code/Magento/Customer/Model/Customer.php +++ b/app/code/Magento/Customer/Model/Customer.php @@ -1034,6 +1034,12 @@ class Customer extends \Magento\Framework\Model\AbstractModel $errors[] = __('Gender is required.'); } + $transport = new \Magento\Framework\Object( + ['errors' => $errors] + ); + $this->_eventManager->dispatch('customer_validate', ['customer' => $this, 'transport' => $transport]); + $errors = $transport->getErrors(); + if (empty($errors)) { return true; } diff --git a/app/code/Magento/Customer/Model/Customer/DataProvider.php b/app/code/Magento/Customer/Model/Customer/DataProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..8597c0da84a866ac3cd2be1812044273e782ec77 --- /dev/null +++ b/app/code/Magento/Customer/Model/Customer/DataProvider.php @@ -0,0 +1,373 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Customer\Model\Customer; + +use Magento\Eav\Model\Config; +use Magento\Eav\Model\Entity\Type; +use Magento\Customer\Model\Address; +use Magento\Customer\Model\Customer; +use Magento\Ui\DataProvider\EavValidationRul; +use Magento\Customer\Model\Resource\Customer\Collection; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; +use Magento\Customer\Model\Resource\Customer\CollectionFactory as CustomerCollectionFactory; + +/** + * Class DataProvider + */ +class DataProvider implements DataProviderInterface +{ + /** + * @var string + */ + protected $primaryFieldName; + + /** + * @var string + */ + protected $requestFieldName; + + /** + * @var Collection + */ + protected $collection; + + /** + * @var Config + */ + protected $eavConfig; + + /** + * @var array + */ + protected $meta = []; + + /** + * Provider configuration data + * + * @var array + */ + protected $data = []; + + /** + * @var array + */ + protected $loadedData; + + /** + * EAV attribute properties to fetch from meta storage + * @var array + */ + protected $metaProperties = [ + 'dataType' => 'frontend_input', + 'visible' => 'is_visible', + 'required' => 'is_required', + 'label' => 'frontend_label', + 'sortOrder' => 'sort_order', + 'notice' => 'note', + 'default' => 'default_value', + 'size' => 'scope_multiline_count' + ]; + + /** + * Form element mapping + * + * @var array + */ + protected $formElement = [ + 'text' => 'input', + 'hidden' => 'input', + 'boolean' => 'checkbox', + ]; + + /** + * @var EavValidationRul + */ + protected $eavValidationRul; + + /** + * Constructor + * + * @param string $primaryFieldName + * @param string $requestFieldName + * @param EavValidationRul $eavValidationRul + * @param CustomerCollectionFactory $customerCollectionFactory + * @param Config $eavConfig + * @param array $meta + * @param array $data + */ + public function __construct( + $primaryFieldName, + $requestFieldName, + EavValidationRul $eavValidationRul, + CustomerCollectionFactory $customerCollectionFactory, + Config $eavConfig, + array $meta = [], + array $data = [] + ) { + $this->primaryFieldName = $primaryFieldName; + $this->requestFieldName = $requestFieldName; + $this->eavValidationRul = $eavValidationRul; + $this->collection = $customerCollectionFactory->create(); + $this->collection->addAttributeToSelect('*'); + $this->eavConfig = $eavConfig; + $this->meta = $meta; + $this->meta['customer']['fields'] = $this->getAttributesMeta( + $this->eavConfig->getEntityType('customer') + ); + $this->meta['address']['fields'] = $this->getAttributesMeta( + $this->eavConfig->getEntityType('customer_address') + ); + $this->data = $data; + } + + /** + * Get meta data + * + * @return array + */ + public function getMeta() + { + return $this->meta; + } + + /** + * Get field meta info + * + * @param string $fieldSetName + * @param string $fieldName + * @return array + */ + public function getFieldMetaInfo($fieldSetName, $fieldName) + { + return isset($this->meta[$fieldSetName]['fields'][$fieldName]) + ? $this->meta[$fieldSetName]['fields'][$fieldName] + : []; + } + + /** + * Get config data + * + * @return mixed + */ + public function getConfigData() + { + return isset($this->data['config']) ? $this->data['config'] : []; + } + + /** + * Set data + * + * @param mixed $config + * @return void + */ + public function setConfigData($config) + { + $this->data['config'] = $config; + } + + /** + * Get data + * + * @return array + */ + public function getData() + { + if (isset($this->loadedData)) { + return $this->loadedData; + } + + $items = $this->collection->getItems(); + /** @var Customer $customer */ + foreach ($items as $customer) { + $result['customer'] = $customer->getData(); + + $addresses = []; + /** @var Address $address */ + foreach ($customer->getAddresses() as $address) { + $addressId = $address->getId(); + $address->load($addressId); + $addresses[$addressId] = $address->getData(); + $this->prepareAddressData($addressId, $addresses, $result['customer']); + } + if (!empty($addresses)) { + $result['address'] = $addresses; + } + + $this->loadedData[$customer->getId()] = $result; + } + + return $this->loadedData; + } + + /** + * Get field name in request + * + * @return string + */ + public function getRequestFieldName() + { + return $this->requestFieldName; + } + + /** + * Get primary field name + * + * @return string + */ + public function getPrimaryFieldName() + { + return $this->primaryFieldName; + } + + /** + * @inheritdoc + */ + public function addFilter($field, $condition = null) + { + $this->collection->addFieldToFilter($field, $condition); + } + + /** + * Add field to select + * + * @param string|array $field + * @param string|null $alias + * @return void + */ + public function addField($field, $alias = null) + { + $this->collection->addAttributeToSelect($field); + } + + /** + * self::setOrder() alias + * + * @param string $field + * @param string $direction + * @return void + */ + public function addOrder($field, $direction) + { + $this->collection->addOrder($field, $direction); + } + + /** + * Set Query limit + * + * @param int $offset + * @param int $size + * @return void + */ + public function setLimit($offset, $size) + { + $this->collection->setPageSize($size); + $this->collection->setCurPage($offset); + } + + /** + * Removes field from select + * + * @param string|null $field + * @param bool $isAlias Alias identifier + * @return void + */ + public function removeField($field, $isAlias = false) + { + $this->collection->removeAttributeToSelect($field); + } + + /** + * Removes all fields from select + * + * @return void + */ + public function removeAllFields() + { + $this->collection->removeAttributeToSelect(); + } + + /** + * Retrieve count of loaded items + * + * @return int + */ + public function count() + { + return $this->collection->count(); + } + + /** + * Get fields meta info + * + * @param string $fieldSetName + * @return array + */ + public function getFieldsMetaInfo($fieldSetName) + { + return isset($this->meta[$fieldSetName]['fields']) ? $this->meta[$fieldSetName]['fields'] : []; + } + + /** + * Get attributes meta + * + * @param Type $entityType + * @return array + * @throws \Magento\Framework\Exception\LocalizedException + */ + protected function getAttributesMeta(Type $entityType) + { + $meta = []; + $attributes = $entityType->getAttributeCollection(); + /* @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */ + foreach ($attributes as $attribute) { + $code = $attribute->getAttributeCode(); + // use getDataUsingMethod, since some getters are defined and apply additional processing of returning value + foreach ($this->metaProperties as $metaName => $origName) { + $value = $attribute->getDataUsingMethod($origName); + $meta[$code][$metaName] = $value; + if ('frontend_input' === $origName) { + $meta[$code]['formElement'] = isset($this->formElement[$value]) + ? $this->formElement[$value] + : $value; + } + if ($attribute->usesSource()) { + $meta[$code]['options'] = $attribute->getSource()->getAllOptions(); + } + } + + $rules = $this->eavValidationRul->build($attribute, $meta[$code]); + if (!empty($rules)) { + $meta[$code]['validation'] = $rules; + } + } + return $meta; + } + + /** + * Prepare address data + * + * @param int $addressId + * @param array $addresses + * @param array $customer + * @return void + */ + protected function prepareAddressData($addressId, array &$addresses, array $customer) + { + if (isset($customer['default_billing']) + && $addressId == $customer['default_billing'] + ) { + $addresses[$addressId]['default_billing'] = $customer['default_billing']; + } + if (isset($customer['default_shipping']) + && $addressId == $customer['default_shipping'] + ) { + $addresses[$addressId]['default_shipping'] = $customer['default_shipping']; + } + if (isset($addresses[$addressId]['street'])) { + $addresses[$addressId]['street'] = explode("\n", $addresses[$addressId]['street']); + } + } +} diff --git a/app/code/Magento/Customer/composer.json b/app/code/Magento/Customer/composer.json index 340ab29eca160e1cca6c80f8426ea2ebe66261cb..0e4da26475620658642e2a1582cbe7391c7b2edc 100644 --- a/app/code/Magento/Customer/composer.json +++ b/app/code/Magento/Customer/composer.json @@ -3,33 +3,33 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-newsletter": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-wishlist": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-review": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/module-page-cache": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-authorization": "0.74.0-beta6", - "magento/module-integration": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/module-ui": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-newsletter": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-wishlist": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-review": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/module-page-cache": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-authorization": "0.74.0-beta7", + "magento/module-integration": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/module-ui": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-cookie": "0.74.0-beta6" + "magento/module-cookie": "0.74.0-beta7" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Customer/etc/data_source/customer.xml b/app/code/Magento/Customer/etc/data_source/customer.xml deleted file mode 100644 index 10fddb904a989f9f5a94fc1af7181458d65fd473..0000000000000000000000000000000000000000 --- a/app/code/Magento/Customer/etc/data_source/customer.xml +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../app/code/Magento/Ui/etc/data_source.xsd"> - <dataSource - name="account" label="Account Information" - dataSet="Magento\Customer\Model\Resource\Customer\Collection"> - <fields entityType="customer"> - <field name="entity_id" dataType="text" visible="false"/> - <field name="default_billing" source="eav" dataType="boolean" visible="false"/> - <field name="default_shipping" source="eav" dataType="boolean" visible="false"/> - <field name="website_id" dataType="number" formElement="select" source="eav" label="Associate to Website"> - <constraints> - <validate name="required-entry"/> - </constraints> - <tooltip> - <link>http://www.magentocommerce.com/knowledge-base/entry/understanding-store-scopes</link> - <description>If your Magento site has multiple views, you can set the scope to apply to a specific view.</description> - </tooltip> - </field> - <field name="prefix" source="eav" dataType="text"/> - <field name="group_id" dataType="number" formElement="select" source="eav" label="Group" fieldGroup="group_id" /> - <field name="disable_auto_group_change" source="eav" dataType="boolean" formElement="checkbox" fieldGroup="group_id"/> - <field name="firstname" source="eav" dataType="text"> - <constraints> - <validate name="required-entry"/> - </constraints> - </field> - <field name="middlename" source="eav" dataType="text"/> - <field name="lastname" source="eav" dataType="text"> - <constraints> - <validate name="required-entry"/> - </constraints> - </field> - <field name="suffix" source="eav" dataType="text"/> - <field name="email" source="eav" formElement="email"> - <constraints> - <validate name="required-entry"/> - <validate name="validate-email"/> - </constraints> - </field> - <field name="dob" source="eav" dataType="text" label="Date Of Birth" formElement="date"/> - <field name="taxvat" source="eav" dataType="text" label="Tax VAT Number"/> - <field name="gender" source="eav" dataType="text" formElement="select"/> - <field name="sendemail" - dataType="boolean" - formElement="checkbox" - label="Welcome Email" - description="Send a Welcome email "/> - <field name="sendemail_store_id" - dataType="number" - formElement="select" - optionProvider="Magento\Store\Model\System\Store::getStoreValuesForForm" - label="Send From"/> - </fields> - </dataSource> -</config> \ No newline at end of file diff --git a/app/code/Magento/Customer/etc/data_source/customer_address.xml b/app/code/Magento/Customer/etc/data_source/customer_address.xml deleted file mode 100644 index e3e88b578a12604b97419639750b8317019d0e51..0000000000000000000000000000000000000000 --- a/app/code/Magento/Customer/etc/data_source/customer_address.xml +++ /dev/null @@ -1,89 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../app/code/Magento/Ui/etc/data_source.xsd"> - <dataSource name="customer_address" - label="Customer Address" - dataSet="Magento\Customer\Model\Resource\Address\Collection"> - <fields entityType="customer_address"> - <field name="parent_id" dataType="number" visible="false"/> - <field name="prefix" source="eav"/> - <field name="firstname" source="eav"> - <constraints> - <validate name="required-entry"/> - </constraints> - </field> - <field name="middlename" source="eav"/> - <field name="lastname" source="eav"> - <constraints> - <validate name="required-entry"/> - </constraints> - </field> - <field name="suffix" source="eav"/> - <field name="company" source="eav" label="Company"/> - <field name="street" dataType="text" formElement="input" size="2" source="eav"> - <constraints> - <validate name="required-entry"/> - </constraints> - </field> - <field name="city" source="eav"> - <constraints> - <validate name="required-entry"/> - </constraints> - </field> - <field name="country_id" source="eav" formElement="select"> - <constraints> - <validate name="required-entry"/> - </constraints> - </field> - <field name="region_id" source="eav" formElement="select" customEntry="region"> - <constraints> - <validate name="required-entry"/> - <filter on="{parentScope}.country_id" by="country_id" /> - </constraints> - </field> - <field name="region" source="eav" formElement="input" visible="false"/> - - <field name="postcode" source="eav" formElement="post_code" > - <constraints> - <validate name="required-entry"/> - </constraints> - </field> - - <field name="telephone" source="eav" label="Phone Number"> - <constraints> - <validate name="required-entry"/> - </constraints> - </field> - <field name="fax" source="eav" label="Fax"/> - <field name="vat_id" source="eav" label="VAT number"/> - <field name="default_billing" source="reference" dataType="boolean" formElement="checkbox" - displayArea="head" description="Default Billing Address" uniqueNs="default_billing" uniqueProp="value"> - <reference target="account" - referencedField="parent_id" - targetField="entity_id" - neededField="default_billing" - /> - </field> - <field name="default_shipping" source="reference" dataType="boolean" formElement="checkbox" - displayArea="head" description="Default Shipping Address" uniqueNs="default_shipping" uniqueProp="value"> - <reference target="account" - referencedField="parent_id" - targetField="entity_id" - neededField="default_shipping" - /> - </field> - </fields> - <references> - <reference target="account" - referencedField="parent_id" - targetField="entity_id" - /> - </references> - </dataSource> -</config> diff --git a/app/code/Magento/Customer/etc/data_source/customer_group.xml b/app/code/Magento/Customer/etc/data_source/customer_group.xml deleted file mode 100644 index 87da4cb4d717c8fc029e1f1331f4a80efffb7963..0000000000000000000000000000000000000000 --- a/app/code/Magento/Customer/etc/data_source/customer_group.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../app/code/Magento/Ui/etc/data_source.xsd"> - <dataSource name="customer_group" label="Customer Group" dataSet="Magento\Customer\Model\Resource\Group\Collection"> - <fields> - <field name="customer_group_id" dataType="number" visible="false"/> - <field name="customer_group_code" dataType="text"/> - </fields> - </dataSource> -</config> \ No newline at end of file diff --git a/app/code/Magento/Customer/view/adminhtml/layout/customer_form.xml b/app/code/Magento/Customer/view/adminhtml/layout/customer_form.xml deleted file mode 100644 index 9893992bb265420ff38bc1b3dd18ccdacaa8b9b2..0000000000000000000000000000000000000000 --- a/app/code/Magento/Customer/view/adminhtml/layout/customer_form.xml +++ /dev/null @@ -1,72 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> - <body> - <referenceBlock name="form"> - <arguments> - <argument name="meta" xsi:type="array"> - <item name="defaults" xsi:type="array"> - <item name="visible" xsi:type="boolean">true</item> - </item> - </argument> - <argument name="label" xsi:type="string">Customer Information</argument> - <argument name="name" xsi:type="string">customer_form</argument> - <argument name="data_sources" xsi:type="array"> - <item name="customer_info" xsi:type="array"> - <item name="name" xsi:type="string">account</item> - <item name="submit_url" xsi:type="url" path="customer/index/save"> - <param name="_current">1</param> - <param name="back"></param> - </item> - <item name="validate_url" xsi:type="url" path="customer/index/validate"> - <param name="_current">1</param> - <param name="back"></param> - </item> - </item> - </argument> - <argument name="layout" xsi:type="array"> - <item name="type" xsi:type="string">tabs</item> - <item name="configuration" xsi:type="array"> - <item name="tabs_container_name" xsi:type="string">left</item> - <item name="areas" xsi:type="array"> - <item name="general" xsi:type="array"> - <item name="index" xsi:type="string">account_info</item> - <item name="type" xsi:type="string">fieldset</item> - <item name="label" xsi:type="string" translate="true">Customer Info</item> - <item name="collapsible" xsi:type="boolean">true</item> - <item name="ajax" xsi:type="boolean">true</item> - </item> - <item name="customer_address" xsi:type="array"> - <item name="index" xsi:type="string">customer_address</item> - <item name="type" xsi:type="string">tab</item> - <item name="label" xsi:type="string" translate="true">Customer Address</item> - </item> - </item> - </item> - </argument> - <argument name="buttons" xsi:type="array"> - <item name="back" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\BackButton</item> - <item name="delete" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\DeleteButton</item> - <item name="invalidateToken" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\InvalidateTokenButton</item> - <item name="resetPassword" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\ResetPasswordButton</item> - <item name="order" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\OrderButton</item> - <item name="reset" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\ResetButton</item> - <item name="save" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\SaveButton</item> - <item name="save_and_continue" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\SaveAndContinueButton</item> - </argument> - </arguments> - <block class="Magento\Customer\Block\Adminhtml\Edit\Tab\View" name="customer_edit_tab_view" template="tab/view.phtml"> - <arguments> - <argument name="tab_label" xsi:type="string">Customer View</argument> - <argument name="sort_order" xsi:type="number">10</argument> - </arguments> - <block class="Magento\Customer\Block\Adminhtml\Edit\Tab\View\PersonalInfo" name="personal_info" template="tab/view/personal_info.phtml"/> - </block> - </referenceBlock> - </body> -</page> diff --git a/app/code/Magento/Customer/view/adminhtml/layout/customer_index_edit.xml b/app/code/Magento/Customer/view/adminhtml/layout/customer_index_edit.xml index 12fa054b6398b5714ecedc796294822336b22b03..4d3ff76ccb80b348cf0a9bee817580682f7dd61b 100644 --- a/app/code/Magento/Customer/view/adminhtml/layout/customer_index_edit.xml +++ b/app/code/Magento/Customer/view/adminhtml/layout/customer_index_edit.xml @@ -5,11 +5,21 @@ * See COPYING.txt for license details. */ --> -<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" + xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" /> <!-- ToDo UI: remove this wrapper with old styles removal. The class name "admin__old" is for tests only, we shouldn't use it in any way --> <referenceContainer name="content"> - <ui_component name="customer_form" component="form" /> + <referenceBlock name="customer_form"> + <block class="Magento\Customer\Block\Adminhtml\Edit\Tab\View" name="customer_edit_tab_view" template="tab/view.phtml"> + <arguments> + <argument name="tab_label" xsi:type="string">Customer View</argument> + <argument name="sort_order" xsi:type="number">10</argument> + </arguments> + <block class="Magento\Customer\Block\Adminhtml\Edit\Tab\View\PersonalInfo" name="personal_info" template="tab/view/personal_info.phtml"/> + </block> + </referenceBlock> + <uiComponent name="customer_form"/> </referenceContainer> </body> </page> diff --git a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml new file mode 100644 index 0000000000000000000000000000000000000000..eb6199714da3274dc2302072d7cf26a60ed2088a --- /dev/null +++ b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml @@ -0,0 +1,553 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Ui/etc/ui_configuration.xsd"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="provider" xsi:type="string">customer_form.customer_form_data_source</item> + </item> + <item name="deps" xsi:type="string">customer_form.customer_form_data_source</item> + </item> + <item name="label" xsi:type="string" translate="true">Customer Information</item> + <item name="layout" xsi:type="array"> + <item name="type" xsi:type="string">tabs</item> + <item name="navContainerName" xsi:type="string">left</item> + </item> + <item name="buttons" xsi:type="array"> + <item name="back" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\BackButton</item> + <item name="delete" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\DeleteButton</item> + <item name="invalidateToken" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\InvalidateTokenButton</item> + <item name="resetPassword" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\ResetPasswordButton</item> + <item name="order" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\OrderButton</item> + <item name="reset" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\ResetButton</item> + <item name="save" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\SaveButton</item> + <item name="save_and_continue" xsi:type="string">Magento\Customer\Block\Adminhtml\Edit\SaveAndContinueButton</item> + </item> + </argument> + <dataSource name="customer_form_data_source"> + <argument name="dataProvider" xsi:type="configurableObject"> + <argument name="class" xsi:type="string">Magento\Customer\Model\Customer\DataProvider</argument> + <argument name="primaryFieldName" xsi:type="string">entity_id</argument> + <argument name="requestFieldName" xsi:type="string">id</argument> + <argument name="meta" xsi:type="array"> + <item name="customer" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="label" xsi:type="string" translate="true">Account Information</item> + </item> + </item> + <item name="address" xsi:type="array"> + <item name="is_collection" xsi:type="boolean">true</item> + <item name="config" xsi:type="array"> + <item name="label" xsi:type="string" translate="true">Addresses</item> + </item> + </item> + </argument> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item> + </item> + <item name="config" xsi:type="array"> + <item name="submit_url" xsi:type="string">customer/index/save</item> + <item name="validate_url" xsi:type="string">customer/index/validate</item> + </item> + </argument> + </argument> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item> + </item> + </argument> + </dataSource> + <fieldset name="customer"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="label" xsi:type="string" translate="true">Account Information</item> + </item> + </argument> + <field name="entity_id"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">false</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">customer</item> + </item> + </argument> + </field> + <field name="created_in"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">false</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">customer</item> + </item> + </argument> + </field> + <field name="default_billing"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">false</item> + <item name="dataType" xsi:type="string">boolean</item> + <item name="formElement" xsi:type="string">checkbox</item> + <item name="source" xsi:type="string">customer</item> + </item> + </argument> + </field> + <field name="default_shipping"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">false</item> + <item name="dataType" xsi:type="string">boolean</item> + <item name="formElement" xsi:type="string">checkbox</item> + <item name="source" xsi:type="string">customer</item> + </item> + </argument> + </field> + <field name="website_id"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">number</item> + <item name="formElement" xsi:type="string">select</item> + <item name="source" xsi:type="string">customer</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> + <item name="tooltip" xsi:type="array"> + <item name="link" xsi:type="string">http://www.magentocommerce.com/knowledge-base/entry/understanding-store-scopes</item> + <item name="description" xsi:type="string">If your Magento site has multiple views, you can set the scope to apply to a specific view.</item> + </item> + </item> + </argument> + </field> + <field name="prefix"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">true</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">customer</item> + </item> + </argument> + </field> + <container name="container_group"> + <argument name="data" xsi:type="array"> + <item name="type" xsi:type="string">group</item> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/components/group</item> + </item> + <item name="config" xsi:type="array"> + <item name="label" xsi:type="string" translate="true">Group</item> + <item name="required" xsi:type="boolean">true</item> + <item name="dataScope" xsi:type="boolean">false</item> + <item name="sortOrder" xsi:type="number">20</item> + </item> + </argument> + <field name="group_id"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="fieldGroup" xsi:type="string">group_id</item> + <item name="dataType" xsi:type="string">number</item> + <item name="formElement" xsi:type="string">select</item> + <item name="source" xsi:type="string">customer</item> + </item> + </argument> + </field> + <field name="disable_auto_group_change"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="fieldGroup" xsi:type="string">group_id</item> + <item name="dataType" xsi:type="string">boolean</item> + <item name="formElement" xsi:type="string">checkbox</item> + <item name="source" xsi:type="string">customer</item> + </item> + </argument> + </field> + </container> + <field name="firstname"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">customer</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> + </item> + </argument> + </field> + <field name="middlename"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">true</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">customer</item> + </item> + </argument> + </field> + <field name="lastname"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">customer</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> + </item> + </argument> + </field> + <field name="suffix"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">true</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">customer</item> + </item> + </argument> + </field> + <field name="email"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="extends" xsi:type="string">input</item> + </item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">email</item> + <item name="source" xsi:type="string">customer</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + <item name="validate-email" xsi:type="boolean">true</item> + </item> + </item> + </argument> + </field> + <field name="dob"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">true</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">date</item> + <item name="source" xsi:type="string">customer</item> + <item name="validation" xsi:type="array"> + <item name="validate-date" xsi:type="boolean">true</item> + </item> + </item> + </argument> + </field> + <field name="taxvat"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">true</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">customer</item> + </item> + </argument> + </field> + <field name="gender"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">true</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">select</item> + <item name="source" xsi:type="string">customer</item> + </item> + </argument> + </field> + <field name="sendemail_store_id"> + <argument name="data" xsi:type="array"> + <item name="options" xsi:type="object">Magento\Store\Model\System\Store</item> + <item name="config" xsi:type="array"> + <item name="label" xsi:type="string">Send From</item> + <item name="dataType" xsi:type="string">number</item> + <item name="formElement" xsi:type="string">select</item> + </item> + </argument> + </field> + <field name="sendemail"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="label" xsi:type="string">Welcome Email</item> + <item name="description" xsi:type="string">Send a Welcome email</item> + <item name="dataType" xsi:type="string">boolean</item> + <item name="formElement" xsi:type="string">checkbox</item> + </item> + </argument> + </field> + </fieldset> + <fieldset name="address"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="is_collection" xsi:type="boolean">true</item> + <item name="label" xsi:type="string" translate="true">Addresses</item> + <item name="removeMessage" xsi:type="string" translate="true">Are you sure you want to delete this item?</item> + </item> + </argument> + <field name="parent_id"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">false</item> + <item name="dataType" xsi:type="string">number</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + </item> + </argument> + </field> + <field name="prefix"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">true</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + </item> + </argument> + </field> + <field name="firstname"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="source" xsi:type="string">address</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> + </item> + </argument> + </field> + <field name="middlename"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">true</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + </item> + </argument> + </field> + <field name="lastname"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> + </item> + </argument> + </field> + <field name="suffix"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">true</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + <item name="sortOrder" xsi:type="string">43</item> + </item> + </argument> + </field> + <field name="company"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + <item name="sortOrder" xsi:type="string">44</item> + <item name="validation" xsi:type="array"> + <item name="min_text_length" xsi:type="number">0</item> + </item> + </item> + </argument> + </field> + <container name="street_container"> + <argument name="data" xsi:type="array"> + <item name="type" xsi:type="string">group</item> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/components/group</item> + </item> + <item name="config" xsi:type="array"> + <item name="label" xsi:type="string" translate="true">Street Address</item> + <item name="required" xsi:type="boolean">true</item> + <item name="dataScope" xsi:type="string">street</item> + <item name="sortOrder" xsi:type="string">45</item> + </item> + </argument> + <field name="street"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">0</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> + </item> + </argument> + </field> + <field name="street_second"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataScope" xsi:type="string">1</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + </item> + </argument> + </field> + </container> + <field name="city"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> + </item> + </argument> + </field> + <field name="country_id"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">select</item> + <item name="source" xsi:type="string">address</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> + </item> + </argument> + </field> + <field name="country_id"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">select</item> + <item name="source" xsi:type="string">address</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> + </item> + </argument> + </field> + <field name="region"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="visible" xsi:type="boolean">false</item> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + </item> + </argument> + </field> + <field name="region_id"> + <argument name="data" xsi:type="array"> + <item name="customEntry" xsi:type="string">region</item> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">select</item> + <item name="source" xsi:type="string">address</item> + <item name="customEntry" xsi:type="string">region</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> + <item name="filterBy" xsi:type="array"> + <item name="target" xsi:type="string"><![CDATA[<%= provider %>:<%= parentScope %>.country_id]]></item> + <item name="field" xsi:type="string">country_id</item> + </item> + </item> + </argument> + </field> + <field name="postcode"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="component" xsi:type="string">Magento_Ui/js/form/element/post-code</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> + </item> + </argument> + </field> + <field name="telephone"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> + </item> + </argument> + </field> + <field name="fax"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + <item name="validation" xsi:type="array"> + <item name="min_text_length" xsi:type="number">0</item> + </item> + </item> + </argument> + </field> + <field name="vat_id"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">text</item> + <item name="formElement" xsi:type="string">input</item> + <item name="source" xsi:type="string">address</item> + </item> + </argument> + </field> + <field name="default_billing"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">boolean</item> + <item name="formElement" xsi:type="string">checkbox</item> + <item name="displayArea" xsi:type="string">head</item> + <item name="uniqueNs" xsi:type="string">default_billing</item> + <item name="uniqueProp" xsi:type="string">value</item> + <item name="description" xsi:type="string" translate="true">Default Billing Address</item> + <item name="source" xsi:type="array"> + <item name="target" xsi:type="string">customer</item> + <item name="targetField" xsi:type="string">default_billing</item> + <item name="referencedField" xsi:type="string">entity_id</item> + </item> + </item> + </argument> + </field> + <field name="default_shipping"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="dataType" xsi:type="string">boolean</item> + <item name="formElement" xsi:type="string">checkbox</item> + <item name="displayArea" xsi:type="string">head</item> + <item name="uniqueNs" xsi:type="string">default_shipping</item> + <item name="uniqueProp" xsi:type="string">value</item> + <item name="description" xsi:type="string" translate="true">Default Shipping Address</item> + <item name="source" xsi:type="array"> + <item name="target" xsi:type="string">customer</item> + <item name="targetField" xsi:type="string">default_shipping</item> + <item name="referencedField" xsi:type="string">entity_id</item> + </item> + </item> + </argument> + </field> + </fieldset> +</form> diff --git a/app/code/Magento/CustomerImportExport/composer.json b/app/code/Magento/CustomerImportExport/composer.json index 3635354b9f3c6e0593281f1465051226cfc8c355..1541d6e931b963ebbe66888254d08f6022586430 100644 --- a/app/code/Magento/CustomerImportExport/composer.json +++ b/app/code/Magento/CustomerImportExport/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-import-export": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-import-export": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/DesignEditor/composer.json b/app/code/Magento/DesignEditor/composer.json index 7a24e23445b99be4268f881b05eff8013e9553da..f9d3156293edff7b668fddde96bc2c1b26871f33 100644 --- a/app/code/Magento/DesignEditor/composer.json +++ b/app/code/Magento/DesignEditor/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-translation": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-translation": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Developer/composer.json b/app/code/Magento/Developer/composer.json index 2acb479e5e7da4b25ea3e78b4269be86c45fa06c..dfe90bb1778175658e44a84c52ce21fc9243573a 100644 --- a/app/code/Magento/Developer/composer.json +++ b/app/code/Magento/Developer/composer.json @@ -3,12 +3,12 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Dhl/composer.json b/app/code/Magento/Dhl/composer.json index 9523a52d2f19d36247e9a99814c24cf43e8ee2a5..41241d5133de99d58082d16c854e2adb73acab39 100644 --- a/app/code/Magento/Dhl/composer.json +++ b/app/code/Magento/Dhl/composer.json @@ -3,22 +3,22 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-shipping": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-shipping": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "lib-libxml": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Directory/composer.json b/app/code/Magento/Directory/composer.json index bc25eea4a4f6717ae53a92714ecf462bfa6f0e6d..610a919710b954d481569fce81e506a5b41f00ab 100644 --- a/app/code/Magento/Directory/composer.json +++ b/app/code/Magento/Directory/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "lib-libxml": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Downloadable/composer.json b/app/code/Magento/Downloadable/composer.json index 69f7d646d0ffd16100c2deddc801ab123ab375ad..0d193d70b390aec33ca02dc0f4bab3f640a738f0 100644 --- a/app/code/Magento/Downloadable/composer.json +++ b/app/code/Magento/Downloadable/composer.json @@ -3,28 +3,28 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-wishlist": "0.74.0-beta6", - "magento/module-gift-message": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-msrp": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-wishlist": "0.74.0-beta7", + "magento/module-gift-message": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-msrp": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Eav/composer.json b/app/code/Magento/Eav/composer.json index 48ba714ad64dafc7360bb73aa31e87ac3a96ac0d..b67c368db4d0263cd85abde008a6fdae9063b397 100644 --- a/app/code/Magento/Eav/composer.json +++ b/app/code/Magento/Eav/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Email/composer.json b/app/code/Magento/Email/composer.json index afc6d37eb433e3b75b32196ad86b641530dbb796..1a17463f5c6eaecae56d40b2f087b987c1ec1d23 100644 --- a/app/code/Magento/Email/composer.json +++ b/app/code/Magento/Email/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-cms": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-variable": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-cms": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-variable": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Fedex/composer.json b/app/code/Magento/Fedex/composer.json index 4e2b254631e2af230d799ecfca6b01371e26afcf..2fa84179799528959e83982cfd815454ce43f311 100644 --- a/app/code/Magento/Fedex/composer.json +++ b/app/code/Magento/Fedex/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-shipping": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-shipping": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "lib-libxml": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GiftMessage/composer.json b/app/code/Magento/GiftMessage/composer.json index 68ce2c1de0918b500fa744563995ea560aa00240..b7da7641a3318d3952c2c24a75fa491fe886c920 100644 --- a/app/code/Magento/GiftMessage/composer.json +++ b/app/code/Magento/GiftMessage/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-multishipping": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-multishipping": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GoogleAdwords/composer.json b/app/code/Magento/GoogleAdwords/composer.json index 81dcd88401f817917d78a4ef6c7662e1cef9e6b8..3aa69ec189227a3ebce792f590d80dc771b01a15 100644 --- a/app/code/Magento/GoogleAdwords/composer.json +++ b/app/code/Magento/GoogleAdwords/composer.json @@ -3,13 +3,13 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GoogleAnalytics/composer.json b/app/code/Magento/GoogleAnalytics/composer.json index 68cfa226900d210e823aae6eb94a46500ba21fd0..3a46c54505deea1536e2d8b0fc8ac690f9448633 100644 --- a/app/code/Magento/GoogleAnalytics/composer.json +++ b/app/code/Magento/GoogleAnalytics/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-cookie": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-cookie": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GoogleOptimizer/composer.json b/app/code/Magento/GoogleOptimizer/composer.json index a20b62e29cb95b1840d2dfc056c0e6df5b9638a2..5ef9e22e90d5654ee85e50d05e854b7319f48cdb 100644 --- a/app/code/Magento/GoogleOptimizer/composer.json +++ b/app/code/Magento/GoogleOptimizer/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-google-analytics": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-cms": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-google-analytics": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-cms": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GoogleShopping/composer.json b/app/code/Magento/GoogleShopping/composer.json index 267a3c8cb23aeea71338a8532432c3e4a133ce26..6960954e41d5609fece948947ce2eb7bf0f89ed2 100644 --- a/app/code/Magento/GoogleShopping/composer.json +++ b/app/code/Magento/GoogleShopping/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GroupedImportExport/composer.json b/app/code/Magento/GroupedImportExport/composer.json index 2d66faa4f5b3761512df683740754d918999fe0c..b74fc2be667c10aebcb7067d20923281e1c17cf0 100644 --- a/app/code/Magento/GroupedImportExport/composer.json +++ b/app/code/Magento/GroupedImportExport/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-import-export": "0.74.0-beta6", - "magento/module-catalog-import-export": "0.74.0-beta6", - "magento/module-grouped-product": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-import-export": "0.74.0-beta7", + "magento/module-catalog-import-export": "0.74.0-beta7", + "magento/module-grouped-product": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/GroupedProduct/composer.json b/app/code/Magento/GroupedProduct/composer.json index cdd8818ca6b36d0d881e58e187ae078e61590d0c..69f557ba1be410195e5790a509f47302711c3173 100644 --- a/app/code/Magento/GroupedProduct/composer.json +++ b/app/code/Magento/GroupedProduct/composer.json @@ -3,22 +3,22 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/module-msrp": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/module-msrp": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json index 747df1717017a7ddeffb4d80ef8640f23e2f5dfd..cc859dbe4b4f79012ea771cf2434247ea9b8cd5c 100644 --- a/app/code/Magento/ImportExport/composer.json +++ b/app/code/Magento/ImportExport/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-indexer": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-indexer": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "ext-ctype": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/ImportExport/view/adminhtml/templates/import/form/after.phtml b/app/code/Magento/ImportExport/view/adminhtml/templates/import/form/after.phtml index 98557c0254c317fbcb7b6803508e9759e222e90b..26275ec71c97b8efd83193db658f05ac0632d576 100644 --- a/app/code/Magento/ImportExport/view/adminhtml/templates/import/form/after.phtml +++ b/app/code/Magento/ImportExport/view/adminhtml/templates/import/form/after.phtml @@ -9,7 +9,7 @@ <span class="icon-head head-edit-form fieldset-legend" id="import_validation_container_header"><?php echo __('Validation Results'); ?></span> </div><br> - <div id="import_validation_messages" class="fieldset admin__scope"><!-- --></div> + <div id="import_validation_messages" class="fieldset"><!-- --></div> </div> <script> require(['jquery', 'prototype'], function(jQuery){ diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json index 1e199e2a193d9de0028b8d9ee4a0c2c62c026580..dc50f4ea54aa7305e118a771a6a57ce857a7d7ee 100644 --- a/app/code/Magento/Indexer/composer.json +++ b/app/code/Magento/Indexer/composer.json @@ -3,13 +3,13 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-backend": "0.74.0-beta6", - "magento/module-page-cache": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-backend": "0.74.0-beta7", + "magento/module-page-cache": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Integration/composer.json b/app/code/Magento/Integration/composer.json index 9fa6582f0d0cd4bb38e11ceed92222616d1abd5a..0c5cf5c42e60e1228d5701fe8df076f5f3c64547 100644 --- a/app/code/Magento/Integration/composer.json +++ b/app/code/Magento/Integration/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-user": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-authorization": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-user": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-authorization": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/LayeredNavigation/composer.json b/app/code/Magento/LayeredNavigation/composer.json index ed19740fa51a2ec85a258179adb1147d47cbe49e..3651e00bcad830257b36b43b9ca6ff3da9ca0fe4 100644 --- a/app/code/Magento/LayeredNavigation/composer.json +++ b/app/code/Magento/LayeredNavigation/composer.json @@ -3,13 +3,13 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Log/composer.json b/app/code/Magento/Log/composer.json index 5179484e4165391b9d64e747c7cde887bacdc2c5..3673638d5fdf881571d1fc6d10276dd7c134415d 100644 --- a/app/code/Magento/Log/composer.json +++ b/app/code/Magento/Log/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/MediaStorage/composer.json b/app/code/Magento/MediaStorage/composer.json index 1a140593019d9982ad679be6ab959f95baf4ac63..e2ff84226413e9021790faeec53aa2c04734bc46 100644 --- a/app/code/Magento/MediaStorage/composer.json +++ b/app/code/Magento/MediaStorage/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Msrp/composer.json b/app/code/Magento/Msrp/composer.json index 5e288eaebe15fdb2d3d2c35d2fa2ca7de5fd5dae..3ddcf10eef3fd3ae49d4bd7ab71c2f74fe5da3df 100644 --- a/app/code/Magento/Msrp/composer.json +++ b/app/code/Magento/Msrp/composer.json @@ -3,19 +3,19 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-bundle": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-downloadable": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-grouped-product": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-bundle": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-downloadable": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-grouped-product": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Multishipping/composer.json b/app/code/Magento/Multishipping/composer.json index ebcccdf5ade42bf663bb71b3bf0c100e6800df47..8b782fc5aa17d9f3702bf2e6babe60e105e3eccf 100644 --- a/app/code/Magento/Multishipping/composer.json +++ b/app/code/Magento/Multishipping/composer.json @@ -3,19 +3,19 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-payment": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-payment": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Newsletter/composer.json b/app/code/Magento/Newsletter/composer.json index 2393d31c94a9e4d4840e0276b8d84bff76ea6237..27860c523bb2d47c78a20cf2e5efbb39ea2d53bc 100644 --- a/app/code/Magento/Newsletter/composer.json +++ b/app/code/Magento/Newsletter/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-widget": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-cms": "0.74.0-beta6", - "magento/module-email": "0.74.0-beta6", - "magento/module-cron": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-require-js": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-widget": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-cms": "0.74.0-beta7", + "magento/module-email": "0.74.0-beta7", + "magento/module-cron": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-require-js": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Newsletter/view/adminhtml/layout/customer_form.xml b/app/code/Magento/Newsletter/view/adminhtml/layout/customer_index_edit.xml similarity index 91% rename from app/code/Magento/Newsletter/view/adminhtml/layout/customer_form.xml rename to app/code/Magento/Newsletter/view/adminhtml/layout/customer_index_edit.xml index 047806721e82afb9d33be6cddf5f72f1da39f182..9370c60513dc798de81b4d8a88a5b3c3b5678c1b 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/layout/customer_form.xml +++ b/app/code/Magento/Newsletter/view/adminhtml/layout/customer_index_edit.xml @@ -7,7 +7,7 @@ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> <body> - <referenceBlock name="form"> + <referenceBlock name="customer_form"> <block acl="Magento_Newsletter::subscriber" class="Magento\Customer\Block\Adminhtml\Edit\Tab\Newsletter" name="newsletter" /> </referenceBlock> </body> diff --git a/app/code/Magento/OfflinePayments/composer.json b/app/code/Magento/OfflinePayments/composer.json index f47d2c7fd2030470d1926ef74a8e7376cf9a4b78..9ec612490167fd5b8f88d2260ab37b367cdf8d73 100644 --- a/app/code/Magento/OfflinePayments/composer.json +++ b/app/code/Magento/OfflinePayments/composer.json @@ -3,12 +3,12 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-payment": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-payment": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/OfflineShipping/composer.json b/app/code/Magento/OfflineShipping/composer.json index b3ddea4da64c2a823e492e92649ee945bc126687..f78263edcb905f19c2530398ae58884d75166fd7 100644 --- a/app/code/Magento/OfflineShipping/composer.json +++ b/app/code/Magento/OfflineShipping/composer.json @@ -3,21 +3,21 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-shipping": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-sales-rule": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-shipping": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-sales-rule": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/PageCache/composer.json b/app/code/Magento/PageCache/composer.json index b8ad947ba68430c71160dc994e099cc10c073d59..c5101231ec2c5549706f8f3a139191e9153df9c0 100644 --- a/app/code/Magento/PageCache/composer.json +++ b/app/code/Magento/PageCache/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Payment/composer.json b/app/code/Magento/Payment/composer.json index b4e88d864a2b2c0868d6bd2cb685f0b81bcb0d4d..f765253fd15845aba891a6d80232c3d0599a3b6d 100644 --- a/app/code/Magento/Payment/composer.json +++ b/app/code/Magento/Payment/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-centinel": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-centinel": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Persistent/composer.json b/app/code/Magento/Persistent/composer.json index 6b71977bb0d02f8105c6b0fc6ab5b57c6345fd7b..820efe841ed01b4dac02fff0edadcc44590e78b1 100644 --- a/app/code/Magento/Persistent/composer.json +++ b/app/code/Magento/Persistent/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-cron": "0.74.0-beta6", - "magento/module-page-cache": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-cron": "0.74.0-beta7", + "magento/module-page-cache": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/ProductAlert/composer.json b/app/code/Magento/ProductAlert/composer.json index f6482671da0a929b537d916d2d9960bcf2b24161..662db83f95e273020c4aa550da04fdf71bf8bb06 100644 --- a/app/code/Magento/ProductAlert/composer.json +++ b/app/code/Magento/ProductAlert/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Quote/composer.json b/app/code/Magento/Quote/composer.json index c4bf2a50e6d26dbf3884fd47edee836d756ea200..1e9c6075223d256f7c0446991c4c26096cff6261 100644 --- a/app/code/Magento/Quote/composer.json +++ b/app/code/Magento/Quote/composer.json @@ -3,25 +3,25 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-catalog-rule": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-authorization": "0.74.0-beta6", - "magento/module-payment": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-shipping": "0.74.0-beta6", - "magento/module-sales-sequence": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-catalog-rule": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-authorization": "0.74.0-beta7", + "magento/module-payment": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-shipping": "0.74.0-beta7", + "magento/module-sales-sequence": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Reports/composer.json b/app/code/Magento/Reports/composer.json index 575834f57dafa4f07f7bb71ab6935fde724e4731..da54b6503db78f7a07f41f55682f196bc169e91a 100644 --- a/app/code/Magento/Reports/composer.json +++ b/app/code/Magento/Reports/composer.json @@ -3,28 +3,28 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-cms": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-widget": "0.74.0-beta6", - "magento/module-log": "0.74.0-beta6", - "magento/module-wishlist": "0.74.0-beta6", - "magento/module-review": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/module-downloadable": "0.74.0-beta6", - "magento/module-sales-rule": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-cms": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-widget": "0.74.0-beta7", + "magento/module-log": "0.74.0-beta7", + "magento/module-wishlist": "0.74.0-beta7", + "magento/module-review": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/module-downloadable": "0.74.0-beta7", + "magento/module-sales-rule": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/RequireJs/composer.json b/app/code/Magento/RequireJs/composer.json index 968f8b00f4780f6abfd675c4d73350b3d1b10f95..09b0a38dcb6ef123f32e19d05b29590d0a1679c1 100644 --- a/app/code/Magento/RequireJs/composer.json +++ b/app/code/Magento/RequireJs/composer.json @@ -3,11 +3,11 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Review/composer.json b/app/code/Magento/Review/composer.json index 35197e270227acf8a04a3e0915411c076af46e0d..10b89c9f5b04bff6ba97ad1d1c720a0970314673 100644 --- a/app/code/Magento/Review/composer.json +++ b/app/code/Magento/Review/composer.json @@ -3,22 +3,22 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-newsletter": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-ui": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-newsletter": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-ui": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-cookie": "0.74.0-beta6" + "magento/module-cookie": "0.74.0-beta7" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Review/view/adminhtml/layout/customer_form.xml b/app/code/Magento/Review/view/adminhtml/layout/customer_index_edit.xml similarity index 91% rename from app/code/Magento/Review/view/adminhtml/layout/customer_form.xml rename to app/code/Magento/Review/view/adminhtml/layout/customer_index_edit.xml index 09fe7121ca4f6407351238f0802a4fd999dd1e35..a6fe4a094eb0f1425af6a7dcf876f619ce58d1c1 100644 --- a/app/code/Magento/Review/view/adminhtml/layout/customer_form.xml +++ b/app/code/Magento/Review/view/adminhtml/layout/customer_index_edit.xml @@ -7,7 +7,7 @@ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> <body> - <referenceBlock name="form"> + <referenceBlock name="customer_form"> <block acl="Magento_Review::reviews_all" class="Magento\Review\Block\Adminhtml\ReviewTab" name="reviews" /> </referenceBlock> </body> diff --git a/app/code/Magento/Rss/composer.json b/app/code/Magento/Rss/composer.json index cb02900c44ef080abe82adcc3879c5394cf4640c..2e3f52bd9644d567c605deb87d855e01c32f6e8c 100644 --- a/app/code/Magento/Rss/composer.json +++ b/app/code/Magento/Rss/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Rule/composer.json b/app/code/Magento/Rule/composer.json index 4e9e4fd3965676ec789fcae5df2f3fc27a1601ca..f03b63cba961c0adf432192ca5b2809a5a134c6e 100644 --- a/app/code/Magento/Rule/composer.json +++ b/app/code/Magento/Rule/composer.json @@ -3,16 +3,16 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "lib-libxml": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 94847e91dbe200c9ea34764d4981d08ac986db98..02077b3e30163a4794f260175e74ec667ed17592 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -920,6 +920,8 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface * Order state setter. * If status is specified, will add order status history with specified comment * the setData() cannot be overridden because of compatibility issues with resource model + * By default allows to set any state. Can also update status to default or specified value + * Complete and closed states are encapsulated intentionally * * @param string $state * @param string|bool $status @@ -927,6 +929,7 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface * @param bool $isCustomerNotified * @param bool $shouldProtectState * @return \Magento\Sales\Model\Order + * @throws \Magento\Framework\Exception\LocalizedException */ public function setState( $state, @@ -935,29 +938,7 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface $isCustomerNotified = null, $shouldProtectState = true ) { - return $this->_setState($state, $status, $comment, $isCustomerNotified, $shouldProtectState); - } - /** - * Order state protected setter. - * By default allows to set any state. Can also update status to default or specified value - * Complete and closed states are encapsulated intentionally, see the _checkState() - * - * @param string $state - * @param string|bool $status - * @param string $comment - * @param bool $isCustomerNotified - * @param bool $shouldProtectState - * @return $this - * @throws \Magento\Framework\Exception\LocalizedException - */ - protected function _setState( - $state, - $status = false, - $comment = '', - $isCustomerNotified = null, - $shouldProtectState = false - ) { // attempt to set the specified state if ($shouldProtectState) { if ($this->isStateProtected($state)) { @@ -966,17 +947,32 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface ); } } - $this->setData('state', $state); + + $transport = new \Magento\Framework\Object( + [ + 'state' => $state, + 'status' => $status, + 'comment' => $comment, + 'is_customer_notified' => $isCustomerNotified + ] + ); + + $this->_eventManager->dispatch( + 'sales_order_state_change_before', + ['order' => $this, 'transport' => $transport] + ); + $status = $transport->getStatus(); + $this->setData('state', $transport->getState()); // add status history if ($status) { if ($status === true) { - $status = $this->getConfig()->getStateDefaultStatus($state); + $status = $this->getConfig()->getStateDefaultStatus($transport->getState()); } $this->setStatus($status); - $history = $this->addStatusHistoryComment($comment, false); + $history = $this->addStatusHistoryComment($transport->getComment(), false); // no sense to set $status again - $history->setIsCustomerNotified($isCustomerNotified); + $history->setIsCustomerNotified($transport->getIsCustomerNotified()); } return $this; } @@ -1167,7 +1163,7 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface $this->setTotalCanceled($this->getGrandTotal() - $this->getTotalPaid()); $this->setBaseTotalCanceled($this->getBaseGrandTotal() - $this->getBaseTotalPaid()); - $this->_setState($cancelState, true, $comment); + $this->setState($cancelState, true, $comment, null, false); } elseif (!$graceful) { throw new \Magento\Framework\Exception\LocalizedException(__('We cannot cancel this order.')); } diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoCommentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoCommentSender.php index 2d6598ec9a830a7f0ca18a53e3291ce1446bb368..09d01d2e0a55cdf874ba8cbe9add9567998a5c5c 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoCommentSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoCommentSender.php @@ -11,6 +11,7 @@ use Magento\Sales\Model\Order\Email\Container\CreditmemoCommentIdentity; use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\NotifySender; use Magento\Sales\Model\Order\Address\Renderer; +use Magento\Framework\Event\ManagerInterface; /** * Class CreditmemoCommentSender @@ -22,22 +23,32 @@ class CreditmemoCommentSender extends NotifySender */ protected $addressRenderer; + /** + * Application Event Dispatcher + * + * @var ManagerInterface + */ + protected $eventManager; + /** * @param Template $templateContainer * @param CreditmemoCommentIdentity $identityContainer * @param Order\Email\SenderBuilderFactory $senderBuilderFactory * @param \Psr\Log\LoggerInterface $logger * @param Renderer $addressRenderer + * @param ManagerInterface $eventManager */ public function __construct( Template $templateContainer, CreditmemoCommentIdentity $identityContainer, \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, \Psr\Log\LoggerInterface $logger, - Renderer $addressRenderer + Renderer $addressRenderer, + ManagerInterface $eventManager ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger); $this->addressRenderer = $addressRenderer; + $this->eventManager = $eventManager; } /** @@ -57,18 +68,28 @@ class CreditmemoCommentSender extends NotifySender $formattedShippingAddress = ''; } $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); - $this->templateContainer->setTemplateVars( - [ - 'order' => $order, - 'creditmemo' => $creditmemo, - 'comment' => $comment, - 'billing' => $order->getBillingAddress(), - 'store' => $order->getStore(), - 'formattedShippingAddress' => $formattedShippingAddress, - 'formattedBillingAddress' => $formattedBillingAddress, + + $transport = new \Magento\Framework\Object( + ['template_vars' => + [ + 'order' => $order, + 'creditmemo' => $creditmemo, + 'comment' => $comment, + 'billing' => $order->getBillingAddress(), + 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress, + ] ] ); + $this->eventManager->dispatch( + 'email_creditmemo_comment_set_template_vars_before', + ['sender' => $this, 'transport' => $transport] + ); + + $this->templateContainer->setTemplateVars($transport->getTemplateVars()); + return $this->checkAndSend($order, $notify); } } diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php index e476e5ec8b544272154e907ce04cf46be2dd08ba..8bcd58fafd941a3dc185de14ac7f33b932ed2d7b 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php @@ -13,6 +13,7 @@ use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\Sender; use Magento\Sales\Model\Resource\Order\Creditmemo as CreditmemoResource; use Magento\Sales\Model\Order\Address\Renderer; +use Magento\Framework\Event\ManagerInterface; /** * Class CreditmemoSender @@ -43,6 +44,13 @@ class CreditmemoSender extends Sender */ protected $addressRenderer; + /** + * Application Event Dispatcher + * + * @var ManagerInterface + */ + protected $eventManager; + /** * @param Template $templateContainer * @param CreditmemoIdentity $identityContainer @@ -52,6 +60,7 @@ class CreditmemoSender extends Sender * @param CreditmemoResource $creditmemoResource * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig * @param Renderer $addressRenderer + * @param ManagerInterface $eventManager */ public function __construct( Template $templateContainer, @@ -61,13 +70,15 @@ class CreditmemoSender extends Sender PaymentHelper $paymentHelper, CreditmemoResource $creditmemoResource, \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig, - Renderer $addressRenderer + Renderer $addressRenderer, + ManagerInterface $eventManager ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger); $this->paymentHelper = $paymentHelper; $this->creditmemoResource = $creditmemoResource; $this->globalConfig = $globalConfig; $this->addressRenderer = $addressRenderer; + $this->eventManager = $eventManager; } /** @@ -100,24 +111,32 @@ class CreditmemoSender extends Sender $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); - $this->templateContainer->setTemplateVars( - [ - 'order' => $order, - 'creditmemo' => $creditmemo, - 'comment' => $creditmemo->getCustomerNoteNotify() ? $creditmemo->getCustomerNote() : '', - 'billing' => $order->getBillingAddress(), - 'payment_html' => $this->getPaymentHtml($order), - 'store' => $order->getStore(), - 'formattedShippingAddress' => $formattedShippingAddress, - 'formattedBillingAddress' => $formattedBillingAddress, + $transport = new \Magento\Framework\Object( + ['template_vars' => + [ + 'order' => $order, + 'creditmemo' => $creditmemo, + 'comment' => $creditmemo->getCustomerNoteNotify() + ? $creditmemo->getCustomerNote() : '', + 'billing' => $order->getBillingAddress(), + 'payment_html' => $this->getPaymentHtml($order), + 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress + ] ] ); + $this->eventManager->dispatch( + 'email_creditmemo_set_template_vars_before', + ['sender' => $this, 'transport' => $transport] + ); + + $this->templateContainer->setTemplateVars($transport->getTemplateVars()); + if ($this->checkAndSend($order)) { $creditmemo->setEmailSent(true); - $this->creditmemoResource->saveAttribute($creditmemo, ['send_email', 'email_sent']); - return true; } } diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceCommentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceCommentSender.php index 75529455b3f5baa8b0e5e089465de1b48e6fc2eb..b994034cf480a12c17738832e1bb44e9920be569 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceCommentSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceCommentSender.php @@ -11,6 +11,7 @@ use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\NotifySender; use Magento\Sales\Model\Order\Invoice; use Magento\Sales\Model\Order\Address\Renderer; +use Magento\Framework\Event\ManagerInterface; /** * Class InvoiceCommentSender @@ -22,22 +23,32 @@ class InvoiceCommentSender extends NotifySender */ protected $addressRenderer; + /** + * Application Event Dispatcher + * + * @var ManagerInterface + */ + protected $eventManager; + /** * @param Template $templateContainer * @param InvoiceCommentIdentity $identityContainer * @param Order\Email\SenderBuilderFactory $senderBuilderFactory * @param \Psr\Log\LoggerInterface $logger * @param Renderer $addressRenderer + * @param ManagerInterface $eventManager */ public function __construct( Template $templateContainer, InvoiceCommentIdentity $identityContainer, \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, \Psr\Log\LoggerInterface $logger, - Renderer $addressRenderer + Renderer $addressRenderer, + ManagerInterface $eventManager ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger); $this->addressRenderer = $addressRenderer; + $this->eventManager = $eventManager; } /** @@ -57,17 +68,28 @@ class InvoiceCommentSender extends NotifySender $formattedShippingAddress = ''; } $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); - $this->templateContainer->setTemplateVars( - [ - 'order' => $order, - 'invoice' => $invoice, - 'comment' => $comment, - 'billing' => $order->getBillingAddress(), - 'store' => $order->getStore(), - 'formattedShippingAddress' => $formattedShippingAddress, - 'formattedBillingAddress' => $formattedBillingAddress, + + $transport = new \Magento\Framework\Object( + ['template_vars' => + [ + 'order' => $order, + 'invoice' => $invoice, + 'comment' => $comment, + 'billing' => $order->getBillingAddress(), + 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress, + ] ] ); + + $this->eventManager->dispatch( + 'email_invoice_comment_set_template_vars_before', + ['sender' => $this, 'transport' => $transport] + ); + + $this->templateContainer->setTemplateVars($transport->getTemplateVars()); + return $this->checkAndSend($order, $notify); } } diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php index 0796ff0443b198be2f4f2533e825fb8eca25c2f9..d879b0f529aab42479a89acc597f14867f4268a4 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php @@ -13,6 +13,7 @@ use Magento\Sales\Model\Order\Email\Sender; use Magento\Sales\Model\Order\Invoice; use Magento\Sales\Model\Resource\Order\Invoice as InvoiceResource; use Magento\Sales\Model\Order\Address\Renderer; +use Magento\Framework\Event\ManagerInterface; /** * Class InvoiceSender @@ -43,6 +44,13 @@ class InvoiceSender extends Sender */ protected $addressRenderer; + /** + * Application Event Dispatcher + * + * @var ManagerInterface + */ + protected $eventManager; + /** * @param Template $templateContainer * @param InvoiceIdentity $identityContainer @@ -52,6 +60,7 @@ class InvoiceSender extends Sender * @param InvoiceResource $invoiceResource * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig * @param Renderer $addressRenderer + * @param ManagerInterface $eventManager */ public function __construct( Template $templateContainer, @@ -61,13 +70,15 @@ class InvoiceSender extends Sender PaymentHelper $paymentHelper, InvoiceResource $invoiceResource, \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig, - Renderer $addressRenderer + Renderer $addressRenderer, + ManagerInterface $eventManager ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger); $this->paymentHelper = $paymentHelper; $this->invoiceResource = $invoiceResource; $this->globalConfig = $globalConfig; $this->addressRenderer = $addressRenderer; + $this->eventManager = $eventManager; } /** @@ -98,25 +109,33 @@ class InvoiceSender extends Sender $formattedShippingAddress = ''; } $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); - - $this->templateContainer->setTemplateVars( - [ - 'order' => $order, - 'invoice' => $invoice, - 'comment' => $invoice->getCustomerNoteNotify() ? $invoice->getCustomerNote() : '', - 'billing' => $order->getBillingAddress(), - 'payment_html' => $this->getPaymentHtml($order), - 'store' => $order->getStore(), - 'formattedShippingAddress' => $formattedShippingAddress, - 'formattedBillingAddress' => $formattedBillingAddress + + $transport = new \Magento\Framework\Object( + ['template_vars' => + [ + 'order' => $order, + 'invoice' => $invoice, + 'comment' => $invoice->getCustomerNoteNotify() ? $invoice->getCustomerNote() + : '', + 'billing' => $order->getBillingAddress(), + 'payment_html' => $this->getPaymentHtml($order), + 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress + ] ] ); + $this->eventManager->dispatch( + 'email_invoice_set_template_vars_before', + ['sender' => $this, 'transport' => $transport] + ); + + $this->templateContainer->setTemplateVars($transport->getTemplateVars()); + if ($this->checkAndSend($order)) { $invoice->setEmailSent(true); - $this->invoiceResource->saveAttribute($invoice, ['send_email', 'email_sent']); - return true; } } diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderCommentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderCommentSender.php index 10abfd138dcc392e9e953ef613214bf28949bdb5..64f67cb80ce8f98b8fc07de60fc5a48efeae534e 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderCommentSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderCommentSender.php @@ -10,6 +10,7 @@ use Magento\Sales\Model\Order\Email\Container\OrderCommentIdentity; use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\NotifySender; use Magento\Sales\Model\Order\Address\Renderer; +use Magento\Framework\Event\ManagerInterface; /** * Class OrderCommentSender @@ -21,22 +22,32 @@ class OrderCommentSender extends NotifySender */ protected $addressRenderer; + /** + * Application Event Dispatcher + * + * @var ManagerInterface + */ + protected $eventManager; + /** * @param Template $templateContainer * @param OrderCommentIdentity $identityContainer * @param Order\Email\SenderBuilderFactory $senderBuilderFactory * @param \Psr\Log\LoggerInterface $logger * @param Renderer $addressRenderer + * @param ManagerInterface $eventManager */ public function __construct( Template $templateContainer, OrderCommentIdentity $identityContainer, \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, \Psr\Log\LoggerInterface $logger, - Renderer $addressRenderer + Renderer $addressRenderer, + ManagerInterface $eventManager ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger); $this->addressRenderer = $addressRenderer; + $this->eventManager = $eventManager; } /** @@ -55,16 +66,27 @@ class OrderCommentSender extends NotifySender $formattedShippingAddress = ''; } $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); - $this->templateContainer->setTemplateVars( - [ - 'order' => $order, - 'comment' => $comment, - 'billing' => $order->getBillingAddress(), - 'store' => $order->getStore(), - 'formattedShippingAddress' => $formattedShippingAddress, - 'formattedBillingAddress' => $formattedBillingAddress, + + $transport = new \Magento\Framework\Object( + ['template_vars' => + [ + 'order' => $order, + 'comment' => $comment, + 'billing' => $order->getBillingAddress(), + 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress, + ] ] ); + + $this->eventManager->dispatch( + 'email_order_comment_set_template_vars_before', + ['sender' => $this, 'transport' => $transport] + ); + + $this->templateContainer->setTemplateVars($transport->getTemplateVars()); + return $this->checkAndSend($order, $notify); } } diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php index dc2d544d335bd35b9aa5c81327f272bb2c927872..59c7e404c940a55abd252ae429a572e0d8b45c66 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php @@ -12,9 +12,11 @@ use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\Sender; use Magento\Sales\Model\Resource\Order as OrderResource; use Magento\Sales\Model\Order\Address\Renderer; +use Magento\Framework\Event\ManagerInterface; /** * Class OrderSender + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class OrderSender extends Sender { @@ -40,6 +42,13 @@ class OrderSender extends Sender */ protected $addressRenderer; + /** + * Application Event Dispatcher + * + * @var ManagerInterface + */ + protected $eventManager; + /** * @param Template $templateContainer * @param OrderIdentity $identityContainer @@ -49,6 +58,7 @@ class OrderSender extends Sender * @param OrderResource $orderResource * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig * @param Renderer $addressRenderer + * @param ManagerInterface $eventManager */ public function __construct( Template $templateContainer, @@ -58,13 +68,15 @@ class OrderSender extends Sender PaymentHelper $paymentHelper, OrderResource $orderResource, \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig, - Renderer $addressRenderer + Renderer $addressRenderer, + ManagerInterface $eventManager ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger); $this->paymentHelper = $paymentHelper; $this->orderResource = $orderResource; $this->globalConfig = $globalConfig; $this->addressRenderer = $addressRenderer; + $this->eventManager = $eventManager; } /** @@ -89,9 +101,7 @@ class OrderSender extends Sender if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) { if ($this->checkAndSend($order)) { $order->setEmailSent(true); - $this->orderResource->saveAttribute($order, ['send_email', 'email_sent']); - return true; } } @@ -109,16 +119,26 @@ class OrderSender extends Sender */ protected function prepareTemplate(Order $order) { - $this->templateContainer->setTemplateVars( - [ - 'order' => $order, - 'billing' => $order->getBillingAddress(), - 'payment_html' => $this->getPaymentHtml($order), - 'store' => $order->getStore(), - 'formattedShippingAddress' => $this->addressRenderer->format($order->getShippingAddress(), 'html'), - 'formattedBillingAddress' => $this->addressRenderer->format($order->getBillingAddress(), 'html'), + $transport = new \Magento\Framework\Object( + ['template_vars' => + [ + 'order' => $order, + 'billing' => $order->getBillingAddress(), + 'payment_html' => $this->getPaymentHtml($order), + 'store' => $order->getStore(), + 'formattedShippingAddress' => $this->addressRenderer->format($order->getShippingAddress(), 'html'), + 'formattedBillingAddress' => $this->addressRenderer->format($order->getBillingAddress(), 'html'), + ] ] ); + + $this->eventManager->dispatch( + 'email_order_set_template_vars_before', + ['sender' => $this, 'transport' => $transport] + ); + + $this->templateContainer->setTemplateVars($transport->getTemplateVars()); + parent::prepareTemplate($order); } diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentCommentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentCommentSender.php index 1173cc951fe6455e4ddd0829d6a31e2274b6c7ca..d3555b8240b9a27934f0bbc6144d64db0a2ba563 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentCommentSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentCommentSender.php @@ -11,6 +11,7 @@ use Magento\Sales\Model\Order\Email\Container\Template; use Magento\Sales\Model\Order\Email\NotifySender; use Magento\Sales\Model\Order\Shipment; use Magento\Sales\Model\Order\Address\Renderer; +use Magento\Framework\Event\ManagerInterface; /** * Class ShipmentCommentSender @@ -22,22 +23,32 @@ class ShipmentCommentSender extends NotifySender */ protected $addressRenderer; + /** + * Application Event Dispatcher + * + * @var ManagerInterface + */ + protected $eventManager; + /** * @param Template $templateContainer * @param ShipmentCommentIdentity $identityContainer * @param Order\Email\SenderBuilderFactory $senderBuilderFactory * @param \Psr\Log\LoggerInterface $logger * @param Renderer $addressRenderer + * @param ManagerInterface $eventManager */ public function __construct( Template $templateContainer, ShipmentCommentIdentity $identityContainer, \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, \Psr\Log\LoggerInterface $logger, - Renderer $addressRenderer + Renderer $addressRenderer, + ManagerInterface $eventManager ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger); $this->addressRenderer = $addressRenderer; + $this->eventManager = $eventManager; } /** @@ -57,17 +68,28 @@ class ShipmentCommentSender extends NotifySender $formattedShippingAddress = ''; } $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); - $this->templateContainer->setTemplateVars( - [ - 'order' => $order, - 'shipment' => $shipment, - 'comment' => $comment, - 'billing' => $order->getBillingAddress(), - 'store' => $order->getStore(), - 'formattedShippingAddress' => $formattedShippingAddress, - 'formattedBillingAddress' => $formattedBillingAddress, + + $transport = new \Magento\Framework\Object( + ['template_vars' => + [ + 'order' => $order, + 'shipment' => $shipment, + 'comment' => $comment, + 'billing' => $order->getBillingAddress(), + 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress, + ] ] ); + + $this->eventManager->dispatch( + 'email_shipment_comment_set_template_vars_before', + ['sender' => $this, 'transport' => $transport] + ); + + $this->templateContainer->setTemplateVars($transport->getTemplateVars()); + return $this->checkAndSend($order, $notify); } } diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php index cedd82ae34d6426ed8fff4d60ff9a48565b8ca20..96a62f88588435d2695a8e97c1a466aa161d4986 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php @@ -13,10 +13,11 @@ use Magento\Sales\Model\Order\Email\Sender; use Magento\Sales\Model\Order\Shipment; use Magento\Sales\Model\Resource\Order\Shipment as ShipmentResource; use Magento\Sales\Model\Order\Address\Renderer; +use Magento\Framework\Event\ManagerInterface; /** * Class ShipmentSender - * + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ShipmentSender extends Sender @@ -43,6 +44,13 @@ class ShipmentSender extends Sender */ protected $addressRenderer; + /** + * Application Event Dispatcher + * + * @var ManagerInterface + */ + protected $eventManager; + /** * @param Template $templateContainer * @param ShipmentIdentity $identityContainer @@ -52,6 +60,7 @@ class ShipmentSender extends Sender * @param ShipmentResource $shipmentResource * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig * @param Renderer $addressRenderer + * @param ManagerInterface $eventManager */ public function __construct( Template $templateContainer, @@ -61,13 +70,15 @@ class ShipmentSender extends Sender PaymentHelper $paymentHelper, ShipmentResource $shipmentResource, \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig, - Renderer $addressRenderer + Renderer $addressRenderer, + ManagerInterface $eventManager ) { parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger); $this->paymentHelper = $paymentHelper; $this->shipmentResource = $shipmentResource; $this->globalConfig = $globalConfig; $this->addressRenderer = $addressRenderer; + $this->eventManager = $eventManager; } /** @@ -99,24 +110,33 @@ class ShipmentSender extends Sender } $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html'); - $this->templateContainer->setTemplateVars( - [ - 'order' => $order, - 'shipment' => $shipment, - 'comment' => $shipment->getCustomerNoteNotify() ? $shipment->getCustomerNote() : '', - 'billing' => $order->getBillingAddress(), - 'payment_html' => $this->getPaymentHtml($order), - 'store' => $order->getStore(), - 'formattedShippingAddress' => $formattedShippingAddress, - 'formattedBillingAddress' => $formattedBillingAddress + $transport = new \Magento\Framework\Object( + ['template_vars' => + [ + 'order' => $order, + 'shipment' => $shipment, + 'comment' => $shipment->getCustomerNoteNotify() + ? $shipment->getCustomerNote() + : '', + 'billing' => $order->getBillingAddress(), + 'payment_html' => $this->getPaymentHtml($order), + 'store' => $order->getStore(), + 'formattedShippingAddress' => $formattedShippingAddress, + 'formattedBillingAddress' => $formattedBillingAddress + ] ] ); + $this->eventManager->dispatch( + 'email_shipment_set_template_vars_before', + ['sender' => $this, 'transport' => $transport] + ); + + $this->templateContainer->setTemplateVars($transport->getTemplateVars()); + if ($this->checkAndSend($order)) { $shipment->setEmailSent(true); - $this->shipmentResource->saveAttribute($shipment, ['send_email', 'email_sent']); - return true; } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php index cd70e51424497d16585475b55edaab6d526e7cef..63ef953d756f00967ade66140431bef520989812 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php @@ -62,6 +62,11 @@ abstract class AbstractSenderTest extends \PHPUnit_Framework_TestCase */ protected $addressMock; + /** + * @var \Magento\Framework\Event\Manager | \PHPUnit_Framework_MockObject_MockObject + */ + protected $eventManagerMock; + /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -128,6 +133,7 @@ abstract class AbstractSenderTest extends \PHPUnit_Framework_TestCase $this->addressRenderer = $this->getMock('Magento\Sales\Model\Order\Address\Renderer', [], [], '', false); $this->addressMock = $this->getMock('Magento\Sales\Model\Order\Address', [], [], '', false); + $this->eventManagerMock = $this->getMock('Magento\Framework\Event\Manager', [], [], '', false); $this->paymentHelper = $this->getMock('\Magento\Payment\Helper\Data', ['getInfoBlockHtml'], [], '', false); $this->paymentHelper->expects($this->any()) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php index 977ded72038ee29f205fa6981c1f534dfdae6120..fe968f3f76438091ba4fb4d99e0901c0c1d6ebc1 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php @@ -45,7 +45,8 @@ class CreditmemoCommentSenderTest extends AbstractSenderTest $this->identityContainerMock, $this->senderBuilderFactoryMock, $this->loggerMock, - $this->addressRenderer + $this->addressRenderer, + $this->eventManagerMock ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php index cfe7bfc22e54f51db6edc23e02859488612fd11b..c42216226dae0a6f5fe4df3b75de089ff8229532 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php @@ -73,7 +73,8 @@ class CreditmemoSenderTest extends AbstractSenderTest $this->paymentHelper, $this->creditmemoResourceMock, $this->globalConfig, - $this->addressRenderer + $this->addressRenderer, + $this->eventManagerMock ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php index 30b838341b5ce16a3d733839f911ee1014c2ccfe..4670ec2824ecb03e26ba446871b1cb7e24c0c28d 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php @@ -61,7 +61,8 @@ class InvoiceCommentSenderTest extends AbstractSenderTest $this->identityContainerMock, $this->senderBuilderFactoryMock, $this->loggerMock, - $this->addressRenderer + $this->addressRenderer, + $this->eventManagerMock ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php index 35cb0e84b6566f2e74c0f17f20d918e8a88945a9..8ca7f14f25b291edbd91de51f28540ea4a48c8db 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php @@ -73,7 +73,8 @@ class InvoiceSenderTest extends AbstractSenderTest $this->paymentHelper, $this->invoiceResourceMock, $this->globalConfig, - $this->addressRenderer + $this->addressRenderer, + $this->eventManagerMock ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php index 9bb5745162152cf85610abaa6cd8af1564586c7d..3b7c92d55986fb7f5435f7210c25b0d412b85e5e 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php @@ -24,7 +24,8 @@ class OrderCommentSenderTest extends AbstractSenderTest $this->identityContainerMock, $this->senderBuilderFactoryMock, $this->loggerMock, - $this->addressRenderer + $this->addressRenderer, + $this->eventManagerMock ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php index 5350c1924f023c6055e59eec341cb024acb687ca..7de676a36f9281413f0d008e44de723d0de385f5 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php @@ -50,7 +50,8 @@ class OrderSenderTest extends AbstractSenderTest $this->paymentHelper, $this->orderResourceMock, $this->globalConfig, - $this->addressRenderer + $this->addressRenderer, + $this->eventManagerMock ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php index 0a69bb2fcf85d7eae3c0f0841ee17be8afdd1221..7351b1444b6691440f087a99ed05fdb2db6b00e8 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php @@ -43,7 +43,8 @@ class ShipmentCommentSenderTest extends AbstractSenderTest $this->identityContainerMock, $this->senderBuilderFactoryMock, $this->loggerMock, - $this->addressRenderer + $this->addressRenderer, + $this->eventManagerMock ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php index a13619f0423eaaa9a0f0ee3636c0c999454a0a9c..89fab376003d21eb36bf6c702785584abab2a861 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php @@ -73,7 +73,8 @@ class ShipmentSenderTest extends AbstractSenderTest $this->paymentHelper, $this->shipmentResourceMock, $this->globalConfig, - $this->addressRenderer + $this->addressRenderer, + $this->eventManagerMock ); } diff --git a/app/code/Magento/Sales/composer.json b/app/code/Magento/Sales/composer.json index 482c2576832b49f12c0e42710c10efb31c419643..d975eed1fc1cf27009dcfa90d0ed6bf5603bd535 100644 --- a/app/code/Magento/Sales/composer.json +++ b/app/code/Magento/Sales/composer.json @@ -3,35 +3,35 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-authorization": "0.74.0-beta6", - "magento/module-payment": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/module-sales-rule": "0.74.0-beta6", - "magento/module-sales-sequence": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-widget": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/module-gift-message": "0.74.0-beta6", - "magento/module-reports": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-wishlist": "0.74.0-beta6", - "magento/module-email": "0.74.0-beta6", - "magento/module-shipping": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-ui": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-authorization": "0.74.0-beta7", + "magento/module-payment": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/module-sales-rule": "0.74.0-beta7", + "magento/module-sales-sequence": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-widget": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/module-gift-message": "0.74.0-beta7", + "magento/module-reports": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-wishlist": "0.74.0-beta7", + "magento/module-email": "0.74.0-beta7", + "magento/module-shipping": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-ui": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Sales/view/adminhtml/layout/customer_form.xml b/app/code/Magento/Sales/view/adminhtml/layout/customer_index_edit.xml similarity index 91% rename from app/code/Magento/Sales/view/adminhtml/layout/customer_form.xml rename to app/code/Magento/Sales/view/adminhtml/layout/customer_index_edit.xml index 971cc57cfe03cca7f828c517d5cf674bcdf42377..b5de5df96a33838f520c890d682404ba1cc4e096 100644 --- a/app/code/Magento/Sales/view/adminhtml/layout/customer_form.xml +++ b/app/code/Magento/Sales/view/adminhtml/layout/customer_index_edit.xml @@ -7,7 +7,7 @@ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> <body> - <referenceBlock name="form"> + <referenceBlock name="customer_form"> <block acl="Magento_Sales::actions_view" class="Magento\Sales\Block\Adminhtml\CustomerOrdersTab" name="orders" /> </referenceBlock> </body> diff --git a/app/code/Magento/SalesRule/composer.json b/app/code/Magento/SalesRule/composer.json index 1ef5ba09232d018b9987d406fc67f2ef65af6209..6a4c27c399741ad9c8d74f2e95d2dc64a56b102a 100644 --- a/app/code/Magento/SalesRule/composer.json +++ b/app/code/Magento/SalesRule/composer.json @@ -3,26 +3,26 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-rule": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-shipping": "0.74.0-beta6", - "magento/module-payment": "0.74.0-beta6", - "magento/module-reports": "0.74.0-beta6", - "magento/module-catalog-rule": "0.74.0-beta6", - "magento/module-widget": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-rule": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-shipping": "0.74.0-beta7", + "magento/module-payment": "0.74.0-beta7", + "magento/module-reports": "0.74.0-beta7", + "magento/module-catalog-rule": "0.74.0-beta7", + "magento/module-widget": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/SalesSequence/composer.json b/app/code/Magento/SalesSequence/composer.json index f3c49c8f01143db554c75ed5abdcb14935ab4ef2..1f2fc3c267dbeeb9456e40b567f52d62b98531c2 100644 --- a/app/code/Magento/SalesSequence/composer.json +++ b/app/code/Magento/SalesSequence/composer.json @@ -3,11 +3,11 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Search/composer.json b/app/code/Magento/Search/composer.json index 69bc52ccfec60bd0b606af29e9748896b6eefe32..841e086af01a4f23d31d3a89f134f5833f0921dc 100644 --- a/app/code/Magento/Search/composer.json +++ b/app/code/Magento/Search/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-catalog-search": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-reports": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-catalog-search": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-reports": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Sendfriend/composer.json b/app/code/Magento/Sendfriend/composer.json index 7acd6e8fa3cece61f1c20f06067106d0b5691ba5..b17ea7f73d12b36993340f6884a195ee48417da0 100644 --- a/app/code/Magento/Sendfriend/composer.json +++ b/app/code/Magento/Sendfriend/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Shipping/composer.json b/app/code/Magento/Shipping/composer.json index 54c613d4a0a95d2ab7d0a5eae1435dbfbffa9fff..9a1f9a4a0d0e500376b57cd48b4d615d3e2a6a3a 100644 --- a/app/code/Magento/Shipping/composer.json +++ b/app/code/Magento/Shipping/composer.json @@ -3,27 +3,27 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-contact": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-payment": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-contact": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-payment": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "ext-gd": "*", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-fedex": "0.74.0-beta6", - "magento/module-ups": "0.74.0-beta6" + "magento/module-fedex": "0.74.0-beta7", + "magento/module-ups": "0.74.0-beta7" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json index 1fa5a0e4091d5cbbe06a12b2229f626960b65e15..883491985063302b2fd8b31d42895b9b2df5ccfe 100644 --- a/app/code/Magento/Sitemap/composer.json +++ b/app/code/Magento/Sitemap/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-cms": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-catalog-url-rewrite": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-cms": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-catalog-url-rewrite": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php b/app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php index 57307c083d01246894146ce4e3aa865a172bee20..4d5e21f50edd3273c794c866c5e86d6ebfc8f679 100644 --- a/app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php +++ b/app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php @@ -79,6 +79,7 @@ class RequestPreprocessor $response = $this->_responseFactory->create(); $response->setRedirect($redirectUrl, $redirectCode); + $response->setNoCacheHeaders(); return $response; } } diff --git a/app/code/Magento/Store/Model/Store.php b/app/code/Magento/Store/Model/Store.php index 7dbf046110e38000509cbd55318a57efbc1b80f0..1da41cae73e20593dcdc498b6b4a1bc94bb5a0b6 100644 --- a/app/code/Magento/Store/Model/Store.php +++ b/app/code/Magento/Store/Model/Store.php @@ -755,7 +755,12 @@ class Store extends AbstractModel implements \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); - if (!$secureBaseUrl) { + if (!$secureBaseUrl || + !$this->_config->getValue( + self::XML_PATH_SECURE_IN_FRONTEND, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ) + ) { return false; } diff --git a/app/code/Magento/Store/Model/System/Store.php b/app/code/Magento/Store/Model/System/Store.php index 1859a2957d92f927491aaa33b541d7cab1fa068f..c3382ce1968cf415874b468b6e8126538a75ec9d 100644 --- a/app/code/Magento/Store/Model/System/Store.php +++ b/app/code/Magento/Store/Model/System/Store.php @@ -5,10 +5,12 @@ */ namespace Magento\Store\Model\System; +use Magento\Framework\Data\OptionSourceInterface; + /** * Core System Store Model */ -class Store extends \Magento\Framework\Object +class Store extends \Magento\Framework\Object implements OptionSourceInterface { /** * Website collection @@ -458,4 +460,14 @@ class Store extends \Magento\Framework\Object $this->_isAdminScopeAllowed = (bool)$value; return $this; } + + /** + * Return array of options as value-label pairs + * + * @return array Format: array(array('value' => '<value>', 'label' => '<label>'), ...) + */ + public function toOptionArray() + { + return $this->getStoreValuesForForm(); + } } diff --git a/app/code/Magento/Store/Test/Unit/Model/StoreTest.php b/app/code/Magento/Store/Test/Unit/Model/StoreTest.php index c43af1f004dfe6972d9521e3d49bd6474fb99a4b..e9a6f8ecf7207c03889a4043d02168d18e6e5b72 100644 --- a/app/code/Magento/Store/Test/Unit/Model/StoreTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/StoreTest.php @@ -546,12 +546,15 @@ class StoreTest extends \PHPUnit_Framework_TestCase * * @param bool $expected * @param array $value + * @param bool $requestSecure + * @param bool $useSecureInFrontend * @param string|null $secureBaseUrl */ public function testIsCurrentlySecure( $expected, $value, $requestSecure = false, + $useSecureInFrontend = true, $secureBaseUrl = 'https://example.com:443' ) { /* @var ReinitableConfigInterface|PHPUnit_Framework_MockObject_MockObject $configMock */ @@ -565,6 +568,12 @@ class StoreTest extends \PHPUnit_Framework_TestCase null, $secureBaseUrl ], + [ + Store::XML_PATH_SECURE_IN_FRONTEND, + ScopeInterface::SCOPE_STORE, + null, + $useSecureInFrontend + ] ])); $this->requestMock->expects($this->any()) @@ -594,8 +603,12 @@ class StoreTest extends \PHPUnit_Framework_TestCase return [ 'secure request, no server setting' => [true, [], true], 'unsecure request, using registered port' => [true, 443], - 'unsecure request, no secure base url registered' => [false, 443, false, null], + 'unsecure request, no secure base url registered' => [false, 443, false, true, null], 'unsecure request, not using registered port' => [false, 80], + 'unsecure request, using registered port, not using secure in frontend' => [false, 443, false, false], + 'unsecure request, no secure base url registered, not using secure in frontend' => + [false, 443, false, false, null], + 'unsecure request, not using registered port, not using secure in frontend' => [false, 80, false, false], ]; } diff --git a/app/code/Magento/Store/Ui/DataProvider/Row.php b/app/code/Magento/Store/Ui/Component/Listing/Column/Store.php similarity index 59% rename from app/code/Magento/Store/Ui/DataProvider/Row.php rename to app/code/Magento/Store/Ui/Component/Listing/Column/Store.php index e48e25ca61cba0b95b52af9c35ef079e8952b0db..08b0387396799d9b63b3a2f7f1b0982605a700b8 100644 --- a/app/code/Magento/Store/Ui/DataProvider/Row.php +++ b/app/code/Magento/Store/Ui/Component/Listing/Column/Store.php @@ -3,16 +3,18 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Store\Ui\DataProvider; +namespace Magento\Store\Ui\Component\Listing\Column; use Magento\Framework\Escaper; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponentFactory; use Magento\Store\Model\System\Store as SystemStore; -use Magento\Ui\Component\Listing\RowInterface; +use Magento\Ui\Component\Listing\Columns\Column; /** * Class Store */ -class Row implements RowInterface +class Store extends Column { /** * Escaper @@ -31,26 +33,48 @@ class Row implements RowInterface /** * Constructor * + * @param ContextInterface $context + * @param UiComponentFactory $uiComponentFactory * @param SystemStore $systemStore * @param Escaper $escaper + * @param array $components + * @param array $data */ - public function __construct(SystemStore $systemStore, Escaper $escaper) - { + public function __construct( + ContextInterface $context, + UiComponentFactory $uiComponentFactory, + SystemStore $systemStore, + Escaper $escaper, + array $components = [], + array $data = [] + ) { $this->systemStore = $systemStore; $this->escaper = $escaper; + parent::__construct($context, $uiComponentFactory, $components, $data); + } + + /** + * @param array $items + * @return array + */ + public function prepareItems(array & $items) + { + foreach ($items as & $item) { + $item[$this->getData('name')] = $this->prepareItem($item); + } + return $items; } /** * Get data * - * @param array $dataRow - * @param array $data + * @param array $item * @return mixed */ - public function getData(array $dataRow, array $data = []) + public function prepareItem(array $item) { $content = ''; - $origStores = $dataRow['store_id']; + $origStores = $item['store_id']; if (empty($origStores)) { return ''; diff --git a/app/code/Magento/Store/Ui/DataProvider/Options.php b/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php similarity index 80% rename from app/code/Magento/Store/Ui/DataProvider/Options.php rename to app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php index 950f5bbb606932f456bbeccf859580d3af187639..308a21b9f3100446ae33487823ae10e73ffcc2e6 100644 --- a/app/code/Magento/Store/Ui/DataProvider/Options.php +++ b/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php @@ -3,16 +3,16 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Store\Ui\DataProvider; +namespace Magento\Store\Ui\Component\Listing\Column\Store; use Magento\Framework\Escaper; +use Magento\Framework\Data\OptionSourceInterface; use Magento\Store\Model\System\Store as SystemStore; -use Magento\Ui\Component\Listing\OptionsInterface; /** - * Class Store + * Class Options */ -class Options implements OptionsInterface +class Options implements OptionSourceInterface { /** * Escaper @@ -28,6 +28,11 @@ class Options implements OptionsInterface */ protected $systemStore; + /** + * @var array + */ + protected $options; + /** * Constructor * @@ -43,11 +48,13 @@ class Options implements OptionsInterface /** * Get options * - * @param array $options * @return array */ - public function getOptions(array $options = []) + public function toOptionArray() { + if ($this->options !== null) { + return $this->options; + } $websiteCollection = $this->systemStore->getWebsiteCollection(); $groupCollection = $this->systemStore->getGroupCollection(); $storeCollection = $this->systemStore->getStoreCollection(); @@ -76,17 +83,18 @@ class Options implements OptionsInterface if (!empty($stores)) { $name = $this->escaper->escapeHtml($group->getName()); $groups[$name]['label'] = str_repeat(' ', 4) . $name; - $groups[$name]['value'] = $stores; + $groups[$name]['value'] = array_values($stores); } } } if (!empty($groups)) { $name = $this->escaper->escapeHtml($website->getName()); $currentOptions[$name]['label'] = $name; - $currentOptions[$name]['value'] = $groups; + $currentOptions[$name]['value'] = array_values($groups); } } + $this->options = array_values($currentOptions); - return array_merge_recursive($currentOptions, $options); + return $this->options; } } diff --git a/app/code/Magento/Store/Ui/DataType/Store.php b/app/code/Magento/Store/Ui/DataType/Store.php deleted file mode 100644 index 906ecaa02921f6a8e8ceef2d33074296c88bffcb..0000000000000000000000000000000000000000 --- a/app/code/Magento/Store/Ui/DataType/Store.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Store\Ui\DataType; - -use Magento\Ui\Component\Form\Element\DataType\AbstractDataType; - -/** - * Class Store - */ -class Store extends AbstractDataType -{ - // -} diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json index d2c3e97181c1e980a0406709dd6c35b74a84a344..2dd66eda7c2112a897d68317d093fa5b0e9fe783 100644 --- a/app/code/Magento/Store/composer.json +++ b/app/code/Magento/Store/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-directory": "0.74.0-beta6", - "magento/module-ui": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-directory": "0.74.0-beta7", + "magento/module-ui": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Store/view/base/layout/ui_components.xml b/app/code/Magento/Store/view/base/layout/ui_components.xml deleted file mode 100644 index 54811dfdf1f4035178f5a1aee01ba34923527b28..0000000000000000000000000000000000000000 --- a/app/code/Magento/Store/view/base/layout/ui_components.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd"> - <block class="Magento\Ui\Component\Filter\Type\Select" name="filter_store"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::filter/type/select/default.phtml</argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Form\Element\DataType\Text" name="store"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::data_type/text/default.phtml</argument> - </arguments> - </block> -</layout> diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json index 27b9422635e75187471b290bb89d920fa9ccb1c5..dd35c3d1f65c9f9890e939efa1acbc2c5022fb64 100644 --- a/app/code/Magento/Tax/composer.json +++ b/app/code/Magento/Tax/composer.json @@ -3,23 +3,23 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-config": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-shipping": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-reports": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-config": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-shipping": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-reports": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/TaxImportExport/composer.json b/app/code/Magento/TaxImportExport/composer.json index 334b8652a6d74ed73e037f5d001b62026444bac6..fd4d50bebb33888f1c8593d8772cca8af776b430 100644 --- a/app/code/Magento/TaxImportExport/composer.json +++ b/app/code/Magento/TaxImportExport/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-tax": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-tax": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json index cb64d49d6d2dae6c61f64b767b8fa2f2a895544f..fd23ba6ec42b957d3ff80683883ca990f4d9e14c 100644 --- a/app/code/Magento/Theme/composer.json +++ b/app/code/Magento/Theme/composer.json @@ -3,23 +3,23 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-cms": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-widget": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/module-media-storage": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-require-js": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-cms": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-widget": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/module-media-storage": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-require-js": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-translation": "0.74.0-beta6" + "magento/module-translation": "0.74.0-beta7" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js index 1c0d89ba473ef4811fe74cd4426863369b99dea8..251c057d689f12e75e85991ed46d8b0e2faee673 100644 --- a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js +++ b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js @@ -46,7 +46,8 @@ var config = { }, "deps": [ "js/theme", - "mage/backend/bootstrap" + "mage/backend/bootstrap", + "mage/adminhtml/globals" ], "paths": { "jquery/ui": "jquery/jquery-ui-1.9.2" diff --git a/app/code/Magento/Theme/view/base/requirejs-config.js b/app/code/Magento/Theme/view/base/requirejs-config.js index 637568a9c357ce6fe69cc80017903ec2e6e6e5a8..58dbd2b841a664e48e1cf98ba8d6bf73a5d40189 100644 --- a/app/code/Magento/Theme/view/base/requirejs-config.js +++ b/app/code/Magento/Theme/view/base/requirejs-config.js @@ -5,6 +5,11 @@ var config = { "waitSeconds": 0, + "map": { + "*": { + "mageUtils": "mage/utils/main" + } + }, "shim": { "jquery/jquery-migrate": ["jquery"], "jquery/jquery.hashchange": ["jquery", "jquery/jquery-migrate"], diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json index 4b817066e92d7a9cccc5efbc1d2909409c383f0a..4a91a1055361628c26e0dd6c961f26925cc699c2 100644 --- a/app/code/Magento/Translation/composer.json +++ b/app/code/Magento/Translation/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-backend": "0.74.0-beta6", - "magento/module-developer": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-backend": "0.74.0-beta7", + "magento/module-developer": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Ui/Component/AbstractComponent.php b/app/code/Magento/Ui/Component/AbstractComponent.php new file mode 100644 index 0000000000000000000000000000000000000000..152b025cfc003da954e17ad9688db719d213cb37 --- /dev/null +++ b/app/code/Magento/Ui/Component/AbstractComponent.php @@ -0,0 +1,261 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component; + +use Magento\Framework\Object; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponent\JsConfigInterface; +use Magento\Framework\View\Element\UiComponent\DataSourceInterface; + +/** + * Abstract class AbstractComponent + * @SuppressWarnings(PHPMD.NumberOfChildren) + */ +abstract class AbstractComponent extends Object implements UiComponentInterface, JsConfigInterface +{ + /** + * Render context + * + * @var ContextInterface + */ + protected $context; + + /** + * @var UiComponentInterface[] + */ + protected $components; + + /** + * @var array + */ + protected $componentData = []; + + /** + * Constructor + * + * @param ContextInterface $context + * @param UiComponentInterface[] $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + array $components = [], + array $data = [] + ) { + $this->context = $context; + $this->components = $components; + parent::__construct($data); + } + + /** + * Get component context + * + * @return ContextInterface + */ + public function getContext() + { + return $this->context; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + // + } + + /** + * Produce and return block's html output + * + * @return string + */ + public function toHtml() + { + $this->render(); + } + + /** + * Render component + * + * @return string + */ + public function render() + { + $result = $this->getContext()->getRenderEngine()->render($this, $this->getTemplate()); + return $result; + } + + /** + * Get component name + * + * @return string + */ + public function getName() + { + return $this->getData('name'); + } + + /** + * Add component + * + * @param string $name + * @param UiComponentInterface $component + * @return void + */ + public function addComponent($name, UiComponentInterface $component) + { + $this->components[$name] = $component; + } + + /** + * @param string $name + * @return UiComponentInterface + */ + public function getComponent($name) + { + return isset($this->components[$name]) ? $this->components[$name] : null; + } + + /** + * Get components + * + * @return UiComponentInterface[] + */ + public function getChildComponents() + { + return $this->components; + } + + /** + * Get template + * + * @return string + */ + public function getTemplate() + { + return $this->getData('template') . '.xhtml'; + } + + /** + * Render child component + * + * @param string $name + * @return string + */ + public function renderChildComponent($name) + { + $result = null; + if (isset($this->components[$name])) { + $result = $this->components[$name]->render(); + } + return $result; + } + + /** + * Component data setter + * + * @param string|array $key + * @param mixed $value + * @return void + */ + public function setData($key, $value = null) + { + parent::setData($key, $value); + } + + /** + * Component data getter + * + * @param string $key + * @param string|int $index + * @return mixed + */ + public function getData($key = '', $index = null) + { + return parent::getData($key, $index); + } + + /** + * Set component configuration + * + * @return void + */ + protected function prepareConfiguration() + { + $config = $this->getDefaultConfiguration(); + if ($this->hasData('config')) { + $config = array_replace_recursive($config, $this->getData('config')); + } + + $this->setData('config', $config); + } + + /** + * Get default parameters + * + * @return array + */ + protected function getDefaultConfiguration() + { + return []; + } + + /** + * Get JS configuration + * + * @param UiComponentInterface $component + * @param null|string $extends + * @return array + */ + protected function getConfiguration(UiComponentInterface $component, $extends = null) + { + $jsConfig = (array) $component->getData('js_config'); + if (isset($jsConfig['extends'])) { + return $jsConfig; + } else if (null !== $extends) { + $jsConfig['extends'] = $extends; + } else { + $jsConfig['extends'] = $component->getContext()->getNamespace(); + } + + return $jsConfig; + } + + /** + * Get JS config + * + * @return array|string + */ + public function getJsConfig() + { + return (array) $this->getData('config'); + } + + /** + * @return array + */ + public function getDataSourceData() + { + $dataSources = []; + foreach ($this->getChildComponents() as $component) { + if ($component instanceof DataSourceInterface) { + $dataSources[] = [ + 'type' => $component->getComponentName(), + 'name' => $component->getName(), + 'dataScope' => $component->getContext()->getNamespace(), + 'config' => [ + 'data' => $component->getDataProvider()->getData() + ] + ]; + } + } + return $dataSources; + } +} diff --git a/app/code/Magento/Ui/Component/AbstractView.php b/app/code/Magento/Ui/Component/AbstractView.php deleted file mode 100644 index e67d0e1ff40ee6b3182c77bebb844c143fa8a84c..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/AbstractView.php +++ /dev/null @@ -1,375 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component; - -use Magento\Framework\View\Asset\Repository; -use Magento\Framework\View\Element\Template; -use Magento\Framework\View\Element\Template\Context as TemplateContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigFactory; -use Magento\Framework\View\Element\UiComponent\ConfigInterface; -use Magento\Framework\View\Element\UiComponent\Context; -use Magento\Framework\View\Element\UiComponentInterface; -use Magento\Ui\ContentType\ContentTypeFactory; -use Magento\Ui\DataProvider\Factory as DataProviderFactory; -use Magento\Ui\DataProvider\Manager; - -/** - * Abstract class AbstractView - * @SuppressWarnings(PHPMD.NumberOfChildren) - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -abstract class AbstractView extends Template implements UiComponentInterface -{ - /** - * Config builder - * - * @var ConfigBuilderInterface - */ - protected $configBuilder; - - /** - * View configuration data - * - * @var ConfigInterface - */ - protected $config; - - /** - * Render context - * - * @var Context - */ - protected $renderContext; - - /** - * Config factory - * - * @var ConfigFactory - */ - protected $configFactory; - - /** - * Content type factory - * - * @var ContentTypeFactory - */ - protected $contentTypeFactory; - - /** - * Asset service - * - * @var Repository - */ - protected $assetRepo; - - /** - * Data provider factory - * - * @var DataProviderFactory - */ - protected $dataProviderFactory; - - /** - * @var \Magento\Ui\DataProvider\Manager - */ - protected $dataManager; - - /** - * Elements for the render - * - * @var ElementRendererInterface[] - */ - protected $elements = []; - - /** - * Constructor - * - * @param TemplateContext $context - * @param Context $renderContext - * @param ContentTypeFactory $contentTypeFactory - * @param ConfigFactory $configFactory - * @param ConfigBuilderInterface $configBuilder - * @param DataProviderFactory $dataProviderFactory - * @param Manager $dataProviderManager - * @param array $data - */ - public function __construct( - TemplateContext $context, - Context $renderContext, - ContentTypeFactory $contentTypeFactory, - ConfigFactory $configFactory, - ConfigBuilderInterface $configBuilder, - DataProviderFactory $dataProviderFactory, - Manager $dataProviderManager, - array $data = [] - ) { - $this->renderContext = $renderContext; - $this->contentTypeFactory = $contentTypeFactory; - $this->assetRepo = $context->getAssetRepository(); - $this->configFactory = $configFactory; - $this->configBuilder = $configBuilder; - $this->dataProviderFactory = $dataProviderFactory; - $this->dataManager = $dataProviderManager; - parent::__construct($context, $data); - } - - /** - * Update data - * - * @param array $data - * @return void - */ - public function update(array $data = []) - { - if (!empty($data)) { - $this->_data = array_merge_recursive($this->_data, $data); - } - } - - /** - * Prepare component data - * - * @return void - */ - public function prepare() - { - // - } - - /** - * Render content - * - * @param array $data - * @return string - */ - public function render(array $data = []) - { - $prevData = $this->getData(); - $this->update($data); - - $renderResult = $this->contentTypeFactory->get($this->renderContext->getAcceptType()) - ->render($this, $this->getContentTemplate()); - - $this->setData($prevData); - - return $renderResult; - } - - /** - * Render label - * - * @return mixed|string - */ - public function renderLabel() - { - return $this->contentTypeFactory->get($this->renderContext->getAcceptType()) - ->render($this, $this->getLabelTemplate()); - } - - /** - * Render element - * - * @param string $elementName - * @param array $arguments - * @return mixed|string - */ - public function renderElement($elementName, array $arguments) - { - $element = $this->renderContext->getRender()->getUiElementView($elementName); - $result = $element->render($arguments); - return $result; - } - - /** - * Render component label - * - * @param string $elementName - * @param array $arguments - * @return string - */ - public function renderElementLabel($elementName, array $arguments) - { - $element = $this->renderContext->getRender()->getUiElementView($elementName); - $prevData = $element->getData(); - $element->update($arguments); - $result = $element->renderLabel(); - $element->setData($prevData); - return $result; - } - - /** - * Shortcut for rendering as HTML - * (used for backward compatibility with standard rendering mechanism via layout interface) - * - * @return string - */ - public function toHtml() - { - return $this->render(); - } - - /** - * Getting label template - * - * @return string|false - */ - public function getLabelTemplate() - { - return 'Magento_Ui::label/default.phtml'; - } - - /** - * Getting content template - * - * @return string|false - */ - public function getContentTemplate() - { - return $this->getData('content_template'); - } - - /** - * Get Layout Node - * - * @param string $fullName - * @param mixed $default - * @return array - */ - public function getLayoutElement($fullName, $default = null) - { - return $this->renderContext->getStorage()->getLayoutNode($fullName, $default); - } - - /** - * Get name component instance - * - * @return string - */ - public function getName() - { - return $this->config->getName(); - } - - /** - * Get parent name component instance - * - * @return string - */ - public function getParentName() - { - return $this->config->getParentName(); - } - - /** - * Get configuration builder - * - * @return ConfigBuilderInterface - */ - public function getConfigBuilder() - { - return $this->configBuilder; - } - - /** - * Set component configuration - * - * @param null $configData - * @param null $name - * @param null $parentName - * @return void - */ - public function prepareConfiguration($configData = null, $name = null, $parentName = null) - { - $arguments = []; - $arguments['name'] = $name ?: $this->renderContext->getNamespace() . '_' . $this->getNameInLayout(); - $arguments['parentName'] = $parentName ?: $this->renderContext->getNamespace(); - if ($configData) { - $arguments['configuration'] = $configData; - } - $this->config = $this->configFactory->create($arguments); - $this->renderContext->getStorage()->addComponentsData($this->config); - } - - /** - * Get component configuration - * - * @return ConfigInterface - */ - public function getConfig() - { - return $this->config; - } - - /** - * Get render context - * - * @return Context - */ - public function getRenderContext() - { - return $this->renderContext; - } - - /** - * Get elements to the render - * - * @return ElementRendererInterface[] - */ - public function getElements() - { - return $this->elements; - } - - /** - * Set elements for the render - * - * @param ElementRendererInterface[] $elements - * @return mixed|void - */ - public function setElements(array $elements) - { - $this->elements = $elements; - } - - /** - * Get default parameters - * - * @return array - */ - protected function getDefaultConfiguration() - { - return []; - } - - /** - * Get render engine - * - * @return \Magento\Ui\ContentType\ContentTypeInterface - */ - protected function getRenderEngine() - { - return $this->contentTypeFactory->get($this->renderContext->getAcceptType()); - } - - /** - * Create data provider - * - * @return void - */ - protected function createDataProviders() - { - if ($this->hasData('data_provider_pool')) { - foreach ($this->getData('data_provider_pool') as $name => $config) { - $arguments = empty($config['arguments']) ? [] : $config['arguments']; - $arguments['params'] = $this->renderContext->getRequestParams(); - - $dataProvider = $this->dataProviderFactory->create($config['class'], $arguments); - $this->renderContext->getStorage()->addDataProvider($name, $dataProvider); - } - } - } -} diff --git a/app/code/Magento/Ui/Component/Container.php b/app/code/Magento/Ui/Component/Container.php new file mode 100644 index 0000000000000000000000000000000000000000..84e86a9fd58cafb876e9b41fbf46dc6405896fee --- /dev/null +++ b/app/code/Magento/Ui/Component/Container.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component; + +/** + * Class Container + */ +class Container extends AbstractComponent +{ + const NAME = 'container'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + $type = $this->getData('type'); + return static::NAME . (!empty($type) ? '.' . $type : ''); + } + + /** + * Register component + * + * @return void + */ + public function prepare() + { + parent::prepare(); + + $jsConfig = $this->getConfiguration($this); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } +} diff --git a/app/code/Magento/Ui/Component/Container/Content.php b/app/code/Magento/Ui/Component/Container/Content.php deleted file mode 100644 index 94c43012e2eac05b4bfae9422461a0be23d1017a..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Container/Content.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Container; - -use Magento\Ui\Component\AbstractView; - -/** - * Class Content - */ -class Content extends AbstractView -{ - /** - * Prepare component data - * - * @return $this|void - */ - public function prepare() - { - $configData = $this->getDefaultConfiguration(); - if ($this->hasData('config')) { - $configData = array_merge($configData, $this->getData('config')); - } - - $this->prepareConfiguration($configData); - } -} diff --git a/app/code/Magento/Ui/Component/Control/Action.php b/app/code/Magento/Ui/Component/Control/Action.php index 5021b8f7c481789233e9135655101b9e08a597e8..8f19a3b84e739d254e66da779aa1443701d66a60 100644 --- a/app/code/Magento/Ui/Component/Control/Action.php +++ b/app/code/Magento/Ui/Component/Control/Action.php @@ -5,11 +5,23 @@ */ namespace Magento\Ui\Component\Control; -use Magento\Ui\Component\AbstractView; +use Magento\Ui\Component\AbstractComponent; +use Magento\Framework\View\Element\UiComponent\Control\ControlInterface; /** * Class Action */ -class Action extends AbstractView implements ControlInterface +class Action extends AbstractComponent implements ControlInterface { + const NAME = 'action'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } } diff --git a/app/code/Magento/Ui/Component/Control/ActionPool.php b/app/code/Magento/Ui/Component/Control/ActionPool.php index 97f5afdba9ed14cf1135cbd2f3e95caa436c764a..74f327fec1531089563d850815d93ad1bdbfc351 100644 --- a/app/code/Magento/Ui/Component/Control/ActionPool.php +++ b/app/code/Magento/Ui/Component/Control/ActionPool.php @@ -5,8 +5,11 @@ */ namespace Magento\Ui\Component\Control; +use Magento\Framework\View\Element\AbstractBlock; +use Magento\Framework\View\Element\BlockInterface; use Magento\Framework\View\Element\UiComponent\Context; use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\Control\ActionPoolInterface; /** * Class ActionPool @@ -40,7 +43,7 @@ class ActionPool implements ActionPoolInterface protected $itemFactory; /** - * @var \Magento\Framework\View\Element\AbstractBlock + * @var AbstractBlock */ protected $toolbarBlock; @@ -54,8 +57,18 @@ class ActionPool implements ActionPoolInterface { $this->context = $context; $this->itemFactory = $itemFactory; - $this->toolbarBlock = $this->context->getPageLayout() - ? $this->context->getPageLayout()->getBlock(static::ACTIONS_PAGE_TOOLBAR) : false; + } + + /** + * Get toolbar block + * + * @return bool|BlockInterface + */ + public function getToolbar() + { + return $this->context->getPageLayout() + ? $this->context->getPageLayout()->getBlock(static::ACTIONS_PAGE_TOOLBAR) + : false; } /** @@ -63,18 +76,19 @@ class ActionPool implements ActionPoolInterface * * @param string $key * @param array $data - * @param UiComponentInterface $view + * @param UiComponentInterface $component * @return void */ - public function add($key, array $data, UiComponentInterface $view) + public function add($key, array $data, UiComponentInterface $component) { $data['id'] = isset($data['id']) ? $data['id'] : $key; - if ($this->toolbarBlock !== false) { + $toolbar = $this->getToolbar(); + if ($toolbar !== false) { $this->items[$key] = $this->itemFactory->create(); $this->items[$key]->setData($data); - $container = $this->createContainer($key, $view); - $this->toolbarBlock->setChild($key, $container); + $container = $this->createContainer($key, $component); + $toolbar->setChild($key, $container); } } @@ -108,7 +122,7 @@ class ActionPool implements ActionPoolInterface * * @param string $key * @param UiComponentInterface $view - * @return \Magento\Ui\Component\Control\Container + * @return Container */ protected function createContainer($key, UiComponentInterface $view) { @@ -122,6 +136,7 @@ class ActionPool implements ActionPoolInterface ] ] ); + return $container; } } diff --git a/app/code/Magento/Ui/Component/Control/Button.php b/app/code/Magento/Ui/Component/Control/Button.php index 51c839b14b2a8dc0592503a6df0619205e682e61..404bbf04bd4484287cdaa4dc63291242792b93ad 100644 --- a/app/code/Magento/Ui/Component/Control/Button.php +++ b/app/code/Magento/Ui/Component/Control/Button.php @@ -6,11 +6,12 @@ namespace Magento\Ui\Component\Control; use Magento\Framework\View\Element\Template; +use Magento\Framework\View\Element\UiComponent\Control\ControlInterface; /** * Class Button */ -class Button extends Template +class Button extends Template implements ControlInterface { /** * Define block template @@ -72,7 +73,7 @@ class Button extends Template } else { $url = $this->hasData('url') ? $this->getData('url') : $this->getUrl(); if (!empty($url)) { - return sprintf("setLocation('%s');", $url); + return sprintf("location.href = '%s';", $url); } return null; diff --git a/app/code/Magento/Ui/Component/Control/Container.php b/app/code/Magento/Ui/Component/Control/Container.php index b4da5f6740eeddc3cc4a7c54b0c17c30eccf709f..2873e2618a168279d231b701a7007afec8de96ca 100644 --- a/app/code/Magento/Ui/Component/Control/Container.php +++ b/app/code/Magento/Ui/Component/Control/Container.php @@ -6,6 +6,7 @@ namespace Magento\Ui\Component\Control; use Magento\Framework\View\Element\AbstractBlock; +use Magento\Framework\View\Element\UiComponent\Control\ControlInterface; /** * Class Container @@ -15,19 +16,19 @@ class Container extends AbstractBlock /** * Default button class */ - const DEFAULT_BUTTON = 'Magento\Ui\Component\Control\Button'; + const DEFAULT_CONTROL = 'Magento\Ui\Component\Control\Button'; /** * Create button renderer * * @param string $blockName * @param string $blockClassName - * @return \Magento\Ui\Component\Control\Button + * @return ControlInterface */ protected function createButton($blockName, $blockClassName = null) { if (null === $blockClassName) { - $blockClassName = static::DEFAULT_BUTTON; + $blockClassName = static::DEFAULT_CONTROL; } return $this->getLayout()->createBlock($blockClassName, $blockName); @@ -40,7 +41,7 @@ class Container extends AbstractBlock */ protected function _toHtml() { - /** @var \Magento\Ui\Component\Control\Item $item */ + /** @var Item $item */ $item = $this->getButtonItem(); $data = $item->getData(); diff --git a/app/code/Magento/Ui/Component/Control/ControlInterface.php b/app/code/Magento/Ui/Component/Control/ControlInterface.php deleted file mode 100644 index 6949ff096573b1045cccae62f42fd9e37e78e42a..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Control/ControlInterface.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Control; - -use Magento\Framework\View\Element\UiComponentInterface; - -/** - * Interface ControlInterface - */ -interface ControlInterface extends UiComponentInterface -{ - // -} diff --git a/app/code/Magento/Ui/Component/Control/Link.php b/app/code/Magento/Ui/Component/Control/Link.php index cdc3c166322a00249d6abd9f4d368246460e164b..ce99dc5064789af0ae33309505f9d9a4c469458f 100644 --- a/app/code/Magento/Ui/Component/Control/Link.php +++ b/app/code/Magento/Ui/Component/Control/Link.php @@ -5,12 +5,23 @@ */ namespace Magento\Ui\Component\Control; -use Magento\Ui\Component\AbstractView; +use Magento\Ui\Component\AbstractComponent; +use Magento\Framework\View\Element\UiComponent\Control\ControlInterface; /** * Class Link */ -class Link extends AbstractView implements ControlInterface +class Link extends AbstractComponent implements ControlInterface { - // + const NAME = 'link'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } } diff --git a/app/code/Magento/Ui/Component/DataSource.php b/app/code/Magento/Ui/Component/DataSource.php new file mode 100644 index 0000000000000000000000000000000000000000..5f50643d73628e55cf5879094b277b1ee019f8b6 --- /dev/null +++ b/app/code/Magento/Ui/Component/DataSource.php @@ -0,0 +1,80 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component; + +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponent\DataSourceInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; + +/** + * Class DataSource + */ +class DataSource extends AbstractComponent implements DataSourceInterface +{ + const NAME = 'dataSource'; + + /** + * @var DataProviderInterface + */ + protected $dataProvider; + + /** + * Constructor + * + * @param ContextInterface $context + * @param DataProviderInterface $dataProvider + * @param array $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + DataProviderInterface $dataProvider, + array $components = [], + array $data = [] + ) { + $this->dataProvider = $dataProvider; + $context->setDataProvider($dataProvider); + parent::__construct($context, $components, $data); + } + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + + $config = $this->getData('config'); + if (isset($config['update_url'])) { + $config['update_url'] = $this->getContext()->getUrl($config['update_url']); + $this->setData('config', $config); + } + + $jsConfig = $this->getConfiguration($this); + unset($jsConfig['extends']); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + + /** + * @return DataProviderInterface + */ + public function getDataProvider() + { + return $this->dataProvider; + } +} diff --git a/app/code/Magento/Ui/Component/ElementRenderer.php b/app/code/Magento/Ui/Component/ElementRenderer.php deleted file mode 100644 index 3d3e2857aa61b447c97b82a24c209e79afa9c7a3..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/ElementRenderer.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component; - -use Magento\Framework\View\Element\UiComponentInterface; - -/** - * Class ElementRenderer - */ -class ElementRenderer implements ElementRendererInterface -{ - /** - * Ui component - * - * @var UiComponentInterface - */ - protected $element; - - /** - * Data to render - * - * @var array - */ - protected $data; - - /** - * Constructor - * - * @param UiComponentInterface $element - * @param array $data - */ - public function __construct(UiComponentInterface $element, array $data) - { - $this->element = $element; - $this->data = $data; - } - - /** - * Render element - * - * @return string - */ - public function render() - { - return $this->element->render($this->data); - } -} diff --git a/app/code/Magento/Ui/Component/ElementRendererBuilder.php b/app/code/Magento/Ui/Component/ElementRendererBuilder.php deleted file mode 100644 index 4672866fc6299fa081258443d9bc149a4e2a733e..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/ElementRendererBuilder.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component; - -use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\View\Element\UiComponentInterface; - -/** - * Class ElementRendererBuilder - */ -class ElementRendererBuilder -{ - /** - * Object manager - * - * @var ObjectManagerInterface - */ - protected $objectManager; - - /** - * Instance class name - * - * @var string - */ - protected $instanceClass = 'Magento\Ui\Component\ElementRenderer'; - - /** - * Constructor - * - * @param ObjectManagerInterface $objectManager - */ - public function __construct(ObjectManagerInterface $objectManager) - { - $this->objectManager = $objectManager; - } - - /** - * Create element to the render - * - * @param UiComponentInterface $element - * @param array $renderData - * @return ElementRendererInterface - */ - public function create(UiComponentInterface $element, array $renderData) - { - return $this->objectManager->create($this->instanceClass, ['element' => $element, 'data' => $renderData]); - } -} diff --git a/app/code/Magento/Ui/Component/ElementRendererInterface.php b/app/code/Magento/Ui/Component/ElementRendererInterface.php deleted file mode 100644 index 2cffde7c864654a4d2618b43af648084eed71127..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/ElementRendererInterface.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component; - -/** - * Interface ElementRendererInterface - */ -interface ElementRendererInterface -{ - /** - * Render element - * - * @return string - */ - public function render(); -} diff --git a/app/code/Magento/Ui/Component/Filter/FilterAbstract.php b/app/code/Magento/Ui/Component/Filter/FilterAbstract.php deleted file mode 100644 index 0da2dc77f3ea2631b28e9bd16e958e9f426af660..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Filter/FilterAbstract.php +++ /dev/null @@ -1,97 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Filter; - -use Magento\Framework\View\Element\Template\Context as TemplateContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigFactory; -use Magento\Framework\View\Element\UiComponent\Context; -use Magento\Ui\Component\AbstractView; -use Magento\Ui\Component\Filter\FilterPool as FilterPoolProvider; -use Magento\Ui\ContentType\ContentTypeFactory; -use Magento\Ui\DataProvider\Factory as DataProviderFactory; -use Magento\Ui\DataProvider\Manager; - -/** - * Class Filter - */ -abstract class FilterAbstract extends AbstractView implements FilterInterface -{ - /** - * Filter variable name - */ - const FILTER_VAR = 'filter'; - - /** - * Filters pool - * - * @var FilterPoolProvider - */ - protected $filterPool; - - /** - * Constructor - * - * @param TemplateContext $context - * @param Context $renderContext - * @param ContentTypeFactory $contentTypeFactory - * @param ConfigFactory $configFactory - * @param ConfigBuilderInterface $configBuilder - * @param FilterPoolProvider $filterPool - * @param DataProviderFactory $dataProviderFactory - * @param Manager $dataProviderManager - * @param array $data - */ - public function __construct( - TemplateContext $context, - Context $renderContext, - ContentTypeFactory $contentTypeFactory, - ConfigFactory $configFactory, - ConfigBuilderInterface $configBuilder, - DataProviderFactory $dataProviderFactory, - Manager $dataProviderManager, - FilterPoolProvider $filterPool, - array $data = [] - ) { - $this->filterPool = $filterPool; - parent::__construct( - $context, - $renderContext, - $contentTypeFactory, - $configFactory, - $configBuilder, - $dataProviderFactory, - $dataProviderManager, - $data - ); - } - - /** - * Prepare component data - * - * @return void - */ - public function prepare() - { - $configData = $this->getDefaultConfiguration(); - if ($this->hasData('config')) { - $configData = array_merge($configData, $this->getData('config')); - } - - $this->prepareConfiguration($configData); - } - - /** - * Get condition by data type - * - * @param string|array $value - * @return array|null - */ - public function getCondition($value) - { - return $value; - } -} diff --git a/app/code/Magento/Ui/Component/Filter/FilterInterface.php b/app/code/Magento/Ui/Component/Filter/FilterInterface.php deleted file mode 100644 index aa1ccfe73e37b2568da3ea5e841be2aec6a89afe..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Filter/FilterInterface.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Filter; - - -/** - * Interface FilterInterface - */ -interface FilterInterface -{ - /** - * Get condition by data type - * - * @param string|array $value - * @return array|null - */ - public function getCondition($value); -} diff --git a/app/code/Magento/Ui/Component/Filter/FilterPool.php b/app/code/Magento/Ui/Component/Filter/FilterPool.php deleted file mode 100644 index 40d15a2c69d524a874fa9703df4db6e27c8dae20..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Filter/FilterPool.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Filter; - -use Magento\Framework\ObjectManagerInterface; - -/** - * Class FilterPool - */ -class FilterPool -{ - /** - * Filter types - * - * @var array - */ - protected $filterTypes = []; - - /** - * Filters poll - * - * @var FilterInterface[] - */ - protected $filters = []; - - /** - * @var ObjectManagerInterface - */ - protected $objectManager; - - /** - * Constructor - * - * @param ObjectManagerInterface $objectManager - * @param array $filters - */ - public function __construct(ObjectManagerInterface $objectManager, array $filters = []) - { - $this->objectManager = $objectManager; - $this->filterTypes = $filters; - } - - /** - * Get filter by type - * - * @param string $filterName - * @return FilterInterface - * @throws \InvalidArgumentException - */ - public function getFilter($filterName) - { - if (!isset($this->filters[$filterName])) { - if (!isset($this->filterTypes[$filterName])) { - throw new \InvalidArgumentException(sprintf('Unknown filter type "%s"', $filterName)); - } - $this->filters[$filterName] = $this->objectManager->create($this->filterTypes[$filterName]); - } - - return $this->filters[$filterName]; - } -} diff --git a/app/code/Magento/Ui/Component/Filter/Type/Date.php b/app/code/Magento/Ui/Component/Filter/Type/Date.php deleted file mode 100644 index 90b7e16a4aeeb16e7d70fa2a4da2663a0f4df92e..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Filter/Type/Date.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Filter\Type; - -use Magento\Framework\Locale\ResolverInterface; -use Magento\Framework\View\Element\Template\Context as TemplateContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigFactory; -use Magento\Framework\View\Element\UiComponent\Context; -use Magento\Ui\Component\Filter\FilterAbstract; -use Magento\Ui\Component\Filter\FilterPool; -use Magento\Ui\ContentType\ContentTypeFactory; -use Magento\Ui\DataProvider\Factory as DataProviderFactory; -use Magento\Ui\DataProvider\Manager; - -/** - * Class Date - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class Date extends FilterAbstract -{ - /** - * Timezone library - * - * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface - */ - protected $localeDate; - - /** - * Scope config - * - * @var \Magento\Framework\App\Config\ScopeConfigInterface - */ - protected $scopeConfig; - - /** - * Locale resolver - * - * @var \Magento\Framework\Locale\ResolverInterface - */ - protected $localeResolver; - - /** - * Constructor - * - * @param TemplateContext $context - * @param Context $renderContext - * @param ContentTypeFactory $contentTypeFactory - * @param ConfigFactory $configFactory - * @param ConfigBuilderInterface $configBuilder - * @param DataProviderFactory $dataProviderFactory - * @param Manager $dataProviderManager - * @param FilterPool $filterPool - * @param ResolverInterface $localeResolver - * @param array $data - * @SuppressWarnings(PHPMD.ExcessiveParameterList) - */ - public function __construct( - TemplateContext $context, - Context $renderContext, - ContentTypeFactory $contentTypeFactory, - ConfigFactory $configFactory, - ConfigBuilderInterface $configBuilder, - DataProviderFactory $dataProviderFactory, - Manager $dataProviderManager, - FilterPool $filterPool, - ResolverInterface $localeResolver, - array $data = [] - ) { - $this->localeDate = $context->getLocaleDate(); - $this->scopeConfig = $context->getScopeConfig(); - $this->localeResolver = $localeResolver; - parent::__construct( - $context, - $renderContext, - $contentTypeFactory, - $configFactory, - $configBuilder, - $dataProviderFactory, - $dataProviderManager, - $filterPool, - $data - ); - } - - /** - * Get condition by data type - * - * @param string|array $value - * @return array|null - */ - public function getCondition($value) - { - return $this->convertValue($value); - } - - /** - * Convert value - * - * @param array|string $value - * @return array|null - */ - protected function convertValue($value) - { - if (!empty($value['from']) || !empty($value['to'])) { - $locale = $this->localeResolver->getLocale(); - if (!empty($value['from'])) { - $value['orig_from'] = $value['from']; - $value['from'] = $this->convertDate(strtotime($value['from']), $locale); - } - if (!empty($value['to'])) { - $value['orig_to'] = $value['to']; - $value['to'] = $this->convertDate(strtotime($value['to']), $locale); - } - $value['datetime'] = true; - $value['locale'] = $this->localeResolver->getLocale(); - } else { - $value = null; - } - - return $value; - } - - /** - * Convert given date to default (UTC) timezone - * - * @param int $date - * @param string $locale - * @return \DateTime|null - */ - protected function convertDate($date, $locale) - { - try { - $dateObj = $this->localeDate->date(new \DateTime($date), $locale, false); - $dateObj->setTime(0, 0, 0); - //convert store date to default date in UTC timezone without DST - $dateObj->setTimezone(new \DateTimeZone('UTC')); - return $dateObj; - } catch (\Exception $e) { - return null; - } - } -} diff --git a/app/code/Magento/Ui/Component/Filter/Type/Input.php b/app/code/Magento/Ui/Component/Filter/Type/Input.php deleted file mode 100644 index 214ae8e8a671c980590352b14943a426887b9799..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Filter/Type/Input.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Filter\Type; - -use Magento\Ui\Component\Filter\FilterAbstract; - -/** - * Class Input - */ -class Input extends FilterAbstract -{ - /** - * Get condition by data type - * - * @param string|array $value - * @return array|null - */ - public function getCondition($value) - { - $condition = null; - if (!empty($value) || is_numeric($value)) { - $condition = ['like' => sprintf('%%%s%%', $value)]; - } - - return $condition; - } -} diff --git a/app/code/Magento/Ui/Component/Filter/Type/Range.php b/app/code/Magento/Ui/Component/Filter/Type/Range.php deleted file mode 100644 index 25583f994f40007f45e654575471e2b9889a4641..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Filter/Type/Range.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Filter\Type; - -use Magento\Ui\Component\Filter\FilterAbstract; - -/** - * Class Range - */ -class Range extends FilterAbstract -{ - /** - * Get condition by data type - * - * @param array|string $value - * @return array|null - */ - public function getCondition($value) - { - if (!empty($value['from']) || !empty($value['to'])) { - if (isset($value['from']) && empty($value['from']) && $value['from'] !== '0') { - $value['orig_from'] = $value['from']; - $value['from'] = null; - } - if (isset($value['to']) && empty($value['to']) && $value['to'] !== '0') { - $value['orig_to'] = $value['to']; - $value['to'] = null; - } - } else { - $value = null; - } - - return $value; - } -} diff --git a/app/code/Magento/Ui/Component/Filter/Type/Select.php b/app/code/Magento/Ui/Component/Filter/Type/Select.php deleted file mode 100644 index 309049fef60012b1f86d7094f8b3211ee378e84b..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Filter/Type/Select.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Filter\Type; - -use Magento\Ui\Component\Filter\FilterAbstract; - -/** - * Class Select - */ -class Select extends FilterAbstract -{ - /** - * Get condition by data type - * - * @param string|array $value - * @return array|null - */ - public function getCondition($value) - { - $condition = null; - if (!empty($value) || is_numeric($value)) { - $condition = ['eq' => $value]; - } - - return $condition; - } -} diff --git a/app/code/Magento/Ui/Component/Filter/Type/Store.php b/app/code/Magento/Ui/Component/Filter/Type/Store.php deleted file mode 100644 index aa0495336a281bb632eeffea466e9758665559ee..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Filter/Type/Store.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Filter\Type; - -use Magento\Ui\Component\Filter\FilterAbstract; - -/** - * Class Store - */ -class Store extends FilterAbstract -{ -} diff --git a/app/code/Magento/Ui/Component/FilterPool.php b/app/code/Magento/Ui/Component/FilterPool.php deleted file mode 100644 index fae9e248d58ab64d3efd2c5355a4dd4b6517524d..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/FilterPool.php +++ /dev/null @@ -1,193 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component; - -use Magento\Framework\View\Element\Template\Context as TemplateContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigFactory; -use Magento\Framework\View\Element\UiComponent\Context; -use Magento\Ui\Component\Filter\FilterAbstract; -use Magento\Ui\Component\Filter\FilterPool as FilterPoolProvider; -use Magento\Ui\ContentType\ContentTypeFactory; -use Magento\Ui\DataProvider\Factory as DataProviderFactory; -use Magento\Ui\DataProvider\Manager; - -/** - * Class FilterPool - */ -class FilterPool extends AbstractView -{ - /** - * Filters pool - * - * @var FilterPoolProvider - */ - protected $filterPoolProvider; - - /** - * Constructor - * - * @param TemplateContext $context - * @param Context $renderContext - * @param ContentTypeFactory $contentTypeFactory - * @param ConfigFactory $configFactory - * @param ConfigBuilderInterface $configBuilder - * @param DataProviderFactory $dataProviderFactory - * @param Manager $dataProviderManager - * @param FilterPoolProvider $filterPoolProvider - * @param array $data - */ - public function __construct( - TemplateContext $context, - Context $renderContext, - ContentTypeFactory $contentTypeFactory, - ConfigFactory $configFactory, - ConfigBuilderInterface $configBuilder, - DataProviderFactory $dataProviderFactory, - Manager $dataProviderManager, - FilterPoolProvider $filterPoolProvider, - array $data = [] - ) { - $this->filterPoolProvider = $filterPoolProvider; - parent::__construct( - $context, - $renderContext, - $contentTypeFactory, - $configFactory, - $configBuilder, - $dataProviderFactory, - $dataProviderManager, - $data - ); - } - - /** - * Prepare component data - * - * @return void - */ - public function prepare() - { - $configData = $this->getDefaultConfiguration(); - if ($this->hasData('config')) { - $configData = array_merge($configData, $this->getData('config')); - } - $this->prepareConfiguration($configData); - $this->updateDataCollection(); - } - - /** - * Get fields - * - * @return array - */ - public function getFields() - { - $meta = $this->renderContext->getStorage()->getMeta($this->getParentName()); - $fields = []; - if (isset($meta['fields'])) { - foreach ($meta['fields'] as $name => $config) { - if (isset($config['filterable']) && $config['filterable'] === false) { - continue; - } - $fields[$name] = $config; - } - } - return $fields; - } - - /** - * Get active filters - * - * @return array - */ - public function getActiveFilters() - { - $metaData = $this->renderContext->getStorage()->getMeta($this->getParentName()); - $metaData = $metaData['fields']; - $filters = []; - $filterData = $this->prepareFilterString( - $this->renderContext->getRequestParam(FilterAbstract::FILTER_VAR) - ); - foreach ($filterData as $field => $value) { - if (isset($metaData[$field]['filter_type'])) { - $filters[$field] = [ - 'label' => $metaData[$field]['label'], - 'current_display_value' => $value, - ]; - } - } - - return $filters; - } - - /** - * Update data collection - * - * @return void - */ - protected function updateDataCollection() - { - $collection = $this->renderContext->getStorage()->getDataCollection($this->getParentName()); - - $metaData = $this->renderContext->getStorage()->getMeta($this->getParentName()); - $metaData = $metaData['fields']; - $filterData = $this->prepareFilterString( - $this->renderContext->getRequestParam(FilterAbstract::FILTER_VAR) - ); - foreach ($filterData as $field => $value) { - if (!isset($metaData[$field]['filter_type'])) { - continue; - } - $condition = $this->filterPoolProvider->getFilter($metaData[$field]['filter_type'])->getCondition($value); - if ($condition !== null) { - $collection->addFieldToFilter($field, $condition); - } - } - } - - /** - * Get list of required filters - * - * @return array - */ - protected function getListOfRequiredFilters() - { - $result = []; - foreach ($this->getFields() as $field) { - $result[] = isset($field['filter_type']) ? $field['filter_type'] : $field['input_type']; - } - - return $result; - } - - /** - * Decode filter string - * - * @param string $filterString - * @return array - */ - protected function prepareFilterString($filterString) - { - $data = []; - $filterString = base64_decode($filterString); - parse_str($filterString, $data); - array_walk_recursive( - $data, - // @codingStandardsIgnoreStart - /** - * Decodes URL-encoded string and trims whitespaces from the beginning and end of a string - * - * @param string $value - */ - // @codingStandardsIgnoreEnd - function (&$value) { - $value = trim(rawurldecode($value)); - } - ); - return $data; - } -} diff --git a/app/code/Magento/Ui/Component/Filters.php b/app/code/Magento/Ui/Component/Filters.php new file mode 100644 index 0000000000000000000000000000000000000000..75c5b0d0472b947d132c779d3b079be5fd5d4af1 --- /dev/null +++ b/app/code/Magento/Ui/Component/Filters.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component; + +/** + * Class Filters + */ +class Filters extends AbstractComponent +{ + const NAME = 'filters'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Register component. + * + * @return void + */ + public function prepare() + { + parent::prepare(); + + $jsConfig = $this->getConfiguration($this); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } +} diff --git a/app/code/Magento/Ui/Component/Filters/Type/AbstractFilter.php b/app/code/Magento/Ui/Component/Filters/Type/AbstractFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..d2aa51c314a4b5f0979ba80093959a3364382350 --- /dev/null +++ b/app/code/Magento/Ui/Component/Filters/Type/AbstractFilter.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Filters\Type; + +use Magento\Ui\Component\AbstractComponent; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponent\ContextInterface; + +/** + * Abstract class AbstractFilter + */ +abstract class AbstractFilter extends AbstractComponent +{ + /** + * Filter variable name + */ + const FILTER_VAR = 'filters'; + + /** + * Filter data + * + * @var array + */ + protected $filterData; + + /** + * @var UiComponentFactory + */ + protected $uiComponentFactory; + + /** + * Constructor + * + * @param ContextInterface $context + * @param UiComponentFactory $uiComponentFactory + * @param array $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + UiComponentFactory $uiComponentFactory, + array $components = [], + array $data = [] + ) { + $this->uiComponentFactory = $uiComponentFactory; + parent::__construct($context, $components, $data); + + $this->filterData = $this->getContext()->getRequestParam(static::FILTER_VAR); + } +} diff --git a/app/code/Magento/Ui/Component/Filters/Type/Date.php b/app/code/Magento/Ui/Component/Filters/Type/Date.php new file mode 100644 index 0000000000000000000000000000000000000000..4211b51838b8eaf3736ab38cd3b612b7486ca5aa --- /dev/null +++ b/app/code/Magento/Ui/Component/Filters/Type/Date.php @@ -0,0 +1,121 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Filters\Type; + +use Magento\Ui\Component\Form\Element\DataType\Date as DataTypeDate; + +/** + * Class Date + */ +class Date extends AbstractFilter +{ + const NAME = 'filter_date'; + + const COMPONENT = 'date'; + + /** + * Wrapped component + * + * @var DataTypeDate + */ + protected $wrappedComponent; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + + $this->wrappedComponent = $this->uiComponentFactory->create( + $this->getName(), + static::COMPONENT, + ['context' => $this->getContext()] + ); + $this->wrappedComponent->prepare(); + + $this->applyFilter(); + $jsConfig = array_replace_recursive( + $this->getConfiguration($this->wrappedComponent), + $this->getConfiguration($this) + ); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + + /** + * Get JS config + * + * @return array + */ + public function getJsConfig() + { + return array_replace_recursive( + (array) $this->wrappedComponent->getData('config'), + (array) $this->getData('config') + ); + } + + /** + * Apply filter + * + * @return void + */ + protected function applyFilter() + { + $condition = $this->getCondition(); + if ($condition !== null) { + $this->getContext()->getDataProvider()->addFilter($this->getName(), $condition); + } + } + + /** + * Get condition + * + * @return array|null + */ + protected function getCondition() + { + $value = isset($this->filterData[$this->getName()]) ? $this->filterData[$this->getName()] : null; + if (!empty($value['from']) || !empty($value['to'])) { + if (!empty($value['from'])) { + $value['orig_from'] = $value['from']; + $value['from'] = $this->wrappedComponent->convertDate( + $value['from'], + $this->wrappedComponent->getLocale() + ); + } else { + unset($value['from']); + } + if (!empty($value['to'])) { + $value['orig_to'] = $value['to']; + $value['to'] = $this->wrappedComponent->convertDate( + $value['to'], + $this->wrappedComponent->getLocale() + ); + } else { + unset($value['to']); + } + $value['datetime'] = true; + $value['locale'] = $this->wrappedComponent->getLocale(); + } else { + $value = null; + } + + return $value; + } +} diff --git a/app/code/Magento/Ui/Component/Filters/Type/DateRange.php b/app/code/Magento/Ui/Component/Filters/Type/DateRange.php new file mode 100644 index 0000000000000000000000000000000000000000..daae0ab2ca7327188259f6c9d9035997dfce5022 --- /dev/null +++ b/app/code/Magento/Ui/Component/Filters/Type/DateRange.php @@ -0,0 +1,105 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Filters\Type; + +use Magento\Ui\Component\Form\Element\DataType\Date as DataTypeDate; + +/** + * Class DateRange + */ +class DateRange extends AbstractFilter +{ + const NAME = 'filter_range'; + + const COMPONENT = 'date'; + + /** + * Wrapped component + * + * @var DataTypeDate + */ + protected $wrappedComponent; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + + $this->wrappedComponent = $this->uiComponentFactory->create( + $this->getName(), + static::COMPONENT, + ['context' => $this->getContext()] + ); + $this->wrappedComponent->prepare(); + + $this->applyFilter(); + $jsConfig = $this->getConfiguration($this); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + + /** + * Apply filter + * + * @return void + */ + protected function applyFilter() + { + $condition = $this->getCondition(); + if ($condition !== null) { + $this->getContext()->getDataProvider()->addFilter($this->getName(), $condition); + } + } + + /** + * Get condition by data type + * + * @return array|null + */ + public function getCondition() + { + $value = isset($this->filterData[$this->getName()]) ? $this->filterData[$this->getName()] : null; + if (!empty($value['from']) || !empty($value['to'])) { + if (!empty($value['from'])) { + $value['orig_from'] = $value['from']; + $value['from'] = $this->wrappedComponent->convertDate( + $value['from'], + $this->wrappedComponent->getLocale() + ); + } else { + unset($value['from']); + } + if (!empty($value['to'])) { + $value['orig_to'] = $value['to']; + $value['to'] = $this->wrappedComponent->convertDate( + $value['to'], + $this->wrappedComponent->getLocale() + ); + } else { + unset($value['to']); + } + $value['datetime'] = true; + $value['locale'] = $this->wrappedComponent->getLocale(); + } else { + $value = null; + } + + return $value; + } +} diff --git a/app/code/Magento/Ui/Component/Filters/Type/Input.php b/app/code/Magento/Ui/Component/Filters/Type/Input.php new file mode 100644 index 0000000000000000000000000000000000000000..5a9e68b0bd72540dc22c9644094bc81c575631b8 --- /dev/null +++ b/app/code/Magento/Ui/Component/Filters/Type/Input.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Filters\Type; + +use Magento\Ui\Component\Form\Element\Input as ElementInput; + +/** + * Class Input + */ +class Input extends AbstractFilter +{ + const NAME = 'filter_input'; + + const COMPONENT = 'input'; + + /** + * Wrapped component + * + * @var ElementInput + */ + protected $wrappedComponent; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + $this->wrappedComponent = $this->uiComponentFactory->create( + $this->getName(), + static::COMPONENT, + ['context' => $this->getContext()] + ); + $this->wrappedComponent->prepare(); + + $this->applyFilter(); + $jsConfig = array_replace_recursive( + $this->getConfiguration($this->wrappedComponent), + $this->getConfiguration($this) + ); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + + /** + * Apply filter + * + * @return void + */ + protected function applyFilter() + { + $condition = $this->getCondition(); + if ($condition !== null) { + $this->getContext()->getDataProvider()->addFilter($this->getName(), $condition); + } + } + + /** + * Get condition by data type + * + * @return array|null + */ + public function getCondition() + { + $value = isset($this->filterData[$this->getName()]) ? $this->filterData[$this->getName()] : null; + $condition = null; + if (!empty($value) || is_numeric($value)) { + $condition = ['like' => sprintf('%%%s%%', $value)]; + } + + return $condition; + } +} diff --git a/app/code/Magento/Ui/Component/Filters/Type/Range.php b/app/code/Magento/Ui/Component/Filters/Type/Range.php new file mode 100644 index 0000000000000000000000000000000000000000..7892ef98f52222d4c75d32ef4676f09656f4e827 --- /dev/null +++ b/app/code/Magento/Ui/Component/Filters/Type/Range.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Filters\Type; + +/** + * Class Range + */ +class Range extends AbstractFilter +{ + const NAME = 'filter_range'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + $this->applyFilter(); + $jsConfig = $this->getConfiguration($this); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + + /** + * Apply filter + * + * @return void + */ + protected function applyFilter() + { + $condition = $this->getCondition(); + if ($condition !== null) { + $this->getContext()->getDataProvider()->addFilter($this->getName(), $condition); + } + } + + /** + * Get condition by data type + * + * @return array|null + */ + public function getCondition() + { + $value = isset($this->filterData[$this->getName()]) ? $this->filterData[$this->getName()] : null; + if (!empty($value['from']) || !empty($value['to'])) { + $value = $this->prepareFrom($value); + $value = $this->prepareTo($value); + } else { + $value = null; + } + + return $value; + } + + /** + * Prepare "from" value + * + * @param array $value + * @return array + */ + protected function prepareFrom(array $value) + { + if (isset($value['from']) && empty($value['from']) && $value['from'] !== '0') { + $value['orig_from'] = $value['from']; + $value['from'] = null; + } + + return $value; + } + + /** + * Prepare "from" value + * + * @param array $value + * @return array + */ + protected function prepareTo(array $value) + { + if (isset($value['to']) && empty($value['to']) && $value['to'] !== '0') { + $value['orig_to'] = $value['to']; + $value['to'] = null; + } + + return $value; + } +} diff --git a/app/code/Magento/Ui/Component/Filters/Type/Select.php b/app/code/Magento/Ui/Component/Filters/Type/Select.php new file mode 100644 index 0000000000000000000000000000000000000000..399ad004d5bbb1a72814d16b697315d34d34c84f --- /dev/null +++ b/app/code/Magento/Ui/Component/Filters/Type/Select.php @@ -0,0 +1,128 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Filters\Type; + +use Magento\Framework\Data\OptionSourceInterface; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Ui\Component\Form\Element\Select as ElementSelect; + +/** + * Class Select + */ +class Select extends AbstractFilter +{ + const NAME = 'filter_select'; + + const COMPONENT = 'select'; + + /** + * Wrapped component + * + * @var ElementSelect + */ + protected $wrappedComponent; + + /** + * @var OptionSourceInterface + */ + protected $optionsProvider; + + /** + * Constructor + * + * @param ContextInterface $context + * @param UiComponentFactory $uiComponentFactory + * @param OptionSourceInterface $optionsProvider + * @param array $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + UiComponentFactory $uiComponentFactory, + OptionSourceInterface $optionsProvider = null, + array $components = [], + array $data = [] + ) { + $this->optionsProvider = $optionsProvider; + parent::__construct($context, $uiComponentFactory, $components, $data); + } + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + $this->wrappedComponent = $this->uiComponentFactory->create( + $this->getName(), + static::COMPONENT, + ['context' => $this->getContext(), 'options' => $this->optionsProvider] + ); + $this->wrappedComponent->prepare(); + + $this->applyFilter(); + $jsConfig = array_replace_recursive( + $this->getConfiguration($this->wrappedComponent), + $this->getConfiguration($this) + ); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + + /** + * Get JS config + * + * @return array + */ + public function getJsConfig() + { + return array_replace_recursive( + (array) $this->wrappedComponent->getData('config'), + (array) $this->getData('config') + ); + } + + /** + * Get condition by data type + * + * @return array|null + */ + public function getCondition() + { + $value = isset($this->filterData[$this->getName()]) ? $this->filterData[$this->getName()] : null; + $condition = null; + if (!empty($value) || is_numeric($value)) { + $condition = ['eq' => $value]; + } + + return $condition; + } + + /** + * Apply filter + * + * @return void + */ + protected function applyFilter() + { + $condition = $this->getCondition(); + if ($condition !== null) { + $this->getContext()->getDataProvider()->addFilter($this->getName(), $condition); + } + } +} diff --git a/app/code/Magento/Ui/Component/Form.php b/app/code/Magento/Ui/Component/Form.php index 4e4435b6773638f14a510253edf655d196508f6a..aa74ffddd3ecabb5967b7aac173534e1ed03ce71 100644 --- a/app/code/Magento/Ui/Component/Form.php +++ b/app/code/Magento/Ui/Component/Form.php @@ -5,222 +5,75 @@ */ namespace Magento\Ui\Component; -use Magento\Framework\View\Element\Template\Context as TemplateContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigFactory; -use Magento\Framework\View\Element\UiComponent\Context; -use Magento\Framework\View\Element\UiElementFactory; -use Magento\Ui\Component\Control\ActionPool; -use Magento\Ui\Component\Control\ButtonProviderFactory; -use Magento\Ui\Component\Control\ButtonProviderInterface; -use Magento\Ui\ContentType\ContentTypeFactory; -use Magento\Ui\DataProvider\Factory as DataProviderFactory; -use Magento\Ui\DataProvider\Manager; +use Magento\Framework\View\Element\UiComponent\DataSourceInterface; /** * Class Form - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Form extends AbstractView +class Form extends AbstractComponent { - /** - * Default form element - */ - const DEFAULT_FORM_ELEMENT = 'input'; + const NAME = 'form'; /** - * From element map + * Get component name * - * @var array - */ - protected $formElementMap = [ - 'text' => 'input', - 'number' => 'input', - ]; - - /** - * Ui element builder - * - * @var ElementRendererBuilder - */ - protected $elementRendererBuilder; - - /** - * @var UiElementFactory - */ - protected $factory; - - /** - * @var ActionPool - */ - protected $actionPool; - - /** - * @var ButtonProviderFactory - */ - protected $buttonProviderFactory; - - /** - * Constructor - * - * @param TemplateContext $context - * @param Context $renderContext - * @param ContentTypeFactory $contentTypeFactory - * @param ConfigFactory $configFactory - * @param ConfigBuilderInterface $configBuilder - * @param DataProviderFactory $dataProviderFactory - * @param Manager $dataProviderManager - * @param ElementRendererBuilder $elementRendererBuilder - * @param UiElementFactory $factory - * @param ActionPool $actionPool - * @param ButtonProviderFactory $buttonProviderFactory - * @param array $data - * @SuppressWarnings(PHPMD.ExcessiveParameterList) + * @return string */ - public function __construct( - TemplateContext $context, - Context $renderContext, - ContentTypeFactory $contentTypeFactory, - ConfigFactory $configFactory, - ConfigBuilderInterface $configBuilder, - DataProviderFactory $dataProviderFactory, - Manager $dataProviderManager, - ElementRendererBuilder $elementRendererBuilder, - UiElementFactory $factory, - ActionPool $actionPool, - ButtonProviderFactory $buttonProviderFactory, - array $data = [] - ) { - $this->elementRendererBuilder = $elementRendererBuilder; - $this->factory = $factory; - $this->actionPool = $actionPool; - $this->buttonProviderFactory = $buttonProviderFactory; - parent::__construct( - $context, - $renderContext, - $contentTypeFactory, - $configFactory, - $configBuilder, - $dataProviderFactory, - $dataProviderManager, - $data - ); + public function getComponentName() + { + return static::NAME; } /** - * Prepare component data + * Register component * * @return void */ public function prepare() { - $this->registerComponents(); - $buttons = $this->getData('buttons'); - if ($buttons) { - foreach ($buttons as $buttonId => $buttonClass) { - /** @var ButtonProviderInterface $button */ - $button = $this->buttonProviderFactory->create($buttonClass); - $buttonData = $button->getButtonData(); - if (!$buttonData) { - unset($buttons[$buttonId]); - continue; - } - $buttons[$buttonId] = $buttonData; - } - uasort($buttons, [$this, 'sortButtons']); - foreach ($buttons as $buttonId => $buttonData) { - $this->actionPool->add($buttonId, $buttonData, $this); - } - } + parent::prepare(); - $layoutSettings = (array) $this->getData('layout'); - $data = [ - 'name' => $this->getData('name'), - 'label' => $this->getData('label'), - 'data_sources' => $this->getData('data_sources'), - 'child_blocks' => $this->getLayout()->getChildBlocks($this->getNameInLayout()), - 'configuration' => isset($layoutSettings['configuration']) - ? $layoutSettings['configuration'] - : [], - ]; - $layoutType = isset($layoutSettings['type']) - ? $layoutSettings['type'] - : \Magento\Ui\Component\Layout\Tabs::NAME; - $layout = $this->factory->create( - $layoutType, - $data - ); - $layout->prepare(); - $this->elements[] = $layout; - } + $jsConfig = $this->getConfiguration($this); + unset($jsConfig['extends']); + $this->getContext()->addComponentDefinition($this->getContext()->getNamespace(), $jsConfig); - /** - * @return string - */ - public function getDataScope() - { - return $this->getData('name'); + $this->getContext()->addButtons($this->getData('buttons'), $this); } /** - * Register all UI Components configuration - * - * @return void + * @return array */ - protected function registerComponents() + public function getDataSourceData() { - $this->renderContext->getStorage()->addComponent( - $this->getData('name'), - [ - 'component' => 'Magento_Ui/js/form/component', - 'config' => [ - 'provider' => $this->getData('name'), - ], - 'deps' => [$this->getData('name')] - ] - ); - foreach ($this->getLayout()->getAllBlocks() as $name => $block) { - if ($block instanceof \Magento\Framework\View\Element\UiComponentInterface) { - $config = (array)$block->getData('js_config'); - if (!isset($config['extends'])) { - $config['extends'] = $this->getData('name'); + $dataSources = []; + foreach ($this->getChildComponents() as $component) { + if ($component instanceof DataSourceInterface) { + $dataProvider = $component->getDataProvider(); + $id = $this->getContext()->getRequestParam($dataProvider->getRequestFieldName()); + $preparedData = []; + if ($id) { + $dataProvider->addFilter($dataProvider->getPrimaryFieldName(), $id); + $preparedData = $dataProvider->getData(); + if (isset($preparedData[$id])) { + $preparedData = ['data' => $preparedData[$id]]; + } } - $this->renderContext->getStorage()->addComponent($name, $config); - } - }; - } - - /** - * @return string - */ - public function getSaveAction() - { - return $this->getUrl('mui/form/save'); - } - /** - * @return string - */ - public function getValidateAction() - { - return $this->getUrl('mui/form/validate'); - } - - /** - * Sort buttons by sort order - * - * @param array $itemA - * @param array $itemB - * @return int - * @SuppressWarnings(PHPMD.NPathComplexity) - */ - public function sortButtons(array $itemA, array $itemB) - { - $sortOrderA = isset($itemA['sort_order']) ? intval($itemA['sort_order']) : 0; - $sortOrderB = isset($itemB['sort_order']) ? intval($itemB['sort_order']) : 0; - if ($sortOrderA == $sortOrderB) { - return 0; + $config = $dataProvider->getConfigData(); + if (isset($config['submit_url'])) { + $config['submit_url'] = $this->getContext()->getUrl($config['submit_url']); + } + if (isset($config['validate_url'])) { + $config['validate_url'] = $this->getContext()->getUrl($config['validate_url']); + } + $dataSources[$component->getName()] = [ + 'type' => $component->getComponentName(), + 'name' => $component->getName(), + 'dataScope' => $component->getContext()->getNamespace(), + 'config' => array_merge($preparedData, $config) + ]; + } } - return ($sortOrderA < $sortOrderB) ? -1 : 1; + return $dataSources; } } diff --git a/app/code/Magento/Ui/Component/Form/Collection.php b/app/code/Magento/Ui/Component/Form/Collection.php index 09b67401aaced6f231d871c1e004ed78113e80b3..c816843578c6b2ba80fcdbfea017d713031b0dac 100644 --- a/app/code/Magento/Ui/Component/Form/Collection.php +++ b/app/code/Magento/Ui/Component/Form/Collection.php @@ -5,13 +5,23 @@ */ namespace Magento\Ui\Component\Form; +use Magento\Ui\Component\AbstractComponent; use Magento\Framework\View\Element\UiComponentInterface; -use Magento\Ui\Component\AbstractView; /** * Class Collection */ -class Collection extends AbstractView implements UiComponentInterface +class Collection extends AbstractComponent implements UiComponentInterface { - // + const NAME = 'collection'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } } diff --git a/app/code/Magento/Ui/Component/Form/Element/AbstractFormElement.php b/app/code/Magento/Ui/Component/Form/Element/AbstractElement.php similarity index 75% rename from app/code/Magento/Ui/Component/Form/Element/AbstractFormElement.php rename to app/code/Magento/Ui/Component/Form/Element/AbstractElement.php index e536143ab6b4a719b6e8582159d748eb1bc8d182..c01990b9d7e8eec7b59844c8f92d6d9bd6e67726 100644 --- a/app/code/Magento/Ui/Component/Form/Element/AbstractFormElement.php +++ b/app/code/Magento/Ui/Component/Form/Element/AbstractElement.php @@ -5,12 +5,12 @@ */ namespace Magento\Ui\Component\Form\Element; -use Magento\Ui\Component\AbstractView; +use Magento\Ui\Component\AbstractComponent; /** - * Class AbstractFormElement + * Class AbstractElement */ -abstract class AbstractFormElement extends AbstractView implements ElementInterface +abstract class AbstractElement extends AbstractComponent implements ElementInterface { /** * @return string @@ -38,9 +38,8 @@ abstract class AbstractFormElement extends AbstractView implements ElementInterf /** * @return bool - * @SuppressWarnings(PHPMD.BooleanGetMethodName) */ - public function getIsReadonly() + public function isReadonly() { return (bool) $this->getData('readonly'); } diff --git a/app/code/Magento/Ui/Component/Form/Element/Checkbox.php b/app/code/Magento/Ui/Component/Form/Element/Checkbox.php index df26d8c21bb31ba861c4d929b070e5854b917ab7..e3e73495628c2671d23c72ea725ed6da25916f55 100644 --- a/app/code/Magento/Ui/Component/Form/Element/Checkbox.php +++ b/app/code/Magento/Ui/Component/Form/Element/Checkbox.php @@ -8,7 +8,30 @@ namespace Magento\Ui\Component\Form\Element; /** * Class Checkbox */ -class Checkbox extends AbstractFormElement +class Checkbox extends AbstractElement { - // + const NAME = 'checkbox'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + + $jsConfig = $this->getConfiguration($this, Input::NAME); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } } diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/AbstractDataType.php b/app/code/Magento/Ui/Component/Form/Element/DataType/AbstractDataType.php index cc196dea37d70c3b3b0ff57e77e4d3ee40e5fc31..e36e3f3589ad6b119aba9ac2d1fd1436c1dc09e7 100644 --- a/app/code/Magento/Ui/Component/Form/Element/DataType/AbstractDataType.php +++ b/app/code/Magento/Ui/Component/Form/Element/DataType/AbstractDataType.php @@ -5,26 +5,20 @@ */ namespace Magento\Ui\Component\Form\Element\DataType; -use Magento\Ui\Component\AbstractView; +use Magento\Ui\Component\AbstractComponent; /** * Class AbstractDataType */ -abstract class AbstractDataType extends AbstractView implements DataTypeInterface +abstract class AbstractDataType extends AbstractComponent implements DataTypeInterface { /** + * Validate value + * * @return bool */ public function validate() { return true; } - - /** - * @return string - */ - public function getDataObjectValue() - { - return $this->getData('data_object')[$this->getData('name')]; - } } diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Boolean.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Boolean.php index 8fe4b24f502d9fc7ae0bb70027164dd42715d951..d7865d61e608eae19c3f72bdd63fe2998179953f 100644 --- a/app/code/Magento/Ui/Component/Form/Element/DataType/Boolean.php +++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Boolean.php @@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType; */ class Boolean extends AbstractDataType { - // + const NAME = 'boolean'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } } diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/DataTypeInterface.php b/app/code/Magento/Ui/Component/Form/Element/DataType/DataTypeInterface.php index 63aefa0b72903f3bf46b029b6046426c356f6193..04bbecb0a8de5b2082931292b5ece267a77cc077 100644 --- a/app/code/Magento/Ui/Component/Form/Element/DataType/DataTypeInterface.php +++ b/app/code/Magento/Ui/Component/Form/Element/DataType/DataTypeInterface.php @@ -5,7 +5,6 @@ */ namespace Magento\Ui\Component\Form\Element\DataType; -use Magento\Framework\Object; use Magento\Framework\View\Element\UiComponentInterface; /** @@ -19,11 +18,4 @@ interface DataTypeInterface extends UiComponentInterface * @return bool */ public function validate(); - - /** - * Get data object value - * - * @return mixed - */ - public function getDataObjectValue(); } diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php index 46bd9267d737c7c65b9584101277e8b7845bdd67..e72be53246d1698337ca34784304cf7801e59a33 100644 --- a/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php +++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php @@ -5,10 +5,109 @@ */ namespace Magento\Ui\Component\Form\Element\DataType; +use Magento\Framework\Locale\ResolverInterface; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; + /** * Class Date */ class Date extends AbstractDataType { - // + const NAME = 'date'; + + /** + * Current locale + * + * @var string + */ + protected $locale; + + /** + * Wrapped component + * + * @var UiComponentInterface + */ + protected $wrappedComponent; + + /** + * Constructor + * + * @param ContextInterface $context + * @param TimezoneInterface $localeDate + * @param ResolverInterface $localeResolver + * @param array $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + TimezoneInterface $localeDate, + ResolverInterface $localeResolver, + array $components = [], + array $data = [] + ) { + $this->locale = $localeResolver->getLocale(); + $this->localeDate = $localeDate; + parent::__construct($context, $components, $data); + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + + $config = $this->getData('config'); + if (!isset($config['dateFormat'])) { + $config['dateFormat'] = $this->localeDate->getDateTimeFormat(\IntlDateFormatter::MEDIUM); + $this->setData('config', $config); + } + + $jsConfig = $this->getConfiguration($this); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + + + /** + * Get locale + * + * @return string + */ + public function getLocale() + { + return $this->locale; + } + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Convert given date to default (UTC) timezone + * + * @param int $date + * @return \DateTime|null + */ + public function convertDate($date) + { + try { + $dateObj = $this->localeDate->date(new \DateTime($date), $this->getLocale(), false); + $dateObj->setTime(0, 0, 0); + //convert store date to default date in UTC timezone without DST + $dateObj->setTimezone(new \DateTimeZone('UTC')); + return $dateObj; + } catch (\Exception $e) { + return null; + } + } } diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Email.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Email.php index 7dda21c016ae980f741b1d98396c23e1a8ac8bb0..49b12bbf6277076373c277ed92f873828d99707e 100644 --- a/app/code/Magento/Ui/Component/Form/Element/DataType/Email.php +++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Email.php @@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType; */ class Email extends AbstractDataType { - // + const NAME = 'email'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } } diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Media.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Media.php index 0f361470f944bc0956bdbdd1b61e0ba1e1050da7..fda46d7b137a0168884f6df5f38656127a8e7755 100644 --- a/app/code/Magento/Ui/Component/Form/Element/DataType/Media.php +++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Media.php @@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType; */ class Media extends AbstractDataType { - // + const NAME = 'media'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } } diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Number.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Number.php index 4b5d7924e53c234d953efac46c438d3a6afc102c..929a86ab19a8a12b9694d3b9d546e3e4ce23680e 100644 --- a/app/code/Magento/Ui/Component/Form/Element/DataType/Number.php +++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Number.php @@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType; */ class Number extends AbstractDataType { - // + const NAME = 'number'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } } diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Password.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Password.php index d58d74bd4c9d9ce839cd98e90e9b5bdac459f5dc..77a93da72288bfa57e0f8f20711461cd1ff4395a 100644 --- a/app/code/Magento/Ui/Component/Form/Element/DataType/Password.php +++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Password.php @@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType; */ class Password extends AbstractDataType { - // + const NAME = 'password'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } } diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Price.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Price.php index 138c224dea80d65aa506d19691d479b80a02bdf5..a183fc4ad1760c3059baf1a37b50dede49e1cbb6 100644 --- a/app/code/Magento/Ui/Component/Form/Element/DataType/Price.php +++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Price.php @@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType; */ class Price extends AbstractDataType { - // + const NAME = 'price'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } } diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Text.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Text.php index 43c259b510bcde506b3a41bbdb8876ae1fd20b8a..c3187b92a7706dd1bc89e830b53205755262483a 100644 --- a/app/code/Magento/Ui/Component/Form/Element/DataType/Text.php +++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Text.php @@ -10,5 +10,15 @@ namespace Magento\Ui\Component\Form\Element\DataType; */ class Text extends AbstractDataType { - // + const NAME = 'text'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } } diff --git a/app/code/Magento/Ui/Component/Form/Element/ElementInterface.php b/app/code/Magento/Ui/Component/Form/Element/ElementInterface.php index f6cd906ed59ec2b3113b6513f3d33e4bd88d2755..3450d6238384ecb7298d7ed642b1bccfa218e19c 100644 --- a/app/code/Magento/Ui/Component/Form/Element/ElementInterface.php +++ b/app/code/Magento/Ui/Component/Form/Element/ElementInterface.php @@ -24,9 +24,8 @@ interface ElementInterface extends UiComponentInterface /** * @return bool - * @SuppressWarnings(PHPMD.BooleanGetMethodName) */ - public function getIsReadonly(); + public function isReadonly(); /** * @return string diff --git a/app/code/Magento/Ui/Component/Form/Element/Input.php b/app/code/Magento/Ui/Component/Form/Element/Input.php index 9d149e9dd290f4dd12712501d1ce778cc9007860..9b43d1b7db952c7907ac8e0152a8b345ff26efb5 100644 --- a/app/code/Magento/Ui/Component/Form/Element/Input.php +++ b/app/code/Magento/Ui/Component/Form/Element/Input.php @@ -8,21 +8,30 @@ namespace Magento\Ui\Component\Form\Element; /** * Class Input */ -class Input extends AbstractFormElement +class Input extends AbstractElement { + const NAME = 'input'; + /** - * @return mixed|string + * Get component name + * + * @return string */ - public function getType() + public function getComponentName() { - return $this->getData('input_type') ? $this->getData('input_type') : 'text'; + return static::NAME; } /** + * Prepare component configuration + * * @return void */ public function prepare() { - parent::prepare(); // TODO: Change the autogenerated stub + parent::prepare(); + + $jsConfig = $this->getConfiguration($this); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); } } diff --git a/app/code/Magento/Ui/Component/Form/Element/Multiline.php b/app/code/Magento/Ui/Component/Form/Element/Multiline.php index 5e8b3b226dcb0bb8827f12809f9d10c756542e29..de3cd8900ddd5c6fdac0ead4735637226ea578e0 100644 --- a/app/code/Magento/Ui/Component/Form/Element/Multiline.php +++ b/app/code/Magento/Ui/Component/Form/Element/Multiline.php @@ -8,8 +8,20 @@ namespace Magento\Ui\Component\Form\Element; /** * Class Multiline */ -class Multiline extends AbstractFormElement +class Multiline extends AbstractElement { + const NAME = 'multiline'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + /** * @return mixed|string */ @@ -19,10 +31,15 @@ class Multiline extends AbstractFormElement } /** + * Prepare component configuration + * * @return void */ public function prepare() { - parent::prepare(); // TODO: Change the autogenerated stub + parent::prepare(); + + $jsConfig = $this->getConfiguration($this, Input::NAME); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); } } diff --git a/app/code/Magento/Ui/Component/Form/Element/Radio.php b/app/code/Magento/Ui/Component/Form/Element/Radio.php index 1737d460db14218d51e0edad5542b86c716a4723..1f93d43aa4fc16083193d5b8138bb4267eddba59 100644 --- a/app/code/Magento/Ui/Component/Form/Element/Radio.php +++ b/app/code/Magento/Ui/Component/Form/Element/Radio.php @@ -8,8 +8,20 @@ namespace Magento\Ui\Component\Form\Element; /** * Class Radio */ -class Radio extends AbstractFormElement +class Radio extends AbstractElement { + const NAME = 'radio'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + /** * @return bool * @SuppressWarnings(PHPMD.BooleanGetMethodName) diff --git a/app/code/Magento/Ui/Component/Form/Element/Range.php b/app/code/Magento/Ui/Component/Form/Element/Range.php index 549b295108c339afb4ca0170af0b76f1e4ae6195..debd3e1acabaa187c0482a73133b972ccecd6ca1 100644 --- a/app/code/Magento/Ui/Component/Form/Element/Range.php +++ b/app/code/Magento/Ui/Component/Form/Element/Range.php @@ -8,8 +8,20 @@ namespace Magento\Ui\Component\Form\Element; /** * Class Range */ -class Range extends AbstractFormElement +class Range extends AbstractElement { + const NAME = 'range'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + /** * @return mixed */ diff --git a/app/code/Magento/Ui/Component/Form/Element/Select.php b/app/code/Magento/Ui/Component/Form/Element/Select.php index 59a366d3e4b2aac3a270c2e41cefa9e2e4e1e1f1..be31eb6acad7955d8cd5757464282834bb016877 100644 --- a/app/code/Magento/Ui/Component/Form/Element/Select.php +++ b/app/code/Magento/Ui/Component/Form/Element/Select.php @@ -5,11 +5,75 @@ */ namespace Magento\Ui\Component\Form\Element; +use Magento\Framework\Data\OptionSourceInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; + /** * Class Select */ -class Select extends AbstractFormElement +class Select extends AbstractElement { + const NAME = 'select'; + + /** + * @var array|OptionSourceInterface|null + */ + protected $options; + + /** + * Constructor + * + * @param ContextInterface $context + * @param array|OptionSourceInterface|null $options + * @param array $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + $options = null, + array $components = [], + array $data = [] + ) { + $this->options = $options; + parent::__construct($context, $components, $data); + } + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + $config = $this->getData('config'); + if (isset($this->options)) { + if (!isset($config['options'])) { + $config['options'] = []; + } + if ($this->options instanceof OptionSourceInterface) { + $options = $this->options->toOptionArray(); + } else { + $options = array_values($this->options); + } + $config['options'] = array_values(array_merge_recursive($options, $config['options'])); + } + $this->setData('config', (array)$config); + + $jsConfig = $this->getConfiguration($this, Input::NAME); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + /** * Check if option value * diff --git a/app/code/Magento/Ui/Component/Form/Element/Textarea.php b/app/code/Magento/Ui/Component/Form/Element/Textarea.php index 0b7031ef8f6ce2dd7a6e76dcc810469704ff2d74..d7f12580d67d5c6b4f68c22a437f7cc28f228af6 100644 --- a/app/code/Magento/Ui/Component/Form/Element/Textarea.php +++ b/app/code/Magento/Ui/Component/Form/Element/Textarea.php @@ -8,7 +8,30 @@ namespace Magento\Ui\Component\Form\Element; /** * Class Textarea */ -class Textarea extends AbstractFormElement +class Textarea extends AbstractElement { - // + const NAME = 'textarea'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + + $jsConfig = $this->getConfiguration($this, Input::NAME); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } } diff --git a/app/code/Magento/Ui/Component/Form/Field.php b/app/code/Magento/Ui/Component/Form/Field.php index 5f0c94dd42d765eb405c94b154e0c0956c10010d..890288d086a2a9c22ca51bb912391e6e220a42b5 100644 --- a/app/code/Magento/Ui/Component/Form/Field.php +++ b/app/code/Magento/Ui/Component/Form/Field.php @@ -5,29 +5,107 @@ */ namespace Magento\Ui\Component\Form; +use Magento\Framework\Exception\LocalizedException; +use Magento\Ui\Component\AbstractComponent; +use Magento\Framework\View\Element\UiComponentFactory; use Magento\Framework\View\Element\UiComponentInterface; -use Magento\Ui\Component\AbstractView; +use Magento\Framework\View\Element\UiComponent\ContextInterface; /** - * Class AbstractFormElement + * Class Field */ -class Field extends AbstractView implements UiComponentInterface +class Field extends AbstractComponent { + const NAME = 'field'; + + /** + * Wrapped component + * + * @var UiComponentInterface + */ + protected $wrappedComponent; + + /** + * UI component factory + * + * @var UiComponentFactory + */ + protected $uiComponentFactory; + /** - * @return mixed + * Constructor + * + * @param ContextInterface $context + * @param UiComponentFactory $uiComponentFactory + * @param UiComponentInterface[] $components + * @param array $data */ - public function renderHeader() + public function __construct( + ContextInterface $context, + UiComponentFactory $uiComponentFactory, + array $components = [], + array $data = [] + ) { + $this->uiComponentFactory = $uiComponentFactory; + parent::__construct($context, $components, $data); + } + + /** + * Get component name + * + * @return string + */ + public function getComponentName() { - return $this->getRenderEngine()->render($this, $this->getHeaderTemplate()); + return 'form.' . $this->wrappedComponent->getComponentName(); } /** - * Getting template for field header section + * Prepare component configuration * - * @return string|false + * @return void + * @throws \Magento\Framework\Exception\LocalizedException */ - public function getHeaderTemplate() + public function prepare() { - return isset($this->configuration['header_template']) ? $this->configuration['header_template'] : false; + parent::prepare(); + $formElement = $this->getData('config/formElement'); + if (null === $formElement) { + throw new LocalizedException(__( + 'The configuration parameter "formElement" is a required for "' . $this->getName() . '" field.' + )); + } + // Create of wrapped component + $this->wrappedComponent = $this->uiComponentFactory->create( + $this->getName(), + $formElement, + array_merge(['context' => $this->getContext()], (array) $this->getData()) + ); + $this->wrappedComponent->prepare(); + + // To prepare the component configuration + $wrappedComponentConfig = $this->getConfiguration($this->wrappedComponent); + $jsConfig = array_replace_recursive( + $wrappedComponentConfig, + $this->getConfiguration($this, $this->wrappedComponent->getComponentName()) + ); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + + /** + * Get JS config + * + * @return array + */ + public function getJsConfig() + { + if (isset($this->wrappedComponent)) { + return array_replace_recursive( + (array) $this->wrappedComponent->getData('config'), + (array) $this->getData('config') + ); + } + + return (array) $this->getData('config'); } } diff --git a/app/code/Magento/Ui/Component/Form/Fieldset.php b/app/code/Magento/Ui/Component/Form/Fieldset.php index 03fd8f62d6e847ba154c2390de4cde80732dcca0..f8d9ee0b012330a138d9d5cbb4ce743d07aef753 100644 --- a/app/code/Magento/Ui/Component/Form/Fieldset.php +++ b/app/code/Magento/Ui/Component/Form/Fieldset.php @@ -5,14 +5,19 @@ */ namespace Magento\Ui\Component\Form; -use Magento\Ui\Component\AbstractView; +use Magento\Framework\Exception\LocalizedException; +use Magento\Ui\Component\Container; +use Magento\Ui\Component\AbstractComponent; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; /** * Class Fieldset */ -class Fieldset extends AbstractView +class Fieldset extends AbstractComponent { - const UI_ELEMENT_FIELDSET = 'fieldset'; + const NAME = 'fieldset'; /** * @var bool @@ -20,43 +25,125 @@ class Fieldset extends AbstractView protected $collapsible = false; /** + * @var UiComponentInterface[] + */ + protected $fieldsInContainers = []; + + /** + * Constructor + * + * @param ContextInterface $context + * @param UiComponentFactory $uiComponentFactory + * @param UiComponentInterface[] $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + UiComponentFactory $uiComponentFactory, + array $components = [], + array $data = [] + ) { + $this->uiComponentFactory = $uiComponentFactory; + parent::__construct($context, $components, $data); + } + + /** + * Get component name + * * @return string */ - public function getLegendText() + public function getComponentName() { - return $this->getData('config/label'); + return static::NAME; } /** - * @return bool - * @SuppressWarnings(PHPMD.BooleanGetMethodName) + * Prepare component configuration + * + * @return void */ - public function getIsCollapsible() + public function prepare() { - return $this->getData('config/collapsible', $this->collapsible); + parent::prepare(); + foreach ($this->getChildComponents() as $name => $child) { + if ($child instanceof Container) { + $this->fieldsInContainers += $child->getChildComponents(); + } + } + + $fieldsMeta = $this->getContext()->getDataProvider()->getFieldsMetaInfo($this->getName()); + foreach ($fieldsMeta as $name => $fieldData) { + if (empty($fieldData)) { + continue; + } + $fieldComponent = $this->getComponent($name); + $this->prepareField($fieldData, $name, $fieldComponent); + } + + $jsConfig = $this->getConfiguration($this); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); } /** - * @return string + * Prepare field component + * + * @param array $fieldData + * @param string $name + * @param UiComponentInterface|null $fieldComponent + * @return void + * @throws \Magento\Framework\Exception\LocalizedException */ - public function getAjaxUrl() + protected function prepareField(array $fieldData, $name, UiComponentInterface $fieldComponent = null) { - return $this->getData('config/source'); + if ($fieldComponent === null) { + if (isset($this->fieldsInContainers[$name])) { + $this->updateField($fieldData, $this->fieldsInContainers[$name]); + return; + } + $fieldData = $this->updateDataScope($fieldData, $name); + $argument = [ + 'context' => $this->getContext(), + 'data' => [ + 'name' => $name, + 'config' => $fieldData + ] + ]; + $fieldComponent = $this->uiComponentFactory->create($name, 'field', $argument); + $fieldComponent->prepare(); + $this->addComponent($name, $fieldComponent); + } else { + $this->updateField($fieldData, $fieldComponent); + } } /** - * @return string + * Update field data + * + * @param array $fieldData + * @param UiComponentInterface $component + * @return void */ - public function getContent() + protected function updateField(array $fieldData, UiComponentInterface $component) { - return $this->getData('config/content'); + $config = $component->getData('config'); + // XML data configuration override configuration coming from the DB + $config = array_replace_recursive($fieldData, $config); + $config = $this->updateDataScope($config, $component->getName()); + $component->setData('config', $config); } /** + * Update DataScope + * + * @param array $data + * @param string $name * @return array */ - public function getChildren() + protected function updateDataScope(array $data, $name) { - return $this->getData('children'); + if (!isset($data['dataScope'])) { + $data['dataScope'] = $name; + } + return $data; } } diff --git a/app/code/Magento/Ui/Component/Form/Fieldset/Factory.php b/app/code/Magento/Ui/Component/Form/Fieldset/Factory.php index f0b10c0b2dd618c161023307a70cab513e245849..191778de59da1f7813cedb6fa4f7daff481bc477 100644 --- a/app/code/Magento/Ui/Component/Form/Fieldset/Factory.php +++ b/app/code/Magento/Ui/Component/Form/Fieldset/Factory.php @@ -5,8 +5,8 @@ */ namespace Magento\Ui\Component\Form\Fieldset; -use Magento\Framework\ObjectManagerInterface; use Magento\Ui\Component\Form\Fieldset; +use Magento\Framework\ObjectManagerInterface; /** * Class Factory diff --git a/app/code/Magento/Ui/Component/Layout.php b/app/code/Magento/Ui/Component/Layout.php new file mode 100644 index 0000000000000000000000000000000000000000..369701019290432daf1a8e3fc31d7cf0166a4843 --- /dev/null +++ b/app/code/Magento/Ui/Component/Layout.php @@ -0,0 +1,89 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component; + +use Magento\Ui\Component\Layout\LayoutPool; +use Magento\Framework\View\Element\Template; +use Magento\Framework\View\Element\UiComponent\LayoutInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; + +/** + * Class Layout + */ +class Layout extends AbstractComponent +{ + const NAME = 'layout'; + + /** + * @var LayoutPool + */ + protected $layoutPool; + + /** + * @var string + */ + protected $type; + + /** + * @var LayoutInterface + */ + protected $layoutTypeObject; + + /** + * @var array + */ + protected $structure = []; + + /** + * Constructor + * + * @param ContextInterface $context + * @param LayoutPool $layoutPool + * @param string $type + * @param array $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + LayoutPool $layoutPool, + $type, + array $components = [], + array $data = [] + ) { + $this->layoutPool = $layoutPool; + $this->type = $type; + parent::__construct($context, $components, $data); + } + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Register component and build layout structure + * + * @inheritdoc + */ + public function prepare() + { + $this->layoutTypeObject = $this->layoutPool->create($this->type); + $this->structure = $this->layoutTypeObject->build($this); + } + + /** + * @return array + */ + public function getStructure() + { + return $this->structure; + } +} diff --git a/app/code/Magento/Ui/Component/Layout/AbstractStructure.php b/app/code/Magento/Ui/Component/Layout/AbstractStructure.php deleted file mode 100644 index 8fdd8616b7c8b2b22eb3b2b390e06d3d534ed9b8..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Layout/AbstractStructure.php +++ /dev/null @@ -1,564 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Layout; - -use Magento\Framework\View\Element\Template; -use Magento\Framework\View\Element\Template\Context as TemplateContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigFactory; -use Magento\Framework\View\Element\UiComponent\Context; -use Magento\Framework\View\Element\UiElementFactory; -use Magento\Ui\Component\AbstractView; -use Magento\Ui\Component\Layout\Tabs\TabInterface; -use Magento\Ui\ContentType\ContentTypeFactory; -use Magento\Ui\DataProvider\Factory as DataProviderFactory; -use Magento\Ui\DataProvider\Manager; -use Magento\Ui\DataProvider\Metadata; - -/** - * Class AbstractStructure - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class AbstractStructure extends AbstractView -{ - /** - * @var array - */ - protected $structure = [ - 'sections' => [], - 'areas' => [], - 'groups' => [], - 'elements' => [], - ]; - - /** - * @var UiElementFactory - */ - protected $factory; - - /** - * Layout Namespace - * - * @var string - */ - protected $ns; - - /** - * @var int - */ - protected $sortInc = 10; - - /** - * Constructor - * - * @param TemplateContext $context - * @param Context $renderContext - * @param ContentTypeFactory $contentTypeFactory - * @param ConfigFactory $configFactory - * @param ConfigBuilderInterface $configBuilder - * @param DataProviderFactory $dataProviderFactory - * @param Manager $dataProviderManager - * @param UiElementFactory $factory - * @param array $data - */ - public function __construct( - TemplateContext $context, - Context $renderContext, - ContentTypeFactory $contentTypeFactory, - ConfigFactory $configFactory, - ConfigBuilderInterface $configBuilder, - DataProviderFactory $dataProviderFactory, - Manager $dataProviderManager, - UiElementFactory $factory, - array $data = [] - ) { - $this->factory = $factory; - parent::__construct( - $context, - $renderContext, - $contentTypeFactory, - $configFactory, - $configBuilder, - $dataProviderFactory, - $dataProviderManager, - $data - ); - } - - /** - * @inheritdoc - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - public function prepare() - { - $this->ns = $this->getData('name'); - - $this->initSections(); - $this->initAreas(); - $this->initGroups(); - $this->initElements(); - - foreach ($this->getDataSources() as $name => $dataSourceConfig) { - $this->processDataSource($dataSourceConfig); - } - - $this->processChildBLocks(); - - $this->renderContext->getStorage()->addLayoutStructure( - $this->getDataScope(), - [ - 'children' => $this->structure - ] - ); - - $navBlock = $this->factory->create( - \Magento\Ui\Component\Layout\Tabs\Nav::NAME, - [ - 'data_scope' => $this->ns - ] - ); - if ($this->getData('configuration/tabs_container_name')) { - $this->getRenderContext()->getPageLayout() - ->addBlock($navBlock, 'tabs_nav', $this->getData('configuration/tabs_container_name')); - } else { - $this->getRenderContext()->getPageLayout() - ->addBlock($navBlock, 'tabs_nav', 'content'); - } - } - - /** - * @return string - */ - public function getDataScope() - { - return $this->ns; - } - - /** - * Prepare initial structure for sections - * - * @return void - */ - protected function initSections() - { - $this->structure['sections'] = [ - 'type' => \Magento\Ui\Component\Layout\Tabs\Nav::NAME, - 'config' => [ - 'label' => $this->getData('label'), - ], - 'children' => [], - ]; - } - - /** - * Prepare initial structure for areas - * - * @return void - */ - protected function initAreas() - { - $this->structure['areas'] = [ - 'type' => 'form', - 'config' => [ - 'namespace' => $this->ns, - ], - 'children' => [], - ]; - } - - /** - * Prepare initial structure for groups - * - * @return void - */ - protected function initGroups() - { - $this->structure['groups'] = [ - 'children' => [], - ]; - } - - /** - * Prepare initial structure for elements - * - * @return void - */ - protected function initElements() - { - $this->structure['elements'] = [ - 'children' => [], - ]; - } - - /** - * Get registered Data Sources - * - * @return array - */ - protected function getDataSources() - { - return $this->getData('data_sources'); - } - - /** - * @param array $dataSourceConfig - * @return void - * @SuppressWarnings(PHPMD.NPathComplexity) - */ - protected function processDataSource(array $dataSourceConfig) - { - $id = $this->renderContext->getRequestParam('id'); - $dataSource = $dataSourceConfig['name']; - - $meta = $this->dataManager->getMetadata($dataSource); - - $this->addArea( - $dataSource, - [ - 'insertTo' => [ - $this->ns . '.sections' => [ - 'position' => $this->getNextSortInc(), - ], - ], - 'config' => [ - 'label' => $meta->getLabel(), - ] - ] - ); - $referenceGroupName = $this->addGroup( - $dataSource, - [ - 'label' => $meta->getLabel() - ] - ); - - $elements = $meta->getFields(); - uasort($elements, [$this, 'sortChildren']); - foreach ($elements as $name => $element) { - if (isset($element['visible']) && $element['visible'] === 'false') { - continue; - } - if ($name != Metadata::CHILD_DATA_SOURCES) { - $collection = & $this->structure['elements']; - $this->addElementToCollection($collection, $name, "{$dataSource}.{$name}", $element); - - $referenceName = "{$this->ns}.elements.{$name}"; - $this->addElementToGroup($dataSource, $name, $referenceName, $element); - } - } - - $this->addToArea($dataSource, $referenceGroupName); - - $children = $meta->get(Metadata::CHILD_DATA_SOURCES); - foreach ($children as $childName => $childMeta) { - $this->processChildDataSource($dataSource, $childName, $childMeta); - } - - $preparedData = []; - $data = $id ? $this->dataManager->getData($dataSource, ['entity_id' => $id]) : []; - if ($data) { - $preparedData[$dataSource] = []; - foreach (array_shift($data) as $key => $value) { - $preparedData[$dataSource][$key] = $value; - } - } - - $this->renderContext->getStorage()->addDataSource( - $this->getData('name'), - [ - 'data' => $preparedData, - 'config' => $dataSourceConfig, - ] - ); - } - - /** - * @param string $dataSource - * @param string $childName - * @param \Magento\Ui\DataProvider\Metadata $childMeta - * @return void - */ - protected function processChildDataSource($dataSource, $childName, \Magento\Ui\DataProvider\Metadata $childMeta) - { - $this->addArea( - $childName, - [ - 'insertTo' => [ - $this->ns . '.sections' => [ - 'position' => $this->getNextSortInc(), - ], - ], - 'config' => [ - 'label' => $childMeta->getLabel(), - ] - ] - ); - $referenceChildGroupName = $this->addGroup( - $childName, - [ - 'label' => $childMeta->getLabel() - ] - ); - $this->addToArea($childName, $referenceChildGroupName); - - $itemTemplate = [ - 'type' => $this->ns, - 'isTemplate' => true, - 'component' => 'Magento_Ui/js/form/components/collection/item', - 'childType' => 'group', - 'config' => [ - 'label' => __('New ' . $childMeta->getLabel()), - ], - ]; - - $elements = $childMeta->getFields(); - uasort($elements, [$this, 'sortChildren']); - foreach ($elements as $name => $element) { - if (isset($element['visible']) && $element['visible'] === 'false') { - continue; - } - $this->addElementToCollection($itemTemplate, $name, $name, $element); - } - - $referenceCollectionName = $this->addCollection( - $childName . 'Collection', - "{$dataSource}.{$childName}", - [ - 'active' => 1, - 'label' => $childMeta->getLabel(), - 'removeLabel' => __('Remove ' . $childMeta->getLabel()), - 'removeMessage' => __('Are you sure you want to delete this item?'), - 'addLabel' => __('Add New ' . $childMeta->getLabel()), - 'itemTemplate' => 'item_template' - ] - ); - $this->addTemplateToCollection($childName . 'Collection', 'item_template', $itemTemplate); - - $this->structure['groups']['children'][$childName]['children'][] = $referenceCollectionName; - } - - /** - * @throws \Exception - * @return void - */ - protected function processChildBlocks() - { - //Add child blocks content - foreach ($this->getData('child_blocks') as $blockName => $childBlock) { - /** @var TabInterface $childBlock */ - if (!($childBlock instanceof TabInterface)) { - throw new \Exception(__('"%1" tab should implement TabInterface', $blockName)); - } - if (!$childBlock->canShowTab()) { - continue; - } - $childBlock->setData('target_form', $this->getDataScope()); - $sortOrder = $childBlock->hasSortOrder() ? $childBlock->getSortOrder() : $this->getNextSortInc(); - $this->addArea( - $blockName, - [ - 'insertTo' => [ - $this->ns . '.sections' => [ - 'position' => (int)$sortOrder, - ], - ], - 'config' => [ - 'label' => $childBlock->getTabTitle(), - ] - ] - ); - - $config = [ - 'label' => $childBlock->getTabTitle(), - ]; - if ($childBlock->isAjaxLoaded()) { - $config['source'] = $childBlock->getTabUrl(); - } else { - $config['content'] = $childBlock->toHtml(); - } - $referenceGroupName = $this->addGroup($blockName, $config, 'html_content'); - $this->addToArea($blockName, $referenceGroupName); - } - } - - /** - * @param string $name - * @param array $config - * @return string - */ - protected function addArea($name, array $config = []) - { - $config['type'] = 'tab'; - $this->structure['areas']['children'][$name] = $config; - return "{$this->ns}.areas.{$name}"; - } - - /** - * @param string $areaName - * @param string $itemName - * @return void - */ - protected function addToArea($areaName, $itemName) - { - $this->structure['areas']['children'][$areaName]['children'][] = $itemName; - } - - /** - * @param string $groupName - * @param array $config - * @param string $type - * @return string - */ - protected function addGroup($groupName, array $config = [], $type = 'fieldset') - { - $this->structure['groups']['children'][$groupName] = [ - 'type' => $type, - 'config' => $config, - ]; - return "{$this->ns}.groups.{$groupName}"; - } - - /** - * @param string $groupName - * @param string $elementName - * @param string $referenceElementName - * @param array $element - * @return void - */ - protected function addElementToGroup($groupName, $elementName, $referenceElementName, array $element) - { - if (isset($element['fieldGroup'])) { - if ($elementName === $element['fieldGroup']) { - $this->structure['groups']['children'][$groupName]['children'][] = $referenceElementName; - } - } else { - $this->structure['groups']['children'][$groupName]['children'][] = $referenceElementName; - } - } - - /** - * @param array $collection - * @param string $elementName - * @param string $dataScope - * @param array $element - * @return string - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - */ - protected function addElementToCollection(array & $collection, $elementName, $dataScope, array $element) - { - $collection['children'][$elementName] = [ - 'type' => 'group', - ]; - if (isset($element['fieldGroup'])) { - $elementName = $element['fieldGroup']; - if ($elementName === $element['fieldGroup']) { - $collection['children'][$elementName]['config'] = [ - 'displayArea' => $element['displayArea'], - ]; - } - } else { - $collection['children'][$elementName]['config'] = [ - 'displayArea' => $element['displayArea'], - ]; - } - - if (isset($element['constraints'])) { - if (isset($element['constraints']['validate'])) { - $element['validation'] = $element['constraints']['validate']; - } - if (isset($element['constraints']['filter'])) { - foreach ($element['constraints']['filter'] as $filter) { - $element['listeners'] = [ - "data:" . $filter['on'] => [ - 'filter' => [$filter['by']], - ], - ]; - } - } - unset($element['constraints']); - } - if (isset($element['size'])) { - $collection['children'][$elementName]['dataScope'] = $dataScope; - $size = (int)$element['size']; - for ($i = 0; $i < $size; $i++) { - $collection['children'][$elementName]['children'][] = [ - 'type' => $element['formElement'], - 'dataScope' => (string)$i, - 'config' => $element, - ]; - if (isset($element['validation']['required-entry'])) { - unset($element['validation']['required-entry']); - } - } - } else { - $collection['children'][$elementName]['children'][] = [ - 'type' => $element['formElement'], - 'dataScope' => $dataScope, - 'config' => $element, - ]; - } - } - - /** - * @param string $collectionName - * @param string $dataScope - * @param array $config - * @return string - */ - protected function addCollection($collectionName, $dataScope, array $config = []) - { - $this->structure['groups']['children'][$collectionName] = [ - 'type' => 'collection', - 'dataScope' => $dataScope, - 'config' => $config, - ]; - return "{$this->ns}.groups.{$collectionName}"; - } - - /** - * @param string $collectionName - * @param string $templateName - * @param array $template - * @return void - */ - protected function addTemplateToCollection($collectionName, $templateName, $template) - { - $this->structure['groups']['children'][$collectionName]['children'][$templateName] = $template; - } - - /** - * @return int - */ - protected function getNextSortInc() - { - $this->sortInc += 10; - return $this->sortInc; - } - - /** - * Sort child elements - * - * @param array $one - * @param array $two - * @return int - * @SuppressWarnings(PHPMD.NPathComplexity) - */ - public function sortChildren(array $one, array $two) - { - if (!isset($one['sortOrder'])) { - return 1; - } - if (!isset($two['sortOrder'])) { - return -1; - } - $sortOrderA = isset($one['sortOrder']) ? intval($one['sortOrder']) : -1; - $sortOrderB = isset($two['sortOrder']) ? intval($two['sortOrder']) : -1; - if ($sortOrderA == $sortOrderB) { - return 0; - } - return ($sortOrderA < $sortOrderB) ? -1 : 1; - } -} diff --git a/app/code/Magento/Ui/Component/Layout/Generator/Structure.php b/app/code/Magento/Ui/Component/Layout/Generator/Structure.php new file mode 100644 index 0000000000000000000000000000000000000000..c26b9c40664a3bd93122a7f6bee509264fcb8049 --- /dev/null +++ b/app/code/Magento/Ui/Component/Layout/Generator/Structure.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Layout\Generator; + +use Magento\Ui\Component\Layout\LayoutPool; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\LayoutInterface; + +/** + * Class Structure + */ +class Structure +{ + /** + * @var LayoutPool + */ + protected $layoutPool; + + /** + * Constructor + * + * @param LayoutPool $layoutPool + */ + public function __construct(LayoutPool $layoutPool) + { + $this->layoutPool = $layoutPool; + } + + /** + * Build component structure and retrieve + * + * @param UiComponentInterface $component + * @return array + */ + public function generate(UiComponentInterface $component) + { + /** @var LayoutInterface $layout */ + if (!$layoutDefinition = $component->getData('layout')) { + $layoutDefinition = ['type' => 'generic']; + } + $layout = $this->layoutPool->create($layoutDefinition['type'], $layoutDefinition); + + return $layout->build($component); + } +} diff --git a/app/code/Magento/Ui/Component/Layout/Generic.php b/app/code/Magento/Ui/Component/Layout/Generic.php new file mode 100644 index 0000000000000000000000000000000000000000..04b0fbabe28de22f1799aa4dc43bd1740022e3bf --- /dev/null +++ b/app/code/Magento/Ui/Component/Layout/Generic.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Layout; + +use Magento\Framework\View\Element\UiComponent\DataSourceInterface; +use Magento\Framework\View\Element\UiComponent\JsConfigInterface; +use Magento\Framework\View\Element\UiComponent\LayoutInterface; +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Class Generic + */ +class Generic implements LayoutInterface +{ + /** + * Generate Java Script configuration element + * + * @param UiComponentInterface $component + * @return array + */ + public function build(UiComponentInterface $component) + { + $children = []; + $context = $component->getContext(); + $this->addChildren($children, $component, $component->getName()); + $dataSources = $component->getDataSourceData(); + $configuration = [ + 'types' => $context->getComponentsDefinitions(), + 'components' => [ + $context->getNamespace() => [ + 'children' => array_merge($children, $dataSources) + ] + ] + ]; + return $configuration; + } + + /** + * Add children data + * + * @param array $topNode + * @param UiComponentInterface $component + * @param string $componentType + * @return void + */ + protected function addChildren( + array &$topNode, + UiComponentInterface $component, + $componentType + ) { + $childrenNode = []; + $childComponents = $component->getChildComponents(); + if (!empty($childComponents)) { + /** @var UiComponentInterface $child */ + foreach ($childComponents as $child) { + if ($child instanceof DataSourceInterface) { + continue; + } + self::addChildren($childrenNode, $child, $child->getComponentName()); + } + } + /** @var JsConfigInterface $component */ + $config = $component->getJsConfig(); + if (is_string($config)) { + $topNode[] = $config; + } else { + $nodeData = [ + 'type' => $componentType, + 'name' => $component->getName(), + ]; + if (!empty($childrenNode)) { + $nodeData['children'] = $childrenNode; + } + if (isset($config['dataScope'])) { + $nodeData['dataScope'] = $config['dataScope']; + unset($config['dataScope']); + } + if (!empty($config)) { + $nodeData['config'] = $config; + } + $topNode[] = $nodeData; + } + } +} diff --git a/app/code/Magento/Ui/Component/Layout/Group.php b/app/code/Magento/Ui/Component/Layout/Group.php deleted file mode 100644 index 4b3eb842c56f9805ae8647c3376b4334ead92199..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Layout/Group.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Layout; - -use Magento\Ui\Component\AbstractView; - -/** - * Class Group - */ -class Group extends AbstractView -{ - /** - * @return string - */ - public function getIsRequired() - { - return $this->getData('required') ? 'required' : ''; - } -} diff --git a/app/code/Magento/Ui/Component/Layout/LayoutPool.php b/app/code/Magento/Ui/Component/Layout/LayoutPool.php new file mode 100644 index 0000000000000000000000000000000000000000..b15a513ff42c604797718731bb16798f670b95a4 --- /dev/null +++ b/app/code/Magento/Ui/Component/Layout/LayoutPool.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Layout; + +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\Element\UiComponent\LayoutInterface; + +/** + * Class LayoutPool + */ +class LayoutPool +{ + const DEFAULT_CLASS = 'Magento\Ui\Component\Layout\Generic'; + + /** + * Layouts pool + * + * @var array + */ + protected $types; + + /** + * @var ObjectManagerInterface + */ + protected $objectManager; + + /** + * Constructor + * + * @param ObjectManagerInterface $objectManager + * @param array $types + */ + public function __construct( + ObjectManagerInterface $objectManager, + array $types = [] + ) { + $this->objectManager = $objectManager; + $this->types = $types; + } + + /** + * Get layout by type + * + * @param string $layoutType + * @param array $arguments + * @return LayoutInterface + */ + public function create($layoutType, array $arguments = []) + { + if (!isset($this->types[$layoutType])) { + throw new \InvalidArgumentException(sprintf('Unknown layout type "%s"', $layoutType)); + } + $defArgs = $this->types[$layoutType]; + $class = isset($defArgs['class']) ? $defArgs['class'] : self::DEFAULT_CLASS; + unset($defArgs['class']); + if ($defArgs) { + $arguments = array_merge($defArgs, $arguments); + } + return $this->objectManager->create($class, $arguments); + } +} diff --git a/app/code/Magento/Ui/Component/Layout/Tabs.php b/app/code/Magento/Ui/Component/Layout/Tabs.php index d56881d3904c3b2f8134020ffbc59b3f7b93f506..ffdfc631486b59dff94fa9b0538e32af9b72641f 100644 --- a/app/code/Magento/Ui/Component/Layout/Tabs.php +++ b/app/code/Magento/Ui/Component/Layout/Tabs.php @@ -5,13 +5,396 @@ */ namespace Magento\Ui\Component\Layout; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\View\Element\Template; +use Magento\Ui\Component\Layout\Tabs\TabInterface; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\LayoutInterface; +use Magento\Framework\View\Element\UiComponent\JsConfigInterface; /** * Class Tabs - * - * @package Magento\Ui\Component\Layout */ -class Tabs extends AbstractStructure +class Tabs extends Generic implements LayoutInterface { - const NAME = 'tabs'; + /** + * @var string + */ + protected $navContainerName; + + /** + * @var UiComponentInterface + */ + protected $component; + + /** + * @var string + */ + protected $namespace; + + /** + * @var array + */ + protected $structure = []; + + /** + * @var int + */ + protected $sortIncrement = 10; + + /** + * @var UiComponentFactory + */ + protected $uiComponentFactory; + + /** + * Constructor + * + * @param UiComponentFactory $uiComponentFactory + * @param null|string $navContainerName + */ + public function __construct(UiComponentFactory $uiComponentFactory, $navContainerName = null) + { + $this->navContainerName = $navContainerName; + $this->uiComponentFactory = $uiComponentFactory; + } + + /** + * Build + * + * @param UiComponentInterface $component + * @return array + */ + public function build(UiComponentInterface $component) + { + $this->component = $component; + $this->namespace = $component->getContext()->getNamespace(); + + $this->addNavigationBlock(); + + // Initialization of structure components + $this->initSections(); + $this->initAreas(); + + return parent::build($component); + } + + /** + * Add children data + * + * @param array $topNode + * @param UiComponentInterface $component + * @param string $componentType + * @return void + * @throws \Magento\Framework\Exception\LocalizedException + */ + protected function addChildren(array &$topNode, UiComponentInterface $component, $componentType) + { + $childrenAreas = []; + $collectedComponents = []; + + foreach ($component->getContext()->getDataProvider()->getMeta() as $name => $meta) { + $childComponent = $component->getComponent($name); + if (null === $childComponent) { + continue; + } + $collectedComponents[$childComponent->getName()] = true; + + if (isset($meta['is_collection']) && $meta['is_collection'] === true) { + $label = $childComponent->getData('config/label'); + $this->component->getContext()->addComponentDefinition( + 'collection', + [ + 'component' => 'Magento_Ui/js/form/components/collection', + 'extends' => $this->namespace + ] + ); + + /** + * @var UiComponentInterface $childComponent + * @var array $structure + */ + list($childComponent, $structure) = $this->prepareChildComponents($childComponent, $name); + + $childrenStructure = $structure[$name]['children']; + + $structure[$name]['children'] = [ + $name . '_collection' => [ + 'type' => 'collection', + 'config' => [ + 'active' => 1, + 'removeLabel' => __('Remove ' . $label), + 'addLabel' => __('Add New ' . $label), + 'removeMessage' => $childComponent->getData('config/removeMessage'), + 'itemTemplate' => 'item_template', + ], + 'children' => [ + 'item_template' => ['type' => $this->namespace, + 'isTemplate' => true, + 'component' => 'Magento_Ui/js/form/components/collection/item', + 'childType' => 'group', + 'config' => [ + 'label' => __('New ' . $label), + ], + 'children' => $childrenStructure + ] + ] + ] + ]; + } else { + /** + * @var UiComponentInterface $childComponent + * @var array $structure + */ + list($childComponent, $structure) = $this->prepareChildComponents($childComponent, $name); + } + + $tabComponent = $this->createTabComponent($childComponent, $name); + + $childrenAreas[$name] = [ + 'type' => $tabComponent->getComponentName(), + 'dataScope' => 'data.' . $name, + 'config' => isset($meta['config']) ? $meta['config'] : [], + 'insertTo' => [ + $this->namespace . '.sections' => [ + 'position' => $this->getNextSortIncrement() + ] + ], + 'children' => $structure, + ]; + } + + $this->addWrappedBlock($childrenAreas, $component, $collectedComponents); + + $this->structure[static::AREAS_KEY]['children'] = $childrenAreas; + $topNode = $this->structure; + } + + /** + * Add wrapped layout block + * + * @param array $areas + * @param UiComponentInterface $component + * @param array $collectedComponents + * @return void + */ + protected function addWrappedBlock(array &$areas, UiComponentInterface $component, array $collectedComponents) + { + /** @var \Magento\Ui\Component\Wrapper\Block $childComponent */ + foreach ($component->getChildComponents() as $name => $childComponent) { + /** @var TabInterface $block */ + $block = $childComponent->getBlock(); + if (isset($collectedComponents[$name]) || !($block instanceof TabInterface) || !$block->canShowTab()) { + continue; + } + $block->setData('target_form', $this->namespace); + + $config = []; + if ($block->isAjaxLoaded()) { + $config['url'] = $block->getTabUrl(); + } else { + $config['content'] = $block->toHtml(); + } + + $tabComponent = $this->createTabComponent($childComponent, $name); + $areas[$name] = [ + 'type' => $tabComponent->getComponentName(), + 'dataScope' => $name, + 'insertTo' => [ + $this->namespace . '.sections' => [ + 'position' => $block->hasSortOrder() ? $block->getSortOrder() : $this->getNextSortIncrement() + ] + ], + 'config' => [ + 'label' => $block->getTabTitle() + ], + 'children' => [ + $name => [ + 'type' => 'html_content', + 'dataScope' => $name, + 'config' => $config, + ] + ], + ]; + } + + $this->component->getContext()->addComponentDefinition( + 'html_content', + [ + 'component' => 'Magento_Ui/js/form/components/html', + 'extends' => $this->namespace + ] + ); + } + + /** + * Create tab component + * + * @param UiComponentInterface $childComponent + * @param string $name + * @return UiComponentInterface + * @throws \Magento\Framework\Exception\LocalizedException + */ + protected function createTabComponent(UiComponentInterface $childComponent, $name) + { + $tabComponent = $this->uiComponentFactory->create( + $name, + 'tab', + [ + 'context' => $this->component->getContext(), + 'components' => [$childComponent->getName() => $childComponent] + ] + ); + $tabComponent->prepare(); + $this->component->addComponent($name, $tabComponent); + + return $tabComponent; + } + + /** + * To prepare the structure of child components + * + * @param UiComponentInterface $component + * @param string $parentName + * @return array + */ + protected function prepareChildComponents(UiComponentInterface $component, $parentName) + { + $name = $component->getName(); + $childComponents = $component->getChildComponents(); + + $childrenStructure = []; + foreach ($childComponents as $childName => $child) { + $isVisible = $child->getData('config/visible'); + if ($isVisible !== null && $isVisible == 0) { + continue; + } + /** + * @var UiComponentInterface $childComponent + * @var array $childStructure + */ + list($childComponent, $childStructure) = $this->prepareChildComponents($child, $component->getName()); + $childrenStructure = array_merge($childrenStructure, $childStructure); + $component->addComponent($childName, $childComponent); + } + + $structure = [ + $name => [ + 'type' => $component->getComponentName(), + 'name' => $component->getName(), + 'children' => $childrenStructure + ] + ]; + + /** @var JsConfigInterface $component */ + list($config, $dataScope) = $this->prepareConfig((array) $component->getJsConfig(), $name, $parentName); + + if ($dataScope !== false) { + $structure[$name]['dataScope'] = $dataScope; + } + $structure[$name]['config'] = $config; + + return [$component, $structure]; + } + + /** + * Prepare config + * + * @param array $config + * @param string $name + * @param string $parentName + * @return array + */ + protected function prepareConfig(array $config, $name, $parentName) + { + $dataScope = false; + if (!isset($config['displayArea'])) { + $config['displayArea'] = 'body'; + } + if (isset($config['dataScope'])) { + $dataScope = $config['dataScope']; + unset($config['dataScope']); + } else if ($name !== $parentName) { + $dataScope = $name; + } + + return [$config, $dataScope]; + } + + /** + * Prepare initial structure for sections + * + * @return void + */ + protected function initSections() + { + $this->structure[static::SECTIONS_KEY] = [ + 'type' => 'nav', + 'config' => [ + 'label' => $this->component->getData('label'), + ], + 'children' => [], + ]; + } + + /** + * Prepare initial structure for areas + * + * @return void + */ + protected function initAreas() + { + $this->structure[static::AREAS_KEY] = [ + 'type' => $this->namespace, + 'config' => [ + 'namespace' => $this->namespace, + ], + 'children' => [], + ]; + } + + /** + * Add navigation block + * + * @return void + */ + protected function addNavigationBlock() + { + $pageLayout = $this->component->getContext()->getPageLayout(); + /** @var \Magento\Ui\Component\Layout\Tabs\Nav $navBlock */ + if (isset($this->navContainerName)) { + $navBlock = $pageLayout->addBlock( + 'Magento\Ui\Component\Layout\Tabs\Nav', + 'tabs_nav', + $this->navContainerName + ); + } else { + $navBlock = $pageLayout->addBlock('Magento\Ui\Component\Layout\Tabs\Nav', 'tabs_nav', 'content'); + } + $navBlock->setTemplate('Magento_Ui::layout/tabs/nav/default.phtml'); + $navBlock->setData('data_scope', $this->namespace); + + $this->component->getContext()->addComponentDefinition( + 'nav', + [ + 'component' => 'Magento_Ui/js/form/components/tab_group', + 'config' => [ + 'template' => 'ui/tab' + ], + 'extends' => $this->namespace + ] + ); + } + + /** + * Get next sort increment + * + * @return int + */ + protected function getNextSortIncrement() + { + $this->sortIncrement += 10; + return $this->sortIncrement; + } } diff --git a/app/code/Magento/Ui/Component/Layout/Tabs/Nav.php b/app/code/Magento/Ui/Component/Layout/Tabs/Nav.php index 885eb69e277de40df6f7d45d4c41928840ea6385..7c93e19f9a0d8653927119f5d8a94d205e41c59c 100644 --- a/app/code/Magento/Ui/Component/Layout/Tabs/Nav.php +++ b/app/code/Magento/Ui/Component/Layout/Tabs/Nav.php @@ -5,12 +5,12 @@ */ namespace Magento\Ui\Component\Layout\Tabs; -use Magento\Ui\Component\AbstractView; +use Magento\Framework\View\Element\Template; /** * Class Nav */ -class Nav extends AbstractView +class Nav extends Template { - const NAME = 'nav'; + // } diff --git a/app/code/Magento/Ui/Component/Layout/Tabs/Tab.php b/app/code/Magento/Ui/Component/Layout/Tabs/Tab.php index 4428717e8bc0774656adeaa07d8644e84f49efc0..ac3c530df89b7dcb80879a0c5a9c1a53cf447cd6 100644 --- a/app/code/Magento/Ui/Component/Layout/Tabs/Tab.php +++ b/app/code/Magento/Ui/Component/Layout/Tabs/Tab.php @@ -5,21 +5,105 @@ */ namespace Magento\Ui\Component\Layout\Tabs; -use Magento\Ui\Component\AbstractView; +use Magento\Ui\Component\AbstractComponent; /** * Class Tab */ -class Tab extends AbstractView +class Tab extends AbstractComponent implements TabInterface { + const NAME = 'tab'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + + $jsConfig = $this->getConfiguration($this); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + + /** + * Return Tab label + * + * @return string + */ + public function getTabLabel() + { + return $this->getData('tab_label'); + } + + /** + * Return Tab title + * + * @return string + */ + public function getTabTitle() + { + return $this->getData('tab_title'); + } + + /** + * Tab class getter + * + * @return string + */ + public function getTabClass() + { + return $this->getData('tab_class'); + } + /** - * Render content + * Return URL link to Tab content * - * @param array $data * @return string */ - public function render(array $data = []) + public function getTabUrl() + { + return $this->getData('tab_url'); + } + + /** + * Tab should be loaded trough Ajax call + * + * @return bool + */ + public function isAjaxLoaded() + { + return $this->getData('is_ajax_loaded'); + } + + /** + * Can show tab in tabs + * + * @return boolean + */ + public function canShowTab() + { + return $this->getData('can_show_tab'); + } + + /** + * Tab is hidden + * + * @return boolean + */ + public function isHidden() { - // + return $this->getData('is_hidden'); } } diff --git a/app/code/Magento/Ui/Component/Layout/Tabs/TabInterface.php b/app/code/Magento/Ui/Component/Layout/Tabs/TabInterface.php index 1e65e984b0732f219b72810c72ba7f68f2a0b05e..cb47ad3afabab2d54745e8ec276bbce32a648617 100644 --- a/app/code/Magento/Ui/Component/Layout/Tabs/TabInterface.php +++ b/app/code/Magento/Ui/Component/Layout/Tabs/TabInterface.php @@ -3,14 +3,11 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ +namespace Magento\Ui\Component\Layout\Tabs; /** - * Tab Interface - * - * @author Magento Core Team <core@magentocommerce.com> + * Interface TabInterface */ -namespace Magento\Ui\Component\Layout\Tabs; - interface TabInterface { /** diff --git a/app/code/Magento/Ui/Component/Layout/Tabs/TabWrapper.php b/app/code/Magento/Ui/Component/Layout/Tabs/TabWrapper.php index 6c0cd88e0a0d3397faf30676f44f537aa5989e66..bccdc5eda3c3da42fb423d13bfa734fad5521616 100644 --- a/app/code/Magento/Ui/Component/Layout/Tabs/TabWrapper.php +++ b/app/code/Magento/Ui/Component/Layout/Tabs/TabWrapper.php @@ -3,11 +3,13 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Ui\Component\Layout\Tabs; use Magento\Framework\View\Element\Text\ListText; +/** + * Class TabWrapper + */ class TabWrapper extends ListText implements TabInterface { /** diff --git a/app/code/Magento/Ui/Component/Listing.php b/app/code/Magento/Ui/Component/Listing.php index 6d8437a886c5e531522c59fe1fae4e13f7461ab3..d84fd74cf278d59f688832bc2bc3bb1bfe114671 100644 --- a/app/code/Magento/Ui/Component/Listing.php +++ b/app/code/Magento/Ui/Component/Listing.php @@ -5,262 +5,102 @@ */ namespace Magento\Ui\Component; -use Magento\Framework\View\Element\Template\Context as TemplateContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigFactory; -use Magento\Framework\View\Element\UiComponent\Context; -use Magento\Ui\Component\Control\ActionPool; -use Magento\Ui\Component\Listing\OptionsFactory; -use Magento\Ui\Component\Listing\RowPool; -use Magento\Ui\ContentType\ContentTypeFactory; -use Magento\Ui\DataProvider\Factory as DataProviderFactory; -use Magento\Ui\DataProvider\Manager; +use Magento\Ui\Component\Listing\Columns; +use Magento\Ui\Component\Listing\Columns\Column; +use Magento\Framework\View\Element\UiComponent\DataSourceInterface; /** * Class Listing - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Listing extends AbstractView +class Listing extends AbstractComponent { - /** - * Options provider key in data array - */ - const OPTIONS_PROVIDER_KEY = 'options_provider'; - - /** - * Row data provider key in data array - */ - const ROW_DATA_PROVIDER_KEY = 'row_data_provider'; - - /** - * Data provider row pool - * - * @var RowPool - */ - protected $dataProviderRowPool; - - /** - * Page action pool - * - * @var ActionPool - */ - protected $actionPool; + const NAME = 'listing'; /** - * Constructor + * Get component name * - * @param TemplateContext $context - * @param Context $renderContext - * @param ContentTypeFactory $contentTypeFactory - * @param ConfigFactory $configFactory - * @param ConfigBuilderInterface $configBuilder - * @param DataProviderFactory $dataProviderFactory - * @param Manager $dataProviderManager - * @param OptionsFactory $optionsFactory - * @param ActionPool $actionPool - * @param RowPool $dataProviderRowPool - * @param array $data - * @SuppressWarnings(PHPMD.ExcessiveParameterList) + * @return string */ - public function __construct( - TemplateContext $context, - Context $renderContext, - ContentTypeFactory $contentTypeFactory, - ConfigFactory $configFactory, - ConfigBuilderInterface $configBuilder, - DataProviderFactory $dataProviderFactory, - Manager $dataProviderManager, - OptionsFactory $optionsFactory, - ActionPool $actionPool, - RowPool $dataProviderRowPool, - array $data = [] - ) { - $this->actionPool = $actionPool; - $this->optionsFactory = $optionsFactory; - $this->dataProviderRowPool = $dataProviderRowPool; - parent::__construct( - $context, - $renderContext, - $contentTypeFactory, - $configFactory, - $configBuilder, - $dataProviderFactory, - $dataProviderManager, - $data - ); + public function getComponentName() + { + return static::NAME; } /** - * Prepare custom data + * Register component and it's page main actions * * @return void */ public function prepare() { - $meta = $this->getMeta(); - $defaultConfigData = $this->getDefaultConfiguration(); - - if ($this->hasData('configuration')) { - $configData = $this->getData('configuration'); - if (!empty($configData['page_actions'])) { - foreach ($configData['page_actions'] as $key => $action) { - $defaultConfigData['page_actions'][$key] = isset($configData['page_actions']) - ? array_replace($defaultConfigData['page_actions'][$key], $configData['page_actions'][$key]) - : $defaultConfigData['page_actions'][$key]; - } - } - unset($configData['page_actions']); - $defaultConfigData = array_merge($defaultConfigData, $configData); - } - - foreach ($defaultConfigData['page_actions'] as $key => $action) { - $this->actionPool->add($key, $action, $this); - } - unset($defaultConfigData['page_actions']); - - $this->prepareConfiguration($defaultConfigData, $this->getData('name')); - $this->renderContext->getStorage()->addMeta($this->getData('name'), $meta); - $this->renderContext->getStorage()->addDataCollection($this->getData('name'), $this->getData('dataSource')); - } + parent::prepare(); - /** - * Render content - * - * @param array $data - * @return string - */ - public function render(array $data = []) - { - $this->initialConfiguration(); + $jsConfig = $this->getConfiguration($this); + unset($jsConfig['extends']); + $this->getContext()->addComponentDefinition($this->getContext()->getNamespace(), $jsConfig); - return parent::render($data); + $this->getContext()->addButtons($this->getData('buttons'), $this); } /** - * Get meta data - * - * @return array + * @inheritdoc */ - public function getMeta() + public function getDataSourceData() { - $meta = $this->getData('meta'); - foreach ($meta['fields'] as $key => $field) { - if ($field['data_type'] === 'date') { - $field['date_format'] = $this->_localeDate->getDateTimeFormat( - \IntlDateFormatter::MEDIUM - ); + $columns = $this->collectColumns(); + $dataSources = []; + foreach ($this->getChildComponents() as $component) { + // we need to process only Data Sources + if (!$component instanceof DataSourceInterface) { + continue; } - - if (isset($field[static::OPTIONS_PROVIDER_KEY])) { - $field['options'] = $this->optionsFactory->create($field[static::OPTIONS_PROVIDER_KEY]) - ->getOptions(empty($field['options']) ? [] : $field['options']); + $data = $component->getDataProvider()->getData(); + if (!empty($data['items']) && !empty($columns)) { + // Columns may need to pre-process data before using it + foreach ($columns as $column) { + $column->prepareItems($data['items']); + } } - unset($field[static::OPTIONS_PROVIDER_KEY]); - $meta['fields'][$key] = $field; - } - - return $meta; - } - - /** - * Apply data provider to row data - * - * @param array $dataRow - * @return array - */ - protected function getDataFromDataProvider(array $dataRow) - { - if ($this->hasData(static::ROW_DATA_PROVIDER_KEY)) { - foreach ($this->getData(static::ROW_DATA_PROVIDER_KEY) as $field => $data) { - $dataRow[$field] = $this->dataProviderRowPool->get($data['class'])->getData($dataRow, $data); - } + $dataSources[] = [ + 'type' => $component->getComponentName(), + 'name' => $component->getName(), + 'dataScope' => $component->getContext()->getNamespace(), + 'config' => array_replace_recursive( + [ + 'data' => $data, + 'totalCount' => $component->getDataProvider()->count(), + ], + (array) $component->getData('config'), + // ensure that namespace hasn't been overridden by accident + [ + 'params' => [ + 'namespace' => $this->getContext()->getNamespace() + ], + ] + ), + ]; } - - return $dataRow; + return $dataSources; } /** - * Get collection items + * Go through child components and collect Column types only. * - * @return array + * @return Column[] */ - public function getCollectionItems() + protected function collectColumns() { - $items = []; - $collection = $this->getDataCollection(); - foreach ($collection->getItems() as $item) { - $actualFields = []; - $itemsData = $this->getDataFromDataProvider($item->getData()); - foreach (array_keys($this->getData('meta/fields')) as $field) { - $actualFields[$field] = $itemsData[$field]; + $columns = []; + foreach ($this->getChildComponents() as $component) { + if ($component instanceof Columns) { + foreach ($component->getChildComponents() as $column) { + if ($column instanceof Column) { + $columns[] = $column; + } + } } - $items[] = $actualFields; } - - return $items; - } - - /** - * @return \Magento\Framework\Api\CriteriaInterface|\Magento\Framework\Data\CollectionDataSourceInterface - */ - protected function getDataCollection() - { - return $this->renderContext->getStorage()->getDataCollection($this->getName()); - } - - /** - * Configuration initialization - * - * @return void - */ - protected function initialConfiguration() - { - $url = $this->getUrl($this->getData('client_root')); - $this->renderContext->getStorage()->addGlobalData( - 'client', - [ - 'root' => $url, - 'ajax' => [ - 'data' => [ - 'component' => $this->getNameInLayout(), - ], - ] - ] - ); - $this->renderContext->getStorage()->addGlobalData('dump', ['extenders' => []]); - - $collection = $this->getDataCollection(); - $totalCount = $collection->count(); - $this->renderContext->getStorage()->addDataSource( - $this->getName(), - [ - 'data' => [ - 'meta_reference' => $this->getName(), - 'items' => $this->getCollectionItems(), - 'pages' => ceil($totalCount / $this->renderContext->getRequestParam('limit', 20)), - 'totalCount' => $totalCount, - ] - ] - ); - } - - /** - * Get default parameters - * - * @return array - */ - public function getDefaultConfiguration() - { - return [ - 'page_actions' => [ - 'add' => [ - 'name' => 'add', - 'label' => __('Add New'), - 'class' => 'primary', - 'url' => $this->getUrl('*/*/new'), - ], - ] - ]; + return $columns; } } diff --git a/app/code/Magento/Ui/Component/Listing/Columns.php b/app/code/Magento/Ui/Component/Listing/Columns.php new file mode 100644 index 0000000000000000000000000000000000000000..6e2eee1180af125d572fef1d048ad6435744f3f8 --- /dev/null +++ b/app/code/Magento/Ui/Component/Listing/Columns.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Listing; + +use Magento\Ui\Component\AbstractComponent; +use Magento\Ui\Component\Listing\Columns\Column; + +/** + * Class Columns + */ +class Columns extends AbstractComponent +{ + const NAME = 'columns'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + foreach ($this->getChildComponents() as $column) { + if ($column instanceof Column) { + $meta = $this->getContext()->getDataProvider()->getFieldMetaInfo($this->getName(), $column->getName()); + if ($meta) { + $config = $column->getData('config'); + $config = array_replace_recursive($config, $meta); + $column->setData('config', $config); + } + } + } + + $jsConfig = $this->getConfiguration($this); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } +} diff --git a/app/code/Magento/Ui/Component/Listing/Columns/Column.php b/app/code/Magento/Ui/Component/Listing/Columns/Column.php new file mode 100644 index 0000000000000000000000000000000000000000..cda819b5f7d0cf61c9d65aa49dec99cba41d90bd --- /dev/null +++ b/app/code/Magento/Ui/Component/Listing/Columns/Column.php @@ -0,0 +1,136 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Listing\Columns; + +use Magento\Ui\Component\AbstractComponent; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; + +/** + * Class Column + */ +class Column extends AbstractComponent implements ColumnInterface +{ + const NAME = 'column'; + + /** + * Wrapped component + * + * @var UiComponentInterface + */ + protected $wrappedComponent; + + /** + * UI component factory + * + * @var UiComponentFactory + */ + protected $uiComponentFactory; + + /** + * Constructor + * + * @param ContextInterface $context + * @param UiComponentFactory $uiComponentFactory + * @param array $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + UiComponentFactory $uiComponentFactory, + array $components = [], + array $data = [] + ) { + $this->uiComponentFactory = $uiComponentFactory; + parent::__construct($context, $components, $data); + } + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME . '.' . $this->getData('config/dataType'); + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + + $dataType = $this->getData('config/dataType'); + $wrappedComponentConfig = []; + if ($dataType) { + $this->wrappedComponent = $this->uiComponentFactory->create( + $this->getName(), + $dataType, + array_merge(['context' => $this->getContext()], (array) $this->getData()) + ); + $this->wrappedComponent->prepare(); + $wrappedComponentConfig = $this->getConfiguration($this->wrappedComponent); + } + + $this->applySorting(); + $jsConfig = array_replace_recursive($wrappedComponentConfig, $this->getConfiguration($this)); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + + /** + * Get JS config + * + * @return array + */ + public function getJsConfig() + { + if (isset($this->wrappedComponent)) { + return array_replace_recursive( + (array) $this->wrappedComponent->getData('config'), + (array) $this->getData('config') + ); + } + + return (array) $this->getData('config'); + } + + /** + * To prepare items of a column + * + * @param array $items + * @return array + */ + public function prepareItems(array & $items) + { + return $items; + } + + /** + * Apply sorting + * + * @return void + */ + protected function applySorting() + { + $sorting = $this->getContext()->getRequestParam('sorting'); + $isSortable = $this->getData('config/sortable'); + if ($isSortable !== false + && !empty($sorting['field']) + && !empty($sorting['direction']) + && $sorting['field'] === $this->getName() + ) { + $this->getContext()->getDataProvider()->addOrder( + $this->getName(), + strtoupper($sorting['direction']) + ); + } + } +} diff --git a/app/code/Magento/Ui/Component/Listing/Columns/ColumnInterface.php b/app/code/Magento/Ui/Component/Listing/Columns/ColumnInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..0fb07d7e415f9a94089c7c0fe4468600e953aaf3 --- /dev/null +++ b/app/code/Magento/Ui/Component/Listing/Columns/ColumnInterface.php @@ -0,0 +1,22 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Listing\Columns; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Interface ColumnInterface + */ +interface ColumnInterface extends UiComponentInterface +{ + /** + * To prepare items of a column + * + * @param array $items + * @return array + */ + public function prepareItems(array & $items); +} diff --git a/app/code/Magento/Ui/Component/Listing/OptionsFactory.php b/app/code/Magento/Ui/Component/Listing/OptionsFactory.php deleted file mode 100644 index ab1e1c822f451e57e73737ea093ce742f87a169a..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Listing/OptionsFactory.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Listing; - -use Magento\Framework\ObjectManagerInterface; - -/** - * Class OptionsFactory - */ -class OptionsFactory -{ - /** - * @var ObjectManagerInterface - */ - protected $objectManager; - - /** - * Constructor - * - * @param ObjectManagerInterface $objectManager - */ - public function __construct(ObjectManagerInterface $objectManager) - { - $this->objectManager = $objectManager; - } - - /** - * Getting provider object - * - * @param string $class - * @param array $arguments - * @return OptionsInterface - * @throws \InvalidArgumentException - */ - public function create($class, array $arguments = []) - { - $object = $this->objectManager->create($class, $arguments); - if (!($object instanceof OptionsInterface)) { - throw new \InvalidArgumentException( - sprintf('"%s" must implement the interface \Magento\Ui\Component\Listing\OptionsInterface', $class) - ); - } - - return $object; - } -} diff --git a/app/code/Magento/Ui/Component/Listing/OptionsInterface.php b/app/code/Magento/Ui/Component/Listing/OptionsInterface.php deleted file mode 100644 index 97ffc3d9c15f19373f518f445813abbee7afe343..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Listing/OptionsInterface.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Listing; - -/** - * Class OptionsInterface - */ -interface OptionsInterface -{ - /** - * Get options - * - * @param array $options - * @return array - */ - public function getOptions(array $options = []); -} diff --git a/app/code/Magento/Ui/Component/Listing/RowPool.php b/app/code/Magento/Ui/Component/Listing/RowPool.php deleted file mode 100644 index 165eaef33ab3d2a8f1ef794b859095b7e9d95f3a..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Listing/RowPool.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component\Listing; - -use Magento\Framework\ObjectManagerInterface; - -/** - * Class RowPool - */ -class RowPool -{ - /** - * @var RowInterface[] - */ - protected $classPool; - - /** - * @var ObjectManagerInterface - */ - protected $objectManager; - - /** - * Constructor - * - * @param ObjectManagerInterface $objectManager - */ - public function __construct(ObjectManagerInterface $objectManager) - { - $this->objectManager = $objectManager; - } - - /** - * Getting provider object - * - * @param string $class - * @param array $arguments - * @return RowInterface - * @throws \InvalidArgumentException - */ - public function get($class, array $arguments = []) - { - if (!isset($this->classPool[$class])) { - $this->classPool[$class] = $this->objectManager->create($class, $arguments); - if (!($this->classPool[$class] instanceof RowInterface)) { - throw new \InvalidArgumentException( - sprintf('"%s" must implement the interface \Magento\Ui\Component\Listing\RowInterface', $class) - ); - } - } - - return $this->classPool[$class]; - } -} diff --git a/app/code/Magento/Ui/Component/MassAction.php b/app/code/Magento/Ui/Component/MassAction.php index e892c9ed2793ef68bf535dea55721fc6f85f8092..140e48c0b15f3eb112d1e17b686f768f6da692ac 100644 --- a/app/code/Magento/Ui/Component/MassAction.php +++ b/app/code/Magento/Ui/Component/MassAction.php @@ -5,33 +5,51 @@ */ namespace Magento\Ui\Component; +use Magento\Framework\View\Element\UiComponent\ContextInterface; + /** * Class MassAction */ -class MassAction extends AbstractView +class MassAction extends AbstractComponent { + const NAME = 'massaction'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + /** - * Prepare component data + * Register component * - * @return $this|void + * @return void */ public function prepare() { - $configData = $this->getDefaultConfiguration(); - if ($this->hasData('config')) { - $configData = array_merge($configData, $this->getData('config')); + $this->prepareConfiguration(); + $config = $this->getData('config'); + if (isset($config['actions'])) { + $config['actions'] = array_values($config['actions']); + array_walk_recursive( + $config['actions'], + function (&$item, $key, $context) { + /** @var ContextInterface $context */ + if ($key === 'url') { + $item = $context->getUrl($item); + } + }, + $this->getContext() + ); + $this->setData('config', $config); } - array_walk_recursive( - $configData, - function (&$item, $key, $object) { - if ($key === 'url') { - $item = $object->getUrl($item); - } - }, - $this - ); - $this->prepareConfiguration($configData); + $jsConfig = $this->getConfiguration($this); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); } /** diff --git a/app/code/Magento/Ui/Component/MassAction/Columns/Column.php b/app/code/Magento/Ui/Component/MassAction/Columns/Column.php new file mode 100644 index 0000000000000000000000000000000000000000..6e1e438782197597e4db7e1545bfe72406b91fd9 --- /dev/null +++ b/app/code/Magento/Ui/Component/MassAction/Columns/Column.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\MassAction\Columns; + +use Magento\Ui\Component\AbstractComponent; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Ui\Component\Listing\Columns\ColumnInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; + +/** + * Class Column + */ +class Column extends AbstractComponent implements ColumnInterface +{ + const NAME = 'column.massaction'; + + /** + * Wrapped component + * + * @var UiComponentInterface + */ + protected $wrappedComponent; + + /** + * UI component factory + * + * @var UiComponentFactory + */ + protected $uiComponentFactory; + + /** + * Constructor + * + * @param ContextInterface $context + * @param UiComponentFactory $uiComponentFactory + * @param array $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + UiComponentFactory $uiComponentFactory, + array $components = [], + array $data = [] + ) { + $this->uiComponentFactory = $uiComponentFactory; + parent::__construct($context, $components, $data); + } + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * Prepare component configuration + * + * @return void + */ + public function prepare() + { + parent::prepare(); + + $jsConfig = $this->getConfiguration($this); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + + /** + * Prepare items + * + * @param array $items + * @return array + */ + public function prepareItems(array & $items) + { + return $items; + } +} diff --git a/app/code/Magento/Ui/Component/Paging.php b/app/code/Magento/Ui/Component/Paging.php index 7c504b74ac8303fff539ffe9671af8a9c68039e7..df104e0948771197d7e688671483e8197c3bc467 100644 --- a/app/code/Magento/Ui/Component/Paging.php +++ b/app/code/Magento/Ui/Component/Paging.php @@ -8,39 +8,80 @@ namespace Magento\Ui\Component; /** * Class Paging */ -class Paging extends AbstractView +class Paging extends AbstractComponent { + const NAME = 'paging'; + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + /** - * Prepare component data + * Register component and apply paging settings to Data Provider * * @return void */ public function prepare() { - $configData = $this->getDefaultConfiguration(); - if ($this->hasData('config')) { - $configData = array_merge($configData, $this->getData('config')); - } + parent::prepare(); + + $this->prepareConfiguration(); + $this->prepareOptions(); + + $paging = $this->getContext()->getRequestParam('paging'); + + $this->getContext()->getDataProvider()->setLimit($this->getOffset($paging), $this->getSize($paging)); + + $jsConfig = $this->getConfiguration($this); + $this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig); + } + + /** + * Get offset + * + * @param array|null $paging + * @return int + */ + protected function getOffset($paging) + { + $defaultPage = $this->getData('config/current') ?: 1; + return (int) (isset($paging['current']) ? $paging['current'] : $defaultPage); + } - $this->prepareConfiguration($configData); - $this->updateDataCollection(); + /** + * Get size + * + * @param array|null $paging + * @return int + */ + protected function getSize($paging) + { + $defaultLimit = $this->getData('config/pageSize') ?: 20; + return (int) (isset($paging['pageSize']) ? $paging['pageSize'] : $defaultLimit); } /** - * Update data collection + * Prepare paging options * * @return void */ - protected function updateDataCollection() + protected function prepareOptions() { - $defaultPage = $this->config->getData('current'); - $offset = $this->renderContext->getRequestParam('page', $defaultPage); - $defaultLimit = $this->config->getData('pageSize'); - $size = $this->renderContext->getRequestParam('limit', $defaultLimit); - $this->renderContext->getStorage() - ->getDataCollection($this->getParentName()) - ->setPageSize($size) - ->setCurPage($offset); + $config = $this->getData('config'); + if (isset($config['options'])) { + $config['options'] = array_values($config['options']); + foreach ($config['options'] as &$item) { + $item['value'] = (int) $item['value']; + } + unset($item); + $this->setData('config', $config); + } } /** @@ -51,7 +92,28 @@ class Paging extends AbstractView protected function getDefaultConfiguration() { return [ - 'sizes' => [20, 30, 50, 100, 200], + 'options' => [ + '20' => [ + 'value' => 20, + 'label' => 20 + ], + '30' => [ + 'value' => 30, + 'label' => 30 + ], + '50' => [ + 'value' => 50, + 'label' => 50 + ], + '100' => [ + 'value' => 100, + 'label' => 100 + ], + '200' => [ + 'value' => 200, + 'label' => 200 + ], + ], 'pageSize' => 20, 'current' => 1 ]; diff --git a/app/code/Magento/Ui/Component/RenderLayoutInterface.php b/app/code/Magento/Ui/Component/RenderLayoutInterface.php deleted file mode 100644 index 34bb85e8d7469fd0280c242b09906225995bb80d..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/RenderLayoutInterface.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component; - -use Magento\Framework\View\Element\UiComponentInterface; - -/** - * Interface RenderLayoutInterface - */ -interface RenderLayoutInterface extends UiComponentInterface -{ -} diff --git a/app/code/Magento/Ui/Component/Search.php b/app/code/Magento/Ui/Component/Search.php deleted file mode 100644 index b32227b5561eb819fead4ab817637f25cfcc7abc..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Search.php +++ /dev/null @@ -1,14 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component; - -/** - * Class Search - */ -class Search extends AbstractView -{ - // -} diff --git a/app/code/Magento/Ui/Component/Sorting.php b/app/code/Magento/Ui/Component/Sorting.php deleted file mode 100644 index 944c8e531b3004400ca35e6a36b58ed84d3792ac..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Component/Sorting.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Component; - -/** - * Class Sorting - */ -class Sorting extends AbstractView -{ - /** - * Prepare component data - * - * @return void - */ - public function prepare() - { - $configData = $this->getDefaultConfiguration(); - if ($this->hasData('config')) { - $configData = array_merge($configData, $this->getData('config')); - } - - $this->prepareConfiguration($configData); - $this->updateDataCollection(); - } - - /** - * Update data collection - * - * @return void - */ - protected function updateDataCollection() - { - $field = $this->config->getData('field'); - $direction = $this->config->getData('direction'); - if (!empty($field) && !empty($direction)) { - $this->renderContext->getStorage()->getDataCollection($this->getParentName())->addOrder( - $this->renderContext->getRequestParam('sort', $field), - strtoupper($this->renderContext->getRequestParam('dir', $direction)) - ); - } - } - - /** - * Get default parameters - * - * @return array - */ - protected function getDefaultConfiguration() - { - return ['direction' => 'asc']; - } -} diff --git a/app/code/Magento/Ui/Component/Wrapper/Block.php b/app/code/Magento/Ui/Component/Wrapper/Block.php new file mode 100644 index 0000000000000000000000000000000000000000..8f352313d94fd153ed1f10112970cc5f8bf18b0a --- /dev/null +++ b/app/code/Magento/Ui/Component/Wrapper/Block.php @@ -0,0 +1,69 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Wrapper; + +use Magento\Framework\View\Element\BlockInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Ui\Component\AbstractComponent; + +/** + * Class Block + */ +class Block extends AbstractComponent +{ + const NAME = 'blockWrapper'; + + /** + * @var BlockInterface + */ + protected $block; + + /** + * Constructor + * + * @param ContextInterface $context + * @param BlockInterface $block + * @param array $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + BlockInterface $block, + array $components = [], + array $data = [] + ) { + $this->block = $block; + parent::__construct($context, $components, $data); + } + + /** + * Get wrapped block + * + * @return BlockInterface + */ + public function getBlock() + { + return $this->block; + } + + /** + * Get component name + * + * @return string + */ + public function getComponentName() + { + return static::NAME; + } + + /** + * @return string + */ + public function render() + { + return $this->block->toHtml(); + } +} diff --git a/app/code/Magento/Ui/Component/Wrapper/UiComponent.php b/app/code/Magento/Ui/Component/Wrapper/UiComponent.php new file mode 100644 index 0000000000000000000000000000000000000000..28f67161272ab1b44f59709a28379379e30178a1 --- /dev/null +++ b/app/code/Magento/Ui/Component/Wrapper/UiComponent.php @@ -0,0 +1,75 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Component\Wrapper; + +use Magento\Framework\View\Element\Template; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\ContainerInterface; +use Magento\Framework\View\Element\Template\Context as TemplateContext; + +/** + * Class UiComponent + * + * Encapsulate UI Component to represent it as standard Layout Block + */ +class UiComponent extends Template implements ContainerInterface +{ + /** + * Ui component + * + * @var UiComponentInterface + */ + protected $component; + + /** + * @var BlockFactory + */ + protected $blockWrapperFactory; + + /** + * Constructor + * + * @param TemplateContext $context + * @param UiComponentInterface $component + * @param BlockFactory $blockWrapperFactory + * @param array $data + */ + public function __construct( + TemplateContext $context, + UiComponentInterface $component, + BlockFactory $blockWrapperFactory, + array $data = [] + ) { + $this->component = $component; + $this->blockWrapperFactory = $blockWrapperFactory; + $this->setNameInLayout($this->component->getName()); + parent::__construct($context, $data); + } + + /** + * Render block HTML + * + * @return string + */ + protected function _toHtml() + { + foreach ($this->getChildNames() as $childName) { + $childBlock = $this->getLayout()->getBlock($childName); + if ($childBlock) { + $wrapper = $this->blockWrapperFactory->create([ + 'block' => $childBlock, + 'data' => [ + 'name' => 'block_' . $childName + ] + ]); + $this->component->addComponent('block_' . $childName, $wrapper); + } + } + + $result = $this->component->render(); + return (string)$result; + } +} diff --git a/app/code/Magento/Ui/ContentType/Builder/ConfigJson.php b/app/code/Magento/Ui/ContentType/Builder/ConfigJson.php deleted file mode 100644 index 74c3af86783591d5c34f50df4918cf1c4a8a2928..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/ContentType/Builder/ConfigJson.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\ContentType\Builder; - -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigInterface; - -/** - * Class ConfigJson - */ -class ConfigJson implements ConfigBuilderInterface -{ - /** - * Config data to JSON by output - * - * @param ConfigInterface $configuration - * @return string - */ - public function toJson(ConfigInterface $configuration) - { - $result = $configuration->getData(); - $result['name'] = $configuration->getName(); - $result['parent_name'] = $configuration->getParentName(); - - return json_encode($result); - } -} diff --git a/app/code/Magento/Ui/ContentType/Builder/ConfigStorageJson.php b/app/code/Magento/Ui/ContentType/Builder/ConfigStorageJson.php deleted file mode 100644 index 99eca8d2994345fba40b8769903002da11fac1a5..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/ContentType/Builder/ConfigStorageJson.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\ContentType\Builder; - -use Magento\Framework\View\Element\UiComponent\ConfigInterface; -use Magento\Framework\View\Element\UiComponent\ConfigStorageBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigStorageInterface; - -/** - * Class ConfigStorageBuilder - */ -class ConfigStorageJson implements ConfigStorageBuilderInterface -{ - /** - * Config storage data to JSON by output - * - * @param ConfigStorageInterface $storage - * @param string $parentName - * @return string - */ - public function toJson(ConfigStorageInterface $storage, $parentName = null) - { - $result = [ - 'config' => [], - ]; - $result['meta'] = $storage->getMeta($parentName); - $dataSource = $storage->getDataSource($parentName); - $data = isset($dataSource['data']) ? $dataSource['data'] : null; - if ($parentName !== null) { - $rootComponent = $storage->getComponentsData($parentName); - $result['name'] = $rootComponent->getName(); - $result['parent_name'] = $rootComponent->getParentName(); - $result['data'] = $data; - $result['config']['components'][$rootComponent->getName()] = $rootComponent->getData(); - } else { - $components = $storage->getComponentsData(); - if (!empty($components)) { - /** @var ConfigInterface $component */ - foreach ($components as $name => $component) { - $result['config']['components'][$name] = $component->getData(); - } - } - $result['data'] = $data; - } - $result['config'] += $storage->getGlobalData(); - $result['dump']['extenders'] = []; - - return json_encode($result); - } - - /** - * Config storage data to JSON by output - * - * @param ConfigStorageInterface $storage - * @return string - */ - public function toJsonNew(ConfigStorageInterface $storage) - { - $result = []; - foreach ($storage->getDataSource() as $name => $dataSource) { - $dataSource['path'] = 'Magento_Ui/js/form/provider'; - $result['providers'][$name] = $dataSource; - } - $result['renderer'] = [ - 'types' => $storage->getComponents(), - 'layout' => $storage->getLayoutStructure(), - ]; - return json_encode($result); - } -} diff --git a/app/code/Magento/Ui/ContentType/Html.php b/app/code/Magento/Ui/ContentType/Html.php deleted file mode 100644 index dee784fdbbd37f279a2ed6637cc9fa70a37e9cac..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/ContentType/Html.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\ContentType; - -use Magento\Framework\View\Element\UiComponentInterface; -use Magento\Framework\View\FileSystem; -use Magento\Framework\View\TemplateEnginePool; - -/** - * Class Html - */ -class Html implements ContentTypeInterface -{ - /** - * @var \Magento\Framework\View\FileSystem - */ - protected $filesystem; - - /** - * @var \Magento\Framework\View\TemplateEnginePool - */ - protected $templateEnginePool; - - /** - * Constructor - * - * @param FileSystem $filesystem - * @param TemplateEnginePool $templateEnginePool - */ - public function __construct(FileSystem $filesystem, TemplateEnginePool $templateEnginePool) - { - $this->filesystem = $filesystem; - $this->templateEnginePool = $templateEnginePool; - } - - /** - * Render data - * - * @param UiComponentInterface $view - * @param string $template - * @return string - */ - public function render(UiComponentInterface $view, $template = '') - { - $templateEngine = false; - if ($template) { - $extension = pathinfo($template, PATHINFO_EXTENSION); - $templateEngine = $this->templateEnginePool->get($extension); - } - if ($templateEngine) { - $path = $this->filesystem->getTemplateFileName($template); - $result = $templateEngine->render($view, $path); - } else { - $result = ''; - } - return $result; - } -} diff --git a/app/code/Magento/Ui/ContentType/Json.php b/app/code/Magento/Ui/ContentType/Json.php deleted file mode 100644 index 4eb26e619a8311974f44615e1a3e448ccc7a1555..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/ContentType/Json.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\ContentType; - -use Magento\Framework\View\Element\UiComponentInterface; -use Magento\Framework\View\FileSystem; -use Magento\Framework\View\TemplateEnginePool; - -/** - * Class Json - */ -class Json implements ContentTypeInterface -{ - /** - * @var \Magento\Framework\View\FileSystem - */ - protected $filesystem; - - /** - * @var \Magento\Framework\View\TemplateEnginePool - */ - protected $templateEnginePool; - - /** - * Constructor - * - * @param FileSystem $filesystem - * @param TemplateEnginePool $templateEnginePool - */ - public function __construct(FileSystem $filesystem, TemplateEnginePool $templateEnginePool) - { - $this->filesystem = $filesystem; - $this->templateEnginePool = $templateEnginePool; - } - - /** - * Render data - * - * @param UiComponentInterface $view - * @param string $template - * @return string - */ - public function render(UiComponentInterface $view, $template = '') - { - return $view->getRenderContext() - ->getConfigBuilder() - ->toJson($view->getRenderContext()->getStorage(), $view->getName()); - } -} diff --git a/app/code/Magento/Ui/Context/Configuration.php b/app/code/Magento/Ui/Context/Configuration.php deleted file mode 100644 index 7711fec456f00869c7b7771d7b6edc9556188034..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Context/Configuration.php +++ /dev/null @@ -1,109 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Context; - -use Magento\Framework\View\Element\UiComponent\ConfigInterface; - -/** - * Class Configuration - */ -class Configuration implements ConfigInterface -{ - /** - * Configuration data - * - * @var array - */ - protected $configuration = []; - - /** - * Name of owner - * - * @var string - */ - protected $name; - - /** - * Name of parent owner - * - * @var string - */ - protected $parentName; - - /** - * Constructor - * - * @param string $name - * @param string $parentName - * @param array $configuration - */ - public function __construct($name, $parentName, $configuration = []) - { - $this->name = $name; - $this->parentName = $parentName; - $this->configuration = $configuration; - } - - /** - * Get configuration data - * - * @param string|null $key - * @return mixed - */ - public function getData($key = null) - { - if ($key === null) { - return (array)$this->configuration; - } - return isset($this->configuration[$key]) ? $this->configuration[$key] : null; - } - - /** - * Add configuration data - * - * @param string $key - * @param mixed $data - * @return mixed - */ - public function addData($key, $data) - { - if (!isset($this->configuration[$key])) { - $this->configuration[$key] = $data; - } - } - - /** - * Update configuration data - * - * @param string $key - * @param mixed $data - * @return mixed - */ - public function updateData($key, $data) - { - $this->configuration[$key] = $data; - } - - /** - * Get owner name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Get owner parent name - * - * @return string - */ - public function getParentName() - { - return $this->parentName; - } -} diff --git a/app/code/Magento/Ui/Context/ConfigurationStorage.php b/app/code/Magento/Ui/Context/ConfigurationStorage.php deleted file mode 100644 index 91218f496e01087985d06a62a06df8184bc3de0e..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Context/ConfigurationStorage.php +++ /dev/null @@ -1,340 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Context; - -use Magento\Framework\Data\CollectionDataSourceInterface; -use Magento\Framework\View\Element\UiComponent\ConfigInterface; -use Magento\Framework\View\Element\UiComponent\ConfigStorageInterface; -use Magento\Framework\View\Element\UiComponent\DataProviderInterface; - -/** - * Class ConfigurationStorage - */ -class ConfigurationStorage implements ConfigStorageInterface -{ - /** - * Components configuration storage - * - * @var array - */ - protected $componentStorage = []; - - /** - * Data storage - * - * @var array - */ - protected $dataStorage = []; - - /** - * Meta storage - * - * @var array - */ - protected $metaStorage = []; - - /** - * Data collection storage - * - * @var CollectionDataSourceInterface[] - */ - protected $collectionStorage = []; - - /** - * Global data storage - * - * @var array - */ - protected $globalDataStorage = []; - - /** - * Data provider storage - * - * @var array - */ - protected $dataProviderStorage = []; - - /** - * @var array - */ - protected $components = []; - - /** - * @var array - */ - protected $layoutStructure = []; - - /** - * @inheritdoc - */ - public function addComponent($name, $data) - { - $this->components[$name] = $data; - } - - /** - * @inheritdoc - */ - public function addComponentsData(ConfigInterface $config) - { - if (!isset($this->componentStorage[$config->getName()])) { - $this->componentStorage[$config->getName()] = $config; - } - } - - /** - * @return array - */ - public function getComponents() - { - return $this->components; - } - - /** - * @return array - */ - public function getMetaKeys() - { - return array_keys($this->metaStorage); - } - - /** - * @inheritdoc - */ - public function removeComponentsData(ConfigInterface $configuration) - { - unset($this->componentStorage[$configuration->getName()]); - } - - /** - * @inheritdoc - */ - public function getComponentsData($name = null) - { - if ($name === null) { - return $this->componentStorage; - } - return isset($this->componentStorage[$name]) ? $this->componentStorage[$name] : null; - } - - /** - * @inheritdoc - */ - public function addDataSource($name, array $dataSource) - { - if (!isset($this->dataStorage[$name])) { - $this->dataStorage[$name] = $dataSource; - } - } - - /** - * @inheritdoc - */ - public function removeDataSource($name) - { - unset($this->dataStorage[$name]); - } - - /** - * @inheritdoc - */ - public function getDataSource($name = null) - { - if ($name === null) { - return $this->dataStorage; - } - return isset($this->dataStorage[$name]) ? $this->dataStorage[$name] : null; - } - - /** - * @inheritdoc - */ - public function updateDataSource($name, array $dataSource) - { - if (isset($this->dataStorage[$name])) { - $this->dataStorage[$name] = $dataSource; - } - } - - /** - * @inheritdoc - */ - public function addMeta($key, array $data) - { - if (!isset($this->metaStorage[$key])) { - $this->metaStorage[$key] = $data; - } - } - - /** - * @inheritdoc - */ - public function removeMeta($key) - { - unset($this->metaStorage[$key]); - } - - /** - * @inheritdoc - */ - public function getMeta($key = null) - { - if ($key === null) { - return $this->metaStorage; - } - return isset($this->metaStorage[$key]) ? $this->metaStorage[$key] : null; - } - - /** - * @inheritdoc - */ - public function updateMeta($key, array $data) - { - if (isset($this->metaStorage[$key])) { - $this->metaStorage[$key] = $data; - } - } - - /** - * @inheritdoc - */ - public function addDataCollection($key, CollectionDataSourceInterface $dataCollection) - { - if (!isset($this->collectionStorage[$key])) { - $this->collectionStorage[$key] = $dataCollection; - } - } - - /** - * @inheritdoc - */ - public function getDataCollection($key = null) - { - if ($key === null) { - return $this->collectionStorage; - } - return isset($this->collectionStorage[$key]) ? $this->collectionStorage[$key] : null; - } - - /** - * @inheritdoc - */ - public function updateDataCollection($key, CollectionDataSourceInterface $dataCollection) - { - if (isset($this->collectionStorage[$key])) { - $this->collectionStorage[$key] = $dataCollection; - } - } - - /** - * @inheritdoc - */ - public function addGlobalData($key, array $data) - { - if (!isset($this->globalDataStorage[$key])) { - $this->globalDataStorage[$key] = $data; - } - } - - /** - * @inheritdoc - */ - public function removeGlobalData($key) - { - unset($this->globalDataStorage[$key]); - } - - /** - * @inheritdoc - */ - public function getGlobalData($key = null) - { - if ($key === null) { - return $this->globalDataStorage; - } - return isset($this->globalDataStorage[$key]) ? $this->globalDataStorage[$key] : null; - } - - /** - * @inheritdoc - */ - public function addDataProvider($key, DataProviderInterface $dataProvider) - { - if (!isset($this->dataProviderStorage[$key])) { - $this->dataProviderStorage[$key] = $dataProvider; - } - } - - /** - * @inheritdoc - */ - public function removeDataProvider($key) - { - if (isset($this->dataProviderStorage[$key])) { - unset($this->dataProviderStorage[$key]); - } - } - - /** - * @inheritdoc - */ - public function getDataProvider($key = null) - { - if ($key === null) { - return $this->dataProviderStorage; - } - return isset($this->dataProviderStorage[$key]) ? $this->dataProviderStorage[$key] : null; - } - - /** - * @inheritdoc - */ - public function updateDataProvider($key, DataProviderInterface $dataProvider) - { - if (isset($this->dataProviderStorage[$key])) { - $this->dataProviderStorage[$key] = $dataProvider; - } - } - - /** - * @inheritdoc - */ - public function addLayoutStructure($dataScope, array $structure) - { - $this->layoutStructure[$dataScope] = $structure; - } - - /** - * @inheritdoc - */ - public function getLayoutStructure() - { - return $this->layoutStructure; - } - - /** - * @inheritdoc - */ - public function getLayoutNode($name, $default = null) - { - if (strpos($name, '.') !== false) { - $nameParts = explode('.', $name); - $firstChunk = array_shift($nameParts); - $node = isset($this->layoutStructure[$firstChunk]) ? $this->layoutStructure[$firstChunk] : []; - foreach ($nameParts as $nodeName) { - if (isset($node['children'][$nodeName])) { - $node = $node['children'][$nodeName]; - } else { - $node = $default; - break; - } - } - } else { - $node = isset($this->layoutStructure[$name]) ? $this->layoutStructure[$name] : []; - } - return $node; - } -} diff --git a/app/code/Magento/Ui/Context/DataProvider.php b/app/code/Magento/Ui/Context/DataProvider.php deleted file mode 100644 index 1621470ec575263082f3ff569b560f721039e92b..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Context/DataProvider.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Context; - -use Magento\Ui\Component\AbstractView; - -/** - * Class DataProvider - */ -class DataProvider extends AbstractView -{ - /** - * @return string - */ - public function getAsJson() - { - return $this->renderContext->getConfigBuilder()->toJson($this->renderContext->getStorage()); - } -} diff --git a/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php b/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php index 46a218025258c33dfd1f9d8425e57bc5dd6d8966..6893905b14938d6e9f4906cb9c205c8563c43244 100644 --- a/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php +++ b/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php @@ -1,19 +1,19 @@ <?php /** - * * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Ui\Controller\Adminhtml; +use Magento\Backend\App\Action; use Magento\Backend\App\Action\Context; -use Magento\Framework\View\Element\UiComponentFactory; use Magento\Ui\Controller\UiActionInterface; +use Magento\Framework\View\Element\UiComponentFactory; /** * Class Render */ -abstract class AbstractAction extends \Magento\Backend\App\Action implements UiActionInterface +abstract class AbstractAction extends Action implements UiActionInterface { /** * @var UiComponentFactory diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Form/Fieldset.php b/app/code/Magento/Ui/Controller/Adminhtml/Form/Fieldset.php deleted file mode 100644 index 9c556c7191cdf6d854d146abea66c7c9586e7126..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Controller/Adminhtml/Form/Fieldset.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -namespace Magento\Ui\Controller\Adminhtml\Form; - -/** - * Class Fieldset - * - * @package Magento\Ui\Controller\Adminhtml\Form - */ -class Fieldset extends \Magento\Ui\Controller\Adminhtml\AbstractAction -{ - /** - * Action for AJAX request - * - * @return void - */ - public function execute() - { - // $component = $this->getComponent(); -// $name = $this->getName(); -// if ($component && $name) { -// $fieldset = $this->factory->createUiComponent($this->getComponent(), $this->getName())->getContainer($this->_request->getParam('container')); -// $fieldset->setNotLoadByAjax(); -// $this->_response->appendBody( -// $fieldset->render() -// ); -// } else { -// $this->_redirect('admin'); -// } -// $tabIndex = $this->getRequest()->getParam('container'); -// $this->getResponse()->appendBody( -// json_encode( -// ['layout' => ['customer_form_tabs' => [$tabIndex => ['label' => 'loaded', 'content' => 'content is loaded']]]] -// ) -// ); - } -} diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Form/Save.php b/app/code/Magento/Ui/Controller/Adminhtml/Form/Save.php deleted file mode 100644 index 27bcd9d5096c5243c8ce52f02106c573df457a66..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Controller/Adminhtml/Form/Save.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Controller\Adminhtml\Form; - -/** - * Class Save - * - * @package Magento\Ui\Controller\Adminhtml\Form - */ -class Save extends \Magento\Ui\Controller\Adminhtml\AbstractAction -{ - /** - * Action for AJAX request - * - * @return void - */ - public function execute() - { - $component = $this->getComponent(); - $name = $this->getName(); - if ($component && $name) { - $formElement = $this->factory->createUiComponent($component, $name); - list($module, $controller, $action) = explode('\\', $formElement->getSaveMca()); - $this->_forward($action, $controller, $module, $this->getRequest()->getParams()); - } else { - $this->_redirect('admin'); - } - } -} diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Form/Validate.php b/app/code/Magento/Ui/Controller/Adminhtml/Form/Validate.php deleted file mode 100644 index 2d55343ed1e1230ea9128a477931187926ab5b70..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Controller/Adminhtml/Form/Validate.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php -/** - * - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Controller\Adminhtml\Form; - -class Validate extends \Magento\Ui\Controller\Adminhtml\AbstractAction -{ - /** - * Action for AJAX request - * - * @return void - */ - public function execute() - { - $component = $this->getComponent(); - $name = $this->getName(); - if ($component && $name) { - $formElement = $this->factory->createUiComponent($component, $name); - list($module, $controller, $action) = explode('\\', $formElement->getValidateMca()); - $this->_forward($action, $controller, $module, $this->getRequest()->getParams()); - } else { - $this->_redirect('admin'); - } - } -} diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php index bda4c09c8751aaf1185e3ee8a61a078bd8354f71..d7d89e88d378fc305dfd01ed98c8dbc00c22e933 100644 --- a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php +++ b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php @@ -1,18 +1,31 @@ <?php /** - * * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Ui\Controller\Adminhtml\Index; +use Magento\Backend\App\Action\Context; +use Magento\Ui\Controller\Adminhtml\AbstractAction; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponentInterface; + /** * Class Render - * - * @package Magento\Ui\Controller\Adminhtml\Index */ -class Render extends \Magento\Ui\Controller\Adminhtml\AbstractAction +class Render extends AbstractAction { + /** + * Constructor + * + * @param Context $context + * @param UiComponentFactory $factory + */ + public function __construct(Context $context, UiComponentFactory $factory) + { + parent::__construct($context, $factory); + } + /** * Action for AJAX request * @@ -20,8 +33,25 @@ class Render extends \Magento\Ui\Controller\Adminhtml\AbstractAction */ public function execute() { - $this->_response->appendBody( - $this->factory->createUiComponent($this->getComponent(), $this->getName())->render() - ); + $component = $this->factory->create($this->_request->getParam('namespace')); + $this->prepareComponent($component); + $this->_response->appendBody((string) $component->render()); + } + + /** + * Call prepare method in the component UI + * + * @param UiComponentInterface $component + * @return void + */ + protected function prepareComponent(UiComponentInterface $component) + { + $childComponents = $component->getChildComponents(); + if (!empty($childComponents)) { + foreach ($childComponents as $child) { + $this->prepareComponent($child); + } + } + $component->prepare(); } } diff --git a/app/code/Magento/Ui/Controller/UiActionInterface.php b/app/code/Magento/Ui/Controller/UiActionInterface.php index 33a13418955a5f5c351f0e8f6600da8acc2d2b00..53932aba49cce3a94a02175a622ab42aab57856e 100644 --- a/app/code/Magento/Ui/Controller/UiActionInterface.php +++ b/app/code/Magento/Ui/Controller/UiActionInterface.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ @@ -8,7 +7,6 @@ namespace Magento\Ui\Controller; /** * Interface UiActionInterface - * @package Magento\Ui\Controller */ interface UiActionInterface { diff --git a/app/code/Magento/Ui/DataProvider/Config/Converter.php b/app/code/Magento/Ui/DataProvider/Config/Converter.php deleted file mode 100644 index 6402821d585af92a6283787813f6e74fbdfcc860..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/DataProvider/Config/Converter.php +++ /dev/null @@ -1,248 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -namespace Magento\Ui\DataProvider\Config; - -use Magento\Framework\Config\ConverterInterface; - -/** - * Class Converter - */ -class Converter implements ConverterInterface -{ - /** - * @var \Magento\Eav\Model\Entity\TypeFactory - */ - protected $entityTypeFactory; - - /** - * Map EAV frontend_input property to form element types - * - * @var array - */ - protected $inputTypeMap = [ - 'text' => 'input', - 'textarea' => 'textarea', - 'multiline' => 'input', - 'date' => 'date', - 'select' => 'select', - 'multiselect' => 'multiselect', - 'boolean' => 'select', - 'file' => 'media', - 'image' => 'media', - ]; - - /** - * @param \Magento\Eav\Model\Entity\TypeFactory $entityTypeFactory - */ - public function __construct(\Magento\Eav\Model\Entity\TypeFactory $entityTypeFactory) - { - $this->entityTypeFactory = $entityTypeFactory; - } - - /** - * Transform Xml to array - * - * @param \DOMNode $source - * @return array - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - */ - protected function toArray(\DOMNode $source) - { - $result = []; - if ($source->hasAttributes()) { - foreach ($source->attributes as $attr) { - $result['@attributes'][$attr->name] = $attr->value; - } - } - - if (!$source->hasChildNodes()) { - if (empty($result)) { - $result = $source->nodeValue; - } - } else { - if ($source->hasChildNodes()) { - $groups = []; - foreach ($source->childNodes as $child) { - if ($child->nodeType == XML_TEXT_NODE || $child->nodeType == XML_COMMENT_NODE) { - continue; - } - if ($this->isTextNode($child)) { - $result[$child->nodeName] = $this->getTextNode($child)->data; - } else { - if (in_array($child->nodeName, ['validate', 'filter', 'readonly'])) { - if (!isset($result[$child->nodeName])) { - $result[$child->nodeName] = []; - } - $result[$child->nodeName][] = $this->toArray($child); - } else { - if (isset($result[$child->nodeName])) { - if (!isset($groups[$child->nodeName])) { - $result[$child->nodeName] = [$result[$child->nodeName]]; - $groups[$child->nodeName] = 1; - } - $result[$child->nodeName][] = $this->toArray($child); - } else { - $result[$child->nodeName] = $this->toArray($child); - } - } - } - } - } - } - return $result; - } - - /** - * Convert configuration - * - * @param \DOMDocument $source - * @return array - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) - */ - public function convert($source) - { - $data = []; - $output = $this->toArray($source); - foreach ($output['config']['dataSource'] as $dataSource) { - $data[$dataSource['@attributes']['name']] = [ - 'name' => $dataSource['@attributes']['name'], - 'label' => $dataSource['@attributes']['label'], - 'dataSet' => $dataSource['@attributes']['dataSet'], - ]; - $fields = []; - if (isset($dataSource['fields']['@attributes']['entityType'])) { - $entityType = $this->entityTypeFactory->create() - ->load($dataSource['fields']['@attributes']['entityType'], 'entity_type_code'); - $attributeCollection = $entityType->getAttributeCollection(); - foreach ($attributeCollection as $attribute) { - if ($attribute->getIsUserDefined()) { - $fields[$attribute->getAttributeCode()] = [ - 'name' => $attribute->getAttributeCode(), - 'source' => 'eav', - 'formElement' => $this->mapFrontendInput($attribute->getFrontendInput()), - 'is_required' => $attribute->getScopeIsRequired(), - 'default_value' => $attribute->getScopeDefaultValue(), - 'visible' => $attribute->getScopeIsVisible(), - 'multiline_count' => $attribute->getScopeMultilineCount(), - ]; - if ($attribute->getValidateRules()) { - $fields[$attribute->getAttributeCode()]['constraints']['validate'] - = $attribute->getValidateRules(); - } - } - } - } - foreach ($dataSource['fields']['field'] as $field) { - foreach ($field['@attributes'] as $key => $value) { - $fields[$field['@attributes']['name']][$key] = $value; - } - if (isset($field['@attributes']['source'])) { - if (in_array($field['@attributes']['source'], ['lookup', 'option', 'reference'])) { - $fields[$field['@attributes']['name']]['reference'] = [ - 'target' => $field['reference']['@attributes']['target'], - 'targetField' => $field['reference']['@attributes']['targetField'], - 'referencedField' => $field['reference']['@attributes']['referencedField'], - 'neededField' => $field['reference']['@attributes']['neededField'], - ]; - } - } - if (isset($field['tooltip'])) { - $fields[$field['@attributes']['name']]['tooltip'] = [ - 'link' => $field['tooltip']['link'], - 'description' => $field['tooltip']['description'], - ]; - } - if (isset($field['constraints']['validate'])) { - foreach ($field['constraints']['validate'] as $rule) { - $fields[$field['@attributes']['name']]['constraints']['validate'][$rule['@attributes']['name']] = - isset($rule['@attribute']['value']) - ? $rule['@attribute']['value'] : true; - } - } - if (isset($field['constraints']['filter'])) { - foreach ($field['constraints']['filter'] as $filter) { - $filterValues['on'] = isset($filter['@attributes']['on']) ? $filter['@attributes']['on'] : null; - $filterValues['by'] = isset($filter['@attributes']['by']) ? $filter['@attributes']['by'] : null; - $filterValues['value'] = isset($filter['@attributes']['value']) - ? $filter['@attributes']['value'] : null; - $fields[$field['@attributes']['name']]['constraints']['filter'][] = $filterValues; - } - } - if (isset($field['constraints']['readonly'])) { - foreach ($field['constraints']['readonly'] as $condition) { - $fields[$field['@attributes']['name']]['constraints']['readonly'][] = [ - 'on' => $condition['@attributes']['on'], - 'value' => $condition['@attributes']['value'], - ]; - } - } - } - $data[$dataSource['@attributes']['name']]['fields'] = $fields; - if (!empty($dataSource['references'])) { - foreach ($dataSource['references'] as $reference) { - $data[$reference['@attributes']['target']]['children'][$dataSource['@attributes']['name']][] = [ - 'targetField' => $reference['@attributes']['targetField'], - 'referencedField' => $reference['@attributes']['referencedField'], - ]; - } - } - } - - return $data; - } - - /** - * @param \DOMNode $node - * @return bool - */ - protected function isTextNode(\DOMNode $node) - { - $result = true; - if (!$node instanceof \DOMText) { - if ($node->hasChildNodes()) { - foreach ($node->childNodes as $child) { - if ($child->nodeType != XML_TEXT_NODE) { - $result = false; - break; - } - } - } else { - $result = false; - } - } - return $result; - } - - /** - * @param \DOMNode $node - * @return \DOMText - */ - protected function getTextNode(\DOMNode $node) - { - if ($node instanceof \DOMText) { - return $node; - } - foreach ($node->childNodes as $child) { - if ($child->nodeType == XML_TEXT_NODE) { - return $child; - } - } - return false; - } - - /** - * @param string $input - * @return string - */ - protected function mapFrontendInput($input) - { - return isset($this->inputTypeMap[$input]) ? $this->inputTypeMap[$input] : 'input'; - } -} diff --git a/app/code/Magento/Ui/DataProvider/Config/Data.php b/app/code/Magento/Ui/DataProvider/Config/Data.php deleted file mode 100644 index a975606507f0dcca2896847d54cf4a261eb09d01..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/DataProvider/Config/Data.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Ui\DataProvider\Config; - -/** - * Class Data - */ -class Data extends \Magento\Framework\Config\Data -{ - /** - * @param Reader $reader - * @param \Magento\Framework\Config\CacheInterface $cache - */ - public function __construct( - Reader $reader, - \Magento\Framework\Config\CacheInterface $cache - ) { - $this->cacheTags = [\Magento\Eav\Model\Entity\Attribute::CACHE_TAG]; - parent::__construct($reader, $cache, 'data_source'); - } - - /** - * @param string $name - * @return array|mixed|null - */ - public function getDataSource($name) - { - return $this->get($name); - } -} diff --git a/app/code/Magento/Ui/DataProvider/Config/FileResolver.php b/app/code/Magento/Ui/DataProvider/Config/FileResolver.php deleted file mode 100644 index fbd093b8c1acd0b47a2811897796da918a3ff14b..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/DataProvider/Config/FileResolver.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -/** - * Hierarchy config file resolver - * - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\DataProvider\Config; - -use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\Config\FileIteratorFactory; -use Magento\Framework\Config\FileResolverInterface; -use Magento\Framework\Filesystem; - -/** - * Class FileResolver - */ -class FileResolver implements \Magento\Framework\Config\FileResolverInterface -{ - /** - * @var \Magento\Framework\Filesystem\Directory\ReadInterface - */ - protected $directoryRead; - - /** - * @var FileIteratorFactory - */ - protected $iteratorFactory; - - /** - * @param Filesystem $filesystem - * @param FileIteratorFactory $iteratorFactory - */ - public function __construct( - Filesystem $filesystem, - FileIteratorFactory $iteratorFactory - ) { - $this->directoryRead = $filesystem->getDirectoryRead(DirectoryList::MODULES); - $this->iteratorFactory = $iteratorFactory; - } - - /** - * {@inheritdoc} - */ - public function get($filename, $scope) - { - $iterator = $this->iteratorFactory->create( - $this->directoryRead, - $this->directoryRead->search('/*/*/etc/data_source/' . $filename) - ); - return $iterator; - } -} diff --git a/app/code/Magento/Ui/DataProvider/Config/Reader.php b/app/code/Magento/Ui/DataProvider/Config/Reader.php deleted file mode 100644 index 6360437f16eb38326cf8a69ec0f6bd8c24102da1..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/DataProvider/Config/Reader.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Ui\DataProvider\Config; - -use Magento\Framework\Config\ValidationStateInterface; - -/** - * Class Reader - */ -class Reader extends \Magento\Framework\Config\Reader\Filesystem -{ - /** - * List of id attributes for merge - * - * @var array - */ - protected $_idAttributes = ['/config/dataSource' => 'name']; - - /** - * @param FileResolver $fileResolver - * @param Converter $converter - * @param SchemaLocator $schemaLocator - * @param ValidationStateInterface $validationState - * @param string $fileName - * @param array $idAttributes - * @param string $domDocumentClass - * @param string $defaultScope - */ - public function __construct( - FileResolver $fileResolver, - Converter $converter, - SchemaLocator $schemaLocator, - ValidationStateInterface $validationState, - $fileName = '*.xml', - $idAttributes = [], - $domDocumentClass = 'Magento\Framework\Config\Dom', - $defaultScope = '' - ) { - parent::__construct( - $fileResolver, - $converter, - $schemaLocator, - $validationState, - $fileName, - $idAttributes, - $domDocumentClass, - $defaultScope - ); - } -} diff --git a/app/code/Magento/Ui/DataProvider/Config/SchemaLocator.php b/app/code/Magento/Ui/DataProvider/Config/SchemaLocator.php deleted file mode 100644 index 02f64378eefe18816c057dff8b19319ba49ec96a..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/DataProvider/Config/SchemaLocator.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\DataProvider\Config; - -/** - * Class SchemaLocator - */ -class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface -{ - /** - * Path to corresponding XSD file with validation rules for both individual and merged configs - * - * @var string - */ - private $_schema; - - /** - * @param \Magento\Framework\Module\Dir\Reader $moduleReader - */ - public function __construct(\Magento\Framework\Module\Dir\Reader $moduleReader) - { - $this->_schema = $moduleReader->getModuleDir('etc', 'Magento_Ui') . '/data_source.xsd'; - } - - /** - * {@inheritdoc} - */ - public function getSchema() - { - return $this->_schema; - } - - /** - * {@inheritdoc} - */ - public function getPerFileSchema() - { - return $this->_schema; - } -} diff --git a/app/code/Magento/Ui/DataProvider/DataProviderCollectionInterface.php b/app/code/Magento/Ui/DataProvider/DataProviderCollectionInterface.php deleted file mode 100644 index b6cc0da7753b1fcd4e9b97558d22c31c19cc7f01..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/DataProvider/DataProviderCollectionInterface.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\DataProvider; - -use Magento\Framework\View\Element\UiComponent\DataProviderInterface; - -/** - * Interface DataProviderCollectionInterface - */ -interface DataProviderCollectionInterface extends DataProviderInterface -{ - /** - * Add a filter to the data - * - * @param array $filter - * @return void - */ - public function addFilter(array $filter); - - /** - * Get data - * - * @return \Magento\Framework\Object[] - */ - public function getData(); -} diff --git a/app/code/Magento/Ui/DataProvider/DataProviderEntityInterface.php b/app/code/Magento/Ui/DataProvider/DataProviderEntityInterface.php deleted file mode 100644 index f36e72f9f2eb7dac08f6556bd9e4f2541a905ef4..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/DataProvider/DataProviderEntityInterface.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\DataProvider; - -use Magento\Framework\View\Element\UiComponent\DataProviderInterface; - -/** - * Interface DataProviderEntityInterface - */ -interface DataProviderEntityInterface extends DataProviderInterface -{ - const CONFIG_KEY = 'field'; -} diff --git a/app/code/Magento/Ui/DataProvider/EavValidationRul.php b/app/code/Magento/Ui/DataProvider/EavValidationRul.php new file mode 100644 index 0000000000000000000000000000000000000000..1d338ec30755af34f8653ca99b65f8202b141d7a --- /dev/null +++ b/app/code/Magento/Ui/DataProvider/EavValidationRul.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\DataProvider; + +use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; + +/** + * Class EavValidationRul + */ +class EavValidationRul +{ + /** + * @var array + */ + protected $validationRul = [ + 'input_validation' => [ + 'email' => ['validate-email' => true], + 'date' => ['validate-date' => true], + ], + ]; + + /** + * Build validation rules + * + * @param AbstractAttribute $attribute + * @param array $data + * @return array + */ + public function build(AbstractAttribute $attribute, array $data) + { + $rules = []; + if (isset($data['required']) && $data['required'] == 1) { + $rules['required-entry'] = true; + } + $validation = $attribute->getValidateRules(); + if (!empty($validation)) { + foreach ($validation as $type => $ruleName) { + switch ($type) { + case 'input_validation': + if (isset($this->validationRul[$type][$ruleName])) { + $rules = array_merge($rules, $this->validationRul[$type][$ruleName]); + } + break; + case 'min_text_length': + case 'max_text_length': + $rules = array_merge($rules, [$type => $ruleName]); + break; + } + + } + } + + return $rules; + } +} diff --git a/app/code/Magento/Ui/DataProvider/Manager.php b/app/code/Magento/Ui/DataProvider/Manager.php deleted file mode 100644 index c2f2379ff77ba8ded751261fe6754a1c1241067c..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/DataProvider/Manager.php +++ /dev/null @@ -1,153 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Ui\DataProvider; - -use Magento\Framework\ObjectManagerInterface; -use Magento\Ui\DataProvider\Config\Data as Config; - -/** - * Class Manager - */ -class Manager -{ - /** - * @var Config - */ - protected $config; - - /** - * @var ObjectManagerInterface - */ - protected $objectManager; - - /** - * @var ObjectManagerInterface - */ - protected $metadataFactory; - - /** - * @var array - */ - protected $cache = []; - - /** - * @param Config $config - * @param ObjectManagerInterface $objectManager - * @param MetadataFactory $metadataFactory - */ - public function __construct(Config $config, ObjectManagerInterface $objectManager, MetadataFactory $metadataFactory) - { - $this->config = $config; - $this->objectManager = $objectManager; - $this->metadataFactory = $metadataFactory; - } - - /** - * Returns Data Source metadata - * - * @param string $dataSource - * @return \Magento\Ui\DataProvider\Metadata - */ - public function getMetadata($dataSource) - { - return $this->metadataFactory->create( - [ - 'config' => $this->config->getDataSource($dataSource), - ] - ); - } - - /** - * @param string $dataSource - * @param array $filters - * @return mixed - */ - public function getCollectionData($dataSource, array $filters = []) - { - $collectionHash = md5($dataSource . serialize($filters)); - if (!isset($this->cache[$collectionHash])) { - $config = $this->config->getDataSource($dataSource); - /** @var \Magento\Framework\Data\Collection\Db $collection */ - $collection = $this->objectManager->create($config['dataSet']); - - foreach ($config['fields'] as $field) { - if (isset($field['source']) && $field['source'] == 'eav') { - $collection->addAttributeToSelect($field['name']); - } - } - - if ($filters) { - foreach ($filters as $field => $expression) { - $collection->addFieldToFilter($field, $expression); - } - } - $this->cache[$collectionHash] = $collection->getItems(); - } - return $this->cache[$collectionHash]; - } - - /** - * Returns data by specified Data Source name - * - * @param string $dataSource - * @param array $filters - * @return array - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - */ - public function getData($dataSource, array $filters = []) - { - $children = $this->getMetadata($dataSource)->getChildren(); - $fields = $this->getMetadata($dataSource)->getFields(); - $items = $this->getCollectionData($dataSource, $filters); - - $rows = []; - foreach ($items as $item) { - $row = []; - foreach ($fields as $name => $field) { - if (isset($field['source']) && $field['source'] == 'lookup') { - $lookupCollection = $this->getCollectionData( - $field['reference']['target'], - [$field['reference']['targetField'] => $item->getData($field['reference']['referencedField'])] - ); - $lookup = reset($lookupCollection); - $row[$name] = $lookup[$field['reference']['neededField']]; - } elseif (isset($field['source']) && $field['source'] == 'reference') { - $lookupCollection = $this->getCollectionData( - $field['reference']['target'], - [$field['reference']['targetField'] => $item->getData($field['reference']['referencedField'])] - ); - $lookup = reset($lookupCollection); - $isReferenced = isset($lookup[$field['reference']['neededField']]) - && $lookup[$field['reference']['neededField']] == $item->getId(); - $row[$name] = $isReferenced; - } elseif (isset($field['source']) && $field['source'] == 'option') { - $row[$name] = $item->getData($field['reference']['referencedField']); - } else { - $row[$name] = $item->getData($name); - } - - if (isset($field['size'])) { - $row[$name] = explode("\n", $row[$name]); - } - } - if (!empty($children)) { - foreach ($children as $name => $reference) { - $filter = []; - foreach ($reference as $metadata) { - $filter[$metadata['referencedField']] = $row[$metadata['targetField']]; - } - $row[$name] = $this->getData($name, $filter); - if (empty($row[$name])) { - unset($row[$name]); - } - } - } - $rows[$item->getId()] = $row; - } - return $rows; - } -} diff --git a/app/code/Magento/Ui/DataProvider/Metadata.php b/app/code/Magento/Ui/DataProvider/Metadata.php deleted file mode 100644 index 0d86e46754b76349a63947d928f43f1cf44b7261..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/DataProvider/Metadata.php +++ /dev/null @@ -1,324 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Ui\DataProvider; - -use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\Validator\UniversalFactory; - -/** - * Class Metadata - */ -class Metadata implements \Iterator, \ArrayAccess -{ - /** - * Node name of children data sources - */ - const CHILD_DATA_SOURCES = 'childDataSources'; - - /** - * @var array - */ - protected $config; - - /** - * @var array - */ - protected $metadata = []; - - /** - * @var array - */ - protected $attributes = []; - - /** - * @var \Magento\Eav\Model\Entity\Collection\AbstractCollection - */ - protected $dataSet; - - /** - * @var array - */ - protected $children; - - /** - * @var Manager - */ - protected $manager; - - /** - * @var UniversalFactory - */ - protected $universalFactory; - - /** - * @param ObjectManagerInterface $objectManager - * @param Manager $manager - * @param UniversalFactory $universalFactory - * @param array $config - */ - public function __construct( - ObjectManagerInterface $objectManager, - Manager $manager, - UniversalFactory $universalFactory, - array $config - ) { - $this->config = $config; - if (isset($this->config['children'])) { - $this->config['fields'][self::CHILD_DATA_SOURCES] = $config['children']; - } - $this->dataSet = $objectManager->get($this->config['dataSet']); - $this->manager = $manager; - $this->universalFactory = $universalFactory; - $this->initAttributes(); - - foreach ($this->config['fields'] as $name => & $field) { - $this->prepare($name, $field); - } - } - - /** - * Return Data Source fields - * - * @return array - */ - public function getFields() - { - return isset($this->config['fields']) ? $this->config['fields'] : []; - } - - /** - * Return Data Source children - * - * @return array - */ - public function getChildren() - { - return isset($this->config['children']) ? $this->config['children'] : []; - } - - /** - * Return Data Source label - * - * @return string - */ - public function getLabel() - { - return $this->config['label']; - } - - /** - * Reset the Collection to the first element - * - * @return mixed - */ - public function rewind() - { - return reset($this->config['fields']); - } - - /** - * Return the current element - * - * @return mixed - */ - public function current() - { - return current($this->config['fields']); - } - - /** - * Return the key of the current element - * - * @return string - */ - public function key() - { - return key($this->config['fields']); - } - - /** - * Move forward to next element - * - * @return mixed - */ - public function next() - { - return next($this->config['fields']); - } - - /** - * Checks if current position is valid - * - * @return bool - */ - public function valid() - { - return (bool)$this->key(); - } - - /** - * Returns price class by code - * - * @param string $code - * @return string|array - */ - public function get($code) - { - return isset($this->config['fields'][$code]) ? $this->config['fields'][$code] : false; - } - - /** - * The value to set. - * - * @param string $offset - * @param string $value - * @return void - */ - public function offsetSet($offset, $value) - { - if ($offset === null) { - $this->config['fields'][] = $value; - } else { - $this->config['fields'][$offset] = $value; - } - } - - /** - * The return value will be casted to boolean if non-boolean was returned. - * - * @param string $offset - * @return bool - */ - public function offsetExists($offset) - { - return isset($this->config['fields'][$offset]); - } - - /** - * The offset to unset. - * - * @param string $offset - * @return void - */ - public function offsetUnset($offset) - { - unset($this->config['fields'][$offset]); - } - - /** - * The offset to retrieve. - * - * @param string $offset - * @return string - */ - public function offsetGet($offset) - { - return isset($this->config['fields'][$offset]) ? $this->config['fields'][$offset] : null; - } - - /** - * @return void - */ - protected function initAttributes() - { - if (empty($this->attributes)) { - foreach ($this->config['fields'] as $field) { - if (isset($field['source']) && $field['source'] == 'eav') { - $attribute = $this->dataSet->getEntity()->getAttribute($field['name']); - if ($attribute) { - $this->attributes[$field['name']] = $attribute->getData(); - $options = []; - if ($attribute->usesSource()) { - $options = $attribute->getSource()->getAllOptions(); - } - $this->attributes[$field['name']]['options'] = $options; - $this->attributes[$field['name']]['is_required'] = $attribute->getIsRequired(); - } - } - } - } - } - - /** - * @param string $name - * @param array $field - * @return void - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - protected function prepare($name, array & $field) - { - if ($name == self::CHILD_DATA_SOURCES) { - foreach ($field as $childName => $childConfig) { - $field[$childName] = $this->manager->getMetadata($childName); - } - return; - } - - $options = []; - if (isset($field['source'])) { - if ($field['source'] == 'option') { - $rawOptions = $this->manager->getData( - $field['reference']['target'] - ); - $options[] = [ - 'label' => __('Please, select...'), - 'value' => null, - ]; - foreach ($rawOptions as $rawOption) { - $options[] = [ - 'label' => $rawOption[$field['reference']['neededField']], - 'value' => $rawOption[$field['reference']['targetField']], - - ]; - } - } - } else { - if (isset($field['optionProvider'])) { - list($source, $method) = explode('::', $field['optionProvider']); - $sourceModel = $this->universalFactory->create($source); - $options = $sourceModel->$method(); - } - } - - $attributeCodes = [ - 'options' => ['eav_map' => 'options', 'default' => $options], - 'dataType' => ['eav_map' => 'frontend_input', 'default' => 'text'], - 'filterType' => ['default' => 'input_filter'], - 'formElement' => ['default' => 'input'], - 'displayArea' => ['default' => 'body'], - 'visible' => ['eav_map' => 'is_visible', 'default' => true], - 'required' => ['eav_map' => 'is_required', 'default' => false], - 'label' => ['eav_map' => 'frontend_label'], - 'sortOrder' => ['eav_map' => 'sort_order'], - 'notice' => ['eav_map' => 'note'], - 'default' => ['eav_map' => 'default_value'], - 'unique' => [], - 'description' => [], - 'constraints' => [], - 'customEntry' => [], - 'size' => ['eav_map' => 'scope_multiline_count'], - 'tooltip' => [], - 'fieldGroup' => [], - ]; - - foreach ($attributeCodes as $code => $info) { - if (!isset($field[$code])) { - if (isset($this->attributes[$name]) && isset($info['eav_map'])) { - $field[$code] = $this->attributes[$name][$info['eav_map']]; - } elseif (empty($field[$code]) && !empty($info['default'])) { - $field[$code] = $info['default']; - } - } - } - - if (isset($field['required']) && $field['required']) { - $field['constraints']['validate']['required-entry'] = true; - } - } -} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml.php b/app/code/Magento/Ui/TemplateEngine/Xhtml.php new file mode 100644 index 0000000000000000000000000000000000000000..e4a7765e90f79c0e2ad0223177707d0ed528c18c --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml.php @@ -0,0 +1,93 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine; + +use Magento\Ui\TemplateEngine\Xhtml\Result; +use Magento\Ui\TemplateEngine\Xhtml\Template; +use Magento\Ui\TemplateEngine\Xhtml\Compiler; +use Magento\Ui\TemplateEngine\Xhtml\ResultFactory; +use Magento\Framework\View\Element\BlockInterface; +use Magento\Framework\View\TemplateEngineInterface; +use Magento\Ui\TemplateEngine\Xhtml\CompilerFactory; +use Magento\Ui\TemplateEngine\Xhtml\TemplateFactory; +use Magento\Framework\View\Element\UiComponent\Config\Provider\Template as TemplateProvider; + +/** + * Class Xhtml + */ +class Xhtml implements TemplateEngineInterface +{ + const INSTANCE_NAME = 'Magento\Ui\Content\Template\Type\Xhtml\Template'; + + /** + * @var TemplateProvider + */ + protected $templateProvider; + + /** + * @var ResultFactory + */ + protected $resultFactory; + + /** + * @var TemplateFactory + */ + protected $templateFactory; + + /** + * @var CompilerFactory + */ + protected $compilerFactory; + + /** + * Constructor + * + * @param TemplateProvider $templateProvider + * @param ResultFactory $resultFactory + * @param TemplateFactory $templateFactory + * @param CompilerFactory $compilerFactory + */ + public function __construct( + TemplateProvider $templateProvider, + ResultFactory $resultFactory, + TemplateFactory $templateFactory, + CompilerFactory $compilerFactory + ) { + $this->templateProvider = $templateProvider; + $this->resultFactory = $resultFactory; + $this->templateFactory = $templateFactory; + $this->compilerFactory = $compilerFactory; + } + + /** + * Render template + * + * Render the named template in the context of a particular block and with + * the data provided in $vars. + * + * @param \Magento\Framework\View\Element\BlockInterface $block + * @param string $templateFile + * @param array $dictionary + * @return Result + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function render(BlockInterface $block, $templateFile, array $dictionary = []) + { + /** @var Template $template */ + $template = $this->templateFactory->create(['content' => $this->templateProvider->getTemplate($templateFile)]); + + /** @var Result $result */ + $result = $this->resultFactory->create( + [ + 'template' => $template, + 'compiler' => $this->compilerFactory->create(), + 'component' => $block + ] + ); + + return $result; + } +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler.php new file mode 100644 index 0000000000000000000000000000000000000000..68830d2a6574ffa1cd1bc82579cff98f56ea7a90 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler.php @@ -0,0 +1,175 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml; + +use Magento\Framework\Object; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Ui\TemplateEngine\Xhtml\Compiler\TextInterface; +use Magento\Ui\TemplateEngine\Xhtml\Compiler\CdataInterface; +use Magento\Ui\TemplateEngine\Xhtml\Compiler\CommentInterface; +use Magento\Ui\TemplateEngine\Xhtml\Compiler\AttributeInterface; +use Magento\Ui\TemplateEngine\Xhtml\Compiler\Element\ElementInterface; + +/** + * Class Compiler + */ +class Compiler +{ + const PATTERN_TAG = '|@|'; + + /** + * @var TextInterface + */ + protected $compilerText; + + /** + * @var AttributeInterface + */ + protected $compilerAttribute; + + /** + * @var CdataInterface + */ + protected $compilerCdata; + + /** + * @var CommentInterface + */ + protected $compilerComment; + + /** + * @var ElementInterface[] + */ + protected $elementCompilers; + + /** + * Postprocessing data + * + * @var array + */ + protected $data; + + /** + * Constructor + * + * @param TextInterface $compilerText + * @param AttributeInterface $compilerAttribute + * @param AttributeInterface|CdataInterface $compilerCdata + * @param CommentInterface $compilerComment + * @param ElementInterface[] $elementCompilers + */ + public function __construct( + TextInterface $compilerText, + AttributeInterface $compilerAttribute, + CdataInterface $compilerCdata, + CommentInterface $compilerComment, + array $elementCompilers + ) { + $this->compilerText = $compilerText; + $this->compilerAttribute = $compilerAttribute; + $this->compilerCdata = $compilerCdata; + $this->compilerComment = $compilerComment; + $this->elementCompilers = $elementCompilers; + } + + /** + * The compilation of the template and filling in the data + * + * @param \DOMNode $node + * @param UiComponentInterface $component + * @param Object $context + * @return void + */ + public function compile(\DOMNode $node, UiComponentInterface $component, Object $context) + { + switch ($node->nodeType) { + case XML_TEXT_NODE: + $this->compilerText->compile($node, $component); + break; + case XML_CDATA_SECTION_NODE: + $this->compilerCdata->compile($node, $component); + break; + case XML_COMMENT_NODE: + $this->compilerComment->compile($node, $component); + break; + default: + /** @var \DomElement $node */ + if ($node->hasAttributes()) { + foreach ($node->attributes as $attribute) { + $this->compilerAttribute->compile($attribute, $component); + } + } + $compiler = $this->getElementCompiler($node->nodeName); + if (null !== $compiler) { + $compiler->compile($this, $node, $component, $context); + } else if ($node->hasChildNodes()) { + foreach ($this->getChildNodes($node) as $child) { + $this->compile($child, $component, $context); + } + } + } + } + + /** + * Run postprocessing contents template + * + * @param string $content + * @return string + */ + public function postprocessing($content) + { + return preg_replace_callback( + '#' . preg_quote(static::PATTERN_TAG) . '(.+?)' . preg_quote(static::PATTERN_TAG) . '#', + function ($match) { + return isset($this->data[$match[1]]) ? $this->data[$match[1]] : ''; + }, + $content + ); + } + + /** + * Set postprocessing data + * + * @param string $key + * @param string $content + * @return void + */ + public function setPostprocessingData($key, $content) + { + $this->data[$key] = $content; + } + + /** + * Get child nodes + * + * @param \DOMElement $node + * @return \DOMElement[] + */ + protected function getChildNodes(\DOMElement $node) + { + $childNodes = []; + foreach ($node->childNodes as $child) { + $childNodes[] = $child; + } + + return $childNodes; + } + + /** + * Get element compiler by name + * + * @param string $name + * @return ElementInterface + */ + protected function getElementCompiler($name) + { + if (isset($this->elementCompilers[$name])) { + return $this->elementCompilers[$name]; + } + + return null; + } +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Attribute.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Attribute.php new file mode 100644 index 0000000000000000000000000000000000000000..f1ab640960831615310268cc4d99e6dc39fcd415 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Attribute.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler; + +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive\DirectiveInterface; + +/** + * Class Attribute + */ +class Attribute implements AttributeInterface +{ + /** + * @var DirectiveInterface[] + */ + protected $directivePool; + + /** + * Constructor + * + * @param DirectiveInterface[] $directivePool + */ + public function __construct(array $directivePool) + { + $this->directivePool = $directivePool; + } + + /** + * Compiles the Element node + * + * @param \DOMAttr $node + * @param UiComponentInterface $component + * @return void + */ + public function compile(\DOMAttr $node, UiComponentInterface $component) + { + foreach ($this->directivePool as $directive) { + $node->value = preg_replace_callback( + $directive->getPattern(), + function ($match) use ($directive, $component) { + return $directive->execute($match, $component); + }, + $node->value + ); + } + } +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/AttributeInterface.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/AttributeInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..274d43bcde56dd2f793d0b5a2fd01abae047c9f6 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/AttributeInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Interface AttributeInterface + */ +interface AttributeInterface +{ + /** + * Compiles the Element node + * + * @param \DOMAttr $node + * @param UiComponentInterface $component + * @return void + */ + public function compile(\DOMAttr $node, UiComponentInterface $component); +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Cdata.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Cdata.php new file mode 100644 index 0000000000000000000000000000000000000000..785a86eb5c2b36a46691383b702b7dd1c39a556b --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Cdata.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Class Cdata + */ +class Cdata implements CdataInterface +{ + /** + * Compiles the CData Section node + * + * @param \DOMCdataSection $node + * @param UiComponentInterface $component + * @return void + */ + public function compile(\DOMCdataSection $node, UiComponentInterface $component) + { + // + } +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/CdataInterface.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/CdataInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..d37d9460fc2f8a49cbef9689a53776918e3fa2d4 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/CdataInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Interface CdataInterface + */ +interface CdataInterface +{ + /** + * Compiles the CData Section node + * + * @param \DOMCdataSection $node + * @param UiComponentInterface $component + * @return void + */ + public function compile(\DOMCdataSection $node, UiComponentInterface $component); +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Comment.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Comment.php new file mode 100644 index 0000000000000000000000000000000000000000..2ad634611ab74b0d762947a1ac54b8695bd37768 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Comment.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Class Comment + */ +class Comment implements CommentInterface +{ + /** + * Compiles the Comment node + * + * @param \DOMComment $node + * @param UiComponentInterface $component + * @return void + */ + public function compile(\DOMComment $node, UiComponentInterface $component) + { + // + } +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/CommentInterface.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/CommentInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..19a2d6569c977a056e22cd69322475616f736acb --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/CommentInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Interface CommentInterface + */ +interface CommentInterface +{ + /** + * Compiles the Comment node + * + * @param \DOMComment $node + * @param UiComponentInterface $component + * @return void + */ + public function compile(\DOMComment $node, UiComponentInterface $component); +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/CallableMethod.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/CallableMethod.php new file mode 100644 index 0000000000000000000000000000000000000000..ef14461f3610f8b3fc914a646b58ba62a73f2122 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/CallableMethod.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Class CallableMethod + */ +class CallableMethod implements DirectiveInterface +{ + /** + * Execute directive + * + * @param array $directive + * @param UiComponentInterface $component + * @return string + */ + public function execute($directive, UiComponentInterface $component) + { + $object = $component; + $result = ''; + foreach (explode('.', $directive[1]) as $method) { + $methodName = substr($method, 0, strpos($method, '(')); + if (is_callable([$object, $methodName])) { + $result = $object->$methodName(); + if (is_scalar($result)) { + break; + } + $object = $result; + continue; + } + break; + } + + return $result; + } + + /** + * Get regexp search pattern + * + * @return string + */ + public function getPattern() + { + return '#\{\{((?:[\w_0-9]+\(\)){1}(?:(?:\.[\w_0-9]+\(\))+)?)\}\}#'; + } +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/DirectiveInterface.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/DirectiveInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..b367a6b84f7b3edb47869b967a88e66dd84a6cf1 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/DirectiveInterface.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Interface DirectiveInterface + */ +interface DirectiveInterface +{ + /** + * Execute directive + * + * @param array $directive + * @param UiComponentInterface $component + * @return string + */ + public function execute($directive, UiComponentInterface $component); + + /** + * Get regexp search pattern + * + * @return string + */ + public function getPattern(); +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/Variable.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/Variable.php new file mode 100644 index 0000000000000000000000000000000000000000..b903855c821912ed3ec9d19eb1feb575c0e8c017 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Directive/Variable.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Class Variable + */ +class Variable implements DirectiveInterface +{ + /** + * Execute directive + * + * @param array $directive + * @param UiComponentInterface $component + * @return string + */ + public function execute($directive, UiComponentInterface $component) + { + return $component->getData($directive[1]); + } + + /** + * Get regexp search pattern + * + * @return string + */ + public function getPattern() + { + return '#\{\{([^\}\(]+)\}\}#'; + } +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Content.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Content.php new file mode 100644 index 0000000000000000000000000000000000000000..1b31288c66fd8d397a64a2ee9e766fa6008856f1 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Content.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Element; + +use Magento\Framework\Object; +use Magento\Ui\TemplateEngine\Xhtml\Compiler; +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Class Content + */ +class Content implements ElementInterface +{ + /** + * Compiles the Element node + * + * @param Compiler $compiler + * @param \DOMElement $node + * @param UiComponentInterface $component + * @param Object $context + * @return void + */ + public function compile( + Compiler $compiler, + \DOMElement $node, + UiComponentInterface $component, + Object $context + ) { + $name = $node->getAttribute('name'); + $content = (string)$component->renderChildComponent($name); + $name .= '_' . sprintf('%x', crc32(spl_object_hash($context))); + if (!empty($content)) { + $compiler->setPostprocessingData($name, $content); + $newNode = $node->ownerDocument->createTextNode( + Compiler::PATTERN_TAG . $name . Compiler::PATTERN_TAG + ); + $node->parentNode->replaceChild($newNode, $node); + } else { + $node->parentNode->removeChild($node); + } + } +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/ElementInterface.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/ElementInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..9ce4c9f74583636d568a83ac45456ecdffb8222c --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/ElementInterface.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Element; + +use Magento\Framework\Object; +use Magento\Ui\TemplateEngine\Xhtml\Compiler; +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Interface ElementInterface + */ +interface ElementInterface +{ + /** + * Compiles the Element node + * + * @param Compiler $compiler + * @param \DOMElement $node + * @param UiComponentInterface $component + * @param Object $context + * @return void + */ + public function compile( + Compiler $compiler, + \DOMElement $node, + UiComponentInterface $component, + Object $context + ); +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Form.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Form.php new file mode 100644 index 0000000000000000000000000000000000000000..513be2d1daf676ed9c433c82a2f23cbce0f3d588 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Form.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Element; + +use Magento\Framework\Object; +use Magento\Ui\TemplateEngine\Xhtml\Compiler; +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Class Form + */ +class Form implements ElementInterface +{ + /** + * Compiles the Element node + * + * @param Compiler $compiler + * @param \DOMElement $node + * @param UiComponentInterface $component + * @param Object $context + * @return void + */ + public function compile( + Compiler $compiler, + \DOMElement $node, + UiComponentInterface $component, + Object $context + ) { + foreach ($this->getChildNodes($node) as $child) { + $compiler->compile($child, $component, $context); + } + } + + /** + * Get child nodes + * + * @param \DOMElement $node + * @return \DOMElement[] + */ + protected function getChildNodes(\DOMElement $node) + { + $childNodes = []; + foreach ($node->childNodes as $child) { + $childNodes[] = $child; + } + + return $childNodes; + } +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Render.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Render.php new file mode 100644 index 0000000000000000000000000000000000000000..9118a5e6b6aef4cd9a00cea1e21ec38234334660 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Element/Render.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler\Element; + +use Magento\Framework\Object; +use Magento\Ui\TemplateEngine\Xhtml\Compiler; +use Magento\Ui\TemplateEngine\Xhtml\Result; +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Class Render + */ +class Render implements ElementInterface +{ + /** + * Compiles the Element node + * + * @param Compiler $compiler + * @param \DOMElement $node + * @param UiComponentInterface $component + * @param Object $context + * @return void + */ + public function compile( + Compiler $compiler, + \DOMElement $node, + UiComponentInterface $component, + Object $context + ) { + $result = $component->renderChildComponent($node->getAttribute('name')); + if ($result instanceof Result) { + $node->parentNode->replaceChild($result->getDocumentElement(), $node); + } else if (!empty($result) && is_scalar($result)) { + $newFragment = $node->ownerDocument->createDocumentFragment(); + $newFragment->appendXML($result); + $node->parentNode->replaceChild($newFragment, $node); + $node->parentNode->removeChild($node); + } else { + $node->parentNode->removeChild($node); + } + } +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Text.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Text.php new file mode 100644 index 0000000000000000000000000000000000000000..5bdfe50622c2a5b13000b10e9848265fc46e847f --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/Text.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler; + +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive\DirectiveInterface; + +/** + * Class Text + */ +class Text implements TextInterface +{ + /** + * @var DirectiveInterface[] + */ + protected $directivePool; + + /** + * Constructor + * + * @param DirectiveInterface[] $directivePool + */ + public function __construct(array $directivePool) + { + $this->directivePool = $directivePool; + } + + /** + * Compiles the Element node + * + * @param \DOMText $node + * @param UiComponentInterface $component + * @return void + */ + public function compile(\DOMText $node, UiComponentInterface $component) + { + $result = ''; + foreach ($this->directivePool as $directive) { + $result = preg_replace_callback( + $directive->getPattern(), + function ($match) use ($directive, $component) { + return $directive->execute($match, $component); + }, + $node->textContent + ); + } + + $newNode = $node->ownerDocument->createTextNode($result); + $node->parentNode->replaceChild($newNode, $node); + } +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/TextInterface.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/TextInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..1f1ffc41586164cbf0da8b960007b0c27c998476 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Compiler/TextInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml\Compiler; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Interface TextInterface + */ +interface TextInterface +{ + /** + * Compiles the Element node + * + * @param \DOMText $node + * @param UiComponentInterface $component + * @return void + */ + public function compile(\DOMText $node, UiComponentInterface $component); +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Result.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Result.php new file mode 100644 index 0000000000000000000000000000000000000000..2ad357022989fe9d7a4c9bd04d71d0faef71e151 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Result.php @@ -0,0 +1,114 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml; + +use Magento\Ui\Component\Layout\Generator\Structure; +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Class Result + */ +class Result +{ + /** + * @var Template + */ + protected $template; + + /** + * @var Compiler + */ + protected $compiler; + + /** + * @var UiComponentInterface + */ + protected $component; + + /** + * @var Structure + */ + protected $structure; + + /** + * Constructor + * + * @param Template $template + * @param Compiler $compiler + * @param UiComponentInterface $component + * @param Structure $structure + */ + public function __construct( + Template $template, + Compiler $compiler, + UiComponentInterface $component, + Structure $structure + ) { + $this->template = $template; + $this->compiler = $compiler; + $this->component = $component; + $this->structure = $structure; + } + + /** + * Get result document root element \DOMElement + * + * @return \DOMElement + */ + public function getDocumentElement() + { + return $this->template->getDocumentElement(); + } + + /** + * Append layout configuration + * + * @return void + */ + public function appendLayoutConfiguration() + { + $layoutConfiguration = $this->wrapContent(json_encode($this->structure->generate($this->component))); + $this->template->append($layoutConfiguration); + } + + /** + * Returns the string representation + * + * @return string + */ + public function __toString() + { + try { + $templateRootElement = $this->getDocumentElement(); + foreach ($templateRootElement->attributes as $name => $attribute) { + if ('noNamespaceSchemaLocation' === $name) { + $this->getDocumentElement()->removeAttributeNode($attribute); + break; + } + } + $templateRootElement->removeAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'xsi'); + $this->compiler->compile($templateRootElement, $this->component, $this->component); + $this->appendLayoutConfiguration(); + $result = $this->compiler->postprocessing($this->template->__toString()); + } catch (\Exception $e) { + $result = ''; + } + return $result; + } + + /** + * Wrap content + * + * @param string $content + * @return string + */ + protected function wrapContent($content) + { + return '<script type="text/x-magento-init"><![CDATA[' + . '{"*": {"Magento_Ui/js/core/app": ' . str_replace(['<![CDATA[', ']]>'], '', $content) . '}}' + . ']]></script>'; + } +} diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Template.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Template.php new file mode 100644 index 0000000000000000000000000000000000000000..52cc35f0cf461c943598ba3206fdebe6ea26b824 --- /dev/null +++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Template.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\TemplateEngine\Xhtml; + +/** + * Class Template + */ +class Template +{ + const XML_VERSION = '1.0'; + + const XML_ENCODING = 'UTF-8'; + + /** + * @var \DOMElement + */ + protected $templateNode; + + /** + * Constructor + * + * @param string $content + */ + public function __construct($content) + { + $document = new \DOMDocument(static::XML_VERSION, static::XML_ENCODING); + $document->loadXML($content); + $this->templateNode = $document->documentElement; + } + + /** + * Get template root element + * + * @return \DOMElement + */ + public function getDocumentElement() + { + return $this->templateNode; + } + + /** + * Append + * + * @param string $content + * @return void + */ + public function append($content) + { + $newFragment = $this->templateNode->ownerDocument->createDocumentFragment(); + $newFragment->appendXML($content); + $this->templateNode->appendChild($newFragment); + } + + /** + * Returns the string representation + * + * @return string + */ + public function __toString() + { + try { + $this->templateNode->ownerDocument->normalizeDocument(); + $result = $this->templateNode->ownerDocument->saveHTML(); + } catch (\Exception $e) { + $result = ''; + } + return $result; + } +} diff --git a/app/code/Magento/Ui/Test/Unit/Component/Control/ActionPoolTest.php b/app/code/Magento/Ui/Test/Unit/Component/Control/ActionPoolTest.php index 461515aafe6c82463b6cde76ca5823502422b171..eaae007216af0aa226ff98336e22c727190102a0 100644 --- a/app/code/Magento/Ui/Test/Unit/Component/Control/ActionPoolTest.php +++ b/app/code/Magento/Ui/Test/Unit/Component/Control/ActionPoolTest.php @@ -127,18 +127,20 @@ class ActionPoolTest extends \PHPUnit_Framework_TestCase ->method('setChild') ->with($this->key, $toolbarContainerMock) ->willReturnSelf(); - $this->assertNull($this->actionPool->add($this->key, $data, $this->uiComponentInterfaceMock)); + $this->actionPool->add($this->key, $data, $this->uiComponentInterfaceMock); } public function testRemove() { - $this->assertNull($this->actionPool->remove($this->key)); + $this->testAdd(); + $this->actionPool->remove($this->key); } public function testUpdate() { + $this->testAdd(); $data = ['id' => 'id']; $this->items[$this->key]->expects($this->any())->method('setData')->with($data)->willReturnSelf(); - $this->assertNull($this->actionPool->update($this->key, $data)); + $this->actionPool->update($this->key, $data); } } diff --git a/app/code/Magento/Ui/Test/Unit/Component/Control/ActionTest.php b/app/code/Magento/Ui/Test/Unit/Component/Control/ActionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..be25a5957f10d22e90fc5f2b91be11910b60b342 --- /dev/null +++ b/app/code/Magento/Ui/Test/Unit/Component/Control/ActionTest.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Test\Unit\Component\Control; + +use Magento\Ui\Component\Control\Action; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +/** + * Class ActionTest + */ +class ActionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Action + */ + protected $action; + + /** + * @var ObjectManager + */ + protected $objectManager; + + /** + * Set up + */ + public function setUp() + { + $this->objectManager = new ObjectManager($this); + + $this->action = $this->objectManager->getObject('Magento\Ui\Component\Control\Action'); + } + + /** + * Run test getComponentName method + * + * @return void + */ + public function testGetComponentName() + { + $this->assertTrue($this->action->getComponentName() === Action::NAME); + } +} diff --git a/app/code/Magento/Ui/Test/Unit/Component/Control/ButtonTest.php b/app/code/Magento/Ui/Test/Unit/Component/Control/ButtonTest.php index 998e677f7e9df92ebdf92df4ae708fa8346e80ae..84284dea69d092dc4b6553734067a846412f83b2 100644 --- a/app/code/Magento/Ui/Test/Unit/Component/Control/ButtonTest.php +++ b/app/code/Magento/Ui/Test/Unit/Component/Control/ButtonTest.php @@ -59,7 +59,7 @@ class ButtonTest extends \PHPUnit_Framework_TestCase public function testGetAttributesHtml() { $expected = 'type="button" class="action- scalable classValue disabled" ' - . 'onclick="setLocation(\'url2\');" disabled="disabled" data-attributeKey="attributeValue" '; + . 'onclick="location.href = \'url2\';" disabled="disabled" data-attributeKey="attributeValue" '; $this->button->setDisabled(true); $this->button->setData('url', 'url2'); $this->button->setData('class', 'classValue'); @@ -98,12 +98,12 @@ class ButtonTest extends \PHPUnit_Framework_TestCase { return [ [null, null, '', null], - [null, null, 'get_url', 'setLocation(\'get_url\');'], + [null, null, 'get_url', 'location.href = \'get_url\';'], ['on_click', null, null, 'on_click'], ['on_click', 'url', 'get_url', 'on_click'], ['on_click', null, '', 'on_click'], - [null, 'url', 'get_url', 'setLocation(\'url\');'], - [null, 'url', '', 'setLocation(\'url\');'], + [null, 'url', 'get_url', 'location.href = \'url\';'], + [null, 'url', '', 'location.href = \'url\';'], ]; } } diff --git a/app/code/Magento/Ui/Test/Unit/Component/Control/ContainerTest.php b/app/code/Magento/Ui/Test/Unit/Component/Control/ContainerTest.php index 72b28b39c7f42637fa77d4d0ffb2b3a194c637bd..9251da5b69dffd7adee6d34dd9fff76c7babe17a 100644 --- a/app/code/Magento/Ui/Test/Unit/Component/Control/ContainerTest.php +++ b/app/code/Magento/Ui/Test/Unit/Component/Control/ContainerTest.php @@ -17,7 +17,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase $blockName = $nameInLayout . '-' . $id . '-button'; $expectedHtml = 'test html'; - $blockButtonMock = $this->getMock(Container::DEFAULT_BUTTON, [], [], '', false); + $blockButtonMock = $this->getMock(Container::DEFAULT_CONTROL, [], [], '', false); $blockButtonMock->expects($this->once())->method('toHtml')->willReturn($expectedHtml); $contextMock = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false); @@ -32,7 +32,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase $layoutMock = $this->getMock('Magento\Framework\View\Layout', [], [], '', false); $layoutMock->expects($this->once()) ->method('createBlock') - ->with(Container::DEFAULT_BUTTON, $blockName) + ->with(Container::DEFAULT_CONTROL, $blockName) ->willReturn($blockButtonMock); $contextMock->expects($this->any())->method('getLayout')->willReturn($layoutMock); diff --git a/app/code/Magento/Ui/Test/Unit/Component/Control/LinkTest.php b/app/code/Magento/Ui/Test/Unit/Component/Control/LinkTest.php new file mode 100644 index 0000000000000000000000000000000000000000..1615690f8674f3668f502e6b45328c535286fe74 --- /dev/null +++ b/app/code/Magento/Ui/Test/Unit/Component/Control/LinkTest.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Test\Unit\Component\Control; + +use Magento\Ui\Component\Control\Link; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +/** + * Class LinkTest + */ +class LinkTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Link + */ + protected $link; + + /** + * @var ObjectManager + */ + protected $objectManager; + + /** + * Set up + */ + public function setUp() + { + $this->objectManager = new ObjectManager($this); + + $this->link = $this->objectManager->getObject('Magento\Ui\Component\Control\Link'); + } + + /** + * Run test getComponentName method + * + * @return void + */ + public function testGetComponentName() + { + $this->assertTrue($this->link->getComponentName() === Link::NAME); + } +} diff --git a/app/code/Magento/Ui/Test/Unit/Component/FilterPoolTest.php b/app/code/Magento/Ui/Test/Unit/Component/FilterPoolTest.php deleted file mode 100644 index f12d71763da6ffb834c31e627825ed606ad993c8..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Test/Unit/Component/FilterPoolTest.php +++ /dev/null @@ -1,408 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Ui\Test\Unit\Component; - -use \Magento\Ui\Component\FilterPool; - -use Magento\Framework\View\Element\Template; -use Magento\Framework\View\Element\Template\Context as TemplateContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigFactory; -use Magento\Framework\View\Element\UiComponent\Context; -use Magento\Ui\Component\Filter\FilterPool as FilterPoolProvider; -use Magento\Ui\ContentType\ContentTypeFactory; - -/** - * Class ViewTest - */ -class FilterPoolTest extends \PHPUnit_Framework_TestCase -{ - /** - * Filter var - */ - const FILTER_VAR = 'filter'; - - /** - * @var TemplateContext|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contextMock; - - /** - * @var Context|\PHPUnit_Framework_MockObject_MockObject - */ - protected $renderContextMock; - - /** - * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contentTypeFactoryMock; - - /** - * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $configFactoryMock; - - /** - * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $configBuilderMock; - - /** - * @var \Magento\Ui\DataProvider\Factory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $dataProviderFactoryMock; - - /** - * @var \Magento\Ui\DataProvider\Manager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $dataProviderManagerMock; - - /** - * @var FilterPoolProvider|\PHPUnit_Framework_MockObject_MockObject - */ - protected $filterPoolProviderMock; - - /** - * @var FilterPool - */ - protected $filterPool; - - /** - * Set up - * - * @return void - */ - protected function setUp() - { - $this->contextMock = $this->getMock( - 'Magento\Framework\View\Element\Template\Context', - [], - [], - '', - false - ); - $this->renderContextMock = $this->getMock( - 'Magento\Framework\View\Element\UiComponent\Context', - ['getNamespace', 'getStorage', 'getRequestParam'], - [], - '', - false - ); - $this->contentTypeFactoryMock = $this->getMock( - 'Magento\Ui\ContentType\ContentTypeFactory', - [], - [], - '', - false - ); - $this->configFactoryMock = $this->getMock( - 'Magento\Framework\View\Element\UiComponent\ConfigFactory', - ['create'], - [], - '', - false - ); - $this->configBuilderMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface', - [], - '', - false - ); - $this->dataProviderFactoryMock = $this->getMock( - 'Magento\Ui\DataProvider\Factory', - [], - [], - '', - false - ); - $this->dataProviderManagerMock = $this->getMock( - 'Magento\Ui\DataProvider\Manager', - [], - [], - '', - false - ); - $this->filterPoolProviderMock = $this->getMock( - 'Magento\Ui\Component\Filter\FilterPool', - ['getFilter'], - [], - '', - false - ); - - $this->filterPool = new FilterPool( - $this->contextMock, - $this->renderContextMock, - $this->contentTypeFactoryMock, - $this->configFactoryMock, - $this->configBuilderMock, - $this->dataProviderFactoryMock, - $this->dataProviderManagerMock, - $this->filterPoolProviderMock - ); - } - - /** - * Run test prepare method - * - * @return void - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - public function testPrepare() - { - /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface - * |\PHPUnit_Framework_MockObject_MockObject $configurationMock - */ - $configurationMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigInterface', - ['getParentName'], - '', - false - ); - /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface - * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock - */ - $configStorageMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface', - ['addComponentsData', 'getDataCollection', 'getMeta'], - '', - false - ); - /** - * @var \Magento\Framework\Data\Collection|\PHPUnit_Framework_MockObject_MockObject $dataCollectionMock - */ - $dataCollectionMock = $this->getMock( - 'Magento\Framework\Data\Collection', - ['setOrder'], - [], - '', - false - ); - - $this->renderContextMock->expects($this->at(0)) - ->method('getNamespace') - ->will($this->returnValue('namespace')); - $this->renderContextMock->expects($this->at(1)) - ->method('getNamespace') - ->will($this->returnValue('namespace')); - $this->configFactoryMock->expects($this->any()) - ->method('create') - ->will($this->returnValue($configurationMock)); - $this->renderContextMock->expects($this->any()) - ->method('getStorage') - ->will($this->returnValue($configStorageMock)); - $configStorageMock->expects($this->at(0)) - ->method('getDataCollection') - ->will($this->returnValue($dataCollectionMock)); - $configStorageMock->expects($this->at(1)) - ->method('getDataCollection') - ->will($this->returnValue($dataCollectionMock)); - - $metaData = [ - 'field-1' => 'value-1', - 'field-2' => 'value-2', - 'field-3' => 'value-3', - 'field-4' => 'value-4', - ]; - $meta = [ - 'fields' => $metaData, - ]; - $filters = $metaData; - - $configStorageMock->expects($this->any()) - ->method('getMeta') - ->will($this->returnValue($meta)); - $this->renderContextMock->expects($this->once()) - ->method('getRequestParam') - ->with(static::FILTER_VAR); - - $filterMock = $this->getMockForAbstractClass( - 'Magento\Ui\Component\Filter\FilterInterface', - ['getCondition'], - '', - false - ); - - $this->filterPoolProviderMock->expects($this->any()) - ->method('getFilter') - ->will($this->returnValue($filterMock)); - $filterMock->expects($this->any()) - ->method('getCondition') - ->will($this->returnValue(true)); - - $dataCollectionMock->expects($this->any()) - ->method('addFieldToFilter'); - - $this->assertNull($this->filterPool->prepare()); - } - - /** - * Run test getFields method - * - * @return void - */ - public function _testGetFields() - { - /** @var \Magento\Ui\Component\FilterPool|\PHPUnit_Framework_MockObject_MockObject $filterPool */ - $filterPool = $this->getMock( - 'Magento\Ui\Component\FilterPool', - ['getParentName'], - [ - $this->contextMock, - $this->renderContextMock, - $this->contentTypeFactoryMock, - $this->configFactoryMock, - $this->configBuilderMock, - $this->dataProviderFactoryMock, - $this->dataProviderManagerMock, - $this->filterPoolProviderMock - ], - '', - false - ); - $filterPool->expects($this->any()) - ->method('getParentName') - ->willReturn('parent'); - - $result = [ - 'field-1' => ['filterable' => 1], - 'field-4' => ['filterable' => 1], - ]; - $meta = [ - 'fields' => [ - 'field-1' => ['filterable' => true], - 'field-2' => ['filterable' => false], - 'field-3' => ['filterable' => false], - 'field-4' => ['filterable' => true], - ], - ]; - /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface - * |\PHPUnit_Framework_MockObject_MockObject $configurationMock - */ - $configMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigInterface', - [], - '', - false - ); - /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface - * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock - */ - $configStorageMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface', - ['addComponentsData', 'getDataCollection', 'getMeta'], - '', - false - ); - - $this->filterPool->setConfig($configMock); - - $this->renderContextMock->expects($this->any()) - ->method('getStorage') - ->will($this->returnValue($configStorageMock)); - $configStorageMock->expects($this->any()) - ->method('getMeta') - ->will($this->returnValue($meta)); - - $this->assertEquals($result, $filterPool->getFields()); - } - - /** - * Run test getActiveFilters method - * - * @return void - */ - public function _testGetActiveFilters() - { - $result = [ - 'field-1' => [ - 'title' => 'title-1', - 'current_display_value' => 'value-1', - ], - 'field-2' => [ - 'title' => 'title-2', - 'current_display_value' => 'value-2', - ], - 'field-3' => [ - 'title' => 'title-3', - 'current_display_value' => 'value-3', - ], - 'field-4' => [ - 'title' => 'title-4', - 'current_display_value' => 'value-4', - ], - ]; - $meta = [ - 'fields' => [ - 'field-1' => [ - 'filter_type' => true, - 'title' => 'title-1', - ], - 'field-2' => [ - 'filter_type' => true, - 'title' => 'title-2', - ], - 'field-3' => [ - 'filter_type' => true, - 'title' => 'title-3', - ], - 'field-4' => [ - 'filter_type' => true, - 'title' => 'title-4', - ], - ], - ]; - $filters = [ - 'field-1' => 'value-1', - 'field-2' => 'value-2', - 'field-3' => 'value-3', - 'field-4' => 'value-4', - ]; - - /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface - * |\PHPUnit_Framework_MockObject_MockObject $configurationMock - */ - $configMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigInterface', - [], - '', - false - ); - /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface - * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock - */ - $configStorageMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface', - ['addComponentsData', 'getDataCollection', 'getMeta'], - '', - false - ); - - $this->filterPool->setConfig($configMock); - - $this->renderContextMock->expects($this->any()) - ->method('getStorage') - ->will($this->returnValue($configStorageMock)); - $configStorageMock->expects($this->any()) - ->method('getMeta') - ->will($this->returnValue($meta)); - $this->dataHelperMock->expects($this->once()) - ->method('prepareFilterString') - ->will($this->returnValue($filters)); - $this->renderContextMock->expects($this->once()) - ->method('getRequestParam') - ->with(static::FILTER_VAR); - - $this->assertEquals($result, $this->filterPool->getActiveFilters()); - } -} diff --git a/app/code/Magento/Ui/Test/Unit/Component/FilterTest.php b/app/code/Magento/Ui/Test/Unit/Component/FilterTest.php deleted file mode 100644 index 656070849515a734268911a185eb1f9d18aae239..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Test/Unit/Component/FilterTest.php +++ /dev/null @@ -1,193 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Test\Unit\Component; - -use Magento\Framework\View\Element\Template; -use Magento\Framework\View\Element\Template\Context as TemplateContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigFactory; -use Magento\Framework\View\Element\UiComponent\Context; -use Magento\Ui\Component\Filter\FilterPool as FilterPoolProvider; -use Magento\Ui\ContentType\ContentTypeFactory; - -/** - * Class FilterTest - */ -class FilterTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var TemplateContext||\PHPUnit_Framework_MockObject_MockObject - */ - protected $contextMock; - - /** - * @var Context|\PHPUnit_Framework_MockObject_MockObject - */ - protected $renderContextMock; - - /** - * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contentTypeFactoryMock; - - /** - * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $configFactoryMock; - - /** - * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $configBuilderMock; - - /** - * @var \Magento\Ui\DataProvider\Factory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $dataProviderFactoryMock; - - /** - * @var \Magento\Ui\DataProvider\Manager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $dataProviderManagerMock; - - /** - * @var \Magento\Backend\Helper\Data|\PHPUnit_Framework_MockObject_MockObject - */ - protected $dataHelperMock; - - /** - * @var FilterPoolProvider|\PHPUnit_Framework_MockObject_MockObject - */ - protected $filterPoolMock; - - /** - * @var \Magento\Ui\Component\FilterPool - */ - protected $filter; - - /** - * Set up - * - * @return void - */ - protected function setUp() - { - $this->contextMock = $this->getMock( - 'Magento\Framework\View\Element\Template\Context', - [], - [], - '', - false - ); - $this->renderContextMock = $this->getMock( - 'Magento\Framework\View\Element\UiComponent\Context', - ['getNamespace', 'getStorage', 'getRequestParam'], - [], - '', - false - ); - $this->contentTypeFactoryMock = $this->getMock( - 'Magento\Ui\ContentType\ContentTypeFactory', - [], - [], - '', - false - ); - $this->configFactoryMock = $this->getMock( - 'Magento\Framework\View\Element\UiComponent\ConfigFactory', - ['create'], - [], - '', - false - ); - $this->configBuilderMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface', - [], - '', - false - ); - $this->dataProviderFactoryMock = $this->getMock( - 'Magento\Ui\DataProvider\Factory', - [], - [], - '', - false - ); - $this->dataProviderManagerMock = $this->getMock( - 'Magento\Ui\DataProvider\Manager', - [], - [], - '', - false - ); - $this->filterPoolMock = $this->getMock( - 'Magento\Ui\Component\Filter\FilterPool', - ['getFilter'], - [], - '', - false - ); - - $this->filter = new \Magento\Ui\Component\FilterPool( - $this->contextMock, - $this->renderContextMock, - $this->contentTypeFactoryMock, - $this->configFactoryMock, - $this->configBuilderMock, - $this->dataProviderFactoryMock, - $this->dataProviderManagerMock, - $this->filterPoolMock - ); - } - - /** - * Run test prepare method - * - * @return void - */ - public function testPrepare() - { - /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface - * |\PHPUnit_Framework_MockObject_MockObject $configurationMock - */ - $configurationMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigInterface', - [], - '', - false - ); - /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface - * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock - */ - $configStorageMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface', - ['addComponentsData', 'getDataCollection', 'getMeta'], - '', - false - ); - - $this->renderContextMock->expects($this->at(0)) - ->method('getNamespace') - ->will($this->returnValue('namespace')); - $this->renderContextMock->expects($this->at(1)) - ->method('getNamespace') - ->will($this->returnValue('namespace')); - $this->configFactoryMock->expects($this->any()) - ->method('create') - ->will($this->returnValue($configurationMock)); - - $this->renderContextMock->expects($this->any()) - ->method('getStorage') - ->will($this->returnValue($configStorageMock)); - $configStorageMock->expects($this->once()) - ->method('addComponentsData') - ->with($configurationMock); - - $this->assertNull($this->filter->prepare()); - } -} diff --git a/app/code/Magento/Ui/Test/Unit/Component/Listing/Columns/ColumnTest.php b/app/code/Magento/Ui/Test/Unit/Component/Listing/Columns/ColumnTest.php new file mode 100644 index 0000000000000000000000000000000000000000..98005246955763c90120fd66e06ff8f9eabb0a1a --- /dev/null +++ b/app/code/Magento/Ui/Test/Unit/Component/Listing/Columns/ColumnTest.php @@ -0,0 +1,164 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Test\Unit\Component\Listing\Columns; + +use Magento\Ui\Component\Listing\Columns\Column; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; + +/** + * Class ColumnTest + */ +class ColumnTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $contextMock; + + /** + * @var ObjectManager + */ + protected $objectManager; + + /** + * Set up + */ + public function setUp() + { + $this->objectManager = new ObjectManager($this); + + $this->contextMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponent\ContextInterface', + [], + '', + false, + true, + true, + [] + ); + } + + /** + * Run test getComponentName method + * + * @return void + */ + public function testGetComponentName() + { + $column = $this->objectManager->getObject( + 'Magento\Ui\Component\Listing\Columns\Column', + [ + 'context' => $this->contextMock, + 'data' => [ + 'js_config' => [ + 'extends' => 'test_config_extends' + ], + 'config' => [ + 'dataType' => 'testType' + ] + ] + ] + ); + + $this->assertEquals($column->getComponentName(), Column::NAME . '.testType'); + } + + /** + * Run test prepareItems method + * + * @return void + */ + public function testPrepareItems() + { + $testItems = ['item1','item2', 'item3']; + $column = $this->objectManager->getObject('Magento\Ui\Component\Listing\Columns\Column'); + + $this->assertEquals($testItems, $column->prepareItems($testItems)); + } + + /** + * Run test prepare method + * + * @return void + */ + public function testPrepare() + { + $data = [ + 'name' => 'test_name', + 'js_config' => ['extends' => 'test_config_extends'], + 'config' => ['dataType' => 'test_type', 'sortable' => true] + ]; + + /** @var UiComponentFactory|\PHPUnit_Framework_MockObject_MockObject $uiComponentFactoryMock */ + $uiComponentFactoryMock = $this->getMock( + 'Magento\Framework\View\Element\UiComponentFactory', + [], + [], + '', + false + ); + + /** @var UiComponentInterface|\PHPUnit_Framework_MockObject_MockObject $wrappedComponentMock */ + $wrappedComponentMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponentInterface', + [], + '', + false + ); + /** @var DataProviderInterface|\PHPUnit_Framework_MockObject_MockObject $dataProviderMock */ + $dataProviderMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface', + [], + '', + false + ); + + $this->contextMock->expects($this->atLeastOnce()) + ->method('getNamespace') + ->willReturn('test_namespace'); + $this->contextMock->expects($this->atLeastOnce()) + ->method('getDataProvider') + ->willReturn($dataProviderMock); + $this->contextMock->expects($this->atLeastOnce()) + ->method('getRequestParam') + ->with('sorting') + ->willReturn(['field' => 'test_name', 'direction' => 'asc']); + $this->contextMock->expects($this->atLeastOnce()) + ->method('addComponentDefinition') + ->with(Column::NAME . '.test_type', ['extends' => 'test_config_extends']); + + $dataProviderMock->expects($this->once()) + ->method('addOrder') + ->with('test_name', 'ASC'); + + $uiComponentFactoryMock->expects($this->once()) + ->method('create') + ->with('test_name', 'test_type', array_merge(['context' => $this->contextMock], $data)) + ->willReturn($wrappedComponentMock); + + $wrappedComponentMock->expects($this->once()) + ->method('getContext') + ->willReturn($this->contextMock); + $wrappedComponentMock->expects($this->once()) + ->method('prepare'); + + /** @var Column $column */ + $column = $this->objectManager->getObject( + 'Magento\Ui\Component\Listing\Columns\Column', + [ + 'context' => $this->contextMock, + 'uiComponentFactory' => $uiComponentFactoryMock, + 'data' => $data + ] + ); + + $column->prepare(); + } +} diff --git a/app/code/Magento/Ui/Test/Unit/Component/Listing/ColumnsTest.php b/app/code/Magento/Ui/Test/Unit/Component/Listing/ColumnsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f6769ba8e306e3f761cf54f135779d0c2815d502 --- /dev/null +++ b/app/code/Magento/Ui/Test/Unit/Component/Listing/ColumnsTest.php @@ -0,0 +1,136 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Test\Unit\Component\Listing; + +use Magento\Ui\Component\Listing\Columns; +use Magento\Ui\Component\Listing\Columns\Column; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; + +/** + * Class ColumnsTest + */ +class ColumnsTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $contextMock; + + /** + * @var ObjectManager + */ + protected $objectManager; + + /** + * Set up + */ + public function setUp() + { + $this->objectManager = new ObjectManager($this); + + $this->contextMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponent\ContextInterface', + [], + '', + false, + true, + true, + [] + ); + } + + /** + * Run test getComponentName method + * + * @return void + */ + public function testGetComponentName() + { + $columns = $this->objectManager->getObject( + 'Magento\Ui\Component\Listing\Columns', + [ + 'context' => $this->contextMock, + 'data' => [ + 'js_config' => [ + 'extends' => 'test_config_extends' + ], + 'config' => [ + 'dataType' => 'testType' + ] + ] + ] + ); + + $this->assertEquals($columns->getComponentName(), Columns::NAME); + } + + /** + * Run test prepare method + * + * @return void + */ + public function testPrepare() + { + /** @var Column|\PHPUnit_Framework_MockObject_MockObject $componentMock */ + $columnMock = $this->getMock( + 'Magento\Ui\Component\Listing\Columns\Column', + [], + [], + '', + false + ); + /** @var DataProviderInterface|\PHPUnit_Framework_MockObject_MockObject $dataProviderMock */ + $dataProviderMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface', + [], + '', + false + ); + + $data = [ + 'name' => 'test_name', + 'js_config' => ['extends' => 'test_config_extends'], + 'config' => ['dataType' => 'test_type', 'sortable' => true] + ]; + + $this->contextMock->expects($this->once()) + ->method('getDataProvider') + ->willReturn($dataProviderMock); + $this->contextMock->expects($this->once()) + ->method('addComponentDefinition') + ->with('columns', ['extends' => 'test_config_extends']); + + $dataProviderMock->expects($this->once()) + ->method('getFieldMetaInfo') + ->with('test_name', 'test_column_name') + ->willReturn(['test_meta' => 'test_meta_value']); + + $columnMock->expects($this->once()) + ->method('getName') + ->willReturn('test_column_name'); + $columnMock->expects($this->once()) + ->method('getData') + ->with('config') + ->willReturn(['test_config_data' => 'test_config_value']); + $columnMock->expects($this->once()) + ->method('setData') + ->with('config', ['test_config_data' => 'test_config_value', 'test_meta' => 'test_meta_value']); + + /** @var Columns $columns */ + $columns = $this->objectManager->getObject( + 'Magento\Ui\Component\Listing\Columns', + [ + 'components' => [$columnMock], + 'context' => $this->contextMock, + 'data' => $data + ] + ); + + $columns->prepare(); + } +} diff --git a/app/code/Magento/Ui/Test/Unit/Component/ListingTest.php b/app/code/Magento/Ui/Test/Unit/Component/ListingTest.php index e5f795227c825879d26bb72cd441cdb7c32eaa22..dcc49cf83f36d8c2a6734adf26bb8d5726357137 100644 --- a/app/code/Magento/Ui/Test/Unit/Component/ListingTest.php +++ b/app/code/Magento/Ui/Test/Unit/Component/ListingTest.php @@ -3,200 +3,218 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Ui\Test\Unit\Component; -use \Magento\Ui\Component\Listing; - -use Magento\Framework\View\Element\Template\Context; -use Magento\Ui\Component\Control\ActionPool; -use Magento\Ui\Component\Listing\OptionsFactory; -use Magento\Ui\Component\Listing\RowPool; -use Magento\Ui\Context\ConfigurationFactory; +use Magento\Ui\Component\Listing; +use Magento\Ui\Component\Listing\Columns; +use Magento\Ui\Component\Listing\Columns\Column; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponent\DataSourceInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; /** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * Class ListingTest */ class ListingTest extends \PHPUnit_Framework_TestCase { /** - * @var ActionPool|\PHPUnit_Framework_MockObject_MockObject - */ - protected $actionPool; - - /** - * @var OptionsFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $optionsFactory; - - /** - * @var RowPool|\PHPUnit_Framework_MockObject_MockObject - */ - protected $rowPool; - - /** - * @var Context - */ - protected $templateContext; - - /** - * @var \Magento\Framework\Stdlib\DateTime\Timezone|\PHPUnit_Framework_MockObject_MockObject + * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $localeDate; + protected $contextMock; /** - * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ObjectManager */ - protected $urlBuilder; + protected $objectManager; /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigFactory|\PHPUnit_Framework_MockObject_MockObject + * Set up */ - protected $configurationFactory; + public function setUp() + { + $this->objectManager = new ObjectManager($this); - /** - * @var \Magento\Framework\View\Element\UiComponent\Context |\PHPUnit_Framework_MockObject_MockObject - */ - protected $renderContext; + $this->contextMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponent\ContextInterface', + [], + '', + false, + true, + true, + [] + ); + } /** - * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + * Run test getComponentName method + * + * @return void */ - protected $objectManagerHelper; + public function testGetComponentName() + { + /** @var Listing $listing */ + $listing = $this->objectManager->getObject( + 'Magento\Ui\Component\Listing', + [ + 'context' => $this->contextMock, + 'data' => [] + ] + ); - /** - * @var \Magento\Ui\Context\Configuration |\PHPUnit_Framework_MockObject_MockObject - */ - protected $configuration; + $this->assertTrue($listing->getComponentName() === Listing::NAME); + } /** - * @var \Magento\Ui\Context\ConfigurationStorage |\PHPUnit_Framework_MockObject_MockObject + * Run test prepare method + * + * @return void */ - protected $configStorage; + public function testPrepare() + { + $buttons = [ + 'button1' => 'button1', + 'button2' => 'button2' + ]; + /** @var Listing $listing */ + $listing = $this->objectManager->getObject( + 'Magento\Ui\Component\Listing', + [ + 'context' => $this->contextMock, + 'data' => [ + 'js_config' => [ + 'extends' => 'test_config_extends', + 'testData' => 'testValue', + ], + 'buttons' => $buttons + ] + ] + ); - /** - * @var \Magento\Ui\ContentType\ContentTypeFactory |\PHPUnit_Framework_MockObject_MockObject - */ - protected $contentTypeFactory; + $this->contextMock->expects($this->once()) + ->method('getNamespace') + ->willReturn(Listing::NAME); + $this->contextMock->expects($this->once()) + ->method('addComponentDefinition') + ->with($listing->getComponentName(), ['testData' => 'testValue']); + $this->contextMock->expects($this->once()) + ->method('addButtons') + ->with($buttons, $listing); + + $listing->prepare(); + } /** - * @var Listing + * Run test getDataSourceData method + * + * @return void + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - protected $listingView; - - public function setUp() + public function testGetDataSourceData() { - $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->actionPool = $this->getMock('\Magento\Ui\Component\Control\ActionPool', [], [], '', false); - $this->optionsFactory = $this->getMock('\Magento\Ui\Component\Listing\OptionsFactory', [], [], '', false); - $this->rowPool = $this->getMock('\Magento\Ui\Component\Listing\RowPool', [], [], '', false); - $this->renderContext = $this->getMock('\Magento\Framework\View\Element\UiComponent\Context', [], [], '', false); - $this->templateContext = $this->getMock( - 'Magento\Framework\View\Element\Template\Context', - [], + $result = [ + [ + 'type' => 'test_component_name', + 'name' => 'test_name', + 'dataScope' => 'test_namespace', + 'config' => [ + 'data' => [ + 'items' => ['data'] + ], + 'totalCount' => 20, + 'testConfig' => 'testConfigValue', + 'params' => [ + 'namespace' => 'test_namespace' + ] + ] + ] + ]; + + /** @var DataSourceInterface|\PHPUnit_Framework_MockObject_MockObject $dataSourceMock */ + $dataSourceMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponent\DataSourceInterface', [], '', false ); - $this->configStorage = $this->getMock( - 'Magento\Ui\Context\ConfigurationStorage', - [], + /** @var DataProviderInterface|\PHPUnit_Framework_MockObject_MockObject $dataProviderMock */ + $dataProviderMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface', [], '', false ); - $this->localeDate = $this->getMock('Magento\Framework\Stdlib\DateTime\Timezone', [], [], '', false); - $this->urlBuilder = $this->getMock('Magento\Backend\Model\Url', ['getUrl'], [], '', false); - $this->templateContext->expects($this->once()) - ->method('getLocaleDate') - ->willReturn($this->localeDate); - $this->templateContext->expects($this->once()) - ->method('getUrlBuilder') - ->willReturn($this->urlBuilder); - $this->contentTypeFactory = $this->getMock('Magento\Ui\ContentType\ContentTypeFactory', [], [], '', false); - $this->configurationFactory = $this->getMock( - 'Magento\Framework\View\Element\UiComponent\ConfigFactory', + /** @var Columns|\PHPUnit_Framework_MockObject_MockObject $columnsMock */ + $columnsMock = $this->getMock( + 'Magento\Ui\Component\Listing\Columns', [], [], '', false ); - $configurationBuilder = $this->getMock( - 'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface', - ['toJson'], + /** @var Column|\PHPUnit_Framework_MockObject_MockObject $columnMock */ + $columnMock = $this->getMock( + 'Magento\Ui\Component\Listing\Columns\Column', + [], [], '', false ); - $this->configuration = $this->getMock('Magento\Ui\Context\Configuration', [], [], '', false); - $this->renderContext->expects($this->any()) - ->method('getStorage') - ->willReturn($this->configStorage); - $this->listingView = $this->objectManagerHelper->getObject( - '\Magento\Ui\Component\Listing', + /** @var Listing $listing */ + $listing = $this->objectManager->getObject( + 'Magento\Ui\Component\Listing', [ - 'context' => $this->templateContext, - 'renderContext' => $this->renderContext, - 'contentTypeFactory' => $this->contentTypeFactory, - 'configFactory' => $this->configurationFactory, - 'configBuilder' => $configurationBuilder, - 'optionsFactory' => $this->optionsFactory, - 'actionPool' => $this->actionPool, - 'dataProviderRowPool' => $this->rowPool + 'context' => $this->contextMock, + 'components' => [$dataSourceMock, $columnsMock], + 'data' => [ + 'js_config' => [ + 'extends' => 'test_config_extends', + 'testData' => 'testValue', + ] + ] ] ); - } - - protected function prepareMeta() - { - $meta = ['fields' => [['data_type' => 'date', 'options_provider' => 'provider', 'options' => ['option1']]]]; - $this->listingView->setData('meta', $meta); - $this->localeDate->expects($this->any()) - ->method('getDateTimeFormat') - ->with(\IntlDateFormatter::MEDIUM) - ->willReturn('format_type'); - $options = $this->getMock('Magento\Cms\Ui\DataProvider\Page\Options\PageLayout', [], [], '', false); - $this->optionsFactory->expects($this->any()) - ->method('create') - ->with('provider') - ->willReturn($options); - $options->expects($this->any()) - ->method('getOptions') - ->with(['option1']) - ->willReturn(['option1']); - } - - public function testPrepare() - { - $this->prepareMeta(); - $config = [ - 'page_actions' => [ - 'add' => [ - 'name' => 'add', - 'label' => __('Add New'), - 'class' => 'primary', - 'url' => 'http://some.url', - ], - ], - ]; - $this->urlBuilder->expects($this->at(0)) - ->method('getUrl') - ->with('*/*/new') - ->willReturn('http://mage.local/category/new'); - $dataCollection = $this->getMock('Magento\Framework\Data\CollectionDataSourceInterface', [], [], '', false); - $this->listingView->setData('configuration', $config); - $this->listingView->setData('name', 'someName'); - $this->listingView->setData('dataSource', $dataCollection); - $this->actionPool->expects($this->once()) - ->method('add') - ->with('add', $config['page_actions']['add'], $this->listingView); - - $this->configurationFactory->expects($this->once()) - ->method('create') - ->willReturn($this->configuration); - - $this->assertNull($this->listingView->prepare()); + $columnsMock->expects($this->once()) + ->method('getChildComponents') + ->willReturn([$columnMock]); + + $dataSourceMock->expects($this->any()) + ->method('getDataProvider') + ->willReturn($dataProviderMock); + $dataProviderMock->expects($this->once()) + ->method('getData') + ->willReturn(['items' => ['data']]); + + $columnMock->expects($this->once()) + ->method('prepareItems') + ->with(['data']); + + $dataSourceMock->expects($this->once()) + ->method('getComponentName') + ->willReturn('test_component_name'); + $dataSourceMock->expects($this->once()) + ->method('getName') + ->willReturn('test_name'); + $dataSourceMock->expects($this->once()) + ->method('getContext') + ->willReturn($this->contextMock); + + $this->contextMock->expects($this->any()) + ->method('getNamespace') + ->willReturn('test_namespace'); + + $dataProviderMock->expects($this->once()) + ->method('count') + ->willReturn(20); + + $dataSourceMock->expects($this->once()) + ->method('getData') + ->with('config') + ->willReturn(['testConfig' => 'testConfigValue']); + + $this->assertEquals($listing->getDataSourceData(), $result); } } diff --git a/app/code/Magento/Ui/Test/Unit/Component/MassAction/Columns/ColumnTest.php b/app/code/Magento/Ui/Test/Unit/Component/MassAction/Columns/ColumnTest.php new file mode 100644 index 0000000000000000000000000000000000000000..43b9271d4e013ab291e2e0b0346298456ef6be12 --- /dev/null +++ b/app/code/Magento/Ui/Test/Unit/Component/MassAction/Columns/ColumnTest.php @@ -0,0 +1,126 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Test\Unit\Component\MassAction\Columns; + +use Magento\Ui\Component\MassAction\Columns\Column; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\View\Element\UiComponent\ContextInterface; + +/** + * Class ColumnTest + */ +class ColumnTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $contextMock; + + /** + * @var Column + */ + protected $column; + + /** + * @var ObjectManager + */ + protected $objectManager; + + /** + * Set up + */ + public function setUp() + { + $this->objectManager = new ObjectManager($this); + + $this->contextMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponent\ContextInterface', + [], + '', + false, + true, + true, + [] + ); + + $this->column = $this->objectManager->getObject( + 'Magento\Ui\Component\MassAction\Columns\Column', + [ + 'context' => $this->contextMock, + 'data' => [ + 'js_config' => [ + 'extends' => 'test_config_extends' + ] + ] + ] + ); + } + + /** + * Run test getComponentName method + * + * @return void + */ + public function testGetComponentName() + { + $this->assertTrue($this->column->getComponentName() === Column::NAME); + } + + /** + * Run test prepareItems method + * + * @return void + */ + public function testPrepareItems() + { + $testItems = ['item1','item2', 'item3']; + + $this->assertEquals($testItems, $this->column->prepareItems($testItems)); + } + + /** + * Run test prepare method + * + * @return void + */ + public function testPrepare() + { + $this->column = $this->objectManager->getObject( + 'Magento\Ui\Component\MassAction\Columns\Column', + [ + 'context' => $this->contextMock, + 'data' => [ + 'js_config' => [] + ] + ] + ); + + $this->contextMock->expects($this->once()) + ->method('getNamespace') + ->willReturn('test_namespace'); + $this->contextMock->expects($this->once()) + ->method('addComponentDefinition') + ->with($this->column->getComponentName(), ['extends' => 'test_namespace']); + + $this->column->prepare(); + } + + /** + * Run test prepare method + * + * @return void + */ + public function testPrepareExtendsFromConfig() + { + $this->contextMock->expects($this->never()) + ->method('getNamespace'); + $this->contextMock->expects($this->once()) + ->method('addComponentDefinition') + ->with($this->column->getComponentName(), ['extends' => 'test_config_extends']); + + $this->column->prepare(); + } +} diff --git a/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php b/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php deleted file mode 100644 index f66f2d6a9de87f2d2fadb1c858ee6b9d2b40de4f..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php +++ /dev/null @@ -1,174 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Test\Unit\Component; - -use \Magento\Ui\Component\MassAction; - -use Magento\Framework\View\Element\Template; -use Magento\Framework\View\Element\Template\Context as TemplateContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigFactory; -use Magento\Framework\View\Element\UiComponent\Context; -use Magento\Ui\ContentType\ContentTypeFactory; - -class MassActionTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var TemplateContext||\PHPUnit_Framework_MockObject_MockObject - */ - protected $contextMock; - - /** - * @var Context|\PHPUnit_Framework_MockObject_MockObject - */ - protected $renderContextMock; - - /** - * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contentTypeFactoryMock; - - /** - * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $configFactoryMock; - - /** - * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $configBuilderMock; - - /** - * @var \Magento\Ui\DataProvider\Factory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $dataProviderFactoryMock; - - /** - * @var \Magento\Ui\DataProvider\Manager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $dataProviderManagerMock; - - /** - * @var MassAction - */ - protected $view; - - /** - * Set up - * - * @return void - */ - protected function setUp() - { - $this->contextMock = $this->getMock( - 'Magento\Framework\View\Element\Template\Context', - [], - [], - '', - false - ); - $this->renderContextMock = $this->getMock( - 'Magento\Framework\View\Element\UiComponent\Context', - ['getNamespace', 'getStorage', 'getRequestParam'], - [], - '', - false - ); - $this->contentTypeFactoryMock = $this->getMock( - 'Magento\Ui\ContentType\ContentTypeFactory', - [], - [], - '', - false - ); - $this->configFactoryMock = $this->getMock( - 'Magento\Framework\View\Element\UiComponent\ConfigFactory', - ['create'], - [], - '', - false - ); - $this->configBuilderMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface', - [], - '', - false - ); - $this->dataProviderFactoryMock = $this->getMock( - 'Magento\Ui\DataProvider\Factory', - [], - [], - '', - false - ); - $this->dataProviderManagerMock = $this->getMock( - 'Magento\Ui\DataProvider\Manager', - [], - [], - '', - false - ); - - $this->view = new MassAction( - $this->contextMock, - $this->renderContextMock, - $this->contentTypeFactoryMock, - $this->configFactoryMock, - $this->configBuilderMock, - $this->dataProviderFactoryMock, - $this->dataProviderManagerMock - ); - } - - /** - * Run test prepare method - * - * @return void - */ - public function testPrepare() - { - /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface - * |\PHPUnit_Framework_MockObject_MockObject $configurationMock - */ - $configurationMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigInterface', - [], - '', - false - ); - /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface - * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock - */ - $configStorageMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface', - ['addComponentsData', 'getDataCollection'], - '', - false - ); - - $this->renderContextMock->expects($this->at(0)) - ->method('getNamespace') - ->will($this->returnValue('namespace')); - $this->renderContextMock->expects($this->at(1)) - ->method('getNamespace') - ->will($this->returnValue('namespace')); - $this->configFactoryMock->expects($this->any()) - ->method('create') - ->will($this->returnValue($configurationMock)); - - $this->renderContextMock->expects($this->any()) - ->method('getStorage') - ->will($this->returnValue($configStorageMock)); - - $configStorageMock->expects($this->once()) - ->method('addComponentsData') - ->with($configurationMock); - - $this->assertNull($this->view->prepare()); - } -} diff --git a/app/code/Magento/Ui/Test/Unit/Component/PagingTest.php b/app/code/Magento/Ui/Test/Unit/Component/PagingTest.php index e8cd28a27665a09b164e93c2f76c58e72ffd1ed7..fd4c63c3b28870ad1a60068d66ee86eb52c6291a 100644 --- a/app/code/Magento/Ui/Test/Unit/Component/PagingTest.php +++ b/app/code/Magento/Ui/Test/Unit/Component/PagingTest.php @@ -5,182 +5,164 @@ */ namespace Magento\Ui\Test\Unit\Component; -use \Magento\Ui\Component\Paging; - -use Magento\Framework\View\Asset\Repository; -use Magento\Framework\View\Element\Template; -use Magento\Framework\View\Element\Template\Context as TemplateContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigFactory; -use Magento\Framework\View\Element\UiComponent\Context; -use Magento\Ui\ContentType\ContentTypeFactory; +use Magento\Ui\Component\Paging; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; +/** + * Class PagingTest + */ class PagingTest extends \PHPUnit_Framework_TestCase { /** - * @var Paging - */ - protected $view; - - /** - * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $configurationBuilderMock; - - /** - * @var TemplateContext|\PHPUnit_Framework_MockObject_MockObject + * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $contextMock; /** - * @var Context|\PHPUnit_Framework_MockObject_MockObject - */ - protected $renderContextMock; - - /** - * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contentTypeFactoryMock; - - /** - * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $configFactoryMock; - - /** - * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ObjectManager */ - protected $configBuilderMock; + protected $objectManager; /** - * @var \Magento\Ui\DataProvider\Factory|\PHPUnit_Framework_MockObject_MockObject + * Set up */ - protected $dataProviderFactoryMock; - - /** - * @var \Magento\Ui\DataProvider\Manager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $dataProviderManagerMock; - - /** - * @var Repository|\PHPUnit_Framework_MockObject_MockObject - */ - protected $assetRepoMock; - public function setUp() { - $this->renderContextMock = $this->getMock( - 'Magento\Framework\View\Element\UiComponent\Context', - ['getNamespace', 'getStorage', 'getRequestParam'], - [], - '', - false - ); - $this->contextMock = $this->getMock( - 'Magento\Framework\View\Element\Template\Context', - ['getAssetRepository'], - [], - '', - false - ); - $this->contentTypeFactoryMock = $this->getMock('Magento\Ui\ContentType\ContentTypeFactory', [], [], '', false); - $this->configurationBuilderMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface' - ); - $this->assetRepoMock = $this->getMock('Magento\Framework\View\Asset\Repository', [], [], '', false); - $this->contextMock->expects($this->any())->method('getAssetRepository')->willReturn($this->assetRepoMock); + $this->objectManager = new ObjectManager($this); - $this->configFactoryMock = $this->getMock( - 'Magento\Framework\View\Element\UiComponent\ConfigFactory', - ['create'], - [], - '', - false - ); - $this->configBuilderMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface', - [], - '', - false - ); - $this->dataProviderFactoryMock = $this->getMock( - 'Magento\Ui\DataProvider\Factory', - [], - [], - '', - false - ); - $this->dataProviderManagerMock = $this->getMock( - 'Magento\Ui\DataProvider\Manager', - [], + $this->contextMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponent\ContextInterface', [], '', - false + false, + true, + true, + [] ); + } - $this->view = new \Magento\Ui\Component\Paging( - $this->contextMock, - $this->renderContextMock, - $this->contentTypeFactoryMock, - $this->configFactoryMock, - $this->configBuilderMock, - $this->dataProviderFactoryMock, - $this->dataProviderManagerMock + /** + * Run test getComponentName method + * + * @return void + */ + public function testGetComponentName() + { + /** @var Paging $listing */ + $paging = $this->objectManager->getObject( + 'Magento\Ui\Component\Paging', + [ + 'context' => $this->contextMock, + 'data' => [] + ] ); + + $this->assertTrue($paging->getComponentName() === Paging::NAME); } + /** + * Run test prepare method + * + * @return void + */ public function testPrepare() { - $paramsSize = 20; - $paramsPage = 1; - $nameSpace = 'namespace'; - $configurationMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigInterface', - ['getData'], - '', - false - ); - $this->renderContextMock->expects($this->any())->method('getNamespace')->willReturn($nameSpace); - $this->configFactoryMock->expects($this->once())->method('create')->willReturn($configurationMock); - - $storageMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface' + $resultData = [ + 'js_config' => [ + 'extends' => 'test_config_extends', + 'testData' => 'testValue' + ], + 'config' => [ + 'options' => [ + [ + 'value' => 20, + 'label' => 20 + ], + [ + 'value' => 30, + 'label' => 30 + ], + [ + 'value' => 50, + 'label' => 50 + ], + [ + 'value' => 100, + 'label' => 100 + ], + [ + 'value' => 200, + 'label' => 200 + ], + [ + 'value' => 20, + 'label' => 'options1' + ], + [ + 'value' => 40, + 'label' => 'options2' + ], + ], + 'pageSize' => 20, + 'current' => 2 + ] + ]; + + /** @var Paging $paging */ + $paging = $this->objectManager->getObject( + 'Magento\Ui\Component\Paging', + [ + 'context' => $this->contextMock, + 'data' => [ + 'js_config' => [ + 'extends' => 'test_config_extends', + 'testData' => 'testValue', + ], + 'config' => [ + 'options' => [ + 'options1' => [ + 'label' => 'options1', + 'value' => '20' + ], + 'options2' => [ + 'label' => 'options2', + 'value' => '40' + ] + ], + 'current' => 2, + 'pageSize' => 20 + ] + ] + ] ); - $dataCollectionMock = $this->getMockForAbstractClass( - '\Magento\Framework\Data\CollectionDataSourceInterface', + /** @var DataProviderInterface|\PHPUnit_Framework_MockObject_MockObject $dataProviderMock */ + $dataProviderMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface', [], '', - false, - true, - true, - ['setPageSize', 'setCurPage'] + false ); - $this->renderContextMock->expects($this->any())->method('getStorage')->willReturn($storageMock); - - $storageMock->expects($this->once())->method('getDataCollection')->willReturn($dataCollectionMock); + $this->contextMock->expects($this->once()) + ->method('getRequestParam') + ->with('paging') + ->willReturn(['pageSize' => 5, 'current' => 3]); + $this->contextMock->expects($this->once()) + ->method('getDataProvider') + ->willReturn($dataProviderMock); - $configurationMock->expects($this->at(0))->method('getData')->with('current')->willReturn($paramsPage); + $dataProviderMock->expects($this->once()) + ->method('setLimit') + ->with(3, 5); - $configurationMock->expects($this->at(1))->method('getData')->with('pageSize')->willReturn($paramsSize); - $this->renderContextMock->expects($this->atLeastOnce()) - ->method('getRequestParam') - ->willReturnMap( - [ - ['page', $paramsPage, $paramsPage], - ['limit', $paramsSize, $paramsSize], - ] - ); + $this->contextMock->expects($this->once()) + ->method('addComponentDefinition') + ->with($paging->getComponentName(), ['extends' => 'test_config_extends', 'testData' => 'testValue']); - $dataCollectionMock->expects($this->any()) - ->method('setPageSize') - ->with($paramsSize) - ->willReturnSelf(); - $dataCollectionMock->expects($this->any()) - ->method('setCurPage') - ->with($paramsPage) - ->willReturnSelf(); + $paging->prepare(); - $this->assertNull($this->view->prepare()); + $this->assertEquals($paging->getData(), $resultData); } } diff --git a/app/code/Magento/Ui/Test/Unit/Component/SortingTest.php b/app/code/Magento/Ui/Test/Unit/Component/SortingTest.php deleted file mode 100644 index 5c7f02a31dc63b71f9b1db2fea3080a8fbef7972..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Test/Unit/Component/SortingTest.php +++ /dev/null @@ -1,211 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Test\Unit\Component; - -use \Magento\Ui\Component\Sorting; - -use Magento\Framework\View\Element\Template; -use Magento\Framework\View\Element\Template\Context as TemplateContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; -use Magento\Framework\View\Element\UiComponent\ConfigFactory; -use Magento\Framework\View\Element\UiComponent\Context; -use Magento\Ui\ContentType\ContentTypeFactory; - -class SortingTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var TemplateContext||\PHPUnit_Framework_MockObject_MockObject - */ - protected $contextMock; - - /** - * @var Context|\PHPUnit_Framework_MockObject_MockObject - */ - protected $renderContextMock; - - /** - * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contentTypeFactoryMock; - - /** - * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $configFactoryMock; - - /** - * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $configBuilderMock; - - /** - * @var \Magento\Ui\DataProvider\Factory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $dataProviderFactoryMock; - - /** - * @var \Magento\Ui\DataProvider\Manager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $dataProviderManagerMock; - - /** - * @var Sorting - */ - protected $view; - - /** - * Set up - * - * @return void - */ - protected function setUp() - { - $this->contextMock = $this->getMock( - 'Magento\Framework\View\Element\Template\Context', - [], - [], - '', - false - ); - $this->renderContextMock = $this->getMock( - 'Magento\Framework\View\Element\UiComponent\Context', - ['getNamespace', 'getStorage', 'getRequestParam'], - [], - '', - false - ); - $this->contentTypeFactoryMock = $this->getMock( - 'Magento\Ui\ContentType\ContentTypeFactory', - [], - [], - '', - false - ); - $this->configFactoryMock = $this->getMock( - 'Magento\Framework\View\Element\UiComponent\ConfigFactory', - ['create'], - [], - '', - false - ); - $this->configBuilderMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface', - [], - '', - false - ); - $this->dataProviderFactoryMock = $this->getMock( - 'Magento\Ui\DataProvider\Factory', - [], - [], - '', - false - ); - $this->dataProviderManagerMock = $this->getMock( - 'Magento\Ui\DataProvider\Manager', - [], - [], - '', - false - ); - - $this->view = new Sorting( - $this->contextMock, - $this->renderContextMock, - $this->contentTypeFactoryMock, - $this->configFactoryMock, - $this->configBuilderMock, - $this->dataProviderFactoryMock, - $this->dataProviderManagerMock - ); - } - - /** - * Run test prepare method - * - * @return void - */ - public function testPrepare() - { - /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface - * |\PHPUnit_Framework_MockObject_MockObject $configurationMock - */ - $configurationMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigInterface', - [], - '', - false - ); - /** - * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface - * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock - */ - $configStorageMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface', - ['addComponentsData', 'getDataCollection'], - '', - false - ); - - $dataCollectionMock = $this->getMockForAbstractClass( - 'Magento\Framework\Api\CriteriaInterface', - ['addOrder'], - '', - false - ); - - $this->renderContextMock->expects($this->at(0)) - ->method('getNamespace') - ->will($this->returnValue('namespace')); - $this->renderContextMock->expects($this->at(1)) - ->method('getNamespace') - ->will($this->returnValue('namespace')); - $this->configFactoryMock->expects($this->any()) - ->method('create') - ->will($this->returnValue($configurationMock)); - - $this->renderContextMock->expects($this->any()) - ->method('getStorage') - ->will($this->returnValue($configStorageMock)); - - $configStorageMock->expects($this->once()) - ->method('addComponentsData') - ->with($configurationMock); - - $configurationMock->expects($this->at(0)) - ->method('getData') - ->with('field') - ->will($this->returnValue('field')); - - $configurationMock->expects($this->at(1)) - ->method('getData') - ->with('direction') - ->will($this->returnValue('direction')); - - $this->renderContextMock->expects($this->any()) - ->method('getStorage') - ->will($this->returnValue($configStorageMock)); - - $configStorageMock->expects($this->once()) - ->method('getDataCollection') - ->will($this->returnValue($dataCollectionMock)); - - $dataCollectionMock->expects($this->once()) - ->method('addOrder') - ->with('field', 'FIELD'); - - $this->renderContextMock->expects($this->any()) - ->method('getRequestParam') - ->will($this->returnValue('field')); - - $this->renderContextMock->expects($this->any()) - ->method('getRequestParam') - ->will($this->returnValue('direction')); - - $this->assertNull($this->view->prepare()); - } -} diff --git a/app/code/Magento/Ui/Test/Unit/ContentType/Builder/ConfigJsonTest.php b/app/code/Magento/Ui/Test/Unit/ContentType/Builder/ConfigJsonTest.php deleted file mode 100644 index 47e6d0ad983f69d450086e0e6689cb625dfe214b..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Test/Unit/ContentType/Builder/ConfigJsonTest.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Test\Unit\ContentType\Builder; - -use \Magento\Ui\ContentType\Builder\ConfigJson; - -/** - * Class ConfigJsonTest - */ -class ConfigJsonTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var ConfigJson - */ - protected $builder; - - public function testToJson() - { - $this->builder = new ConfigJson(); - $result = ['name' => 'resultName', 'parent_name' => 'resultParentName']; - $configurationMock = $this->getMock( - 'Magento\Ui\Context\Configuration', - ['getData', 'getName', 'getParentName'], - [], - '', - false - ); - $configurationMock->expects($this->once())->method('getData')->willReturn($result); - $configurationMock->expects($this->once())->method('getName')->willReturn($result['name']); - $configurationMock->expects($this->once())->method('getParentName')->willReturn($result['parent_name']); - $this->assertEquals(json_encode($result), $this->builder->toJson($configurationMock)); - } -} diff --git a/app/code/Magento/Ui/Test/Unit/ContentType/Builder/ConfigStorageJsonTest.php b/app/code/Magento/Ui/Test/Unit/ContentType/Builder/ConfigStorageJsonTest.php deleted file mode 100644 index 22511628d15e2631c499c186dbb91b0bf291d5fe..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Test/Unit/ContentType/Builder/ConfigStorageJsonTest.php +++ /dev/null @@ -1,99 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Test\Unit\ContentType\Builder; - -use \Magento\Ui\ContentType\Builder\ConfigStorageJson; - -/** - * Class ConfigStorageJsonTest - */ -class ConfigStorageJsonTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var ConfigStorageJson - */ - protected $builder; - - public function testToJson() - { - $this->builder = new ConfigStorageJson(); - $name = 'name'; - $data = []; - $parentName = 'parentName'; - $dataSource = [ - 'data' => null, - ]; - $result = [ - 'config' => ['components' => [$name => $data], 'globalData' => ['globalData']], - 'meta' => null, - 'name' => $name, - 'parent_name' => $parentName, - 'data' => null, - 'dump' => ['extenders' => []], - ]; - - $rootComponentMock = $this->getMock( - 'Magento\Ui\Context\Configuration', - ['getName', 'getParentName', 'getData'], - [], - '', - false - ); - $storageMock = $this->getMock( - 'Magento\Ui\Context\ConfigurationStorage', - ['getComponentsData', 'getGlobalData', 'getMeta', 'getDataSource'], - [], - '', - false - ); - - $storageMock->expects($this->once()) - ->method('getComponentsData') - ->with($parentName) - ->will($this->returnValue($rootComponentMock)); - $rootComponentMock->expects($this->any())->method('getName')->willReturn($result['name']); - $rootComponentMock->expects($this->once())->method('getParentName')->willReturn($result['parent_name']); - $rootComponentMock->expects($this->once()) - ->method('getData') - ->willReturn($data); - $storageMock->expects($this->once())->method('getGlobalData')->willReturn($result['config']); - $storageMock->expects($this->once())->method('getDataSource')->will($this->returnValue($dataSource)); - - $this->assertEquals(json_encode($result), $this->builder->toJson($storageMock, $parentName)); - } - - public function testToJsonNoParentName() - { - $this->builder = new ConfigStorageJson(); - $data = []; - $dataSource = [ - 'data' => $data, - ]; - $result = [ - 'config' => ['components' => ['name' => $data], 'globalData' => ['globalData']], - 'meta' => null, - 'data' => [], - 'dump' => ['extenders' => []], - ]; - $componentsMock = $this->getMock('Magento\Ui\Context\Configuration', ['getData'], [], '', false); - $storageMock = $this->getMock( - 'Magento\Ui\Context\ConfigurationStorage', - ['getComponentsData', 'getGlobalData', 'getMeta', 'getDataSource'], - [], - '', - false - ); - - $storageMock->expects($this->once())->method('getComponentsData')->will($this->returnValue($componentsMock)); - $componentsMock->expects($this->any())->method('getData')->willReturn($data); - - $storageMock->expects($this->once())->method('getMeta')->will($this->returnValue($result['meta'])); - $storageMock->expects($this->once())->method('getDataSource')->will($this->returnValue($dataSource)); - $storageMock->expects($this->once())->method('getGlobalData')->willReturn($result['config']); - - $this->assertEquals(json_encode($result), $this->builder->toJson($storageMock)); - } -} diff --git a/app/code/Magento/Ui/Test/Unit/ContentType/ContentTypeFactoryTest.php b/app/code/Magento/Ui/Test/Unit/ContentType/ContentTypeFactoryTest.php deleted file mode 100644 index 3f1c82345fcdb2706a63ef4c3a42849ca16a6441..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Test/Unit/ContentType/ContentTypeFactoryTest.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Test\Unit\ContentType; - -use \Magento\Ui\ContentType\ContentTypeFactory; - -/** - * Class ContentTypeFactoryTest - */ -class ContentTypeFactoryTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var ContentTypeFactory - */ - protected $contentTypeFactory; - - /** - * @param $type - * @param @expected - * @dataProvider getDataProvider - */ - public function testGet($type, $contentRender, $expected) - { - $objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface'); - $this->contentTypeFactory = new ContentTypeFactory($objectManagerMock); - $objectManagerMock->expects($this->once())->method('get')->with($expected)->willReturn($contentRender); - $this->assertInstanceOf($expected, $this->contentTypeFactory->get($type)); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testGetTypeException() - { - $objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface'); - $this->contentTypeFactory = new ContentTypeFactory($objectManagerMock); - $this->contentTypeFactory->get('bad_type'); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testGetInstanceException() - { - $objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface'); - $this->contentTypeFactory = new ContentTypeFactory($objectManagerMock); - $objectManagerMock->expects($this->once())->method('get')->willReturnSelf(); - $this->contentTypeFactory->get(); - } - - /** - * @return array - */ - public function getDataProvider() - { - $htmlMock = $this->getMock('Magento\Ui\ContentType\Html', [], [], '', false); - $jsonMock = $this->getMock('Magento\Ui\ContentType\Json', [], [], '', false); - $xmlMock = $this->getMock('Magento\Ui\ContentType\Xml', [], [], '', false); - return [ - ['html', $htmlMock, 'Magento\Ui\ContentType\Html'], - ['json', $jsonMock, 'Magento\Ui\ContentType\Json'], - ['xml', $xmlMock, 'Magento\Ui\ContentType\Xml'] - ]; - } -} diff --git a/app/code/Magento/Ui/Test/Unit/ContentType/HtmlTest.php b/app/code/Magento/Ui/Test/Unit/ContentType/HtmlTest.php deleted file mode 100644 index e9485bff9816cfe6704329d76202e4bf172ccf32..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Test/Unit/ContentType/HtmlTest.php +++ /dev/null @@ -1,86 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Test\Unit\ContentType; - -use \Magento\Ui\ContentType\Html; - -/** - * Class HtmlTest - */ -class HtmlTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var Html - */ - protected $html; - - /** - * @var \Magento\Framework\View\FileSystem|\PHPUnit_Framework_MockObject_MockObject - */ - protected $filesystemMock; - - /** - * @var \Magento\Framework\View\TemplateEnginePool|\PHPUnit_Framework_MockObject_MockObject - */ - protected $templateEnginePoolMock; - - /** - * @var \Magento\Framework\View\Element\UiComponentInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $viewInterfaceMock; - - public function setUp() - { - $this->filesystemMock = $this->getMock( - 'Magento\Framework\View\FileSystem', - ['getTemplateFileName'], - [], - '', - false - ); - $this->templateEnginePoolMock = $this->getMock( - 'Magento\Framework\View\TemplateEnginePool', - ['get'], - [], - '', - false - ); - $this->html = new Html($this->filesystemMock, $this->templateEnginePoolMock); - $this->viewInterfaceMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponentInterface' - ); - } - - public function testRender() - { - $template = 'test_template'; - $result = 'result'; - $path = 'path'; - $this->viewInterfaceMock = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\UiComponentInterface' - ); - $templateEngineMock = $this->getMockForAbstractClass('Magento\Framework\View\TemplateEngineInterface'); - - $this->templateEnginePoolMock->expects($this->once()) - ->method('get') - ->willReturn($templateEngineMock); - $this->filesystemMock->expects($this->once()) - ->method('getTemplateFileName') - ->with($template) - ->willReturn($path); - $templateEngineMock->expects($this->once()) - ->method('render') - ->with($this->viewInterfaceMock, $path) - ->willReturn($result); - - $this->assertEquals($result, $this->html->render($this->viewInterfaceMock, $template)); - } - - public function testRenderEmpty() - { - $this->assertEquals('', $this->html->render($this->viewInterfaceMock, '')); - } -} diff --git a/app/code/Magento/Ui/Test/Unit/Context/ConfigurationStorageTest.php b/app/code/Magento/Ui/Test/Unit/Context/ConfigurationStorageTest.php deleted file mode 100644 index bd2419521963bc29c6de5cbad8069356857f06c4..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Test/Unit/Context/ConfigurationStorageTest.php +++ /dev/null @@ -1,157 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Ui\Test\Unit\Context; - -use \Magento\Ui\Context\ConfigurationStorage; -use \Magento\Ui\Context\Configuration; -use Magento\Framework\Data\Collection as DataCollection; - -/** - * Class ConfigurationStorageTest - * @package Magento\Ui - */ -class ConfigurationStorageTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var array - */ - protected $componentStorage = []; - - /** - * @var array - */ - protected $dataStorage = []; - - /** - * @var array - */ - protected $metaStorage = []; - - /** - * @var DataCollection[] - */ - protected $collectionStorage = []; - - /** - * @var array - */ - protected $cloudDataStorage = []; - - /** - * @var ConfigurationStorage - */ - protected $configurationStorage; - - public function setUp() - { - $this->configurationStorage = new ConfigurationStorage(); - } - - public function testAddGetComponentsData() - { - $configuration = ['key' => 'value']; - $name = 'myName'; - $parentName = 'thisParentName'; - $configurationModel = new Configuration($name, $parentName, $configuration); - $this->componentStorage = [$configurationModel->getName() => $configurationModel]; - $this->configurationStorage->addComponentsData($configurationModel); - - $this->assertEquals($this->componentStorage, $this->configurationStorage->getComponentsData(null)); - $this->assertEquals(null, $this->configurationStorage->getComponentsData('someKey')); - $this->assertEquals($configurationModel, $this->configurationStorage->getComponentsData($name)); - } - - public function testRemoveComponentsData() - { - $configuration = ['key' => 'value']; - $name = 'myName'; - $parentName = 'thisParentName'; - $configurationModel = new Configuration($name, $parentName, $configuration); - $this->componentStorage = [$configurationModel->getName() => $configurationModel]; - $this->configurationStorage->addComponentsData($configurationModel); - $this->assertEquals($configurationModel, $this->configurationStorage->getComponentsData($name)); - $this->configurationStorage->removeComponentsData($configurationModel); - $this->assertEquals(null, $this->configurationStorage->getComponentsData($name)); - } - - public function testAddGetData() - { - $name = 'myName'; - $dataSource = [ - 'data' => ['key' => 'value'], - 'config' => ['key' => 'value'], - ]; - $this->configurationStorage->addDataSource($name, $dataSource); - $this->assertEquals([$name => $dataSource], $this->configurationStorage->getDataSource(null)); - $this->assertEquals(null, $this->configurationStorage->getDataSource('someKey')); - $this->assertEquals($dataSource, $this->configurationStorage->getDataSource($name)); - } - - public function testUpdateRemoveData() - { - $dataSource = [ - 'data' => ['key' => 'value'], - 'config' => ['key' => 'value'], - ]; - $key = 'myKey'; - $this->configurationStorage->addDataSource($key, $dataSource); - $this->assertEquals($dataSource, $this->configurationStorage->getDataSource($key)); - $dataSource = [ - 'data' => ['key1' => 'value1'], - 'config' => ['key1' => 'value1'], - ]; - $this->configurationStorage->updateDataSource($key, $dataSource); - $this->assertEquals($dataSource, $this->configurationStorage->getDataSource($key)); - $this->configurationStorage->removeDataSource($key); - $this->assertEquals(null, $this->configurationStorage->getDataSource($key)); - } - - public function testAddGetMeta() - { - $data = ['key' => 'value']; - $key = 'myName'; - $this->configurationStorage->addMeta($key, $data); - $this->assertEquals([$key => $data], $this->configurationStorage->getMeta(null)); - $this->assertEquals(null, $this->configurationStorage->getMeta('someKey')); - $this->assertEquals($data, $this->configurationStorage->getMeta($key)); - } - - public function testUpdateRemoveMeta() - { - $data = ['key' => 'value']; - $key = 'myKey'; - $this->configurationStorage->addMeta($key, $data); - $this->assertEquals($data, $this->configurationStorage->getMeta($key)); - $data = ['key1' => 'value1']; - $this->configurationStorage->updateMeta($key, $data); - $this->assertEquals($data, $this->configurationStorage->getMeta($key)); - $this->configurationStorage->removeMeta($key); - $this->assertEquals(null, $this->configurationStorage->getMeta($key)); - } - - public function testAddGetDataCollection() - { - $key = 'myName'; - $dataCollection = $this->getMock('Magento\Framework\Data\CollectionDataSourceInterface', [], [], '', false); - $this->configurationStorage->addDataCollection($key, $dataCollection); - - $this->assertEquals([$key => $dataCollection], $this->configurationStorage->getDataCollection(null)); - $this->assertEquals(null, $this->configurationStorage->getDataCollection('someKey')); - $this->assertEquals($dataCollection, $this->configurationStorage->getDataCollection($key)); - } - - public function testRemoveDataCollection() - { - $key = 'myName'; - $dataCollection = $this->getMock('Magento\Framework\Data\CollectionDataSourceInterface', [], [], '', false); - $update = clone $dataCollection; - $this->configurationStorage->addDataCollection($key, $dataCollection); - $this->assertEquals($dataCollection, $this->configurationStorage->getDataCollection($key)); - $this->configurationStorage->updateDataCollection($key, $update); - $this->assertEquals($update, $this->configurationStorage->getDataCollection($key)); - } -} diff --git a/app/code/Magento/Ui/Test/Unit/Context/ConfigurationTest.php b/app/code/Magento/Ui/Test/Unit/Context/ConfigurationTest.php deleted file mode 100644 index ae2de3bb751f3f62222e4410206f00c9a34205bf..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Test/Unit/Context/ConfigurationTest.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Ui\Test\Unit\Context; - -use \Magento\Ui\Context\Configuration; - -class ConfigurationTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var [] - */ - protected $configuration; - - /** - * @var string - */ - protected $name; - - /** - * @var string - */ - protected $parentName; - - /** - * @var Configuration - */ - protected $configurationModel; - - public function setUp() - { - $this->configuration = ['key' => 'value']; - $this->name = 'myName'; - $this->parentName = 'thisParentName'; - $this->configurationModel = new Configuration($this->name, $this->parentName, $this->configuration); - } - - public function testGetData() - { - $this->assertEquals($this->configuration, $this->configurationModel->getData(null)); - $this->assertEquals(null, $this->configurationModel->getData('someKey')); - $this->assertEquals('value', $this->configurationModel->getData('key')); - } - - public function testAddData() - { - $this->configurationModel->addData('new_key', 'value1'); - $this->assertEquals('value1', $this->configurationModel->getData('new_key')); - } - - public function testUpdateData() - { - $this->configurationModel->addData('new_key', 'value1'); - $this->assertEquals('value1', $this->configurationModel->getData('new_key')); - $this->configurationModel->updateData('new_key', 'value2'); - $this->assertEquals('value2', $this->configurationModel->getData('new_key')); - } - - public function testGetName() - { - $this->assertEquals($this->name, $this->configurationModel->getName()); - } - - public function testGetParentName() - { - $this->assertEquals($this->parentName, $this->configurationModel->getParentName()); - } -} diff --git a/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php b/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php index 9239d619dbb64f5ed10cb6cda9820376c1bdfcfc..f3bc80d217c4d7cdadffd44ae412aa26d777a5fe 100644 --- a/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php +++ b/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php @@ -63,24 +63,31 @@ class RenderTest extends \PHPUnit_Framework_TestCase $this->requestMock->expects($this->at(0)) ->method('getParam') - ->with('component') - ->willReturn($name); - $this->requestMock->expects($this->at(1)) - ->method('getParam') - ->with('name') + ->with('namespace') ->willReturn($name); $this->responseMock->expects($this->once()) ->method('appendBody') ->with($renderedData); - $viewMock = $this->getMock('Magento\Ui\Form\Field', ['render'], [], '', false); + /** + * @var \Magento\Framework\View\Element\UiComponentInterface|\PHPUnit_Framework_MockObject_MockObject $viewMock + */ + $viewMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponentInterface', + [], + '', + false, + true, + true, + ['render'] + ); $viewMock->expects($this->once()) ->method('render') ->willReturn($renderedData); $this->uiFactoryMock->expects($this->once()) - ->method('createUiComponent') + ->method('create') ->willReturn($viewMock); - $this->assertNull($this->render->execute()); + $this->render->execute(); } } diff --git a/app/code/Magento/Ui/Test/Unit/DataProvider/Config/FileResolverTest.php b/app/code/Magento/Ui/Test/Unit/DataProvider/Config/FileResolverTest.php deleted file mode 100644 index c1518f0b1a7f18b023df12ae17dc91cf3fd4ab68..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/Test/Unit/DataProvider/Config/FileResolverTest.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Ui\Test\Unit\DataProvider\Config; - -use \Magento\Ui\DataProvider\Config\FileResolver; - -use Magento\Framework\Filesystem; - -class FileResolverTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var \Magento\Framework\Filesystem\Directory\Read | \PHPUnit_Framework_MockObject_MockObject - */ - private $mockDirectoryRead; - - /** - * @var FileResolver - */ - private $fileResolver; - - public function setUp() - { - $this->mockDirectoryRead = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\Read') - ->disableOriginalConstructor() - ->getMock(); - $stubFileIteratorFactory = $this->getMockBuilder('Magento\Framework\Config\FileIteratorFactory') - ->disableOriginalConstructor() - ->getMock(); - $stubFilesystem = $this->getMockBuilder('Magento\Framework\Filesystem') - ->disableOriginalConstructor() - ->getMock(); - $stubFilesystem->expects($this->any()) - ->method('getDirectoryRead') - ->willReturn($this->mockDirectoryRead); - $this->fileResolver = new FileResolver($stubFilesystem, $stubFileIteratorFactory); - } - - public function testItAppliesTheFilenamePattern() - { - $this->mockDirectoryRead->expects($this->once()) - ->method('search') - ->with($this->matchesRegularExpression('#\*\.xml$#')) - ->willReturn([]); - - $this->fileResolver->get('*.xml', ''); - } -} diff --git a/app/code/Magento/Ui/composer.json b/app/code/Magento/Ui/composer.json index ecf417cad0f81fd792b366b6d2f314848fbfcf7b..07c4a7c8ab3910486f2e7369f3f7b47d30eb6f3b 100644 --- a/app/code/Magento/Ui/composer.json +++ b/app/code/Magento/Ui/composer.json @@ -3,13 +3,13 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-backend": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", + "magento/module-backend": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Ui/etc/di.xml b/app/code/Magento/Ui/etc/di.xml index 55a44cd9d4df72096e6fc157f80ba2cedd56d11a..b5684f5734d9b6e641b01f26aaee55b92befa5ea 100644 --- a/app/code/Magento/Ui/etc/di.xml +++ b/app/code/Magento/Ui/etc/di.xml @@ -6,20 +6,250 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> - <preference for="Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface" type="Magento\Ui\ContentType\Builder\ConfigJson" /> - <preference for="Magento\Framework\View\Element\UiComponent\ConfigStorageBuilderInterface" type="Magento\Ui\ContentType\Builder\ConfigStorageJson" /> - <preference for="Magento\Framework\View\Element\UiComponent\ConfigInterface" type="Magento\Ui\Context\Configuration" /> - <preference for="Magento\Framework\View\Element\UiComponent\ConfigStorageInterface" type="Magento\Ui\Context\ConfigurationStorage" /> - <preference for="Magento\Ui\Component\Control\ActionPoolInterface" type="Magento\Ui\Component\Control\ActionPool" /> + <preference for="Magento\Framework\View\Element\UiComponent\ContainerInterface" type="Magento\Ui\Component\Wrapper\UiComponent" /> + <preference for="Magento\Framework\View\Element\UiComponent\Control\ActionPoolInterface" type="Magento\Ui\Component\Control\ActionPool" /> + <preference for="Magento\Framework\Data\Argument\InterpreterInterface" type="Magento\Framework\Data\Argument\Interpreter\Composite" /> + <preference for="Magento\Framework\Config\ConverterInterface" type="Magento\Framework\View\Element\UiComponent\Config\Converter" /> + <preference for="Magento\Framework\View\Element\UiComponent\Config\ManagerInterface" type="Magento\Framework\View\Element\UiComponent\Config\Manager" /> + <preference for="Magento\Framework\View\Element\UiComponent\ContextInterface" type="Magento\Framework\View\Element\UiComponent\Context" /> + <preference for="Magento\Framework\View\Element\UiComponent\LayoutInterface" type="Magento\Ui\Component\Layout\Generic"/> + <type name="Magento\Framework\View\Element\UiComponent\TemplateAdapter" shared="false" /> + <type name="Magento\Framework\View\TemplateEngineFactory"> + <arguments> + <argument name="engines" xsi:type="array"> + <item name="xhtml" xsi:type="string">Magento\Ui\TemplateEngine\Xhtml</item> + </argument> + </arguments> + </type> + <type name="Magento\Ui\TemplateEngine\Xhtml"> + <arguments> + <argument name="compiler" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler</argument> + </arguments> + </type> + <type name="Magento\Framework\View\Element\UiComponent\ContentType\ContentTypeFactory"> + <arguments> + <argument name="types" xsi:type="array"> + <item name="html" xsi:type="string">Magento\Framework\View\Element\UiComponent\ContentType\Html</item> + <item name="json" xsi:type="string">Magento\Framework\View\Element\UiComponent\ContentType\Json</item> + <item name="xml" xsi:type="string">Magento\Framework\View\Element\UiComponent\ContentType\Xml</item> + </argument> + </arguments> + </type> + <type name="Magento\Ui\TemplateEngine\Xhtml\Compiler\Text"> + <arguments> + <argument name="directivePool" xsi:type="array"> + <item name="variable" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive\Variable</item> + <item name="callableMethod" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive\CallableMethod</item> + </argument> + </arguments> + </type> + <type name="Magento\Ui\TemplateEngine\Xhtml\Compiler\Attribute"> + <arguments> + <argument name="directivePool" xsi:type="array"> + <item name="variable" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive\Variable</item> + <item name="callableMethod" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Directive\CallableMethod</item> + </argument> + </arguments> + </type> + <type name="Magento\Ui\TemplateEngine\Xhtml\Compiler" shared="false"> + <arguments> + <argument name="compilerText" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Text</argument> + <argument name="compilerAttribute" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Attribute</argument> + <argument name="compilerCdata" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Cdata</argument> + <argument name="compilerComment" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Comment</argument> + <argument name="elementCompilers" xsi:type="array"> + <item name="render" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Element\Render</item> + <item name="content" xsi:type="object">\Magento\Ui\TemplateEngine\Xhtml\Compiler\Element\Content</item> + <item name="form" xsi:type="object">Magento\Ui\TemplateEngine\Xhtml\Compiler\Element\Form</item> + </argument> + </arguments> + </type> + <virtualType name="uiConfigurationDomMerger" type="Magento\Framework\View\Element\UiComponent\Config\DomMerger"> + <arguments> + <argument name="schemaFileType" xsi:type="string">etc</argument> + <argument name="schemaFileModule" xsi:type="string">Magento_Ui</argument> + <argument name="schemaFileName" xsi:type="string">ui_configuration.xsd</argument> + <argument name="contextXPath" xsi:type="array"> + <item name="ui_context" xsi:type="string">/</item> + </argument> + <argument name="idAttributes" xsi:type="array"> + <item name="attribute_name" xsi:type="string">name</item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Framework\View\Element\UiComponent\Config\Manager"> + <arguments> + <argument name="domMerger" xsi:type="object">uiConfigurationDomMerger</argument> + </arguments> + </type> + <virtualType name="uiTemplateDomMerger" type="Magento\Framework\View\Element\UiComponent\Config\DomMerger"> + <arguments> + <argument name="schemaFileType" xsi:type="string">etc</argument> + <argument name="schemaFileModule" xsi:type="string">Magento_Ui</argument> + <argument name="schemaFileName" xsi:type="string">ui_template.xsd</argument> + <argument name="contextXPath" xsi:type="array"> + <item name="ui_context" xsi:type="string">/</item> + </argument> + <argument name="idAttributes" xsi:type="array"> + <item name="attribute_name" xsi:type="string">name</item> + <item name="attribute_id" xsi:type="string">id</item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Framework\View\Element\UiComponent\Config\Provider\Template"> + <arguments> + <argument name="domMerger" xsi:type="object">uiTemplateDomMerger</argument> + </arguments> + </type> + <virtualType name="uiDefinitionDomMerger" type="Magento\Framework\View\Element\UiComponent\Config\DomMerger"> + <arguments> + <argument name="schemaFileType" xsi:type="string">etc</argument> + <argument name="schemaFileModule" xsi:type="string">Magento_Ui</argument> + <argument name="schemaFileName" xsi:type="string">ui_definition.xsd</argument> + <argument name="contextXPath" xsi:type="array"> + <item name="ui_context" xsi:type="string">/components</item> + </argument> + <argument name="idAttributes" xsi:type="array"> + <item name="attribute_name" xsi:type="string">name</item> + </argument> + <argument name="isMergeSimpleXMLElement" xsi:type="boolean">true</argument> + </arguments> + </virtualType> + <virtualType name="uiDefinitionFileCollector" type="Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollector"> + <arguments> + <argument name="searchPattern" xsi:type="string">etc/definition.xml</argument> + </arguments> + </virtualType> + <virtualType name="uiDefinitionReader" type="Magento\Framework\View\Element\UiComponent\Config\Reader"> + <arguments> + <argument name="fileCollector" xsi:type="object">uiDefinitionFileCollector</argument> + <argument name="domMerger" xsi:type="object">uiDefinitionDomMerger</argument> + </arguments> + </virtualType> + <type name="Magento\Framework\View\Element\UiComponent\Config\Provider\Component\Definition"> + <arguments> + <argument name="uiReader" xsi:type="object">uiDefinitionReader</argument> + </arguments> + </type> <type name="Magento\Ui\Component\Filter\FilterPool"> <arguments> <argument name="filters" xsi:type="array"> <item name="filter_input" xsi:type="string">Magento\Ui\Component\Filter\Type\Input</item> <item name="filter_select" xsi:type="string">Magento\Ui\Component\Filter\Type\Select</item> <item name="filter_range" xsi:type="string">Magento\Ui\Component\Filter\Type\Range</item> - <item name="filter_date" xsi:type="string">Magento\Ui\Component\Filter\Type\Date</item> <item name="filter_store" xsi:type="string">Magento\Ui\Component\Filter\Type\Store</item> </argument> </arguments> </type> + <type name="Magento\Ui\Component\Layout\LayoutPool"> + <arguments> + <argument name="types" xsi:type="array"> + <item name="generic" xsi:type="array"> + <item name="class" xsi:type="string">Magento\Ui\Component\Layout\Generic</item> + <item name="template" xsi:type="string">templates/layout/generic</item> + </item> + <item name="tabs" xsi:type="array"> + <item name="class" xsi:type="string">Magento\Ui\Component\Layout\Tabs</item> + <item name="template" xsi:type="string">templates/layout/tabs</item> + </item> + </argument> + </arguments> + </type> + <virtualType name="arrayArgumentInterpreterProxy" type="Magento\Framework\Data\Argument\InterpreterInterface\Proxy"> + <arguments> + <argument name="instanceName" xsi:type="string">Magento\Framework\Data\Argument\Interpreter\ArrayType</argument> + </arguments> + </virtualType> + <virtualType name="configurableObjectArgumentInterpreterProxy" type="Magento\Framework\Data\Argument\InterpreterInterface\Proxy"> + <arguments> + <argument name="instanceName" xsi:type="string">Magento\Framework\View\Element\UiComponent\Argument\Interpreter\ConfigurableObject</argument> + </arguments> + </virtualType> + <type name="Magento\Framework\Data\Argument\Interpreter\Composite"> + <arguments> + <argument name="interpreters" xsi:type="array"> + <item name="object" xsi:type="object">Magento\Framework\Data\Argument\Interpreter\Object</item> + <item name="configurableObject" xsi:type="object">configurableObjectArgumentInterpreterProxy</item> + <item name="array" xsi:type="object">arrayArgumentInterpreterProxy</item> + <item name="boolean" xsi:type="object">Magento\Framework\Data\Argument\Interpreter\Boolean</item> + <item name="number" xsi:type="object">Magento\Framework\Data\Argument\Interpreter\Number</item> + <item name="string" xsi:type="object">Magento\Framework\Data\Argument\Interpreter\String</item> + <item name="null" xsi:type="object">Magento\Framework\Data\Argument\Interpreter\NullType</item> + </argument> + <argument name="discriminator" xsi:type="string">xsi:type</argument> + </arguments> + </type> + <type name="Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollector"> + <arguments> + <argument name="collectorAggregated" xsi:type="object">uiComponentAggregatedCollector</argument> + </arguments> + </type> + <virtualType name="uiComponentAggregatedCollector" type="Magento\Framework\View\Layout\File\Collector\Aggregated"> + <arguments> + <argument name="baseFiles" xsi:type="object">uiComponentAggregatedSourceBaseSorted</argument> + <argument name="themeFiles" xsi:type="object">uiComponentAggregatedSourceThemeSorted</argument> + <argument name="overrideBaseFiles" xsi:type="object">uiComponentAggregatedSourceOverrideBaseSorted</argument> + <argument name="overrideThemeFiles" xsi:type="object">uiComponentAggregatedSourceOverrideThemeSorted</argument> + </arguments> + </virtualType> + <virtualType name="uiComponentAggregatedSourceBase" type="Magento\Framework\View\File\Collector\Base"> + <arguments> + <argument name="subDir" xsi:type="string">ui_component</argument> + </arguments> + </virtualType> + <virtualType shared="false" name="uiComponentAggregatedSourceBaseFiltered" type="Magento\Framework\View\File\Collector\Decorator\ModuleOutput"> + <arguments> + <argument name="subject" xsi:type="object">uiComponentAggregatedSourceBase</argument> + </arguments> + </virtualType> + <virtualType name="uiComponentAggregatedSourceBaseSorted" type="Magento\Framework\View\File\Collector\Decorator\ModuleDependency"> + <arguments> + <argument name="subject" xsi:type="object">uiComponentAggregatedSourceBaseFiltered</argument> + </arguments> + </virtualType> + <virtualType name="uiComponentAggregatedSourceTheme" type="Magento\Framework\View\File\Collector\ThemeModular"> + <arguments> + <argument name="subDir" xsi:type="string">ui_component</argument> + </arguments> + </virtualType> + <virtualType name="uiComponentAggregatedSourceThemeFiltered" type="Magento\Framework\View\File\Collector\Decorator\ModuleOutput"> + <arguments> + <argument name="subject" xsi:type="object">uiComponentAggregatedSourceTheme</argument> + </arguments> + </virtualType> + <virtualType name="uiComponentAggregatedSourceThemeSorted" type="Magento\Framework\View\File\Collector\Decorator\ModuleDependency"> + <arguments> + <argument name="subject" xsi:type="object">uiComponentAggregatedSourceThemeFiltered</argument> + </arguments> + </virtualType> + <virtualType name="uiComponentAggregatedSourceOverrideBase" type="Magento\Framework\View\File\Collector\Override\Base"> + <arguments> + <argument name="subDir" xsi:type="string">layout/override/base</argument> + </arguments> + </virtualType> + <virtualType name="uiComponentAggregatedSourceOverrideBaseFiltered" type="Magento\Framework\View\File\Collector\Decorator\ModuleOutput"> + <arguments> + <argument name="subject" xsi:type="object">uiComponentAggregatedSourceOverrideBase</argument> + </arguments> + </virtualType> + <virtualType name="uiComponentAggregatedSourceOverrideBaseSorted" type="Magento\Framework\View\File\Collector\Decorator\ModuleDependency"> + <arguments> + <argument name="subject" xsi:type="object">uiComponentAggregatedSourceOverrideBaseFiltered</argument> + </arguments> + </virtualType> + <virtualType name="uiComponentAggregatedSourceOverrideTheme" type="Magento\Framework\View\File\Collector\Override\ThemeModular"> + <arguments> + <argument name="subDir" xsi:type="string">layout/override/theme</argument> + </arguments> + </virtualType> + <virtualType name="uiComponentAggregatedSourceOverrideThemeFiltered" type="Magento\Framework\View\File\Collector\Decorator\ModuleOutput"> + <arguments> + <argument name="subject" xsi:type="object">uiComponentAggregatedSourceOverrideTheme</argument> + </arguments> + </virtualType> + <virtualType name="uiComponentAggregatedSourceOverrideThemeSorted" type="Magento\Framework\View\File\Collector\Decorator\ModuleDependency"> + <arguments> + <argument name="subject" xsi:type="object">uiComponentAggregatedSourceOverrideThemeFiltered</argument> + </arguments> + </virtualType> </config> diff --git a/app/code/Magento/Ui/etc/ui_components.xsd b/app/code/Magento/Ui/etc/ui_components.xsd new file mode 100644 index 0000000000000000000000000000000000000000..6cd0edbfc363f24af6de5d73fb43ab467ac69737 --- /dev/null +++ b/app/code/Magento/Ui/etc/ui_components.xsd @@ -0,0 +1,322 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> + <!-- Include section --> + <xs:include schemaLocation="../../../../../lib/internal/Magento/Framework/Data/etc/argument/types.xsd"/> + <!-- Defined the types of components --> + <xs:complexType name="layout" xml:base="ui_element"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="tab"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="columns"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="column"> + <xs:complexContent> + <xs:extension base="field"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="dataSource"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="listing"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + <xs:attribute name="sorting" use="optional"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="true"/> + <xs:enumeration value="false"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="paging"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="filters"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="filterSelect"> + <xs:complexContent> + <xs:extension base="select"/> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="filterRange"> + <xs:complexContent> + <xs:extension base="input"/> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="filterInput"> + <xs:complexContent> + <xs:extension base="input"/> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="filterDate"> + <xs:complexContent> + <xs:extension base="input"/> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="container"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="massaction"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="form"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="input"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + <xs:attribute name="displayZone" use="optional"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="header"/> + <xs:enumeration value="content"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="checkbox"> + <xs:complexContent> + <xs:extension base="input"/> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="select"> + <xs:complexContent> + <xs:extension base="input"/> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="multiselect"> + <xs:complexContent> + <xs:extension base="select"/> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="textarea"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="fieldset"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="field" type="field" /> + <xs:element name="container" type="container" /> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="field"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="dataTypeText"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="dataTypeBoolean"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="dataTypeNumber"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="dataTypePrice"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="dataTypeMedia"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="dataTypeDate"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="dataTypeEmail"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="nav"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="actions"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <!-- Global groups --> + <xs:group name="configurable"> + <xs:sequence> + <xs:element type="argumentType" name="argument" minOccurs="0" maxOccurs="unbounded"> + <xs:key name="configurableArgumentItemName"> + <xs:selector xpath="item"/> + <xs:field xpath="@name"/> + </xs:key> + </xs:element> + </xs:sequence> + </xs:group> + <!-- Global types --> + <xs:complexType name="constant"> + <xs:complexContent> + <xs:extension base="argumentType"/> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="ui_element"> + <xs:attribute type="xs:string" name="name" use="optional"/> + <xs:attribute type="xs:boolean" name="disabled" use="optional"/> + <xs:attribute type="xs:string" name="layout" use="optional"/> + <xs:attribute type="xs:string" name="dataSource" use="optional"/> + <xs:attribute type="xs:string" name="class" use="optional"/> + </xs:complexType> + <!-- Simple types --> + <xs:simpleType name="referenceAttributeType"> + <xs:annotation> + <xs:documentation>The value should only be {[a-z_-]+} since it is used as a reference to a database field.</xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:pattern value="[a-z_-]+" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="textAttributeType"> + <xs:annotation> + <xs:documentation>Any text value</xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:pattern value="[A-Za-z0-9,_.\\: -]+" /> + </xs:restriction> + </xs:simpleType> +</xs:schema> diff --git a/app/code/Magento/Ui/etc/ui_configuration.xsd b/app/code/Magento/Ui/etc/ui_configuration.xsd new file mode 100644 index 0000000000000000000000000000000000000000..84f16e2db35d60bc40b48e4eeeb4b45c58ff59ca --- /dev/null +++ b/app/code/Magento/Ui/etc/ui_configuration.xsd @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> + <xs:annotation> + <xs:appinfo>The definition of a configuration item components</xs:appinfo> + <xs:documentation>The definition of a configuration item components</xs:documentation> + </xs:annotation> + <!-- Include section --> + <xs:include schemaLocation="ui_components.xsd"/> + <!-- Components list --> + <xs:element type="formConfiguration" name="form"/> + <xs:element type="listingConfiguration" name="listing"/> + <!-- Custom configuration --> + <xs:complexType name="containerConfiguration"> + <xs:complexContent> + <xs:extension base="container"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element type="paging" name="paging"/> + <xs:element type="filtersConfiguration" name="filters"/> + <xs:element type="massaction" name="massaction"/> + <xs:element type="columnsConfiguration" name="columns"/> + <xs:element type="containerConfiguration" name="container"/> + <xs:element name="field" type="field" /> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="fieldsetConfiguration"> + <xs:complexContent> + <xs:extension base="container"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element type="containerConfiguration" name="container"/> + <xs:element name="field" type="field" /> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="listingConfiguration"> + <xs:complexContent> + <xs:extension base="listing"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element type="paging" name="paging"/> + <xs:element type="filtersConfiguration" name="filters"/> + <xs:element type="massaction" name="massaction"/> + <xs:element type="dataSource" name="dataSource"/> + <xs:element type="columnsConfiguration" name="columns"/> + <xs:element type="containerConfiguration" name="container"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="formConfiguration"> + <xs:complexContent> + <xs:extension base="form"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="fieldset" type="fieldsetConfiguration" /> + <xs:element name="field" type="field" /> + <xs:element type="dataSource" name="dataSource"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="columnsConfiguration"> + <xs:complexContent> + <xs:extension base="columns"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="column" type="column" /> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="filtersConfiguration"> + <xs:complexContent> + <xs:extension base="filters"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="filterDate" type="filterDate" /> + <xs:element name="filterInput" type="filterInput" /> + <xs:element name="filterRange" type="filterRangeConfiguration" /> + <xs:element name="filterSelect" type="filterSelect" /> + <xs:element name="containerConfiguration" type="container" /> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="filterRangeConfiguration"> + <xs:complexContent> + <xs:extension base="filterRange"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="filterDate" type="filterDate" /> + <xs:element name="filterInput" type="filterInput" /> + <xs:element name="filterSelect" type="filterSelect" /> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> +</xs:schema> diff --git a/app/code/Magento/Ui/etc/ui_definition.xsd b/app/code/Magento/Ui/etc/ui_definition.xsd new file mode 100644 index 0000000000000000000000000000000000000000..fc279745827db502f0c3504c96a8e521ec102dc3 --- /dev/null +++ b/app/code/Magento/Ui/etc/ui_definition.xsd @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> + <!-- Include section --> + <xs:include schemaLocation="ui_components.xsd"/> + <!-- Definition the document element --> + <xs:element name="components" type="definition"/> + <!-- Registering components in the system --> + <xs:complexType name="definition"> + <xs:annotation> + <xs:appinfo>Registering components in the system and basic setup</xs:appinfo> + <xs:documentation>Registering components in the system and basic setup</xs:documentation> + </xs:annotation> + <xs:all> + <!-- Components list --> + <xs:element type="tab" name="tab"/> + <xs:element type="dataSource" name="dataSource"/> + <xs:element type="paging" name="paging"/> + <xs:element type="massaction" name="massaction"/> + <xs:element type="listingDefinition" name="listing"/> + <xs:element type="formDefinition" name="form"/> + <xs:element type="fieldset" name="fieldset"/> + <xs:element type="field" name="field"/> + <xs:element type="filters" name="filters"/> + <xs:element type="columns" name="columns"/> + <xs:element type="column" name="column"/> + <xs:element type="filterSelect" name="filterSelect"/> + <xs:element type="filterRange" name="filterRange"/> + <xs:element type="filterInput" name="filterInput"/> + <xs:element type="filterDate" name="filterDate"/> + <xs:element type="container" name="container"/> + <xs:element type="input" name="input"/> + <xs:element type="checkbox" name="checkbox"/> + <xs:element type="select" name="select"/> + <xs:element type="multiselect" name="multiselect"/> + <xs:element type="textarea" name="textarea"/> + <xs:element type="dataTypeText" name="text"/> + <xs:element type="dataTypeBoolean" name="boolean"/> + <xs:element type="dataTypeNumber" name="number"/> + <xs:element type="dataTypePrice" name="price"/> + <xs:element type="dataTypeMedia" name="media"/> + <xs:element type="dataTypeDate" name="date"/> + <xs:element type="dataTypeEmail" name="email"/> + <xs:element type="nav" name="nav"/> + <xs:element type="actions" name="actions"/> + </xs:all> + </xs:complexType> + <!-- Custom configuration --> + <xs:complexType name="listingDefinition"> + <xs:complexContent> + <xs:extension base="listing"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element type="dataSource" name="dataSource"/> + <xs:element type="paging" name="paging"/> + <xs:element type="massaction" name="massaction"/> + <xs:element type="columns" name="columns"/> + <xs:element type="filters" name="filters"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="formDefinition"> + <xs:complexContent> + <xs:extension base="form"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element type="fieldset" name="fieldset"/> + <xs:element type="dataSource" name="dataSource"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> +</xs:schema> diff --git a/app/code/Magento/Ui/etc/ui_template.xsd b/app/code/Magento/Ui/etc/ui_template.xsd new file mode 100644 index 0000000000000000000000000000000000000000..ef5b731067363469152765f0a5579edb76e129d6 --- /dev/null +++ b/app/code/Magento/Ui/etc/ui_template.xsd @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> + <xs:element name="form"> + <xs:complexType > + <xs:sequence> + <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax" /> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="div" > + <xs:complexType > + <xs:sequence> + <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax" /> + </xs:sequence> + <xs:anyAttribute processContents="lax" /> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/app/code/Magento/Ui/view/base/layout/default.xml b/app/code/Magento/Ui/view/base/layout/default.xml deleted file mode 100644 index 289b9006c48b5014637cea71d5f054d2ba733e70..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/layout/default.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> - <body> - <referenceContainer name="footer"> - <block class="Magento\Ui\Context\DataProvider" name="ui.global.config" after="-"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::context/default.phtml</argument> - </arguments> - </block> - </referenceContainer> - </body> -</page> diff --git a/app/code/Magento/Ui/view/base/layout/ui_components.xml b/app/code/Magento/Ui/view/base/layout/ui_components.xml deleted file mode 100644 index d8d2be00aa0e54a757831b1d04d749dca4a29ae1..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/layout/ui_components.xml +++ /dev/null @@ -1,245 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd"> - <block class="Magento\Ui\Component\Listing" name="listing"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::listing/horizontal_grid.phtml</argument> - <argument name="save_parameters_in_session" xsi:type="string">1</argument> - <argument name="client_root" xsi:type="string">mui/index/render</argument> - </arguments> - <container label="Listing Head" name="listing_head"/> - <container label="Listing Before" name="listing_before"> - <ui_component name="sorting" component="component_sorting" /> - <ui_component name="paging" component="component_paging" /> - <ui_component name="filters" component="component_filter_pool" /> - <ui_component name="massactions" component="component_control_massaction" /> - </container> - </block> - <block class="Magento\Ui\Component\Paging" name="component_paging"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::paging/default.phtml</argument> - </arguments> - </block> - <block class="Magento\Ui\Component\FilterPool" name="component_filter_pool"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::filter_pool/default.phtml</argument> - <argument name="config" xsi:type="array"> - <item name="types" xsi:type="array"> - <item name="filter_date" xsi:type="array"> - <item name="dateFormat" xsi:type="string">mm/dd/yyyy</item> - </item> - <item name="filter_input" xsi:type="array"/> - <item name="filter_select" xsi:type="array"/> - <item name="filter_range" xsi:type="array"/> - </item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Filter\Type\Select" name="filter_select" /> - <block class="Magento\Ui\Component\Filter\Type\Range" name="filter_range" /> - <block class="Magento\Ui\Component\Filter\Type\Input" name="filter_input" /> - <block class="Magento\Ui\Component\Filter\Type\Date" name="filter_date" /> - - <block class="Magento\Ui\Component\Sorting" name="component_sorting"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::sorting/default.phtml</argument> - <argument name="config" xsi:type="array"> - <item name="direction" xsi:type="string">asc</item> - </argument> - </arguments> - </block> - - <block class="Magento\Ui\Component\MassAction" name="component_control_massaction"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::listingcontainer/massaction/default.phtml</argument> - </arguments> - </block> - - <block class="Magento\Ui\Component\Control\Action" name="actions" /> - - <block class="Magento\Ui\Component\Form\Element\Input" name="input"> - <arguments> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item> - <item name="config" xsi:type="array"> - <item name="input_type" xsi:type="string">input</item> - </item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Form\Element\Input" name="checkbox"> - <arguments> - <argument name="input_type" xsi:type="string">checkbox</argument> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/element/boolean</item> - <item name="config" xsi:type="array"> - <item name="input_type" xsi:type="string">checkbox</item> - </item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Form\Element\Select" name="select"> - <arguments> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/element/select</item> - <item name="config" xsi:type="array"> - <item name="input_type" xsi:type="string">select</item> - </item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Form\Element\Select" name="multiselect"> - <arguments> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/element/multiselect</item> - <item name="config" xsi:type="array"> - <item name="input_type" xsi:type="string">multiselect</item> - <item name="template" xsi:type="string">ui/form/element/multiselect</item> - </item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Form\Element\Textarea" name="textarea"> - <arguments> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/element/textarea</item> - <item name="config" xsi:type="array"> - <item name="input_type" xsi:type="string">textarea</item> - </item> - </argument> - </arguments> - </block> - - <block class="Magento\Ui\Component\Form\Element\DataType\Text" name="text" /> - <block class="Magento\Ui\Component\Form\Element\DataType\Number" name="number" /> - <block class="Magento\Ui\Component\Form\Element\DataType\Price" name="price" /> - <block class="Magento\Ui\Component\Form\Element\DataType\Media" name="media"> - <arguments> - <argument name="js_config" xsi:type="array"> - <item name="extends" xsi:type="string">input</item> - <item name="config" xsi:type="array"> - <item name="input_type" xsi:type="string">media</item> - </item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Form\Element\DataType\Date" name="date"> - <arguments> - <argument name="js_config" xsi:type="array"> - <item name="extends" xsi:type="string">input</item> - <item name="component" xsi:type="string">Magento_Ui/js/form/element/date</item> - <item name="config" xsi:type="array"> - <item name="input_type" xsi:type="string">date</item> - </item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Form\Element\DataType\Boolean" name="boolean"> - <arguments> - <argument name="js_config" xsi:type="array"> - <item name="extends" xsi:type="string">input</item> - <item name="config" xsi:type="array"> - <item name="input_type" xsi:type="string">select</item> - </item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Form\Element\DataType\Email" name="email"> - <arguments> - <argument name="js_config" xsi:type="array"> - <item name="extends" xsi:type="string">input</item> - <item name="config" xsi:type="array"> - <item name="input_type" xsi:type="string">email</item> - </item> - </argument> - </arguments> - </block> - - <block class="Magento\Ui\Component\Form" name="form"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::form/default.phtml</argument> - <argument name="save_url" xsi:type="string">mui/form/save</argument> - <argument name="validate_url" xsi:type="string">mui/form/validate</argument> - <argument name="layout" xsi:type="array"> - <item name="type" xsi:type="string">tabs</item> - </argument> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form</item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Form\Fieldset" name="fieldset"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::form/fieldset/default.phtml</argument> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/components/fieldset</item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Layout\Tabs" name="tabs"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::layout/tabs/default.phtml</argument> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/components/tabs</item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Layout\Tabs\Tab" name="tab"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::layout/tabs/tab/default.phtml</argument> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/components/area</item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Layout\Group" name="group"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::layout/group/default.phtml</argument> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/components/group</item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Layout\Tabs\Nav" name="nav"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::layout/tabs/nav/default.phtml</argument> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/components/tab_group</item> - <item name="config" xsi:type="array"> - <item name="template" xsi:type="string">ui/tab</item> - </item> - </argument> - </arguments> - </block> - <block class="Magento\Ui\Component\Container\Content" name="html_content"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::container/content/default.phtml</argument> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/components/html</item> - </argument> - </arguments> - </block> - - <block class="Magento\Ui\Component\Form\Collection" name="collection"> - <arguments> - <argument name="content_template" xsi:type="string">Magento_Ui::form/collection/default.phtml</argument> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/components/collection</item> - </argument> - </arguments> - </block> - - <block class="Magento\Ui\Component\Form\Element\Input" name="post_code"> - <arguments> - <argument name="js_config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/element/post-code</item> - <item name="dependentFiled" xsi:type="string">country_id</item> - </argument> - </arguments> - </block> -</layout> diff --git a/app/code/Magento/Ui/view/base/requirejs-config.js b/app/code/Magento/Ui/view/base/requirejs-config.js index 8f1227f8bf26407d0418aeecfead532701ba900c..50196fbadd38064a068d4850c11b6da7e74e31ad 100644 --- a/app/code/Magento/Ui/view/base/requirejs-config.js +++ b/app/code/Magento/Ui/view/base/requirejs-config.js @@ -7,5 +7,11 @@ var config = { paths: { 'ui/template': 'Magento_Ui/templates', 'i18n': 'Magento_Ui/js/lib/i18n' + }, + map: { + '*': { + uiComponent: 'Magento_Ui/js/lib/component/main', + uiRegistry: 'Magento_Ui/js/lib/registry/registry' + } } }; \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/templates/context/default.phtml b/app/code/Magento/Ui/view/base/templates/context/default.phtml index ecd62351fb8d098b71c2dc9a6c611893be33c01d..e05848ba175c40b7cc3e95ef5e37472730bd3a96 100644 --- a/app/code/Magento/Ui/view/base/templates/context/default.phtml +++ b/app/code/Magento/Ui/view/base/templates/context/default.phtml @@ -3,10 +3,5 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -/** - * @var \Magento\Ui\Context\DataProvider $block - */ ?> -<script type="application/json"> - <?php echo $block->getAsJson(); ?> -</script> +<script data-mage-init='{ "Magento_Ui/js/core/app": "" }' type="application/json"></script> diff --git a/app/code/Magento/Ui/view/base/templates/filter_pool/active.phtml b/app/code/Magento/Ui/view/base/templates/filter_pool/active.phtml deleted file mode 100644 index f4419a7023e503893ffa2d07219e20f1900997d2..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/templates/filter_pool/active.phtml +++ /dev/null @@ -1,15 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -/** - * @var \Magento\Ui\Component\Filter $block - */ -?> -<strong class="item-label" data-bind-="text: $t(filter.title)"><?php echo $block->getData('label') ?></strong> -<span class="item-value" data-bind-="text: $t(filter.output)"><?php echo $block->getData('current_display_value') ?></span> -<button data-bind-="click: $parent.onClear(filter)" type="button" class="action action-remove"><span data-bind-="text: $t('Remove')"></span></button> diff --git a/app/code/Magento/Ui/view/base/templates/filter_pool/default.phtml b/app/code/Magento/Ui/view/base/templates/filter_pool/default.phtml deleted file mode 100644 index caec2660f677e5534558308e33021b753a8639e6..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/templates/filter_pool/default.phtml +++ /dev/null @@ -1,19 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -/** - * @var \Magento\Ui\Component\FilterPool $block - */ -?> -<script type="text/x-magento-init"> - { - "*": { - "Magento_Ui/js/listing/filter": <?php echo $block->getConfigBuilder()->toJson($block->getConfig()); ?> - } - } -</script> -<div data-bind="scope: '<?php echo $block->getParentName(); ?>:<?php echo $block->getName(); ?>'"> - <!-- ko template: 'ui/filter' --><!-- /ko --> -</div> diff --git a/app/code/Magento/Ui/view/base/templates/form/default.phtml b/app/code/Magento/Ui/view/base/templates/form/default.phtml index 7c51b5cb65711b8067c4abc21e1ee53d6f738754..3f42ae43172860c4eb6769bf949c7255f97e2dc6 100644 --- a/app/code/Magento/Ui/view/base/templates/form/default.phtml +++ b/app/code/Magento/Ui/view/base/templates/form/default.phtml @@ -6,20 +6,13 @@ /** * @var \Magento\Ui\Component\Form $block */ -$formConfig = $block->getRenderContext()->getConfigBuilder()->toJsonNew($block->getRenderContext()->getStorage()); +echo $block->renderChildComponent('before_form'); ?> -<script type="text/x-magento-init"> - { - "*": { - "Magento_Ui/js/core/app": <?php echo $formConfig; ?> - } - } -</script> -<div data-role="spinner" data-component="<?php echo $block->getDataScope(); ?>.areas" class="grid-loading-mask"> - <div class="spinner"> - <span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span> - </div> +<div data-role="spinner" data-component="<?php echo $block->getName(); ?>.areas" class="admin__data-grid-loading-mask"> + <div class="grid-loader"></div> </div> -<div data-bind="scope: '<?php echo $block->getDataScope(); ?>.areas'"> +<div data-bind="scope: '<?php echo $block->getName(); ?>.areas'" class="entry-edit form-inline"> <!-- ko template: getTemplate() --><!-- /ko --> </div> +<?php +echo $block->renderChildComponent('after_form'); diff --git a/app/code/Magento/Ui/view/base/templates/form/fieldset/default.phtml b/app/code/Magento/Ui/view/base/templates/form/fieldset/default.phtml deleted file mode 100644 index 0d814d882b5f9ca4524523847e639d1680bf7516..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/templates/form/fieldset/default.phtml +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -/** - * @var \Magento\Ui\Component\Form\Fieldset $block - */ -$children = $block->getChildren(); -$content = $block->getContent(); -$ajaxUrl = $block->getAjaxUrl(); -?> -<div class="admin__fieldset-wrapper-title" tabindex="3" data-bind="click: onClick, keyboard: { 13: toggle }"> - <strong class="title"> - <span data-bind="text: label"><?php echo $block->getData('config/label'); ?></span> - </strong> -</div> - -<div class="admin__fieldset-wrapper-content"> - <fieldset id="<?php echo $block->getData('index'); ?>" class="admin__fieldset"> - <?php if (!empty($content)): ?> - <?php echo $content; ?> - <?php endif; ?> - <?php if (is_array($children) && !$ajaxUrl): ?> - <?php foreach ($children as $childName): ?> - <?php $childElement = $block->getLayoutElement($childName);?> - <p><?php echo $block->renderElement('group', $childElement); ?></p> - <?php endforeach; ?> - <?php endif; ?> - </fieldset> -</div> diff --git a/app/code/Magento/Ui/view/base/templates/label/default.phtml b/app/code/Magento/Ui/view/base/templates/label/default.phtml index b1cf43ddc16f714217fc24f76de9a8920d0fd27e..d9937521b97202e4c3358982b6f31661cc89a959 100644 --- a/app/code/Magento/Ui/view/base/templates/label/default.phtml +++ b/app/code/Magento/Ui/view/base/templates/label/default.phtml @@ -3,9 +3,6 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -/** - * @var \Magento\Ui\Component\AbstractView $block - */ ?> <span> <?php echo $block->getData('label'); ?> diff --git a/app/code/Magento/Ui/view/base/templates/layout/group/default.phtml b/app/code/Magento/Ui/view/base/templates/layout/group/default.phtml deleted file mode 100644 index c3a67828419eda7d3fd5465d6b45acd1181dd23f..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/templates/layout/group/default.phtml +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -/** - * @var \Magento\Ui\Component\Layout\Group $block - */ - -?> -<div class="admin__field <?php echo $block->getIsRequired()?>" data-bind="css: {'required': required}"> - <label class="admin__field-label" data-bind="attr: { for: <?php echo $block->getData('index')?> }" for="R1WKK"> - <span data-bind="text: element.label"><?php echo $block->getData('label')?></span> - </label> - <div class="admin__field-control"> - <?php if ($block->getChildren()): ?> - <?php foreach ($block->getChildren() as $child): ?> - <?php echo $block->renderElement($child['dataType'], ['field_config' => $child]); ?> - <?php endforeach; ?> - <?php endif;?> - </div> -</div> diff --git a/app/code/Magento/Ui/view/base/templates/layout/tabs/nav/default.phtml b/app/code/Magento/Ui/view/base/templates/layout/tabs/nav/default.phtml index 46f9c9a8f0ec5672b8b8bed3a9b48fefa7d58bf6..471cf5f85bb6c48b670f61871040913c100a4ded 100644 --- a/app/code/Magento/Ui/view/base/templates/layout/tabs/nav/default.phtml +++ b/app/code/Magento/Ui/view/base/templates/layout/tabs/nav/default.phtml @@ -7,11 +7,6 @@ * @var \Magento\Ui\Component\Layout\Tabs\Nav $block */ ?> -<div data-role="spinner" data-component="<?php echo $block->getDataScope(); ?>.sections" class="grid-loading-mask"> - <div class="spinner"> - <span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span> - </div> -</div> <div data-bind="scope: '<?php echo $block->getDataScope(); ?>.sections' " class="ui-tabs"> <!-- ko template: getTemplate() --><!-- /ko --> </div> diff --git a/app/code/Magento/Ui/view/base/templates/listing/horizontal_grid.phtml b/app/code/Magento/Ui/view/base/templates/listing/horizontal_grid.phtml deleted file mode 100644 index 32f2356edd984294bd88fc9387e1a8bf7376aee6..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/templates/listing/horizontal_grid.phtml +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -?> -<?php -/** - * @var \Magento\Ui\Component\Listing $block - */ -?> -<script type="text/x-magento-init"> -{ - "*": { - "Magento_Ui/js/lib/provider": - <?php echo $block->getRenderContext() - ->getConfigBuilder() - ->toJson($block->getRenderContext()->getStorage(), $block->getName()); - ?>, - "Magento_Ui/js/listing/grid": <?php echo $block->getConfigBuilder()->toJson($block->getConfig()); ?> - } -} -</script> -<?php echo $block->getChildHtml('listing_head'); ?> -<div class="grid"> - <?php echo $block->getChildHtml('listing_before'); ?> - <div data-bind="scope: '<?php echo $block->getParentName(); ?>:<?php echo $block->getName(); ?>'"> - <!-- ko template: getTemplate() --><!-- /ko --> - </div> - <?php echo $block->getChildHtml('listing_after'); ?> -</div> -<div data-role="spinner" class="grid-loading-mask"> - <div class="grid-loader"></div> -</div> diff --git a/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/default.phtml b/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/default.phtml deleted file mode 100644 index f0e80904214fb86fad22be517b94e6ef1643b362..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/default.phtml +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -?> -<?php -/** - * @var \Magento\Ui\Component\MassAction $block - */ -?> -<script type="text/x-magento-init"> - { - "*": { - "Magento_Ui/js/listing/massaction": <?php echo $block->getConfigBuilder()->toJson($block->getConfig()); ?> - } - } -</script> -<div data-bind="scope: '<?php echo $block->getParentName(); ?>:<?php echo $block->getName(); ?>'" class="grid-actions"> - <!-- ko template: 'ui/massaction' --><!-- /ko --> -</div> diff --git a/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/page_actions.phtml b/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/page_actions.phtml deleted file mode 100644 index 1bba18bb5ff432a80fd15a98edb53ae1cbed53a3..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/page_actions.phtml +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -?> -<?php -/** - * @var \Magento\Ui\Component\MassAction $block - */ -?> -<script type="text/x-magento-init"> - { - "*": { - "Magento_Ui/js/listing/massaction": <?php echo $block->getConfigBuilder()->toJson($block->getConfig()); ?> - } - } -</script> -<div data-bind="scope: '<?php echo $block->getParentName(); ?>:<?php echo $block->getName(); ?>'"> - <!-- ko template: 'ui/pageactions' --><!-- /ko --> -</div> diff --git a/app/code/Magento/Ui/view/base/templates/paging/default.phtml b/app/code/Magento/Ui/view/base/templates/paging/default.phtml deleted file mode 100644 index 6c710bdf1b15441e91ba811da8951d3166919276..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/templates/paging/default.phtml +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -?> -<?php -/** - * @var \Magento\Ui\Component\Paging $block - */ -?> -<script type="text/x-magento-init"> - { - "*": { - "Magento_Ui/js/listing/paging": <?php echo $block->getConfigBuilder()->toJson($block->getConfig()); ?> - } - } -</script> -<div data-bind="scope: '<?php echo $block->getParentName(); ?>:<?php echo $block->getName(); ?>'" class="pager"> - <!-- ko template: 'ui/pagination' --><!-- /ko --> -</div> diff --git a/app/code/Magento/Ui/view/base/templates/sorting/default.phtml b/app/code/Magento/Ui/view/base/templates/sorting/default.phtml deleted file mode 100644 index 1b85352c82b4ee8da9e30b2847869a48d187c84a..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/templates/sorting/default.phtml +++ /dev/null @@ -1,19 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -?> -<?php -/** - * @var \Magento\Ui\Component\Sorting $block - */ - -?> -<script type="text/x-magento-init"> - { - "*": { - "Magento_Ui/js/listing/sorting": <?php echo $block->getConfigBuilder()->toJson($block->getConfig()); ?> - } - } -</script> diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml new file mode 100644 index 0000000000000000000000000000000000000000..4ebc69d2284abb3514c412081e36b0225781eb0e --- /dev/null +++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml @@ -0,0 +1,225 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../etc/ui_definition.xsd"> + <dataSource class="Magento\Ui\Component\DataSource"/> + <listing sorting="true" class="Magento\Ui\Component\Listing"> + <argument name="data" xsi:type="array"> + <item name="template" xsi:type="string">templates/listing/default</item> + <item name="save_parameters_in_session" xsi:type="string">1</item> + <item name="client_root" xsi:type="string">mui/index/render</item> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">uiComponent</item> + </item> + </argument> + </listing> + <paging class="Magento\Ui\Component\Paging"> + <argument name="data" xsi:type="array"> + <item name="template" xsi:type="string">templates/paging/default</item> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/paging</item> + </item> + </argument> + </paging> + <filters class="Magento\Ui\Component\Filters"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/filters/filters</item> + </item> + </argument> + </filters> + <filterSelect class="Magento\Ui\Component\Filters\Type\Select"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="template" xsi:type="string" translate="true">ui/grid/filters/elements/select</item> + </item> + </argument> + </filterSelect> + <filterRange class="Magento\Ui\Component\Filters\Type\Range"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/filters/group</item> + </item> + </argument> + </filterRange> + <filterInput class="Magento\Ui\Component\Filters\Type\Input"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="template" xsi:type="string">ui/grid/filters/elements/input</item> + </item> + </argument> + </filterInput> + <filterDate class="Magento\Ui\Component\Filters\Type\Date"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="template" xsi:type="string">ui/grid/filters/elements/date</item> + </item> + </argument> + </filterDate> + <container class="Magento\Ui\Component\Container"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">uiComponent</item> + </item> + </argument> + </container> + <massaction class="Magento\Ui\Component\MassAction"> + <argument name="data" xsi:type="array"> + <item name="template" xsi:type="string">templates/listingcontainer/massaction/default</item> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/massactions</item> + </item> + </argument> + </massaction> + <actions class="Magento\Ui\Component\Control\Action"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/actions</item> + </item> + </argument> + </actions> + <input class="Magento\Ui\Component\Form\Element\Input"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item> + <item name="config" xsi:type="array"> + <item name="template" xsi:type="string">ui/form/field</item> + <item name="elementTmpl" xsi:type="string">ui/form/element/input</item> + </item> + </item> + </argument> + </input> + <checkbox class="Magento\Ui\Component\Form\Element\Checkbox"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/element/boolean</item> + <item name="config" xsi:type="array"> + <item name="elementTmpl" xsi:type="string">ui/form/element/checkbox</item> + </item> + </item> + </argument> + </checkbox> + <select class="Magento\Ui\Component\Form\Element\Select"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/element/select</item> + <item name="config" xsi:type="array"> + <item name="elementTmpl" xsi:type="string">ui/form/element/select</item> + </item> + </item> + </argument> + </select> + <multiselect class="Magento\Ui\Component\Form\Element\Select"> + <argument name="data" xsi:type="array"> + <item name="template" xsi:type="string">ui/form/element/multiselect</item> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/element/multiselect</item> + <item name="config" xsi:type="array"> + <item name="elementTmpl" xsi:type="string">ui/form/element/multiselect</item> + </item> + </item> + </argument> + </multiselect> + <textarea class="Magento\Ui\Component\Form\Element\Textarea"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/element/textarea</item> + <item name="config" xsi:type="array"> + <item name="elementTmpl" xsi:type="string">ui/form/element/textarea</item> + </item> + </item> + </argument> + </textarea> + <text class="Magento\Ui\Component\Form\Element\DataType\Text"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/element/text</item> + </item> + </argument> + </text> + <number class="Magento\Ui\Component\Form\Element\DataType\Number"/> + <price class="Magento\Ui\Component\Form\Element\DataType\Price"/> + <media class="Magento\Ui\Component\Form\Element\DataType\Media"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="extends" xsi:type="string">input</item> + </item> + </argument> + </media> + <date class="Magento\Ui\Component\Form\Element\DataType\Date"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="extends" xsi:type="string">input</item> + <item name="component" xsi:type="string">Magento_Ui/js/form/element/date</item> + <item name="config" xsi:type="array"> + <item name="elementTmpl" xsi:type="string">ui/form/element/date</item> + </item> + </item> + </argument> + </date> + <boolean class="Magento\Ui\Component\Form\Element\DataType\Boolean"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="extends" xsi:type="string">input</item> + </item> + </argument> + </boolean> + <email class="Magento\Ui\Component\Form\Element\DataType\Email"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="extends" xsi:type="string">input</item> + <item name="config" xsi:type="array"> + <item name="elementTmpl" xsi:type="string">ui/form/element/email</item> + </item> + </item> + <item name="config" xsi:type="array"> + <item name="addbefore" xsi:type="string">@email:</item> + </item> + </argument> + </email> + <columns class="Magento\Ui\Component\Listing\Columns"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/listing</item> + </item> + </argument> + </columns> + <column class="Magento\Ui\Component\Listing\Columns\Column"/> + <form class="Magento\Ui\Component\Form"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/form</item> + </item> + <item name="template" xsi:type="string">templates/form/default</item> + </argument> + </form> + <fieldset class="Magento\Ui\Component\Form\Fieldset"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/components/fieldset</item> + </item> + </argument> + </fieldset> + <field class="Magento\Ui\Component\Form\Field"/> + <tab class="Magento\Ui\Component\Layout\Tabs\Tab"> + <argument name="data" xsi:type="array"> + <item name="template" xsi:type="string">templates/layout/tabs/tab/default</item> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/components/area</item> + </item> + </argument> + </tab> + <!-- navigation --> + <nav class="Magento\Ui\Component\Layout\Tabs\Nav"> + <argument name="data" xsi:type="array"> + <item name="template" xsi:type="string">ui/tab</item> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/components/tab_group</item> + </item> + </argument> + </nav> +</components> diff --git a/app/code/Magento/Ui/view/base/ui_component/templates/form/default.xhtml b/app/code/Magento/Ui/view/base/ui_component/templates/form/default.xhtml new file mode 100644 index 0000000000000000000000000000000000000000..a27dc54abfbf6c5e5faab7ddd31e8834e8705051 --- /dev/null +++ b/app/code/Magento/Ui/view/base/ui_component/templates/form/default.xhtml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<div xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../Ui/etc/ui_template.xsd"> + <div data-role="spinner" data-component="{{getName()}}.areas" class="admin__data-grid-loading-mask"> + <div class="grid-loader"></div> + </div> + <div data-bind="scope: '{{getName()}}.areas'" class="entry-edit form-inline"> + <!-- ko template: getTemplate() --><!-- /ko --> + </div> +</div> diff --git a/app/code/Magento/Ui/view/base/ui_component/templates/listing/default.xhtml b/app/code/Magento/Ui/view/base/ui_component/templates/listing/default.xhtml new file mode 100644 index 0000000000000000000000000000000000000000..c56eea763192e5ce99fa92bc376ea3a33d5f7b5d --- /dev/null +++ b/app/code/Magento/Ui/view/base/ui_component/templates/listing/default.xhtml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<div data-bind="scope: '{{getName()}}.{{getName()}}'" class="admin__data-grid-wrap" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../Ui/etc/ui_template.xsd"> + <div data-role="spinner" data-component="{{getName()}}.{{getName()}}.{{spinner}}" class="admin__data-grid-loading-mask"> + <div class="grid-loader"></div> + </div> + <!-- ko template: getTemplate() --><!-- /ko --> +</div> diff --git a/app/code/Magento/Ui/view/base/web/js/core/app.js b/app/code/Magento/Ui/view/base/web/js/core/app.js index 9e8f5be7e0165a310b5f7a0406d1717beb7dd5c9..5c4593bd486a312ecc1233c2a4cc2940d2025817 100644 --- a/app/code/Magento/Ui/view/base/web/js/core/app.js +++ b/app/code/Magento/Ui/view/base/web/js/core/app.js @@ -3,46 +3,13 @@ * See COPYING.txt for license details. */ define([ - 'underscore', - './renderer/renderer', - 'Magento_Ui/js/lib/registry/registry' -], function (_, Renderer, registry) { + './renderer/types', + './renderer/layout' +], function (types, layout) { 'use strict'; - function load(config, name){ - require([config.path], function(constr){ - registry.set(name, new constr(config)); - }); - } - - var global = { - init: function(data){ - this.data = {}; - - this.register() - .initRenderer(data.renderer) - .initProviders(data.providers) - .register(); - }, - - initRenderer: function(data){ - this.renderer = new Renderer(data); - - return this; - }, - - initProviders: function(providers){ - _.each(providers, load); - - return this; - }, - - register: function () { - registry.set('globalStorage', this); - - return this; - } + return function (data) { + types.set(data.types); + layout(data.components); }; - - return global.init.bind(global); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/core/renderer/components/layout.js b/app/code/Magento/Ui/view/base/web/js/core/renderer/components/layout.js deleted file mode 100644 index 6866bf0d0e644900b44834d5e061bd066da6bb0b..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/core/renderer/components/layout.js +++ /dev/null @@ -1,241 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'underscore', - 'jquery', - 'mage/utils', - 'Magento_Ui/js/lib/class', - 'Magento_Ui/js/lib/registry/registry' -], function(_, $, utils, Class, registry) { - 'use strict'; - - function getNodeName(parent, node, name) { - var parentName = parent && parent.name; - - if (typeof name !== 'string') { - name = node.name || name; - } - - if (parentName) { - name = parentName + '.' + name; - } - - return name; - } - - function getNodeType(parent, node){ - return node.type || (parent && parent.childType); - } - - function getDataScope(parent, node){ - var dataScope = node.dataScope, - parentScope = parent && parent.dataScope; - - return notEmpty(parentScope) ? - ( notEmpty(dataScope) ? - (parentScope + '.' + dataScope) : - parentScope ) : - (dataScope || ''); - } - - function notEmpty(value){ - return !_.isUndefined(value) && value !== ''; - } - - function mergeNode(node, config){ - return $.extend(true, {}, config, node); - } - - function additional(node){ - return _.pick(node, 'name', 'index', 'dataScope'); - } - - function loadDeps(node){ - var loaded = $.Deferred(); - - registry.get(node.deps, function(){ - loaded.resolve(node); - }); - - return loaded.promise(); - } - - function loadSource(node){ - var loaded = $.Deferred(), - source = node.component; - - require([source], function(constr){ - loaded.resolve(node, constr); - }); - - return loaded.promise(); - } - - function initComponent(node, constr){ - var component = new constr( - node.config, - additional(node) - ); - - registry.set(node.name, component); - } - - function Layout(nodes, types){ - this.types = types; - this.registry = registry.create(); - - this.run(nodes); - } - - _.extend(Layout.prototype, { - run: function(nodes, parent){ - _.each(nodes || [], this.iterator.bind(this, parent)); - - return this; - }, - - iterator: function(parent, node, name){ - var action = _.isString(node) ? - this.addChild : - this.process; - - action.apply(this, arguments); - }, - - process: function(parent, node, name) { - if(!parent && node.parent){ - return this.waitParent(node, name); - } - - if(node.template){ - return this.waitTemplate.apply(this, arguments); - } - - node = this.build.apply(this, arguments); - - if(node){ - this.addChild(parent, node.name) - .manipulate(node) - .initComponent(node) - .run(node.children, node); - } - - return this; - }, - - build: function(parent, node, name){ - var type; - - type = getNodeType.apply(null, arguments); - node = mergeNode(node, this.types.get(type)); - - node.index = node.name || name; - node.name = getNodeName(parent, node, name); - node.dataScope = getDataScope(parent, node); - - delete node.type; - - this.registry.set(node.name, node); - - return node.isTemplate ? - (node.isTemplate = false) : - node; - }, - - initComponent: function(node){ - if(!node.component){ - return this; - } - - loadDeps(node) - .then(loadSource) - .done(initComponent); - - return this; - } - }); - - _.extend(Layout.prototype, { - waitTemplate: function(parent, node, name){ - var args = _.toArray(arguments); - - this.registry.get(node.template, function(){ - this.applyTemplate.apply(this, args); - }.bind(this)); - - return this; - }, - - waitParent: function(node, name){ - var process = this.process.bind(this); - - this.registry.get(node.parent, function(parent){ - process(parent, node, name); - }); - - return this; - }, - - applyTemplate: function(parent, node, name){ - var template = this.registry.get(node.template); - - node = mergeNode(node, template); - - delete node.template; - - this.process(parent, node, name); - } - }); - - _.extend(Layout.prototype, { - manipulate: function(node) { - var name = node.name; - - if (node.appendTo) { - this.insert(name, node.appendTo, -1); - } - - if (node.prependTo) { - this.insert(name, node.prependTo, 0); - } - - if(node.insertTo){ - this.insertTo(name, node.insertTo); - } - - return this; - }, - - insert: function(item, target, position){ - registry.get(target, function(target){ - target.insert(item, position); - }); - - return this; - }, - - insertTo: function(item, targets){ - _.each(targets, function(info, target){ - this.insert(item, target, info.position); - }, this); - - return this; - }, - - addChild: function(parent, child){ - if(parent && parent.component){ - this.insert(child, parent.name); - } - - return this; - }, - - clear: function(name){ - this.registry.remove(name); - } - }); - - return Layout; -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/core/renderer/components/types.js b/app/code/Magento/Ui/view/base/web/js/core/renderer/components/types.js deleted file mode 100644 index 461bd8332cfd43a8ac96b4caf3c11acfcd19daf5..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/core/renderer/components/types.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'underscore', - 'jquery', - 'mage/utils', - 'Magento_Ui/js/lib/class', - 'Magento_Ui/js/lib/registry/registry' -], function(_, $, utils, Class, registry) { - 'use strict'; - - return Class.extend({ - initialize: function(types){ - this.types = {}; - - this.set(types); - - return this; - }, - - set: function(types){ - types = types || []; - - _.each(types, function(data, type){ - this.types[type] = this.flatten(data); - }, this); - }, - - get: function(type){ - return this.types[type] || {}; - }, - - flatten: function(data){ - var extender = data.extends || [], - result = {}; - - extender = utils.stringToArray(extender); - - extender.push(data); - - extender.forEach(function(item){ - if(_.isString(item)){ - item = this.get(item); - } - - $.extend(true, result, item); - }, this); - - delete result.extends; - - return result - } - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js b/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js new file mode 100644 index 0000000000000000000000000000000000000000..aac43507a35b6725c750624d7635461f88d89763 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js @@ -0,0 +1,230 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + 'jquery', + 'mageUtils', + 'uiRegistry', + './types' +], function (_, $, utils, registry, types) { + 'use strict'; + + var templates = registry.create(), + layout = {}; + + function getNodeName(parent, node, name) { + var parentName = parent && parent.name; + + if (typeof name !== 'string') { + name = node.name || name; + } + + return utils.fullPath(parentName, name); + } + + function getNodeType(parent, node) { + return node.type || parent && parent.childType; + } + + function getDataScope(parent, node) { + var dataScope = node.dataScope, + parentScope = parent && parent.dataScope; + + return !utils.isEmpty(parentScope) ? + !utils.isEmpty(dataScope) ? + parentScope + '.' + dataScope : + parentScope : + dataScope || ''; + } + + function loadDeps(node) { + var loaded = $.Deferred(); + + registry.get(node.deps, function () { + loaded.resolve(node); + }); + + return loaded.promise(); + } + + function loadSource(node) { + var loaded = $.Deferred(), + source = node.component; + + require([source], function (constr) { + loaded.resolve(node, constr); + }); + + return loaded.promise(); + } + + function initComponent(node, Constr) { + var component = new Constr(_.omit(node, 'children')); + + registry.set(node.name, component); + } + + function run(nodes, parent) { + _.each(nodes || [], layout.iterator.bind(layout, parent)); + } + + _.extend(layout, { + iterator: function (parent, node) { + var action = _.isString(node) ? + this.addChild : + this.process; + + action.apply(this, arguments); + }, + + process: function (parent, node, name) { + if (!parent && node.parent) { + return this.waitParent(node, name); + } + + if (node.template) { + return this.waitTemplate.apply(this, arguments); + } + + node = this.build.apply(this, arguments); + + if (node) { + this.addChild(parent, node) + .manipulate(node) + .initComponent(node); + + run(node.children, node); + } + + return this; + }, + + build: function (parent, node, name) { + var defaults = parent && parent.childDefaults || {}, + children = node.children, + type = getNodeType(parent, node); + + node.children = false; + + node = utils.extend({ + }, types.get(type), defaults, node); + + _.extend(node, node.config || {}, { + index: node.name || name, + name: getNodeName(parent, node, name), + dataScope: getDataScope(parent, node) + }); + + node.children = children; + + delete node.type; + delete node.config; + + if (node.isTemplate) { + node.isTemplate = false; + + templates.set(node.name, node); + + return false; + } + + return node; + }, + + initComponent: function (node) { + if (!node.component) { + return this; + } + + loadDeps(node) + .then(loadSource) + .done(initComponent); + + return this; + } + }); + + _.extend(layout, { + waitTemplate: function (parent, node) { + var args = _.toArray(arguments); + + templates.get(node.template, function () { + this.applyTemplate.apply(this, args); + }.bind(this)); + + return this; + }, + + waitParent: function (node, name) { + var process = this.process.bind(this); + + registry.get(node.parent, function (parent) { + process(parent, node, name); + }); + + return this; + }, + + applyTemplate: function (parent, node, name) { + var template = templates.get(node.template); + + node = utils.extend({}, template, node); + + delete node.template; + + this.process(parent, node, name); + } + }); + + _.extend(layout, { + manipulate: function (node) { + var name = node.name; + + if (node.appendTo) { + this.insert(name, node.appendTo, -1); + } + + if (node.prependTo) { + this.insert(name, node.prependTo, 0); + } + + if (node.insertTo) { + this.insertTo(name, node.insertTo); + } + + return this; + }, + + insert: function (item, target, position) { + registry.get(target, function (container) { + container.insert(item, position); + }); + + return this; + }, + + insertTo: function (item, targets) { + _.each(targets, function (info, target) { + this.insert(item, target, info.position); + }, this); + + return this; + }, + + addChild: function (parent, child) { + var name; + + if (parent && parent.component) { + name = child.name || child; + + this.insert(name, parent.name, child.sortOrder); + } + + return this; + } + }); + + return run; +}); diff --git a/app/code/Magento/Ui/view/base/web/js/core/renderer/renderer.js b/app/code/Magento/Ui/view/base/web/js/core/renderer/renderer.js deleted file mode 100644 index 5b7de47144ebb0ca7da594aa157c507540f2c0c9..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/core/renderer/renderer.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - './components/types', - './components/layout', - 'Magento_Ui/js/lib/class' -], function(Types, Layout, Class){ - 'use strict'; - - return Class.extend({ - initialize: function(data){ - this.types = new Types(data.types); - this.layout = new Layout(data.layout, this.types); - - return this; - }, - - render: function(data){ - this.layout.run(data.layout); - this.types.set(data.types); - } - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/core/renderer/types.js b/app/code/Magento/Ui/view/base/web/js/core/renderer/types.js new file mode 100644 index 0000000000000000000000000000000000000000..2975abbcdbe3bc86b3edcd1938735fd9b20cc0d3 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/core/renderer/types.js @@ -0,0 +1,49 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + 'mageUtils' +], function (_, utils) { + 'use strict'; + + var store = {}; + + function flatten(data) { + var extender = data.extends || [], + result = {}; + + extender = utils.stringToArray(extender); + + extender.push(data); + + extender.forEach(function (item) { + if (_.isString(item)) { + item = store[item] || {}; + } + + utils.extend(result, item); + }); + + delete result.extends; + + return result; + } + + return { + set: function (types) { + types = types || {}; + + utils.extend(store, types); + + _.each(types, function (data, type) { + store[type] = flatten(data); + }); + }, + + get: function (type) { + return store[type] || {}; + } + }; +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form.js b/app/code/Magento/Ui/view/base/web/js/form.js deleted file mode 100644 index ef54b43da90399b6894c697e2f49cb46795af55a..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/form.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'jquery', - 'underscore', - 'Magento_Ui/js/form/component', - 'Magento_Ui/js/lib/spinner', - './form/adapter' -], function ($, _, Component, loader, adapter) { - 'use strict'; - - function collectData(selector) { - var data = $(selector).serializeArray(), - result = {}; - - data.forEach(function (item) { - result[item.name] = item.value; - }); - - return result; - } - - return Component.extend({ - - initialize: function(){ - this._super() - .initAdapter() - .initSelector() - .hideLoader(); - - return this; - }, - - initAdapter: function(){ - adapter.on({ - 'reset': this.reset.bind(this), - 'save': this.save.bind(this, true), - 'saveAndContinue': this.save.bind(this, false) - }); - - return this; - }, - - initSelector: function(){ - this.selector = '[data-form-part='+ this.namespace +']'; - - return this; - }, - - hideLoader: function () { - loader.get(this.name).hide(); - - return this; - }, - - save: function(redirect){ - var params = this.provider.params; - - this.validate(); - - if (!params.get('invalid')) { - this.submit(redirect); - } - }, - - /** - * Submits form - */ - submit: function (redirect) { - var additional = collectData(this.selector), - provider = this.provider; - - _.each(additional, function(value, name){ - provider.data.set(name, value); - }); - - provider.save({ - redirect: redirect - }); - }, - - /** - * Validates each element and returns true, if all elements are valid. - */ - validate: function () { - var provider = this.provider; - - provider.params.set('invalid', false); - provider.data.trigger('validate'); - }, - - reset: function(){ - var data = this.provider.data; - - data.trigger('reset'); - } - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/form/client.js b/app/code/Magento/Ui/view/base/web/js/form/client.js index 4526c775a39f69a51f1b93ac16d92153aff0182c..c8750c3129530719b24d7d8f3d8b4c4fc11b705e 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/client.js +++ b/app/code/Magento/Ui/view/base/web/js/form/client.js @@ -5,21 +5,19 @@ define([ 'jquery', 'underscore', - 'mage/utils', + 'mageUtils', 'Magento_Ui/js/lib/class' -], function($, _, utils, Class){ +], function ($, _, utils, Class) { 'use strict'; - - var defaults = {}; - function beforeSave(data, url){ + function beforeSave(data, url) { var save = $.Deferred(); - + data = utils.serialize(data); data.form_key = FORM_KEY; - - if(!url){ + + if (!url) { save.resolve(); } @@ -28,12 +26,12 @@ define([ $.ajax({ url: url, data: data, - success: function(resp){ - if(!resp.error){ + success: function (resp) { + if (!resp.error) { save.resolve(); } }, - complete: function(){ + complete: function () { $('body').trigger('processStop'); } }); @@ -46,8 +44,8 @@ define([ * Initializes DataProvider instance. * @param {Object} settings - Settings to initialize object with. */ - initialize: function(config) { - _.extend(this, defaults, config); + initialize: function (config) { + _.extend(this, config); return this; }, @@ -55,32 +53,32 @@ define([ /** * Assembles data and submits it using 'utils.submit' method */ - save: function(data, options){ - var url = this.urls.beforeSave, - save = this._save.bind(this, data, options); + save: function (data, options) { + var url = this.urls.beforeSave, + save = this._save.bind(this, data, options); beforeSave(data, url).then(save); return this; }, - _save: function(data, options){ + _save: function (data, options) { var url = this.urls.save; options = options || {}; data.form_key = FORM_KEY; - if(!options.redirect){ + if (!options.redirect) { url += 'back/edit'; } utils.submit({ - url: url, - data: data + url: url, + data: data }); return this; } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/component.js b/app/code/Magento/Ui/view/base/web/js/form/component.js deleted file mode 100644 index 5b207bfc22205f174d739688231dd187caa24fcd..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/form/component.js +++ /dev/null @@ -1,473 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'underscore', - 'mage/utils', - 'Magento_Ui/js/lib/ko/scope', - 'Magento_Ui/js/lib/events', - 'Magento_Ui/js/lib/registry/registry' -], function(_, utils, Scope, EventsBus, registry) { - 'use strict'; - - function getOffsetFor(elems, offset){ - if(typeof offset === 'undefined'){ - offset = -1; - } - - if(offset < 0){ - offset += elems.length + 1; - } - - return offset; - } - - function getProxy(callback, data){ - if(_.isArray(data)){ - data = { - additional: data - } - } - - _.defaults(data, { - conditions: '*', - additional: [], - callback: callback - }); - - return proxy.bind(null, data); - } - - function proxy(data, value){ - var conditions = data.conditions, - args; - - if(conditions === value || conditions === '*'){ - args = data.additional.slice(); - - args.push(value); - - data.callback.apply(null, args); - } - } - - function parseSource(source, storages, data){ - var storage; - - source = utils.template(source, data); - source = source.split(':'); - - storage = source.shift(); - - return { - source: source[0], - storage: storages[storage] - } - } - - var Component = Scope.extend({ - initialize: function(config, additional){ - _.extend(this, config, additional); - - _.bindAll(this, '_insert'); - - this.initProperties() - .initObservable() - .initListeners() - .initUnique(); - - return this; - }, - - /** - * Defines various properties. - * - * @returns {Component} Chainable. - */ - initProperties: function () { - _.extend(this,{ - 'parentName': this.getPart(this.name, -2), - 'parentScope': this.getPart(this.dataScope, -2), - 'provider': registry.get(this.provider), - 'renderer': registry.get('globalStorage').renderer, - 'containers': [], - 'regions': [], - '_elems': [] - }); - - return this; - }, - - /** - * Initializes observable properties. - * - * @returns {Component} Chainable. - */ - initObservable: function(){ - this.observe({ - 'elems': [] - }); - - this.regions.forEach(function(region){ - this.observe(region, []); - }, this); - - return this; - }, - - /** - * Initializes storages listeners. - * - * @returns {Component} Chainable. - */ - initListeners: function(){ - var listeners = this.listeners || {}, - params, - iterator; - - _.each(listeners, function(handlers, source){ - params = parseSource(source, this.provider, this); - iterator = this.initListener.bind(this, params); - - _.each(handlers, iterator); - }, this); - - return this; - }, - - /** - * Initializes listeners of the unique property. - * - * @returns {Component} Chainable. - */ - initUnique: function(){ - var update = this.onUniqueUpdate.bind(this), - params = this.provider.params, - uniqueNs = this.uniqueNs; - - this.hasUnique = this.uniqueProp && uniqueNs; - - if(this.hasUnique){ - params.on('update:' + uniqueNs, update, this.name); - } - - return this; - }, - - /** - * Used as iterator for the listeners object. - * Creates callbacks and assigns it to the specified storage. - * - * @param {Object} data - - Data object that contains storage object and - it's property name that should be listened. - * @param {Object} params - Parameters of the callback. - * @param {String} callback - Callback's name. - */ - initListener: function(data, params, callback){ - var storage = data.storage, - source = data.source; - - callback = this[callback].bind(this); - callback = getProxy(callback, params); - - callback(storage.get(source)); - - storage.on('update:' + source, callback, this.name); - }, - - /** - * Called when current element was injected to another component. - * - * @param {Object} parent - Instance of a 'parent' component. - * @returns {Component} Chainable. - */ - initContainer: function(parent){ - this.containers.push(parent); - - return this; - }, - - /** - * Called when another element was added to current component. - * - * @param {Object} elem - Instance of an element that was added. - * @returns {Component} Chainable. - */ - initElement: function(elem){ - elem.initContainer(this); - - return this; - }, - - /** - * Splits incoming string and returns its' part specified by offset. - * - * @param {String} parts - * @param {Number} [offset] - * @param {String} [delimiter=.] - * @returns {String} - */ - getPart: function(parts, offset, delimiter){ - delimiter = delimiter || '.'; - parts = parts.split(delimiter); - offset = getOffsetFor(parts, offset); - - parts.splice(offset, 1); - - return parts.join(delimiter) || ''; - }, - - /** - * Returns path to components' template. - * @returns {String} - */ - getTemplate: function(){ - return this.template || 'ui/collection'; - }, - - /** - * Updates property specified in uniqueNs - * if components' unique property is set to 'true'. - * - * @returns {Component} Chainable. - */ - setUnique: function () { - var params = this.provider.params, - property = this.uniqueProp; - - if (this[property]()) { - params.set(this.uniqueNs, this.name); - } - - return this; - }, - - /** - * Callback which fires when property under uniqueNs has changed. - */ - onUniqueUpdate: function(name){ - var active = name === this.name, - property = this.uniqueProp; - - this[property](active); - } - }, EventsBus); - - - /** - * Elements manipulation methods. - */ - _.extend(Component.prototype, { - /** - * Requests specified components to insert - * them into 'elems' array starting from provided position. - * - * @param {String} elem - Name of the component to insert. - * @param {Number} [offset=-1] - Position at which to insert elements. - * @returns {Component} Chainable. - */ - insert: function(elem, offset){ - var _elems = this._elems, - insert = this._insert; - - offset = getOffsetFor(_elems, offset); - - _elems.splice(offset, 0, false); - - registry.get(elem, function(elem){ - insert(elem, offset); - }); - - return this; - }, - - /** - * Removes specified element from the 'elems' array. - * - * @param {Object} elem - Element to be removed. - * @returns {Component} Chainable. - */ - remove: function(elem) { - utils.remove(this._elems, elem); - this._update(); - - return this; - }, - - /** - * Destroys current instance along with all of its' children. - */ - destroy: function(){ - this._dropHandlers() - ._clearData() - ._clearRefs(); - }, - - /** - * Removes events listeners. - * @private - * - * @returns {Component} Chainable. - */ - _dropHandlers: function(){ - var provider = this.provider; - - this.off(); - - provider.data.off(this.name); - provider.params.off(this.name); - - return this; - }, - - /** - * Clears all data associated with component. - * @private - * - * @returns {Component} Chainable. - */ - _clearData: function(){ - var provider = this.provider, - layout = this.renderer.layout; - - provider.data.remove(this.dataScope); - provider.params.remove(this.name); - - layout.clear(this.name); - - return this; - }, - - /** - * Removes all references to current instance and - * calls 'destroy' method on all of its' children. - * @private - * - * @returns {Component} Chainable. - */ - _clearRefs: function(){ - registry.remove(this.name); - - this.containers.forEach(function(parent){ - parent.remove(this); - }, this); - - this.elems().forEach(function(child){ - child.destroy(); - }); - - return this; - }, - - /** - * Inserts provided component into 'elems' array at a specified position. - * @private - * - * @param {Object} elem - Element to insert. - * @param {Number} index - Position of the element. - */ - _insert: function(elem, index){ - this._elems[index] = elem; - - this._update() - .initElement(elem); - }, - - /** - * Synchronizes multiple elements arrays with a core '_elems' container. - * Performs elemets grouping by theirs 'displayArea' property. - * @private - * - * @returns {Component} Chainable. - */ - _update: function(){ - var _elems = _.compact(this._elems), - grouped = _.groupBy(_elems, 'displayArea'), - group; - - this.regions.forEach(function(region) { - if ((group = grouped[region])) { - this[region](group); - } - }, this); - - this.elems(_elems); - - return this; - }, - }); - - - /** - * Elements traversing methods. - */ - _.extend(Component.prototype, { - /** - * Tries to call specified method of a current component, - * otherwise delegates attempt to its' children. - * - * @param {String} target - Name of the method. - * @param [...] Arguments that will be passed to method. - * @returns {*} Result of the method calls. - */ - delegate: function(target){ - var args = _.toArray(arguments); - - target = this[target]; - - if(_.isFunction(target)){ - return target.apply(this, args.slice(1)); - } - - return this._delegate(args); - }, - - /** - * Calls 'delegate' method of all of it's children components. - * @private - * - * @param {Array} args - An array of arguments to pass to the next delegation call. - * @returns {Array} An array of delegation resutls. - */ - _delegate: function(args){ - var result; - - result = this.elems.map(function(elem){ - return elem.delegate.apply(elem, args); - }); - - return _.flatten(result); - }, - - /** - * Overrides 'EventsBus.trigger' method to implement events bubbling. - * - * @param {String} name - Name of the event. - * @param [...] Any number of arguments that should be to the events' handler. - * @returns {Boolean} False if event bubbling was canceled. - */ - trigger: function(){ - var args = _.toArray(arguments), - bubble = EventsBus.trigger.apply(this, args), - result; - - if(!bubble){ - return false; - } - - this.containers.forEach(function(parent) { - result = parent.trigger.apply(parent, args); - - if (result === false) { - bubble = false; - } - }); - - return !!bubble; - } - }); - - return Component; -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/area.js b/app/code/Magento/Ui/view/base/web/js/form/components/area.js index 387260f10e1b0bca802a1965641edb123e77c1b4..b9d2884597e2c30884226894c3d44e4f194c6918 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/area.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/area.js @@ -5,12 +5,12 @@ define([ 'underscore', './tab' -], function(_, Tab) { +], function (_, Tab) { 'use strict'; return Tab.extend({ defaults: { - uniqueNs: 'activeArea', + uniqueNs: 'params.activeArea', template: 'ui/area', changed: false, loading: false @@ -20,7 +20,7 @@ define([ * Extends instance with defaults. Invokes parent initialize method. * Calls initListeners and pushParams methods. */ - initialize: function() { + initialize: function () { _.bindAll(this, 'onChildrenUpdate', 'onContentLoading', 'onContentLoaded'); return this._super(); @@ -31,7 +31,7 @@ define([ * Defines observable properties of instance. * @return {Object} - reference to instance */ - initObservable: function() { + initObservable: function () { this._super() .observe('changed loading'); @@ -44,7 +44,7 @@ define([ * @param {Object} elem * @return {Object} - reference to instance */ - initElement: function(elem){ + initElement: function (elem) { this._super(); elem.on({ @@ -61,11 +61,11 @@ define([ * Sets changed property to one incoming. * Invokes setActive method if settings * contain makeVisible property set to true. - * - * @param {Boolean} changed + * + * @param {Boolean} hasChanged */ - onChildrenUpdate: function(hasChanged){ - if(!hasChanged){ + onChildrenUpdate: function (hasChanged) { + if (!hasChanged) { hasChanged = _.some(this.delegate('hasChanged')); } @@ -75,15 +75,15 @@ define([ /** * Callback that sets loading property to true. */ - onContentLoading: function(){ + onContentLoading: function () { this.loading(true); }, /** * Callback that sets loading property to true. */ - onContentLoaded: function(){ + onContentLoaded: function () { this.loading(false); } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/collection.js b/app/code/Magento/Ui/view/base/web/js/form/components/collection.js index 0dd910f3e3ca37a6ab59212125cf0b3dfa16c7f4..5835bb0b486a089e6b1e56ba27597ce6c20c9680 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/collection.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/collection.js @@ -4,17 +4,18 @@ */ define([ 'underscore', - 'mage/utils', - 'Magento_Ui/js/lib/registry/registry', - 'Magento_Ui/js/form/component', -], function (_, utils, registry, Component) { + 'mageUtils', + 'uiRegistry', + 'uiComponent', + 'Magento_Ui/js/core/renderer/layout' +], function (_, utils, registry, Component, layout) { 'use strict'; var childTemplate = { - template: "{name}.{itemTemplate}", - parent: "{name}", - name: "{childIndex}", - dataScope: "{childIndex}" + template: '<%= $data.name %>.<%= $data.itemTemplate %>', + parent: '<%= $data.name %>', + name: '<%= $data.childIndex %>', + dataScope: '<%= name %>' }; return Component.extend({ @@ -39,7 +40,7 @@ define([ * * @param {Object} elem - Incoming child. */ - initElement: function(elem) { + initElement: function (elem) { this._super(); elem.activate(); @@ -55,12 +56,11 @@ define([ * * @returns {Collection} Chainable. */ - initChildren: function() { - var data = this.provider.data, - children = data.get(this.dataScope), - initial = this.initialItems = []; + initChildren: function () { + var children = this.source.get(this.dataScope), + initial = this.initialItems = []; - _.each(children, function(item, index) { + _.each(children, function (item, index) { initial.push(index); this.addChild(index); }, this); @@ -74,16 +74,12 @@ define([ * @param {String|Object} [index] - Index of a child. * @returns {Collection} Chainable. */ - addChild: function(index) { + addChild: function (index) { this.childIndex = !_.isString(index) ? - ('new_' + this.lastIndex++) : + 'new_' + this.lastIndex++ : index; - this.renderer.render({ - layout: [ - utils.template(childTemplate, this) - ] - }); + layout([utils.template(childTemplate, this)]); return this; }, @@ -94,12 +90,12 @@ define([ * * @returns {Boolean} */ - hasChanged: function(){ + hasChanged: function () { var initial = this.initialItems, current = this.elems.pluck('index'), changed = !utils.identical(initial, current); - return changed || this.elems.some(function(elem){ + return changed || this.elems.some(function (elem) { return _.some(elem.delegate('hasChanged')); }); }, @@ -109,12 +105,12 @@ define([ * * @returns {Array} An array of validation results. */ - validate: function(){ + validate: function () { var elems; this.allValid = true; - elems = this.elems.sortBy(function(elem){ + elems = this.elems.sortBy(function (elem) { return !elem.active(); }); @@ -130,23 +126,23 @@ define([ * @param {Object} elem - Element to run validation on. * @returns {Array} An array of validation results. */ - _validate: function(elem){ + _validate: function (elem) { var result = elem.delegate('validate'), invalid; - invalid = _.some(result, function(item){ + invalid = _.some(result, function (item) { return !item.valid; }); - if(this.allValid && invalid){ + if (this.allValid && invalid) { this.allValid = false; elem.activate(); } - return result; + return result; }, - + /** * Creates function that removes element * from collection using '_removeChild' method. @@ -155,15 +151,12 @@ define([ * Since this method is used by 'click' binding, * it requires function to invoke. */ - removeChild: function(elem) { - return function() { - var confirmed = confirm(this.removeMessage); - - if (confirmed) { - this._removeChild(elem); - } + removeChild: function (elem) { + var confirmed = confirm(this.removeMessage); - }.bind(this); + if (confirmed) { + this._removeChild(elem); + } }, /** @@ -173,7 +166,7 @@ define([ * * @param {Object} elem - Element to remove. */ - _removeChild: function(elem) { + _removeChild: function (elem) { var isActive = elem.active(), first; @@ -189,4 +182,3 @@ define([ } }); }); - diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/collection/item.js b/app/code/Magento/Ui/view/base/web/js/form/components/collection/item.js index 44413dd4555972fc7b8f86323921d10d04584640..d8b4bf4cc4192fe038f7d1c74c00af1f23f4daa6 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/collection/item.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/collection/item.js @@ -4,7 +4,7 @@ */ define([ 'underscore', - 'mage/utils', + 'mageUtils', '../tab' ], function (_, utils, Tab) { 'use strict'; @@ -16,12 +16,12 @@ define([ /** * Parses incoming data and returnes result merged with default preview config - * + * * @param {Object|String} data * @return {Object} */ - function parsePreview(data){ - if (typeof data === 'string') { + function parsePreview(data) { + if (typeof data == 'string') { data = { items: data }; @@ -34,10 +34,9 @@ define([ return Tab.extend({ defaults: { - template: 'ui/form/components/collection/item', - label: '', - uniqueNs: 'activeCollectionItem', - previewTpl: 'ui/form/components/collection/preview' + label: '', + uniqueNs: 'activeCollectionItem', + previewTpl: 'ui/form/components/collection/preview' }, /** @@ -50,25 +49,23 @@ define([ }, /** - * Calls initProperties of parent class, initializes properties - * of instance - * + * Calls initProperties of parent class, initializes properties + * of instance. + * * @return {Object} - reference to instance */ initProperties: function () { this._super(); this.displayed = []; - - utils.add(this.regions, 'body', 'head'); return this; }, /** * Calls initObservable of parent class, initializes observable - * properties of instance - * + * properties of instance. + * * @return {Object} - reference to instance */ initObservable: function () { @@ -76,7 +73,7 @@ define([ this.observe({ 'noPreview': true, - 'indexed': {} + 'indexed': {} }); return this; @@ -98,73 +95,76 @@ define([ /** * Adds element to observable indexed object of instance - * + * * @param {Object} elem * @return {Object} - reference to instance */ insertToIndexed: function (elem) { var indexed = this.indexed(); - + indexed[elem.index] = elem; this.indexed(indexed); - + return this; }, /** - * Formats incoming previews array via parsePreview function - * + * Formats incoming previews array via parsePreview function. + * * @param {Array} previews * @return {Array} - formatted previews */ - formatPreviews: function(previews){ + formatPreviews: function (previews) { return previews.map(parsePreview); }, /** * Creates string view of previews - * + * * @param {Object} data * @return {Strict} - formatted preview string */ - buildPreview: function(data){ + buildPreview: function (data) { var preview = this.getPreview(data.items), - prefix = data.prefix; + prefix = data.prefix; return prefix + preview.join(data.separator); }, /** * Defines if instance has preview for incoming data - * + * * @param {Object} data * @return {Boolean} */ - hasPreview: function(data){ + hasPreview: function (data) { return !!this.getPreview(data.items).length; }, /** * Creates an array of previews for elements specified in incoming * items array, calls updatePreview afterwards. - * + * * @param {Array} items - An array of element's indexes. * @returns {Array} An array of previews. */ - getPreview: function(items){ - var elems = this.indexed(), - displayed = this.displayed, + getPreview: function (items) { + var elems = this.indexed(), + displayed = this.displayed, preview; - items = items.map(function(index){ + items = items.map(function (index) { var elem = elems[index]; - preview = elem ? elem.delegate('getPreview') : []; - preview = _.compact(preview).join(', '); + preview = elem ? elem.delegate('getPreview') : ''; + + preview = Array.isArray(preview) ? + _.compact(preview).join(', ') : + preview; utils.toggle(displayed, index, !!preview); - + return preview; }); @@ -173,4 +173,4 @@ define([ return _.compact(items); } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js index 752a678fc72fe58805fe89e38696d144fa1881aa..2369c3740f4688f8116628a1cb561170342c544b 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js @@ -3,13 +3,15 @@ * See COPYING.txt for license details. */ define([ - './collapsible' -], function(Collapsible) { + 'Magento_Ui/js/lib/collapsible' +], function (Collapsible) { 'use strict'; return Collapsible.extend({ defaults: { - template: 'ui/fieldset/fieldset' + template: 'ui/form/fieldset', + collapsible: false, + opened: true } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/group.js b/app/code/Magento/Ui/view/base/web/js/form/components/group.js index 2a23cb48a54da5f3e6d2764a39554a4558691928..325e4e0f4295e06d3326d94d75ab08573db58d99 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/group.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/group.js @@ -4,45 +4,25 @@ */ define([ 'underscore', - '../component', - 'mage/utils' -], function(_, Component, utils) { + 'uiComponent' +], function (_, Component) { 'use strict'; - - function extractData(container, field){ - var data, - value; - - container.some(function(item){ - value = item[field]; - - if(_.isFunction(value)){ - value = value(); - } - - return !item.hidden() && (data = value); - }); - - return data || ''; - } return Component.extend({ defaults: { - hidden: false, - label: '', - required: false, - template: 'ui/group/group', - fieldTemplate: 'ui/group/field', - breakLine: true + hidden: false, + label: '', + required: false, + template: 'ui/group/group', + fieldTemplate: 'ui/form/field', + breakLine: true }, /** * Extends this with defaults and config. * Then calls initObservable, iniListenes and extractData methods. - * - * @param {Object} config */ - initialize: function() { + initialize: function () { _.bindAll(this, 'toggle'); return this._super(); @@ -51,12 +31,12 @@ define([ /** * Calls initObservable of parent class. * Defines observable properties of instance. - * + * * @return {Object} - reference to instance */ - initObservable: function(){ + initObservable: function () { this._super() - .observe('hidden label required'); + .observe('hidden required'); return this; }, @@ -64,41 +44,25 @@ define([ /** * Assignes onUpdate callback to update event of incoming element. * Calls extractData method. - * @param {Object} element + * @param {Object} elem * @return {Object} - reference to instance */ - initElement: function(elem){ + initElement: function (elem) { this._super(); elem.on({ 'toggle': this.toggle }); - this.extractData(); - - return this; - }, - - /** - * Extracts label and required properties from child elements - * - * @return {Object} - reference to instance - */ - extractData: function(){ - var elems = this.elems(); - - this.label(extractData(elems, 'label')); - this.required(extractData(elems, 'required')); - return this; }, /** * Sets incoming value to hidden observable, calls extractData method - * + * * @param {Boolean} value */ - toggle: function(value){ + toggle: function (value) { this.extractData() .hidden(value); }, @@ -119,4 +83,4 @@ define([ return this.elems.getLength() > 1; } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/html.js b/app/code/Magento/Ui/view/base/web/js/form/components/html.js index d9dd813981d5f03ea6abbaca1deef638664b6bed..e8cf03cc4e1bc266f16987cf65a653842f8b432b 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/html.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/html.js @@ -5,8 +5,8 @@ define([ 'jquery', 'underscore', - '../component' -], function($, _, Component) { + 'uiComponent' +], function ($, _, Component) { 'use strict'; return Component.extend({ @@ -14,14 +14,17 @@ define([ content: '', showSpinner: false, loading: false, - template: 'ui/content/content' + template: 'ui/content/content', + listens: { + loading: 'toggleLoadState' + } }, /** * Extends instance with default config, calls 'initialize' method of * parent, calls 'initAjaxConfig' */ - initialize: function() { + initialize: function () { _.bindAll(this, 'onContainerToggle', 'onDataLoaded'); this._super() @@ -32,33 +35,18 @@ define([ /** * Calls 'initObservable' method of parent, initializes observable - * properties of instance - * + * properties of instance + * * @return {Object} - reference to instance */ - initObservable: function() { + initObservable: function () { this._super() .observe('content loading'); return this; }, - /** - * Calls 'initListeners' method of parent, defines instance's subscriptions - * - * @return {Object} - reference to instance - */ - initListeners: function() { - this._super(); - - this.loading.subscribe(function(value) { - this.trigger(value ? 'loading' : 'loaded'); - }, this); - - return this; - }, - - initContainer: function(parent) { + initContainer: function (parent) { this._super(); parent.on('active', this.onContainerToggle); @@ -68,13 +56,15 @@ define([ /** * Initializes default ajax config on instance - * + * * @return {Object} - reference to instance */ - initAjaxConfig: function(){ + initAjaxConfig: function () { this.ajaxConfig = { - url: this.source, - data: { FORM_KEY: FORM_KEY }, + url: this.url, + data: { + FORM_KEY: FORM_KEY + }, success: this.onDataLoaded }; @@ -83,40 +73,44 @@ define([ /** * Calls 'loadData' if both 'active' variable and 'shouldLoad' - * property are truthy - * + * property are truthy + * * @param {Boolean} active */ - onContainerToggle: function(active) { + onContainerToggle: function (active) { if (active && this.shouldLoad()) { this.loadData(); } }, + toggleLoadState: function (value) { + this.trigger(value ? 'loading' : 'loaded'); + }, + /** - * Defines if instance has 'content' property defined - * + * Defines if instance has 'content' property defined. + * * @return {Boolean} [description] */ - hasData: function() { + hasData: function () { return !!this.content(); }, /** * Defines if instance should load external data - * + * * @return {Boolean} */ - shouldLoad: function() { - return this.source && !this.hasData() && !this.loading(); + shouldLoad: function () { + return this.url && !this.hasData() && !this.loading(); }, /** * Sets loading property to true, makes ajax call - * + * * @return {Object} - reference to instance */ - loadData: function() { + loadData: function () { this.loading(true); $.ajax(this.ajaxConfig); @@ -126,25 +120,25 @@ define([ /** * Ajax's request success handler. Calls 'updateContent' passing 'data' - * to it, then sets 'loading' property to false - * + * to it, then sets 'loading' property to false. + * * @param {String} data */ - onDataLoaded: function(data) { + onDataLoaded: function (data) { this.updateContent(data) .loading(false); }, /** * Sets incoming data 'content' property's value - * + * * @param {String} content * @return {Object} - reference to instance */ - updateContent: function(content) { + updateContent: function (content) { this.content(content); return this; } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/tab.js b/app/code/Magento/Ui/view/base/web/js/form/components/tab.js index c15e513883219106dfc7639dcf7b6ef6fc41a38e..61560892e3e9ddd8dc3885644eb3d874a50ea9fb 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/tab.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/tab.js @@ -3,8 +3,8 @@ * See COPYING.txt for license details. */ define([ - '../component' -], function(Component) { + 'uiComponent' +], function (Component) { 'use strict'; return Component.extend({ @@ -18,7 +18,7 @@ define([ * Extends instance with defaults. Invokes parent initialize method. * Calls initListeners and pushParams methods. */ - initialize: function() { + initialize: function () { this._super() .setUnique(); }, @@ -28,29 +28,29 @@ define([ * Defines observable properties of instance. * @return {Object} - reference to instance */ - initObservable: function() { + initObservable: function () { this._super() .observe('active wasActivated'); return this; }, - - onUniqueUpdate: function(name){ + + onUniqueUpdate: function (name) { var active = name === this.name; this._super(); this.trigger('active', active); }, - + /** * Sets active property to true, then invokes pushParams method. */ - activate: function(){ + activate: function () { this.active(true); this.wasActivated(true); this.setUnique(); } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/tab_group.js b/app/code/Magento/Ui/view/base/web/js/form/components/tab_group.js index 625d2ba848c6bfd0c60d6453e3835fb072dd0748..474814559d3cae9f0f364bdf593332ecb12654bb 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/tab_group.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/tab_group.js @@ -4,12 +4,18 @@ */ define([ 'underscore', - './collapsible', - 'Magento_Ui/js/lib/spinner' -], function(_, Collapsible, loader) { + 'Magento_Ui/js/lib/collapsible' +], function (_, Collapsible) { 'use strict'; - + return Collapsible.extend({ + defaults: { + listens: { + '<%= provider %>:data.validate': 'onValidate' + }, + collapsible: false, + opened: true + }, /** * Invokes initElement method of parent class, calls 'initActivation' method @@ -17,27 +23,10 @@ define([ * @param {Object} elem * @returns {Object} - reference to instance */ - initElement: function(elem){ + initElement: function (elem) { this._super() - .initActivation(elem) - .hideLoader(); - - return this; - }, - - /** - * Binds 'onValidate' method as handler for data storage's 'validate' event - * - * @return {Object} - reference to instance - */ - initListeners: function(){ - var data = this.provider.data, - handler = this.onValidate.bind(this); - - this._super(); + .initActivation(elem); - data.on('validate', handler, this.name); - return this; }, @@ -48,40 +37,36 @@ define([ * @param {Object} elem * @returns {Object} - reference to instance */ - initActivation: function(elem){ + initActivation: function (elem) { var elems = this.elems(), isFirst = !elems.indexOf(elem); - if(isFirst || elem.active()){ + if (isFirst || elem.active()) { elem.activate(); } return this; }, - hideLoader: function () { - loader.get(this.name).hide(); - }, - /** * Delegates 'validate' method on element, then reads 'invalid' property - * of params storage, and if defined, activates element, sets + * of params storage, and if defined, activates element, sets * 'allValid' property of instance to false and sets invalid's * 'focused' property to true. * * @param {Object} elem */ - validate: function(elem){ - var params = this.provider.params, + validate: function (elem) { + var source = this.source, result = elem.delegate('validate'), invalid = false; - _.some(result, function(item){ + _.some(result, function (item) { return !item.valid && (invalid = item.target); }); - if (invalid && !params.get('invalid')) { - params.set('invalid', invalid); + if (invalid && !source.get('params.invalid')) { + source.set('params.invalid', true); elem.activate(); invalid.focused(true); @@ -90,16 +75,16 @@ define([ /** * Sets 'allValid' property of instance to true, then calls 'validate' method - * of instance for each element + * of instance for each element. */ - onValidate: function(){ + onValidate: function () { var elems; - elems = this.elems.sortBy(function(elem){ + elems = this.elems.sortBy(function (elem) { return !elem.active(); - }); + }); - elems.each(this.validate, this); + elems.forEach(this.validate, this); } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index e1d66754af6285e4a6938ca4f878a3a2b7fdca3d..1e5f1168ffbe0fd7c4ba037f65fe91f53f35bee8 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -4,59 +4,69 @@ */ define([ 'underscore', - 'mage/utils', - 'Magento_Ui/js/form/component', + 'mageUtils', + 'uiComponent', 'Magento_Ui/js/lib/validation/validator' ], function (_, utils, Component, validator) { 'use strict'; - - /** - * Checks wether the incoming value is not empty, - * e.g. not 'null' or 'undefined' - * - * @param {*} value - Value to check. - * @returns {Boolean} - */ - function isEmpty(value){ - return _.isUndefined(value) || _.isNull(value); - } return Component.extend({ defaults: { - hidden: false, - preview: '', - focused: false, - required: false, - disabled: false, - tmpPath: 'ui/form/element/', - tooltipTpl: 'ui/form/element/helper/tooltip', - input_type: 'input', - placeholder: '', - description: '', - label: '', - error: '', - notice: '' + visible: true, + preview: '', + focused: false, + required: false, + disabled: false, + tmpPath: 'ui/form/element/', + tooltipTpl: 'ui/form/element/helper/tooltip', + input_type: 'input', + placeholder: '', + description: '', + label: '', + error: '', + notice: '', + + listens: { + value: 'onUpdate', + visible: 'setPreview', + '<%= provider %>:data.reset': 'reset', + '<%= provider %>:data.validate': 'validate' + }, + + links: { + value: '<%= provider %>:<%= dataScope %>' + }, + + exports: { + visible: '<%= provider %>:config.<%= name %>.visible' + }, + + imports: { + setPreview: '<%= name %>:value' + } }, /** * Invokes initialize method of parent class, contains initialization * logic - * + * * @param {Object} config - form element configuration */ initialize: function () { - _.bindAll(this, 'onUpdate', 'reset'); + _.bindAll(this, 'reset'); + + this._super(); + + this.initialValue = this.getInititalValue(); - this._super() - .setHidden(this.hidden()) - .store(this.value()); + this.value(this.initialValue); return this; }, /** * Initializes observable properties of instance - * + * * @returns {Abstract} Chainable. */ initObservable: function () { @@ -64,11 +74,8 @@ define([ this._super(); - this.initialValue = this.getInititalValue(); - - this.observe('error disabled focused preview hidden') + this.observe('error disabled focused preview visible') .observe({ - 'value': this.initialValue, 'required': !!rules['required-entry'] }); @@ -77,7 +84,7 @@ define([ /** * Initializes regular properties of instance. - * + * * @returns {Abstract} Chainable. */ initProperties: function () { @@ -86,87 +93,37 @@ define([ this._super(); _.extend(this, { - 'uid': uid, - 'noticeId': 'notice-' + this.uid, - 'inputName': utils.serializeName(this.dataScope) - }); - - _.defaults(this, { - 'template': this.tmpPath + this.input_type + 'uid': uid, + 'noticeId': 'notice-' + uid, + 'inputName': utils.serializeName(this.dataScope) }); return this; }, - /** - * Initializes instance's listeners. - * - * @returns {Abstract} Chainable. - */ - initListeners: function(){ - var provider = this.provider, - data = provider.data; - - this._super(); - - data.on('reset', this.reset, this.name); - - this.value.subscribe(this.onUpdate); - - return this; - }, - /** * Gets initial value of element - * + * * @returns {*} Elements' value. */ - getInititalValue: function(){ - var data = this.provider.data, - values = [data.get(this.dataScope), this.default], + getInititalValue: function () { + var values = [this.value(), this.default], value; - values.some(function(v){ - return !isEmpty(value = v); + values.some(function (v) { + return !utils.isEmpty(value = v); }); - return isEmpty(value) ? '': value; + return utils.isEmpty(value) ? '' : value; }, /** * Sets value to preview observable - * + * * @returns {Abstract} Chainable. */ - setPreview: function(value){ - this.preview(this.hidden() ? '' : value); - - return this; - }, - - /** - * Returnes unwrapped preview observable. - * - * @returns {String} Value of the preview observable. - */ - getPreview: function(){ - return this.preview(); - }, - - /** - * Calls 'setHidden' passing true to it. - */ - hide: function(){ - this.setHidden(true); - - return this; - }, - - /** - * Calls 'setHidden' passing false to it. - */ - show: function(){ - this.setHidden(false); + setPreview: function (value) { + this.preview(!this.visible() ? '' : value); return this; }, @@ -175,25 +132,29 @@ define([ * Sets 'value' as 'hidden' propertie's value, triggers 'toggle' event, * sets instance's hidden identifier in params storage based on * 'value'. - * + * * @returns {Abstract} Chainable. */ - setHidden: function(isHidden){ - var params = this.provider.params; - - this.hidden(isHidden); - - this.setPreview(this.value()) - .trigger('toggle', isHidden); + setVisible: function (isVisible) { + this.visible(isVisible); - params.set(this.name + '.hidden', isHidden); + this.trigger('toggle', isVisible); return this; }, + /** + * Returnes unwrapped preview observable. + * + * @returns {String} Value of the preview observable. + */ + getPreview: function () { + return this.preview(); + }, + /** * Checkes if element has addons - * + * * @returns {Boolean} */ hasAddons: function () { @@ -205,29 +166,20 @@ define([ * * @returns {Boolean} */ - hasChanged: function(){ + hasChanged: function () { var notEqual = this.value() != this.initialValue; - return this.hidden() ? false : notEqual; + return !this.visible() ? false : notEqual; }, - /** - * Stores element's value to registry by element's path value - * @param {*} value - current value of form element - * @returns {Abstract} Chainable. - */ - store: function (value) { - var data = this.provider.data; - - data.set(this.dataScope, value); - - return this; + hasData: function () { + return !utils.isEmpty(this.value()); }, /** * Sets value observable to initialValue property. */ - reset: function(){ + reset: function () { this.value(this.initialValue); }, @@ -235,18 +187,18 @@ define([ * Validates itself by it's validation rules using validator object. * If validation of a rule did not pass, writes it's message to * 'error' observable property. - * + * * @returns {Boolean} True, if element is invalid. */ validate: function () { - var value = this.value(), - msg = validator(this.validation, value), - isValid = this.hidden() || !msg; + var value = this.value(), + msg = validator(this.validation, value), + isValid = !this.visible() || !msg; this.error(msg); return { - valid: isValid, + valid: isValid, target: this }; }, @@ -254,12 +206,10 @@ define([ /** * Callback that fires when 'value' property is updated. */ - onUpdate: function (value) { - this.store(value) - .setPreview(value) - .trigger('update', this.hasChanged()); + onUpdate: function () { + this.trigger('update', this.hasChanged()); this.validate(); } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/boolean.js b/app/code/Magento/Ui/view/base/web/js/form/element/boolean.js index 8b13f063ce2052649d4c0ce6c335e1d43b6c5063..4782c853d210b11696c71f31d8d855a8e64eb4b0 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/boolean.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/boolean.js @@ -10,28 +10,26 @@ define([ return Abstract.extend({ /** * Converts the result of parent 'getInitialValue' call to boolean - * + * * @return {Boolean} */ - getInititalValue: function(){ + getInititalValue: function () { return !!+this._super(); }, /** * Calls 'store' method of parent, if value is defined and instance's * 'unique' property set to true, calls 'setUnique' method - * + * * @param {*} value * @return {Object} - reference to instance */ - store: function() { - this._super(); - + onUpdate: function () { if (this.hasUnique) { this.setUnique(); } - return this; + return this._super(); } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/date.js b/app/code/Magento/Ui/view/base/web/js/form/element/date.js index 6e53005137b69fac101db602d58b930d24c24473..4943d845c0504730963115b9bee9e6187e4f72e4 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/date.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/date.js @@ -4,13 +4,21 @@ */ define([ 'moment', + 'mageUtils', './abstract' -], function (moment, Abstract) { +], function (moment, utils, Abstract) { 'use strict'; return Abstract.extend({ defaults: { - dateFormat: 'MM/DD/YYYY' + dateFormat: 'MM/DD/YYYY', + options: {} + }, + + initProperties: function () { + this.dateFormat = utils.normalizeDate(this.dateFormat); + + return this._super(); }, /** diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/multiselect.js b/app/code/Magento/Ui/view/base/web/js/form/element/multiselect.js index 1afc75a8837ef240151de7f884dc8cef07ae2fdb..a6dc9e3b3afe600527a5b0fd470b05547b955789 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/multiselect.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/multiselect.js @@ -4,7 +4,7 @@ */ define([ 'underscore', - 'mage/utils', + 'mageUtils', './select' ], function (_, utils, Select) { 'use strict'; @@ -17,10 +17,10 @@ define([ /** * Calls 'getInitialValue' of parent and if the result of it is not empty * string, returs it, else returnes caption or first found option's value - * + * * @returns {Number|String} */ - getInititalValue: function(){ + getInititalValue: function () { var value = this._super(); return _.isString(value) ? value.split(',') : value; @@ -31,7 +31,7 @@ define([ * @returns {Boolean} */ hasChanged: function () { - var value = this.value(), + var value = this.value(), initial = this.initialValue; return !utils.identical(value, initial); diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/post-code.js b/app/code/Magento/Ui/view/base/web/js/form/element/post-code.js index 066d99b1d21078ebe36d2bf12077a15643ce002d..97cb38dcbb07b9aa0018cb54f6535f2c6a2c8c3c 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/post-code.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/post-code.js @@ -4,62 +4,37 @@ */ define([ 'underscore', - 'Magento_Ui/js/lib/registry/registry', + 'uiRegistry', './abstract' ], function (_, registry, Abstract) { 'use strict'; return Abstract.extend({ - /** - * Extended list of Listeners - * - * @return {this} - */ - initListeners: function () { - this._super() - .update() - .provider.data.on('update:' + this.parentScope + '.country_id', this.update.bind(this)); - - return this; + defaults: { + imports: { + update: '<%= parentName %>.country_id:value' + } }, - /** - * Fix _postcode_ depend on _country_id_ change: - * - If country in list "Zip/Postal Code is Optional countries" then - * - field "postcode" should not be required - * - * @returns {this} - */ - update: function () { - var parentScope = this.getPart(this.getPart(this.name, -2), -2), - option, - postcode = this; - - registry.get(parentScope + '.country_id.0', function (countryComponent) { - var value = countryComponent.value(); - - if (!value) { // empty value discard logic - return; - } + update: function (value) { + var country = registry.get(this.parentName + '.' + 'country_id'), + options = country.indexedOptions, + option; - countryComponent - .options() - .some(function (el) { - option = el; + if (!value) { + return; + } - return el.value === value; - }); + option = options[value]; - if (!option.is_region_required) { - postcode.error(false); - postcode.validation = _.omit(postcode.validation, 'required-entry'); - } else { - postcode.validation['required-entry'] = true; - } - postcode.required(!!option.is_region_required); - }); + if (!option.is_region_required) { + this.error(false); + this.validation = _.omit(this.validation, 'required-entry'); + } else { + this.validation['required-entry'] = true; + } - return this; + this.required(!!option.is_region_required); } }); }); diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/select.js b/app/code/Magento/Ui/view/base/web/js/form/element/select.js index bd2e6d6d13ca04562b5cfe2472ff119ac00c9d54..2dd476c24a50aaadee6dd7484f8d23c8f329a63f 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/select.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/select.js @@ -4,44 +4,37 @@ */ define([ 'underscore', - 'mage/utils', - './abstract' -], function (_, utils, Abstract) { + 'mageUtils', + 'uiRegistry', + './abstract', + 'Magento_Ui/js/core/renderer/layout' +], function (_, utils, registry, Abstract, layout) { 'use strict'; var inputNode = { - name: '{index}_input', - type: 'input', - parent: '{parentName}', - dataScope: '{customEntry}', - config: { - hidden: true, - label: '{label}', - listeners: { - "params:{parentName}.{index}.hidden":{ - "hide": { - "conditions": false - }, - "show": { - "conditions": true - } - } - } - } + parent: '<%= $data.parentName %>', + type: 'form.input', + name: '<%= $data.index %>_input', + dataScope: '<%= $data.customEntry %>', + sortOrder: { + after: '<%= $data.name %>' + }, + displayArea: 'body', + label: '<%= $data.label %>' }; /** * Parses incoming options, considers options with undefined value property * as caption - * + * * @param {Array} nodes * @return {Object} */ - function parseOptions(nodes){ + function parseOptions(nodes) { var caption, value; - nodes = _.map(nodes, function(node) { + nodes = _.map(nodes, function (node) { value = node.value; if (value == null || value === '') { @@ -55,24 +48,24 @@ define([ return { options: _.compact(nodes), - caption: caption + caption: caption || false }; } /** * Recursively loops over data to find non-undefined, non-array value - * + * * @param {Array} data * @return {*} - first non-undefined value in array */ - function findFirst(data){ + function findFirst(data) { var value; - data.some(function(node){ + data.some(function (node) { value = node.value; - if(Array.isArray(value)){ - value = findFirst(value); + if (Array.isArray(value)) { + value = findFirst(value); } return !_.isUndefined(value); @@ -81,9 +74,27 @@ define([ return value; } + function indexOptions(data, result) { + var value; + + result = result || {}; + + data.forEach(function (item) { + value = item.value; + + if (Array.isArray(value)) { + indexOptions(value, result); + } else { + result[value] = item; + } + }); + + return result; + } + return Abstract.extend({ defaults: { - template: 'ui/form/element/select' + customName: '<%= parentName %>.<%= index %>_input' }, /** @@ -91,24 +102,47 @@ define([ * and options, and invokes initialize method of AbstractElement class. * If instance's 'customEntry' property is set to true, calls 'initInput' */ - initialize: function (config) { - this.initOptions(config) - ._super(); - - if(this.customEntry){ + initialize: function () { + this._super(); + + if (this.customEntry) { this.initInput(); } + if (this.filterBy) { + this.initFilter(); + } + + return this; + }, + + /** + * Parses options and merges the result with instance + * + * @param {Object} config + * @returns {Select} Chainable. + */ + initConfig: function (config) { + var result = parseOptions(config.options); + + if (config.caption) { + delete result.caption; + } + + _.extend(config, result); + + this._super(); + return this; }, /** * Calls 'initObservable' of parent, initializes 'options' and 'initialOptions' * properties, calls 'setOptions' passing options to it - * + * * @returns {Select} Chainable. */ - initObservable: function(){ + initObservable: function () { this._super(); this.initialOptions = this.options; @@ -119,31 +153,23 @@ define([ return this; }, - /** - * Parses options and merges the result with instance - * - * @param {Object} config - * @returns {Select} Chainable. - */ - initOptions: function(config){ - var result = parseOptions(config.options); + initFilter: function () { + var filter = this.filterBy; - _.extend(config, result); + this.setLinks({ + filter: filter.target + }, 'imports'); return this; }, /** * Creates input from template, renders it via renderer. - * + * * @returns {Select} Chainable. */ - initInput: function(){ - this.renderer.render({ - layout: [ - utils.template(inputNode, this) - ] - }); + initInput: function () { + layout([utils.template(inputNode, this)]); return this; }, @@ -151,54 +177,67 @@ define([ /** * Calls 'getInitialValue' of parent and if the result of it is not empty * string, returs it, else returnes caption or first found option's value - * + * * @returns {Number|String} */ - getInititalValue: function(){ + getInititalValue: function () { var value = this._super(); - if(value !== ''){ + if (value !== '') { return value; } - - if(!this.caption){ + + if (!this.caption) { return findFirst(this.options); } }, /** * Filters 'initialOptions' property by 'field' and 'value' passed, - * calls 'setOptions' passing the result to it - * - * @param {String} field + * calls 'setOptions' passing the result to it + * * @param {*} value + * @param {String} field */ - filter: function(field, value){ + filter: function (value, field) { var source = this.initialOptions, result; - result = _.filter(source, function(item){ + field = field || this.filterBy.field; + + result = _.filter(source, function (item) { return item[field] === value; }); this.setOptions(result); }, + toggleInput: function (isVisible) { + registry.get(this.customName, function (input) { + input.setVisible(isVisible); + }); + }, + /** - * Sets 'data' to 'options' observable array, if instance has + * Sets 'data' to 'options' observable array, if instance has * 'customEntry' property set to true, calls 'setHidden' method * passing !options.length as a parameter - * + * * @param {Array} data * @returns {Select} Chainable. */ - setOptions: function(data){ - this.indexedOptions = _.indexBy(data, 'value'); + setOptions: function (data) { + var isVisible; + + this.indexedOptions = indexOptions(data); this.options(data); - - if(this.customEntry){ - this.setHidden(!data.length); + + if (this.customEntry) { + isVisible = !!data.length; + + this.setVisible(isVisible); + this.toggleInput(!isVisible); } return this; @@ -207,17 +246,17 @@ define([ /** * Processes preview for option by it's value, and sets the result * to 'preview' observable - * + * * @param {String} value * @returns {Select} Chainable. */ - setPreview: function(value){ - var option = this.indexedOptions[value], + setPreview: function (value) { + var option = this.indexedOptions[value], preview = option ? option.label : ''; - + this.preview(preview); return this; } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/textarea.js b/app/code/Magento/Ui/view/base/web/js/form/element/textarea.js index a575e352e6ffcbdce395b56b78cb722123c8f3b8..ebd8a85fac67c2c055c0c1a1ee47ebc1bfb9a93c 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/textarea.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/textarea.js @@ -14,4 +14,4 @@ define([ template: 'ui/form/element/textarea' } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/form.js b/app/code/Magento/Ui/view/base/web/js/form/form.js new file mode 100644 index 0000000000000000000000000000000000000000..2a192c20c2463e29397750f0ade0e147ac0d80bd --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/form/form.js @@ -0,0 +1,95 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + 'uiComponent', + 'Magento_Ui/js/lib/spinner', + './adapter' +], function (_, Component, loader, adapter) { + 'use strict'; + + function collectData(selector) { + var items = document.querySelectorAll(selector), + result = {}; + + items = Array.prototype.slice.call(items); + + items.forEach(function (item) { + result[item.name] = item.value; + }); + + return result; + } + + return Component.extend({ + initialize: function () { + this._super() + .initAdapter() + .hideLoader(); + + return this; + }, + + initAdapter: function () { + adapter.on({ + 'reset': this.reset.bind(this), + 'save': this.save.bind(this, true), + 'saveAndContinue': this.save.bind(this, false) + }); + + return this; + }, + + initProperties: function () { + this._super(); + + this.selector = '[data-form-part=' + this.namespace + ']'; + + return this; + }, + + hideLoader: function () { + loader.get(this.name).hide(); + + return this; + }, + + save: function (redirect) { + this.validate(); + + if (!this.source.get('params.invalid')) { + this.submit(redirect); + } + }, + + /** + * Submits form + */ + submit: function (redirect) { + var additional = collectData(this.selector), + source = this.source; + + _.each(additional, function (value, name) { + source.set('data.' + name, value); + }); + + source.save({ + redirect: redirect + }); + }, + + /** + * Validates each element and returns true, if all elements are valid. + */ + validate: function () { + this.source.set('params.invalid', false); + this.source.trigger('data.validate'); + }, + + reset: function () { + this.source.trigger('data.reset'); + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/provider.js b/app/code/Magento/Ui/view/base/web/js/form/provider.js index ccf45e2f2f0fdb55efd2f1285b3b0081912551a0..c388763fc4ce7b25cc535cfcbdba5419ccbd0e03 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/provider.js +++ b/app/code/Magento/Ui/view/base/web/js/form/provider.js @@ -4,72 +4,36 @@ */ define([ 'underscore', - './client', - './storages', - 'Magento_Ui/js/lib/registry/registry', - 'Magento_Ui/js/lib/class', - 'Magento_Ui/js/lib/events', -], function(_, Client, storages, registry, Class, EventsBus){ + 'Magento_Ui/js/lib/provider', + './client' +], function (_, Provider, Client) { 'use strict'; - - var defaults = { - stores: ['data', 'params'] - }; - return Class.extend({ - /** - * Initializes DataProvider instance. - * @param {Object} settings - Settings to initialize object with. - */ - initialize: function(settings) { - _.extend(this, defaults, settings, settings.config || {}); - - this.initStorages() + return Provider.extend({ + initialize: function () { + this._super() .initClient(); - }, - - /** - * Creates instances of storage objects. - * @returns {DataProvider} Chainable. - */ - initStorages: function() { - var storage, - config; - - this.stores.forEach(function(store) { - storage = storages[store]; - config = this[store] || {}; - - if(Array.isArray(config)){ - config = {}; - } - - this[store] = new storage(config); - }, this); return this; }, - initClient: function(){ + initClient: function () { this.client = new Client({ urls: { - beforeSave: this.validate_url, - save: this.submit_url - } + beforeSave: this.data.validate_url, + save: this.data.submit_url + } }); return this; }, - /** - * Assembles data and submits it using 'utils.submit' method - */ - save: function(options){ - var data = this.data.get(); - + save: function (options) { + var data = this.get('data'); + this.client.save(data, options); return this; } - }, EventsBus); -}); \ No newline at end of file + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/storages.js b/app/code/Magento/Ui/view/base/web/js/form/storages.js deleted file mode 100644 index 9eba0b970be472943833cdaa2286c1ab29abbe85..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/form/storages.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -/** - * Assembles storages for form provider - */ -define([ - 'Magento_Ui/js/lib/storage/storage' -], function(Storage){ - 'use strict'; - - return { - meta: Storage, - params: Storage, - data: Storage, - dump: Storage - } -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js new file mode 100644 index 0000000000000000000000000000000000000000..33a095e64e806024affa49638b9fe8bb40566e79 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js @@ -0,0 +1,27 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + './column' +], function (_, Column) { + 'use strict'; + + return Column.extend({ + defaults: { + headerTmpl: 'ui/grid/columns/actions', + bodyTmpl: 'ui/grid/cells/actions' + }, + + getDisplayed: function (actions) { + actions = _.filter(actions, function (action) { + return !('hidden' in action) || !action.hidden; + }); + + this.displayed = actions; + + return actions; + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/column.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/column.js new file mode 100644 index 0000000000000000000000000000000000000000..dd91490b300a037bb258775ffdd39f15f5900a52 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/column.js @@ -0,0 +1,53 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'uiComponent' +], function (Component) { + 'use strict'; + + return Component.extend({ + defaults: { + headerTmpl: 'ui/grid/columns/text', + bodyTmpl: 'ui/grid/cells/text', + sortable: false, + visible: true, + defaultVisible: '<%= visible %>', + imports: { + visible: '<%= provider %>:config.columns.<%= index %>.visible' + } + }, + + resetVisible: function () { + this.visible(this.defaultVisible); + }, + + getClickUrl: function (row) { + var field = row[this.actionField], + action = field && field[this.clickAction]; + + return action ? action.href : ''; + }, + + isClickable: function (row) { + return !!this.getClickUrl(row); + }, + + redirect: function (url) { + window.location.href = url; + }, + + getLabel: function (data) { + return data; + }, + + getHeader: function () { + return this.headerTmpl; + }, + + getBody: function () { + return this.bodyTmpl; + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/date.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/date.js new file mode 100644 index 0000000000000000000000000000000000000000..0e319022a8b040491976c758cc2476c5286af112 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/date.js @@ -0,0 +1,27 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'mageUtils', + 'moment', + './sortable' +], function (utils, moment, Sortable) { + 'use strict'; + + return Sortable.extend({ + defaults: { + dateFormat: 'MMM D, YYYY h:mm:ss A' + }, + + initProperties: function () { + this.dateFormat = utils.normalizeDate(this.dateFormat); + + return this._super(); + }, + + getLabel: function (data) { + return moment(data).format(this.dateFormat); + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js new file mode 100644 index 0000000000000000000000000000000000000000..a88d981dac96cee9b0538a52732252ba27fb0ac1 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js @@ -0,0 +1,331 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + 'mage/translate', + './column' +], function (_, $t, Column) { + 'use strict'; + + return Column.extend({ + defaults: { + headerTmpl: 'ui/grid/columns/multiselect', + bodyTmpl: 'ui/grid/cells/multiselect', + menuVisible: false, + excludeMode: false, + allSelected: false, + indetermine: false, + selected: [], + excluded: [], + ns: '<%= provider %>:params', + actions: [{ + value: 'selectAll', + label: $t('Select all') + }, { + value: 'deselectAll', + label: $t('Deselect all') + }, { + value: 'selectPage', + label: $t('Select all on this page') + }, { + value: 'deselectPage', + label: $t('Deselect all on this page') + }], + + imports: { + totalRecords: '<%= provider %>:data.totalRecords', + rows: '<%= provider %>:data.items' + }, + + listens: { + '<%= ns %>.applyFilters': 'deselectAll', + selected: 'onSelectedChange', + rows: 'onRowsChange' + } + }, + + /** + * Initializes observable properties. + * + * @returns {Multiselect} Chainable. + */ + initObservable: function () { + this._super() + .observe([ + 'menuVisible', + 'selected', + 'excluded', + 'excludeMode', + 'totalSelected', + 'allSelected', + 'indetermine' + ]); + + return this; + }, + + /** + * Toggles menu with a list of select actions. + */ + toggleMenu: function () { + this.menuVisible(!this.menuVisible()); + }, + + /** + * Hides menu with a list of select actions. + */ + hideMenu: function () { + this.menuVisible(false); + }, + + /** + * Selects all grid records, even those that are not visible on the page. + */ + selectAll: function () { + this.excludeMode(true); + + this.clearExcluded() + .selectPage(); + + return this; + }, + + /** + * Deselects all grid records. + */ + deselectAll: function () { + this.excludeMode(false); + + this.clearExcluded() + .deselectPage(); + this.selected.removeAll(); + + return this; + }, + + /** + * Selects or deselects all records. + */ + toggleSelectAll: function () { + return this.allSelected() ? + this.deselectAll() : + this.selectAll(); + }, + + /** + * Selects all records on the current page. + */ + selectPage: function () { + this.selected( + _.union(this.selected(), this.getIds()) + ); + + return this; + }, + + /** + * Deselects all records on the current page. + */ + deselectPage: function () { + var currentPageIds = this.getIds(); + this.selected.remove(function (value) { + return currentPageIds.indexOf(value) !== -1; + }); + + return this; + }, + + /** + * Clears the array of not selected records. + * + * @returns {Multiselect} Chainable. + */ + clearExcluded: function () { + this.excluded.removeAll(); + + return this; + }, + + /** + * Retrieve all id's from available records. + * + * @param {Boolean} [exclude] - Whether to exclude not selected ids' from result. + * @returns {Array} An array of ids'. + */ + getIds: function (exclude) { + var items = this.rows(), + ids = _.pluck(items, this.indexField); + + return exclude ? + _.difference(ids, this.excluded()) : + ids; + }, + + /** + * Recalculates list of the excluded records. + * Changes value of `excluded`. + * + * @param {Array} selected - List of the currently selected records. + * @returns {Multiselect} Chainable. + */ + updateExcluded: function (selected) { + var excluded = this.excluded(), + fromPage = _.difference(this.getIds(), selected); + + excluded = _.union(excluded, fromPage); + excluded = _.difference(excluded, selected); + + this.excluded(excluded); + + return this; + }, + + /** + * Calculates number of the selected records. + * Changes value of `totalSelected`. + * + * @returns {Multiselect} Chainable. + */ + countSelected: function () { + var total = this.totalRecords(), + excluded = this.excluded().length, + selected = this.selected().length; + + if (this.excludeMode()) { + selected = total - excluded; + } + + this.totalSelected(selected); + + return this; + }, + + /** + * Exports selections to the data provider. + */ + exportSelections: function () { + var data = {}, + type; + + type = this.excludeMode() ? 'excluded' : 'selected'; + + data[type] = this[type](); + data.total = this.totalSelected(); + + this.source.set('config.multiselect', data); + }, + + /** + * Defines if provided select/deselect action is relevant. + * + * @param {String} actionId - Id of the action to be checked. + * @returns {Boolean} + */ + isActionRelevant: function (actionId) { + var pageIds = this.getIds().length, + multiplePages = pageIds < this.totalRecords(); + + switch (actionId) { + case 'selectPage': + + return multiplePages && !this.isPageSelected(true); + + case 'deselectPage': + + return multiplePages && this.isPageSelected(); + + case 'selectAll': + + return !this.allSelected(); + + case 'deselectAll': + + return this.totalSelected() > 0; + } + + return true; + }, + + /** + * Defines if current page has selected records on it. + * + * @param {Boolean} [all=false] - If set to 'true' checks that every + * record on the page is selected. Otherwise checks that + * page has some selected records. + * @returns {Boolean} + */ + isPageSelected: function (all) { + var pageIds = this.getIds(), + selected = this.selected(), + excluded = this.excluded(), + iterator = all ? 'every' : 'some'; + + if (this.allSelected()) { + return true; + } + + if (this.excludeMode()) { + return pageIds[iterator](function (id) { + return !~excluded.indexOf(id); + }); + } + + return pageIds[iterator](function (id) { + return !!~selected.indexOf(id); + }); + }, + + /** + * Updates values of the 'allSelected' + * and 'indetermine' properties. + */ + updateState: function () { + var selected = this.selected().length, + excluded = this.excluded().length, + totalSelected = this.totalSelected(), + totalRecords = this.totalRecords(), + allSelected = totalRecords && totalSelected === totalRecords; + + if (this.excludeMode()) { + if (excluded === totalRecords) { + this.deselectAll(); + } + } else if (totalRecords && selected === totalRecords) { + this.selectAll(); + } + + this.allSelected(allSelected); + this.indetermine(totalSelected > 0 && !allSelected); + + return this; + }, + + /** + * Callback method to handle change of the selected items. + * + * @param {Array} selected - List of the currently selected items. + */ + onSelectedChange: function (selected) { + this.updateExcluded(selected) + .countSelected() + .updateState() + .exportSelections(); + }, + + /** + * Is invoked when rows has changed. Recalculates selected items + * based on "selectMode" property. + */ + onRowsChange: function () { + var newSelected; + + if (this.excludeMode()) { + newSelected = _.union(this.getIds(true), this.selected()); + + this.selected(newSelected); + } + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/select.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/select.js new file mode 100644 index 0000000000000000000000000000000000000000..75acdbca9c150981798d0d689a75c0beae1e13d8 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/select.js @@ -0,0 +1,24 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + './sortable' +], function (Sortable) { + 'use strict'; + + return Sortable.extend({ + getLabel: function (data) { + var options = this.options || [], + label = ''; + + options.some(function (item) { + label = item.label; + + return item.value == data; + }); + + return label; + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/sortable.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/sortable.js new file mode 100644 index 0000000000000000000000000000000000000000..6e4221ae565fcb0718211fed3c81ef518cbe4dc5 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/sortable.js @@ -0,0 +1,76 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + './column' +], function (Column) { + 'use strict'; + + return Column.extend({ + defaults: { + sortable: true, + sorting: false, + classes: { + 'asc': '_ascend', + 'desc': '_descend' + }, + listens: { + '<%= provider %>:params.sorting.field': 'onSortChange', + sorting: 'setSortClass push' + } + }, + + initObservable: function () { + this._super() + .observe('sorting sortClass'); + + this.setSortClass(this.sorting()); + + return this; + }, + + sort: function (enabled) { + var direction; + + direction = enabled !== false ? + this.sorting() ? + this.toggleDirection() : + 'asc' : + false; + + this.sorting(direction); + }, + + push: function (sorting) { + if (!sorting) { + return; + } + + this.source.set('params.sorting', { + field: this.index, + direction: sorting + }); + + this.source.reload(); + }, + + toggleDirection: function () { + return this.sorting() === 'asc' ? + 'desc' : + 'asc'; + }, + + setSortClass: function (sorting) { + var sortClass = this.classes[sorting] || ''; + + this.sortClass(sortClass); + }, + + onSortChange: function (field) { + if (field !== this.index) { + this.sort(false); + } + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/controls/columns.js b/app/code/Magento/Ui/view/base/web/js/grid/controls/columns.js new file mode 100644 index 0000000000000000000000000000000000000000..c46a1b81cf6e3bac1c6da0a38f749baefd1d74f0 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/controls/columns.js @@ -0,0 +1,115 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'mageUtils', + 'mage/translate', + 'underscore', + 'Magento_Ui/js/lib/collapsible' +], function (utils, $t, _, Collapsible) { + 'use strict'; + + return Collapsible.extend({ + defaults: { + template: 'ui/grid/controls/columns', + viewportSize: 18, + viewportMaxSize: 30 + }, + + /** + * Action Reset + */ + reset: function () { + this.delegate('resetVisible'); + }, + + /** + * Action Apply + */ + apply: function () { + var data = {}, + current; + + this.close(); + + current = this.source.get('config.columns') || {}; + + this.elems().forEach(function (elem) { + data[elem.index] = { + visible: elem.visible() + }; + }); + + utils.extend(current, data); + + this.source.store('config.columns', current); + }, + + /** + * Action Cancel + */ + cancel: function () { + var previous = this.source.get('config.columns'), + config; + + this.close(); + + if (!previous) { + return; + } + + this.elems().forEach(function (elem) { + config = previous[elem.index] || {}; + + elem.visible(config.visible); + }); + }, + + /** + * Helper, wich helps to stop resizing and + * @returns {Boolean} + */ + hasOverflow: function () { + return this.elems().length > this.viewportSize; + }, + + /** + * Helper, checks + * - if less than one item choosen + * - if more then viewportMaxSize choosen + * @param {Object} elem + * @returns {Boolean} + */ + isDisabled: function (elem) { + var count = this.countVisible(), + isLast = elem.visible() && count === 1, + isTooMuch = count > this.viewportMaxSize; + + return isLast || isTooMuch; + }, + + /** + * Helper, returns number of visible checkboxes + * @returns {Number} + */ + countVisible: function () { + return this.elems().filter(function (elem) { + return elem.visible(); + }).length; + }, + + /** + * Compile header message from headerMessage setting. + * Expects Underscore template format + * @param {String} text - underscore-format template + * @returns {String} + */ + getHeaderMessage: function (text) { + return _.template(text)({ + visible: this.countVisible(), + total: this.elems().length + }); + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/controls/view.js b/app/code/Magento/Ui/view/base/web/js/grid/controls/view.js new file mode 100644 index 0000000000000000000000000000000000000000..4ad292e5801d2c2b96ec491265d8bc68013a297d --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/controls/view.js @@ -0,0 +1,24 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'Magento_Ui/js/lib/collapsible' +], function (Collapsible) { + 'use strict'; + + return Collapsible.extend({ + defaults: { + template: 'ui/grid/controls/view', + sampleData: [{ + label: 'Cameras' + }, { + label: 'Products by weight' + }, { + label: 'Greg\'s view' + }, { + label: 'Default View' + }] + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js new file mode 100644 index 0000000000000000000000000000000000000000..e196cfad0db8d89c98de0e003961d90b7a28d8ab --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js @@ -0,0 +1,76 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + 'Magento_Ui/js/lib/collapsible' +], function (_, Collapsible) { + 'use strict'; + + function extractPreview(elem) { + return { + label: elem.label, + preview: elem.delegate('getPreview'), + elem: elem + }; + } + + function hasData(elem) { + return elem.delegate('hasData'); + } + + function resetValue(elem) { + return elem.delegate('reset'); + } + + return Collapsible.extend({ + defaults: { + template: 'ui/grid/filters/filters', + listens: { + active: 'extractPreviews' + } + }, + + initObservable: function () { + this._super() + .observe({ + active: [], + previews: [] + }); + + return this; + }, + + apply: function () { + this.extractActive(); + + this.source.trigger('params.applyFilters'); + this.source.reload(); + }, + + reset: function (filter) { + filter ? + resetValue(filter) : + this.active.each(resetValue); + + this.apply(); + }, + + extractActive: function () { + var active = this.elems.filter(hasData); + + this.active(active); + + return this; + }, + + extractPreviews: function (elems) { + var previews = elems.map(extractPreview); + + this.previews(_.compact(previews)); + + return this; + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/group.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/group.js new file mode 100644 index 0000000000000000000000000000000000000000..d59ba8fd942d41f53607587eecc69ecd8d5bd090 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/group.js @@ -0,0 +1,32 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + 'Magento_Ui/js/form/components/group' +], function (_, Group) { + 'use strict'; + + return Group.extend({ + defaults: { + template: 'ui/grid/filters/elements/group' + }, + + hasData: function () { + return this.elems.some(function (elem) { + return elem.delegate('hasData'); + }); + }, + + getPreview: function () { + var previews = this.elems.map(function (elem) { + if (elem.hasData()) { + return elem.label + ': ' + elem.getPreview(); + } + }); + + return _.compact(previews).join(' '); + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/listing.js b/app/code/Magento/Ui/view/base/web/js/grid/listing.js new file mode 100644 index 0000000000000000000000000000000000000000..3885e4f3a34d28f34ae5bc4d7be6e5731106afbd --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/listing.js @@ -0,0 +1,46 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'uiComponent', + 'Magento_Ui/js/lib/spinner' +], function (Component, loader) { + 'use strict'; + + return Component.extend({ + defaults: { + template: 'ui/grid/listing', + imports: { + rows: '<%= provider %>:data.items' + }, + listens: { + '<%= provider %>:reload': 'showLoader', + '<%= provider %>:reloaded': 'hideLoader' + } + }, + + initialize: function () { + this._super() + .hideLoader(); + + return this; + }, + + hideLoader: function () { + loader.get(this.name).hide(); + }, + + showLoader: function () { + loader.get(this.name).show(); + }, + + getColspan: function () { + return this.elems().length; + }, + + hasData: function () { + return !!this.rows().length; + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/massactions.js b/app/code/Magento/Ui/view/base/web/js/grid/massactions.js new file mode 100644 index 0000000000000000000000000000000000000000..35c792feaba23e40c19c68f2609171c798983297 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/massactions.js @@ -0,0 +1,40 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + 'mageUtils', + 'Magento_Ui/js/lib/collapsible' +], function (_, utils, Collapsible) { + 'use strict'; + + return Collapsible.extend({ + defaults: { + template: 'ui/grid/actions', + noItems: 'You haven\'t selected any items!' + }, + + applyAction: function (action) { + var proceed = true, + selections = this.source.get('config.multiselect'); + + if (!selections || !selections.total) { + proceed = false; + + alert(this.noItems); + } + + if (proceed && action.confirm) { + proceed = window.confirm(action.confirm); + } + + if (proceed) { + utils.submit({ + url: action.url, + data: selections + }); + } + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/paging.js b/app/code/Magento/Ui/view/base/web/js/grid/paging.js new file mode 100644 index 0000000000000000000000000000000000000000..cb6e5367cab328e9aa411d4023b9a6daa205b387 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/paging.js @@ -0,0 +1,148 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'ko', + 'uiComponent' +], function (ko, Component) { + 'use strict'; + + /** + * Returns closest existing page number to page argument + * @param {Number} value + * @param {Number} max + * @returns {Number} closest existing page number + */ + function getInRange(value, max) { + return Math.min(Math.max(1, value), max); + } + + return Component.extend({ + defaults: { + template: 'ui/grid/paging', + pageSize: 20, + current: 1, + + imports: { + totalSelected: '<%= provider %>:config.multiselect.total', + totalRecords: '<%= provider %>:data.totalRecords' + }, + + exports: { + pageSize: '<%= provider %>:params.paging.pageSize', + current: '<%= provider %>:params.paging.current', + pages: '<%= provider %>:data.pages' + }, + + listens: { + 'pageSize': 'onSizeChange', + 'pageSize current': 'reload', + 'pageSize totalRecords': 'countPages' + } + }, + + initialize: function () { + this._super() + .countPages(); + + return this; + }, + + initObservable: function () { + this._super(); + + this._current = ko.pureComputed({ + read: function () { + return +this.current(); + }, + + /** + * Validates page change according to user's input. + * Sets current observable to result of validation. + * Calls reload method then. + */ + write: function (value) { + var valid; + + value = +value; + valid = !isNaN(value) ? getInRange(value, this.pages()) : 1; + + this.current(valid); + this._current.notifySubscribers(value); + }, + + owner: this + }); + + return this; + }, + + /** + * Increments current observable prop by val and call reload method + * @param {String} val + */ + go: function (val) { + var current = this.current; + + current(current() + val); + }, + + /** + * Calls go method with 1 as agrument + */ + next: function () { + this.go(1); + }, + + /** + * Calls go method with -1 as agrument + */ + prev: function () { + this.go(-1); + }, + + /** + * Compares current and pages observables and returns boolean result + * + * @returns {Boolean} is current equal to pages property + */ + isLast: function () { + return this.current() === this.pages(); + }, + + /** + * Compares current observable to 1. + * + * @returns {Boolean} is current page first + */ + isFirst: function () { + return this.current() === 1; + }, + + reload: function () { + this.source.reload(); + }, + + /** + * Calculates number of pages. + */ + countPages: function () { + var pages = Math.ceil(this.totalRecords() / this.pageSize()); + + this.pages(pages || 1); + }, + + /** + * Is being triggered on user interaction with page size select. + * Resets current page to first if needed. + */ + onSizeChange: function () { + var size = this.pageSize(); + + if (size * this.current() > this.totalRecords()) { + this.current(1); + } + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/grid/provider.js b/app/code/Magento/Ui/view/base/web/js/grid/provider.js new file mode 100644 index 0000000000000000000000000000000000000000..52868c288ca8391c4851e0f7ab9cdf62a268ef69 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/provider.js @@ -0,0 +1,37 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'jquery', + 'underscore', + 'mageUtils', + 'Magento_Ui/js/lib/provider' +], function ($, _, utils, Provider) { + 'use strict'; + + return Provider.extend({ + initialize: function () { + utils.limit(this, 'reload', 50); + _.bindAll(this, 'onReload'); + + return this._super(); + }, + + reload: function () { + this.trigger('reload'); + + $.ajax({ + url: this.data.update_url, + method: 'GET', + data: this.get('params'), + dataType: 'json' + }).done(this.onReload); + }, + + onReload: function (data) { + this.set('data', data); + this.trigger('reloaded'); + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/class.js b/app/code/Magento/Ui/view/base/web/js/lib/class.js index 1cc6e8955cf81820349c0d61c8ada238ee11c5a5..be53c19ea135fb9566ecbfaece5ce7128e77afe3 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/class.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/class.js @@ -3,8 +3,9 @@ * See COPYING.txt for license details. */ define([ - 'underscore' -], function(_) { + 'underscore', + 'mageUtils' +], function (_, utils) { 'use strict'; var superReg = /\b_super\b/; @@ -15,7 +16,7 @@ define([ * @param {Function} method - Method to be checked. * @returns {Boolean} */ - function hasSuper(method){ + function hasSuper(method) { return _.isFunction(method) && superReg.test(method); } @@ -27,13 +28,13 @@ define([ * @param {Function} method - Method to be wrapped. * @returns {Function} Wrapped method. */ - function superWrapper(parent, name, method){ - return function(){ - var superTmp = this._super, - args = arguments, + function superWrapper(parent, name, method) { + return function () { + var superTmp = this._super, + args = arguments, result; - this._super = function(){ + this._super = function () { var superArgs = arguments.length ? arguments : args; return parent[name].apply(this, superArgs); @@ -44,52 +45,49 @@ define([ this._super = superTmp; return result; - } + }; } /** * Analogue of Backbone.extend function. * - * @param {Object} extender - - * Object, that describes the prototype of + * @param {Object} extender - Object, that describes the prototype of * created constructor. - * @param {...Object} Multiple amount of mixins. * @returns {Function} New constructor. */ - function extend(extender){ - var parent = this, + function extend(extender) { + var parent = this, + defaults = extender.defaults || {}, parentProto = parent.prototype, - defaults = extender.defaults || {}, - child, - childProto, - mixins; + child; - child = function(){ - _.defaults(this, defaults); - - parent.apply(this, arguments); - }; + defaults = defaults || {}; + extender = extender || {}; delete extender.defaults; - childProto = child.prototype = Object.create(parentProto); + if (extender.hasOwnProperty('constructor')) { + child = extender.constructor; + } else { + child = function () { + parent.apply(this, arguments); + }; + } + + defaults = utils.extend({}, parent.defaults, defaults); - childProto.constructor = child; + child.prototype = Object.create(parentProto); + child.prototype.constructor = child; - _.each(extender, function(method, name){ - childProto[name] = hasSuper(method) ? + _.each(extender, function (method, name) { + child.prototype[name] = hasSuper(method) ? superWrapper(parentProto, name, method) : method; }); - mixins = _.toArray(arguments).slice(1); - - mixins.forEach(function(mixin){ - _.extend(childProto, mixin); - }); - child.__super__ = parentProto; - child.extend = extend; + child.extend = extend; + child.defaults = defaults; return child; } @@ -101,9 +99,10 @@ define([ this.initialize.apply(this, arguments); } - Class.prototype.initialize = function(){}; + Class.prototype.initialize = function () {}; Class.extend = extend; + Class.defaults = {}; return Class; }); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/collapsible.js b/app/code/Magento/Ui/view/base/web/js/lib/collapsible.js similarity index 54% rename from app/code/Magento/Ui/view/base/web/js/form/components/collapsible.js rename to app/code/Magento/Ui/view/base/web/js/lib/collapsible.js index 00b4768b37127a684fb8e9eea00274d9c0b4fe67..5b831ae4460aa4d82483a2d3ee02ae7adc320fb5 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/collapsible.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/collapsible.js @@ -3,22 +3,22 @@ * See COPYING.txt for license details. */ define([ - 'Magento_Ui/js/form/component' -], function(Component) { + 'uiComponent' +], function (Component) { 'use strict'; return Component.extend({ defaults: { - collapsible: false, - opened: true + opened: false, + collapsible: true }, /** * Initializes 'opened' observable, calls 'initObservable' of parent - * + * * @return {Object} - reference to instance */ - initObservable: function(){ + initObservable: function () { this._super() .observe('opened'); @@ -27,25 +27,21 @@ define([ /** * Toggles 'active' observable, triggers 'active' event - * + * * @return {Object} - reference to instance */ - toggle: function() { - var opened = this.opened, - active = opened(!opened()); - - this.trigger('active', active); + toggleOpened: function () { + if (this.collapsible) { + this.opened(!this.opened()); + } return this; }, - /** - * Invokes 'toggle' method if instance has 'collapsible' property set to true - */ - onClick: function(){ - if(this.collapsible){ - this.toggle(); + close: function () { + if (this.collapsible) { + this.opened(false); } } }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component.js b/app/code/Magento/Ui/view/base/web/js/lib/component.js deleted file mode 100644 index 7d179bcf36633a131021962d53eb57a06cc3964d..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/component.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'Magento_Ui/js/lib/registry/registry' -], function(registry) { - 'use strict'; - - /** - * Extends configuration that will be retrieved from the data provider - * with configuration that is stored in a 'baseConfig' object. - * @param {Object} provider - DataProvider instance. - * @param {Object} baseConfig - Basic configuration. - * @returns {Object} Resulting configurational object. - */ - function getConfig(provider, baseConfig) { - var configs = provider.config.get('components'), - storeConfig = configs[baseConfig.name] || {}; - - return _.extend({ - provider: provider - }, storeConfig, baseConfig); - } - - /** - * Creates new instance of a grids' component. - * @param {Object} data - - Data object that was passed while creating component initializer. - * @param {Object} base - - Basic configuration. - */ - function init(data, base) { - var providerName = base.parent_name, - component = providerName + ':' + base.name; - - if (registry.has(component)) { - return; - } - - registry.get(providerName, function(provider) { - var config = getConfig(provider, base); - - registry.set(component, new data.constr(config)); - }); - } - - return function(data) { - return init.bind(this, data); - }; -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component/core.js b/app/code/Magento/Ui/view/base/web/js/lib/component/core.js new file mode 100644 index 0000000000000000000000000000000000000000..f5944f007f83e4bb005c576f0c005fb8c1b7faf3 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/lib/component/core.js @@ -0,0 +1,222 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'ko', + 'mageUtils', + 'underscore', + 'uiRegistry' +], function (ko, utils, _, registry) { + 'use strict'; + + /** + * Wrapper for ko.observable and ko.observableArray. + * Assignes one or another ko property to obj[key] + * @param {Object} obj - object to store property to + * @param {String} key - key + * @param {*} value - initial value of observable + */ + function observe(obj, key, value) { + var method = Array.isArray(value) ? 'observableArray' : 'observable'; + + if (!ko.isObservable(obj[key])) { + obj[key] = ko[method](value); + } else { + obj[key](value); + } + } + + return { + defaults: { + parentName: '<%= $data.getPart(name, -2) %>', + parentScope: '<%= $data.getPart(dataScope, -2) %>', + template: 'ui/collection', + containers: [], + _elems: [] + }, + + initialize: function (options) { + _.bindAll(this, '_insert'); + + this.initConfig(options) + .initProperties() + .initObservable() + .initUnique() + .initLinks() + .setListners(this.listens); + + return this; + }, + + initConfig: function (options) { + var defaults = this.constructor.defaults, + config = utils.extend({}, defaults, options); + + config = utils.template(config, this); + + _.extend(this, config); + + return this; + }, + + /** + * Defines various properties. + * + * @returns {Component} Chainable. + */ + initProperties: function () { + this.regions = []; + this.source = registry.get(this.provider); + + return this; + }, + + /** + * Initializes observable properties. + * + * @returns {Component} Chainable. + */ + initObservable: function () { + this.observe({ + 'elems': [] + }); + + this.regions.forEach(function (region) { + this.observe(region, []); + }, this); + + return this; + }, + + initLinks: function () { + _.each({ + both: this.links, + exports: this.exports, + imports: this.imports + }, this.setLinks, this); + + return this; + }, + + /** + * Initializes listeners of the unique property. + * + * @returns {Component} Chainable. + */ + initUnique: function () { + var update = this.onUniqueUpdate.bind(this), + uniqueNs = this.uniqueNs; + + this.hasUnique = this.uniqueProp && uniqueNs; + + if (this.hasUnique) { + this.source.on(uniqueNs, update, this.name); + } + + return this; + }, + + /** + * Called when current element was injected to another component. + * + * @param {Object} parent - Instance of a 'parent' component. + * @returns {Component} Chainable. + */ + initContainer: function (parent) { + this.containers.push(parent); + + return this; + }, + + /** + * Called when another element was added to current component. + * + * @param {Object} elem - Instance of an element that was added. + * @returns {Component} Chainable. + */ + initElement: function (elem) { + elem.initContainer(this); + + return this; + }, + + /** + * Splits incoming string and returns its' part specified by offset. + * + * @param {String} parts + * @param {Number} [offset] + * @param {String} [delimiter=.] + * @returns {String} + */ + getPart: function (parts, offset, delimiter) { + delimiter = delimiter || '.'; + parts = parts.split(delimiter); + offset = utils.formatOffset(parts, offset); + + parts.splice(offset, 1); + + return parts.join(delimiter) || ''; + }, + + /** + * Returns path to components' template. + * @returns {String} + */ + getTemplate: function () { + return this.template; + }, + + /** + * Updates property specified in uniqueNs + * if components' unique property is set to 'true'. + * + * @returns {Component} Chainable. + */ + setUnique: function () { + var property = this.uniqueProp; + + if (this[property]()) { + this.source.set(this.uniqueNs, this.name); + } + + return this; + }, + + /** + * If 2 params passed, path is considered as key. + * Else, path is considered as object. + * Assignes props to this based on incoming params + * @param {Object|String} path + */ + observe: function (path) { + var type = typeof path; + + if (type === 'string') { + path = path.split(' '); + } + + if (Array.isArray(path)) { + path.forEach(function (key) { + observe(this, key, this[key]); + }, this); + } else if (type === 'object') { + _.each(path, function (value, key) { + observe(this, key, value); + }, this); + } + + return this; + }, + + /** + * Callback which fires when property under uniqueNs has changed. + */ + onUniqueUpdate: function (name) { + var active = name === this.name, + property = this.uniqueProp; + + this[property](active); + } + }; +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component/links.js b/app/code/Magento/Ui/view/base/web/js/lib/component/links.js new file mode 100644 index 0000000000000000000000000000000000000000..4434ca6896eeb5150ad679b8f7be9b8e5d724889 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/lib/component/links.js @@ -0,0 +1,128 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'ko', + 'underscore', + 'mageUtils', + 'Magento_Ui/js/lib/registry/registry' +], function (ko, _, utils, registry) { + 'use strict'; + + function extractData(str) { + var data = str.split(':'); + + return { + component: data[0], + prop: data[1] + }; + } + + function update(target, prop, value) { + if (_.isFunction(target[prop])) { + target[prop](value); + } else if (target.set) { + target.set(prop, value); + } else { + target[prop] = value; + } + } + + function imports(owner, target, ownerProp, targetProp, auto) { + var callback = update.bind(null, owner, ownerProp), + value; + + value = target.get ? + target.get(targetProp) : + utils.nested(target, targetProp); + + if (ko.isObservable(value)) { + value.subscribe(callback); + value = value(); + } else if (target.on) { + target.on(targetProp, callback); + } + + if (auto && typeof value !== 'undefined') { + callback(value); + } + } + + function exports(owner, target, ownerProp, targetProp, auto) { + var to = update.bind(null, target, targetProp); + + ownerProp = owner[ownerProp]; + + ownerProp.subscribe(to); + + if (auto) { + to(ownerProp()); + } + } + + function links(owner, target, ownerProp, direction) { + if (!ko.isObservable(owner[ownerProp]) && !_.isFunction(owner[ownerProp])) { + owner.observe(ownerProp); + } + + target = extractData(target); + + registry.get(target.component, function (component) { + var args = [owner, component, ownerProp, target.prop, true]; + + switch (direction) { + case 'imports': + imports.apply(null, args); + break; + + case 'exports': + exports.apply(null, args); + break; + + case 'both': + imports.apply(null, args); + exports.apply(null, args); + break; + } + }); + } + + function listen(owner, target, callback) { + target = extractData(target); + + if (!target.prop) { + target.prop = target.component; + target.component = owner.name; + } + + registry.get(target.component, function (component) { + imports(owner, component, callback, target.prop); + }); + } + + return { + setLinks: function (data, direction) { + var owner = this; + + _.each(data, function (target, prop) { + links(owner, target, prop, direction); + }); + }, + + setListners: function (listeners) { + var owner = this; + + _.each(listeners, function (callbacks, sources) { + sources = sources.split(' '); + callbacks = callbacks.split(' '); + + sources.forEach(function (target) { + callbacks.forEach(function (callback) { + listen(owner, target, callback); + }); + }); + }); + } + }; +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component/main.js b/app/code/Magento/Ui/view/base/web/js/lib/component/main.js new file mode 100644 index 0000000000000000000000000000000000000000..9b5f99cf7cb895c378c072e26103c579fd219df0 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/lib/component/main.js @@ -0,0 +1,21 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + './core', + './links', + './manip', + './traversal', + 'Magento_Ui/js/lib/class', + 'Magento_Ui/js/lib/ko/initialize' +], function (_, core, links, manip, traversal, Class) { + 'use strict'; + + var extenders; + + extenders = _.extend({}, core, links, manip, traversal); + + return Class.extend(extenders); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component/manip.js b/app/code/Magento/Ui/view/base/web/js/lib/component/manip.js new file mode 100644 index 0000000000000000000000000000000000000000..301beed7381d053c19f734a094d00db2aada6205 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/lib/component/manip.js @@ -0,0 +1,190 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'ko', + 'underscore', + 'mageUtils', + 'uiRegistry' +], function (ko, _, utils, registry) { + 'use strict'; + + function getIndex(container, target) { + var result; + + container.some(function (item, index) { + result = index; + + return item && (item.name === target || item === target); + }); + + return result; + } + + function compact(container) { + return container.filter(utils.isObject); + } + + function reserve(container, elem, position) { + var offset = position, + target; + + if (_.isObject(position)) { + target = position.after || position.before; + offset = getIndex(container, target); + + if (position.after) { + ++offset; + } + } + + offset = utils.formatOffset(container, offset); + + container[offset] ? + container.splice(offset, 0, elem) : + container[offset] = elem; + + return offset; + } + + return { + getRegion: function (name) { + var regions = this.regions; + + if (!regions[name]) { + regions[name] = ko.observable([]); + } + + return regions[name]; + }, + + updateRegion: function (items, name) { + var region = this.getRegion(name); + + region(items); + }, + + /** + * Requests specified components to insert + * them into 'elems' array starting from provided position. + * + * @param {String} elem - Name of the component to insert. + * @param {Number} [position=-1] - Position at which to insert elements. + * @returns {Component} Chainable. + */ + insert: function (elem, position) { + reserve(this._elems, elem, position); + registry.get(elem, this._insert); + + return this; + }, + + /** + * Removes specified element from the 'elems' array. + * + * @param {Object} elem - Element to be removed. + * @returns {Component} Chainable. + */ + remove: function (elem) { + utils.remove(this._elems, elem); + this._update(); + + return this; + }, + + /** + * Destroys current instance along with all of its' children. + */ + destroy: function () { + this._dropHandlers() + ._clearData() + ._clearRefs(); + }, + + /** + * Removes events listeners. + * @private + * + * @returns {Component} Chainable. + */ + _dropHandlers: function () { + this.off(); + + this.source.off(this.name); + + return this; + }, + + /** + * Clears all data associated with component. + * @private + * + * @returns {Component} Chainable. + */ + _clearData: function () { + this.source.remove(this.dataScope); + this.source.remove('params.' + this.name); + + return this; + }, + + /** + * Removes all references to current instance and + * calls 'destroy' method on all of its' children. + * @private + * + * @returns {Component} Chainable. + */ + _clearRefs: function () { + registry.remove(this.name); + + this.containers.forEach(function (parent) { + parent.remove(this); + }, this); + + this.elems().forEach(function (child) { + child.destroy(); + }); + + return this; + }, + + /** + * Inserts provided component into 'elems' array at a specified position. + * @private + * + * @param {Object} elem - Element to insert. + */ + _insert: function (elem) { + var index = this._elems.indexOf(elem.name); + + if (!~index) { + return; + } + + this._elems[index] = elem; + + this._update() + .initElement(elem); + }, + + /** + * Synchronizes multiple elements arrays with a core '_elems' container. + * Performs elemets grouping by theirs 'displayArea' property. + * @private + * + * @returns {Component} Chainable. + */ + _update: function () { + var _elems = compact(this._elems), + grouped = _.groupBy(_elems, 'displayArea'); + + _.each(grouped, this.updateRegion, this); + + this.elems(_elems); + + return this; + } + }; +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component/traversal.js b/app/code/Magento/Ui/view/base/web/js/lib/component/traversal.js new file mode 100644 index 0000000000000000000000000000000000000000..d94770d90f9e888b0ff08869c268663064e0c9d1 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/lib/component/traversal.js @@ -0,0 +1,76 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + 'Magento_Ui/js/lib/events' +], function (_, EventsBus) { + 'use strict'; + + return _.extend({}, EventsBus, { + /** + * Tries to call specified method of a current component, + * otherwise delegates attempt to its' children. + * + * @param {String} target - Name of the method. + * @param [...] Arguments that will be passed to method. + * @returns {*} Result of the method calls. + */ + delegate: function (target) { + var args = _.toArray(arguments); + + target = this[target]; + + if (_.isFunction(target)) { + return target.apply(this, args.slice(1)); + } + + return this._delegate(args); + }, + + /** + * Calls 'delegate' method of all of it's children components. + * @private + * + * @param {Array} args - An array of arguments to pass to the next delegation call. + * @returns {Array} An array of delegation resutls. + */ + _delegate: function (args) { + var result; + + result = this.elems.map(function (elem) { + return elem.delegate.apply(elem, args); + }); + + return _.flatten(result); + }, + + /** + * Overrides 'EventsBus.trigger' method to implement events bubbling. + * + * @param {String} name - Name of the event. + * @param [...] Any number of arguments that should be to the events' handler. + * @returns {Boolean} False if event bubbling was canceled. + */ + trigger: function () { + var args = _.toArray(arguments), + bubble = EventsBus.trigger.apply(this, args), + result; + + if (!bubble) { + return false; + } + + this.containers.forEach(function (parent) { + result = parent.trigger.apply(parent, args); + + if (result === false) { + bubble = false; + } + }); + + return !!bubble; + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/data_provider.js b/app/code/Magento/Ui/view/base/web/js/lib/data_provider.js deleted file mode 100644 index 281f6afa6a5fa379063368469064c96d19556041..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/data_provider.js +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'underscore', - './rest', - 'Magento_Ui/js/lib/storage/index', - 'Magento_Ui/js/lib/class', - 'Magento_Ui/js/lib/events' -], function(_, Rest, storages, Class, EventsBus) { - 'use strict'; - - var defaults = { - stores: ['config', 'meta', 'data', 'params', 'dump'] - }; - - var DataProvider = Class.extend({ - /** - * Initializes DataProvider instance. - * @param {Object} settings - Settings to initialize object with. - */ - initialize: function(settings) { - _.extend(this, defaults, settings); - - this.initStorages() - .initClient(); - }, - - /** - * Creates instances of storage objects. - * @returns {DataProvider} Chainable. - */ - initStorages: function() { - var storage, - config; - - this.stores.forEach(function(store) { - storage = storages[store]; - config = this[store]; - - this[store] = new storage(config); - }, this); - - return this; - }, - - /** - * Creates instances of a REST client. - * @returns {DataProvider} Chainable. - */ - initClient: function() { - var config = this.config.get('client'); - - this.client = new Rest(config); - - this.client.on('read', this.onRead.bind(this)); - - return this; - }, - - /** - * Tries to retrieve data from server using REST client. - * Allways attaches cached parameters to request. - * @param {Object} [options] - Additional paramters to be attached. - * @returns {DataProvider} Chainable. - */ - refresh: function(options) { - var stored = this.params.get(), - params = _.extend({}, stored, options || {}); - - this.trigger('beforeRefresh'); - this.client.read(params); - - return this; - }, - - /** - * Updates list of storages with a specified data. - * @param {Object} data - Data to update storages with. - * @returns {DataProvider} Chainable. - */ - updateStorages: function(data) { - var value; - - this.stores.forEach(function(store) { - value = data[store]; - - if(value){ - this[store].set(value); - } - }, this); - - return this; - }, - - /** - * Callback method that fires when REST client - * will resolve requets to the server. - * @param {Object} result - Server response. - */ - onRead: function(result) { - result = { - data: result.data - }; - - this.updateStorages(result) - .trigger('refresh', result); - } - }, EventsBus); - - return DataProvider; -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/deferred_events.js b/app/code/Magento/Ui/view/base/web/js/lib/deferred_events.js deleted file mode 100644 index 3b9dbd90425927e8d82a83fddbaa47930eca01d8..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/deferred_events.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'jquery', - './events' -], function ($, EventBus) { - 'use strict'; - - var events = {}; - - function isResolved(promise) { - return promise.state() === 'resolved'; - }; - - function toArray(obj, from) { - return Array.prototype.slice.call(obj, from || 0); - }; - - function on(context, name, callback) { - return EventBus.on.call(context, name, callback); - }; - - function trigger(name) { - return EventBus.trigger.apply(this, toArray(arguments)); - }; - - function getStorage(name) { - return events[name] || {}; - }; - - function getCallbacks(name) { - var storage = getStorage(name); - return storage.callbacks || []; - }; - - return { - when: function (name, callback) { - var storage = events[name] = getStorage(name), - callbacks = storage.callbacks = getCallbacks(name), - promise = storage.promise = storage.promise || $.Deferred(), - args = toArray(arguments), - resolveArgs; - - if (isResolved(promise)) { - return on(this, name, callback); - } - - if (~!callbacks.indexOf(callback)) { - callbacks.push(callback); - } - - promise.done(function () { - - callback.apply(this, arguments); - on(this, name, callback); - - }.bind(this)); - - return this; - }, - - resolve: function (name) { - var args = toArray(arguments, 1), - storage = events[name] = getStorage(name), - promise = storage.promise = storage.promise || $.Deferred(); - - if (isResolved(promise)) { - return trigger.bind(this, name).apply(this, args); - } - - promise.resolve.apply(promise, args); - - return this; - } - } -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/events.js b/app/code/Magento/Ui/view/base/web/js/lib/events.js index 00cb42852122575ecfb5a565f69d02e42432956d..7a8be3f5ad51a81ae69b5f2286978da3ed45b73a 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/events.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/events.js @@ -4,7 +4,7 @@ */ define([ 'underscore' -], function(_) { +], function (_) { 'use strict'; function addHandler(events, ns, callback, name) { @@ -20,19 +20,19 @@ define([ return name ? events[name] : events; } - function keepHandler(ns, handler){ - if(!ns){ + function keepHandler(ns, handler) { + if (!ns) { return false; } return handler.ns !== ns; } - function trigger(handlers, args){ - var bubble = true, + function trigger(handlers, args) { + var bubble = true, callback; - handlers.forEach(function(handler){ + handlers.forEach(function (handler) { callback = handler.callback; if (callback.apply(null, args) === false) { @@ -46,10 +46,9 @@ define([ return { /** * Calls callback when name event is triggered. - * @param {String} events - * @param {Function} callback - * @param {Function} ns - * @return {Object} reference to this + * @param {String} events + * @param {Function} callback + * @return {Object} reference to this */ on: function (events, callback, ns) { var storage = getEvents(this), @@ -69,20 +68,20 @@ define([ }, /** - * Removed callback from listening to target events + * Removed callback from listening to target event * @param {String} ns * @return {Object} reference to this */ off: function (ns) { var storage = getEvents(this), - filter = keepHandler.bind(null, ns); + filter = keepHandler.bind(null, ns); _.each(storage, function (handlers, name) { handlers = handlers.filter(filter); handlers.length ? - (storage[name] = handlers) : - (delete storage[name]); + storage[name] = handlers : + delete storage[name]; }); return this; @@ -95,9 +94,13 @@ define([ */ trigger: function (name) { var handlers = getEvents(this, name), - args = _.toArray(arguments).slice(1); + args = _.toArray(arguments).slice(1); + + if (_.isUndefined(handlers)) { + return true; + } - return _.isUndefined(handlers) || trigger(handlers, args); + return trigger(handlers, args); } }; }); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/date.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/date.js deleted file mode 100644 index ae14f38dd4d5f873641e5d919e2a36063a2e6699..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/date.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'ko', - 'moment', - 'jquery', - 'date-format-normalizer' -], function(ko, moment, $, convert) { - 'use strict'; - - ko.bindingHandlers.date = { - - /** - * Reads passed date and format from valueAccessor, uses convert function to format it. - * Writes date to el.innerText using jQuery - * @param {HTMLElement} el - Element, that binding is applied to - * @param {Function} valueAccessor - Function that returns value, passed to binding - */ - init: function(element, valueAccessor) { - var config = valueAccessor(), - format = convert(config.format), - date = moment(config.value).format(format); - - $(element).text(date); - } - }; -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js index ec2823c793be641c03c0bef8f3acd901532e1756..843c126b663413058238b86dc03e5f82d2622f14 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js @@ -9,6 +9,14 @@ define([ ], function (ko, $) { 'use strict'; + function clickWrapper(elem, callback, e) { + var target = e.target; + + if (target !== elem && !elem.contains(target)) { + callback(); + } + } + ko.bindingHandlers.outerClick = { /** @@ -19,15 +27,17 @@ define([ * @param {Object} viewModel - reference to viewmodel */ init: function (element, valueAccessor, allBindings, viewModel) { - var callback = valueAccessor(); + var callback = valueAccessor(), + wrapper; callback = callback.bind(viewModel); + wrapper = clickWrapper.bind(null, element, callback); - $(document).on('click', callback); + $(document).on('click', wrapper); ko.utils.domNodeDisposal.addDisposeCallback(element, function () { - $(document).off('click', callback); + $(document).off('click', wrapper); }); } - } -}); \ No newline at end of file + }; +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js index b8c32c121da6aa20930c724b511cc6084cb405ee..a2e303c11fe436872229169724caf8459b3fc60d 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js @@ -6,12 +6,10 @@ define([ 'ko', './template/engine', - './bind/date', './bind/scope', './bind/datepicker', './bind/stop_propagation', './bind/outer_click', - './bind/class', './bind/keyboard', './bind/optgroup', './extender/observable_array' diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/scope.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/scope.js deleted file mode 100644 index 65ee522bc2af1301ee2c3ca6726765546c581a6b..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/ko/scope.js +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'ko', - 'underscore', - '../class', - './initialize' -], function(ko, _, Class) { - 'use strict'; - - /** - * Wrapper for ko.observable and ko.observableArray. - * Assignes one or another ko property to obj[key] - * @param {Object} obj - object to store property to - * @param {String} key - key - * @param {*} value - initial value of observable - */ - function observe(obj, key, value){ - var method = Array.isArray(value) ? 'observableArray' : 'observable'; - - obj[key] = ko[method](value); - } - - return Class.extend({ - - /** - * If 2 params passed, path is considered as key. - * Else, path is considered as object. - * Assignes props to this based on incoming params - * @param {Object|String} path - * @param {*} value - */ - observe: function(path, value) { - var type = typeof path; - - if(arguments.length === 1){ - if(type === 'string'){ - path = path.split(' '); - } - - if(Array.isArray(path)){ - path.forEach(function(key){ - observe(this, key, this[key]); - }, this); - } - else if(type==='object'){ - _.each(path, function(value, key){ - observe(this, key, value); - }, this); - } - } - else if(type === 'string') { - observe(this, path, value); - } - - return this; - }, - - /** - * Reads it's params from provider and stores it into its params object - * @return {Object} reference to instance - */ - pushParams: function(){ - var params = this.params, - provider = this.provider.params, - data = {}; - - params.items.forEach(function(name) { - data[name] = this[name](); - }, this); - - provider.set(params.dir, data); - - return this; - }, - - /** - * Loops over params.items and writes it's corresponding {key: value} - * pairs to this as observables. - * @return {Object} reference to instance - */ - pullParams: function(){ - var params = this.params, - provider = this.provider.params, - data = provider.get(params.dir); - - params.items.forEach(function(name) { - this[name](data[name]); - }, this); - - return this; - }, - - /** - * Calls pushParams and calls refresh on this.provider - */ - reload: function() { - this.pushParams() - .provider.refresh(); - } - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js index eee3e1c6c08d2f8c0c7bc0948eab8e06e0dc3883..647cc2b985972513ce70f29d6b68d0774cb3a52d 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js @@ -5,9 +5,8 @@ define([ 'ko', './observable_source', - '../../renderer/renderer', - 'mage/apply/main' -], function (ko, Source, Renderer, Mage) { + '../../renderer/renderer' +], function (ko, Source, Renderer) { 'use strict'; var sources = {}; @@ -27,7 +26,7 @@ define([ /** * Remote template engine class. Is used to be able to load remote templates via knockout template binding. */ - var RemoteTemplateEngine = function() {}; + var RemoteTemplateEngine = function () {}; var NativeTemplateEngine = ko.nativeTemplateEngine; RemoteTemplateEngine.prototype = new NativeTemplateEngine; @@ -42,9 +41,8 @@ define([ * @param {Object} options - options, passed to template binding * @return {TemplateSource} - object with methods 'nodes' and 'data'. */ - RemoteTemplateEngine.prototype.makeTemplateSource = function(template, templateDocument, options) { + RemoteTemplateEngine.prototype.makeTemplateSource = function (template, templateDocument, options) { var source, - extenders = options.extenders || [], templateId; if (typeof template === 'string') { @@ -55,9 +53,8 @@ define([ source = new Source(template); sources[templateId] = source; - Renderer.render(template, extenders).done(function(rendered) { + Renderer.render(template).done(function (rendered) { source.nodes(rendered); - Mage.apply(); }); } @@ -99,4 +96,4 @@ define([ }; return new RemoteTemplateEngine; -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/loader.js b/app/code/Magento/Ui/view/base/web/js/lib/loader.js index 9949551220945a95b6b89ce08cfede0223be30ac..03d97b399d7130727a01ff43eb4264dfa3b82d72 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/loader.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/loader.js @@ -11,26 +11,17 @@ define([ /** * Formats path of type "path.to.template" to RequireJS compatible * @param {String} path - * @returns {String} - formatted template path + * @return {String} - formatted template path */ function formatTemplatePath(path) { return 'text!' + path.replace(/^([^\/]+)/g, '$1/template') + '.html'; } - /** - * Waits for all items in passed array of promises to resolve. - * @param {Array} promises - array of promises - * @returns {Deferred} - promise of promises to resolve - */ - function waitFor(promises) { - return $.when.apply($, promises); - } - /** * Removes license from incoming template * * @param {String} tmpl - * @returns {String} - template without license + * @return {String} - template without license */ function removeLicense(tmpl) { var regEx = /<!--[\s\S]*?-->/; @@ -44,7 +35,7 @@ define([ * Loads template by path, resolves promise with it if defined * * @param {String} path - * @params {Deferred} promise + * @param {Deferred} promise */ function load(path, promise) { require([path], function (template) { @@ -59,12 +50,11 @@ define([ * Loops over arguments and loads template for each. * @return {Deferred} - promise of templates to be loaded */ - loadTemplate: function () { - var isLoaded = $.Deferred(), - templates = _.toArray(arguments); + loadTemplate: function (source) { + var isLoaded = $.Deferred(); - waitFor(templates.map(this._loadTemplate)).done(function () { - isLoaded.resolve.apply(isLoaded, arguments); + this._loadTemplate(source).done(function (tmpl) { + isLoaded.resolve(tmpl); }); return isLoaded.promise(); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/mixins/loader.js b/app/code/Magento/Ui/view/base/web/js/lib/mixins/loader.js deleted file mode 100644 index 4e310b1ca86a992706cbc98941cf7d09075eae9e..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/mixins/loader.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'Magento_Ui/js/lib/spinner' -], function (spinner) { - 'use strict'; - - return { - /** - * Activates spinner - * @return {Object} reference to instance - */ - lock: function() { - spinner.show(); - - return this; - }, - - /** - * Deactivates spinner - * @return {Object} reference to instance - */ - unlock: function() { - spinner.hide(); - - return this; - } - } -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/provider.js b/app/code/Magento/Ui/view/base/web/js/lib/provider.js index 66454fee11c9bf0b5cdba395fe36c320f183d173..dafb8ad304893a957e261fabb503af434a79fe30 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/provider.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/provider.js @@ -3,43 +3,92 @@ * See COPYING.txt for license details. */ define([ - 'jquery', - './data_provider', - 'Magento_Ui/js/lib/registry/registry' -], function($, DataProvider, registry) { + 'underscore', + 'mageUtils', + 'Magento_Ui/js/lib/class', + 'Magento_Ui/js/lib/events' +], function (_, utils, Class, EventsBus) { 'use strict'; - /** - * Merges passed settings with preset ajax properties - * @param {Object} settings - * @returns {Object} - mutated settings - */ - function getConfig(settings) { - var config = settings.config, - client = config.client = config.client || {}; - - $.extend(true, client, { - ajax: { - data: { - name: settings.name, - form_key: FORM_KEY - } - } - }); + function getStored(ns) { + var stored = localStorage.getItem(ns); - return settings; + return !_.isNull(stored) ? JSON.parse(stored) : {}; } - /** - * Creates new data provider and register it by settings.name - * @param {Object} settings - */ - function init(settings) { - var name = settings.name, - config = getConfig(settings); + function store(ns, property, data) { + var stored = getStored(ns); + + utils.nested(stored, property, data); - registry.set(name, new DataProvider(config)); + localStorage.setItem(ns, JSON.stringify(stored)); } - return init; -}); \ No newline at end of file + var Provider = _.extend({ + /** + * Initializes DataProvider instance. + * @param {Object} config - Settings to initialize object with. + */ + initialize: function (config) { + _.extend(this.data = {}, config); + + this.restore(); + + return this; + }, + + /** + * If path specified, returnes this.data[path], else returns this.data + * @param {String} path + * @return {*} this.data[path] or simply this.data + */ + get: function (path) { + return utils.nested(this.data, path); + }, + + /** + * Sets value property to path and triggers update by path, passing result + * @param {String|*} path + * @param {String|*} value + * @return {Object} reference to instance + */ + set: function (path, value) { + var data = utils.nested(this.data, path), + diffs = utils.compare(data, value, path); + + utils.nested(this.data, path, value); + + diffs.changes.forEach(function (change) { + this.trigger(change.name, change.value, change); + }, this); + + _.each(diffs.containers, function (changes, name) { + this.trigger(name, changes); + }, this); + + return this; + }, + + restore: function () { + var stored = getStored(this.data.dataScope); + + utils.extend(this.data, stored); + }, + + store: function (property, data) { + if (!data) { + data = this.get(property); + } else { + this.set(property, data); + } + + store(this.data.dataScope, property, data); + }, + + remove: function (path) { + utils.nestedRemove(this.data, path); + } + }, EventsBus); + + return Class.extend(Provider); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/registry/events.js b/app/code/Magento/Ui/view/base/web/js/lib/registry/events.js index 21969f43dc8529e879a2193ee4b70892b5136a42..cf4b3b13d10936ae149320b54ec767079a0e8241 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/registry/events.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/registry/events.js @@ -4,7 +4,7 @@ */ define([ 'underscore', - 'mage/utils' + 'mageUtils' ], function (_, utils) { 'use strict'; diff --git a/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js b/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js index db002ca2a3cf703b238b514691c7c74b4534e32d..8c0448aaa49b38d71181d480df436fb3949b392e 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js @@ -3,10 +3,10 @@ * See COPYING.txt for license details. */ define([ - 'mage/utils', + 'mageUtils', './storage', './events' -], function (utils, Storage, Events) { +], function(utils, Storage, Events) { 'use strict'; function Registry() { @@ -20,21 +20,22 @@ define([ /** * Retrieves data from registry. * - * @param {(String|Array)} elems - An array of elements' names or - * a string of names divided by spaces. - * @param {Function} [callback] - Callback function that will be triggered + * @params {(String|Array)} elems - + * An array of elements' names or a string of names divided by spaces. + * @params {Function} [callback] - + * Callback function that will be triggered * when all of the elements are registered. * @returns {Array|*|Undefined} * Returns either an array of elements * or an element itself if only is requested. * If callback function is specified then returns 'undefined'. */ - get: function (elems, callback) { + get: function(elems, callback) { var records; elems = utils.stringToArray(elems) || []; - if (typeof callback == 'function') { + if (typeof callback !== 'undefined') { this.events.wait(elems, callback); } else { records = this.storage.get(elems); @@ -45,11 +46,12 @@ define([ } }, - /** + + /** * Sets data to registry. * - * @param {String} elem - Elements' name. - * @param {*} value - Value that will be assigned to the element. + * @params {String} elems - Elements' name. + * @params {*} value - Value that will be assigned to the element. * @returns {registry} Chainable. */ set: function (elem, value) { @@ -61,8 +63,8 @@ define([ /** * Removes specified elements from a storage. - * @param {(String|Array)} elems - An array of elements' names or - * a string of names divided by spaces. + * @params {(String|Array)} elems - + * An array of elements' names or a string of names divided by spaces. * @returns {registry} Chainable. */ remove: function (elems) { @@ -76,8 +78,8 @@ define([ /** * Checks whether specified elements has been registered. * - * @param {(String|Array)} elems - An array of elements' names or - * a string of names divided by spaces. + * @params {(String|Array)} elems - + * An array of elements' names or a string of names divided by spaces. * @returns {Boolean} */ has: function (elems) { diff --git a/app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js b/app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js index bf701810285e24c5589f2a1f28bb39b9f56c0f55..f7d95da8b4f622aea4d1e315dc7b6ae2d462a2ad 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js @@ -19,17 +19,12 @@ define([], function () { * @returns {Array} Array of values. */ get: function (elems) { - var data = this.data, - record; + var data = this.data; elems = elems || []; return elems.map(function (elem) { - record = data[elem]; - - if (record) { - return record.value; - } + return data[elem]; }); }, @@ -41,10 +36,9 @@ define([], function () { * returns {storage} Chainable. */ set: function (elem, value) { - var data = this.data, - record = data[elem] = data[elem] || {}; + var data = this.data; - record.value = value; + data[elem] = value; return this; }, diff --git a/app/code/Magento/Ui/view/base/web/js/lib/renderer/overrides.js b/app/code/Magento/Ui/view/base/web/js/lib/renderer/overrides.js deleted file mode 100644 index 4569fc6d34d13b4f021e475c4a12e4ad09d3c0af..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/renderer/overrides.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define(['jquery'], function($) { - 'use strict'; - - return { - - /** - * Removes passed html element. - * @param {HTMLElement} oldPart - html element to remove - */ - remove: function(oldPart) { - $(oldPart).remove(); - }, - - /** - * Picks last node of newParts and replaces oldPart node with it. - * @param {HTMLElement} oldPart - html element to replace - * @param {Array} newParts - array of html elements - */ - replace: function(oldPart, newParts) { - var newPart = _.last(newParts); - - $(oldPart).replaceWith(newPart); - }, - - /** - * Picks last node of newParts and replaces oldPart node with it's children. - * @param {HTMLElement} oldPart - html element to replace - * @param {HTMLElement} newParts - array of html elements - */ - body: function(oldPart, newParts) { - var newPart = _.last(newParts); - - $(oldPart).replaceWith(newPart.children); - }, - - /** - * Picks the last item of newParts array and overides oldPart's html attributes with ones of it's own. - * @param {HTMLElement} oldPart - target html element to update - * @param {Array} newParts - array of html elements to get attributes from - */ - update: function(oldPart, newParts) { - var newPart = _.last(newParts); - - var attributes = newPart.attributes; - var value, name; - - _.each(attributes, function(attr) { - value = attr.value; - name = attr.name; - - if (attr.name.indexOf('data-part') !== -1) { - return; - } - - $(oldPart).attr(name, value); - }); - }, - - /** - * Prepends oldPart with each html element's children from newParts array. - * @param {HTMLElement} oldPart - html element to prepend to - * @param {Array} newParts - array of html elements to get attributes from - */ - prepend: function(oldPart, newParts) { - newParts.forEach(function (node) { - $(oldPart).prepend(node.children); - }); - }, - - /** - * Appends oldPart with each html element's children from newParts array. - * @param {HTMLElement} oldPart - html element to append to - * @param {Array} newParts - array of html elements to get attributes from - */ - append: function(oldPart, newParts) { - newParts.forEach(function (node) { - $(oldPart).append(node.children); - }); - }, - - /** - * @return {Array} - array of strings representing available set of actions - */ - getActions: function() { - return 'replace remove body update append prepend'.split(' '); - } - }; -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js b/app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js index 3237dfd4ffef689634a37860f0a10941c5ab2c0e..9da1291111f07e421eb1f41ca8b1ee6aa67bf1bb 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js @@ -4,53 +4,28 @@ */ define([ '../loader', - './overrides', 'jquery', 'underscore' -], function(loader, overrides, $, _) { +], function (loader, $, _) { 'use strict'; return { - /** * Renders template and it's extenders using this._parse function. * Loads all extenders then merges them and wraps into div[data-template-extend="parent"] where parent is target template. * If no extenders provider, simply loads target template and passes execution to _parse. * @param {String} template - string, representing path to core template and it's extenders. - * @param {Array} extenders - array of strings - * @return {Deferred} - Promise of template to be rendered. Is being resolved with array of HTML elements. + * @returns {Deferred} - Promise of template to be rendered. Is being resolved with array of HTML elements. */ - render: function (template, extenders) { + render: function (template) { var isRendered = $.Deferred(), - parent = template, - - extenders = extenders || [], - extendersToLoad = [], - extendersHtml = '', - resolve = isRendered.resolve.bind(isRendered), loadTemplate = this._load.bind(this), parseTemplate = this._parse.bind(this); - if (extenders.length) { - - loadTemplate.apply(this, extenders).done(function () { - - toArray(arguments).forEach(function (chunk) { - extendersHtml += chunk; - }); - - extendersHtml = '<div data-template-extend="' + parent+ '">' + extendersHtml + '</div>'; - - parseTemplate(extendersHtml).done(resolve); - - }); - } else { - - loadTemplate(parent) - .then(parseTemplate) - .done(resolve); - } + loadTemplate(template) + .then(parseTemplate) + .done(resolve); return isRendered.promise(); }, @@ -73,186 +48,8 @@ define([ * @param {String} rawHtml - loaded raw text (html) * @return {Deferred} - Promise of template to be parsed. Is being resolved with array of HTML elements. */ - _parse: function(rawHtml) { - var templatePath, - templateContainer, - extendNodes, - templatesToRender = [], - extendPointsToRender = []; - - templateContainer = document.createElement('div'); - - wrap(toArray($.parseHTML(rawHtml)), templateContainer); - - extendNodes = getExtendNodesFrom(templateContainer); - templatesToRender = extendNodes.map(extractTemplatePath, this) - extendPointsToRender = templatesToRender.map(this.render, this); - - return waitFor(extendPointsToRender).then(function() { - var correspondingExtendNode, - container, - newParts = [], - args = toArray(arguments); - - args.forEach(function(renderedNodes, idx) { - container = document.createElement('div'); - wrap(renderedNodes, container); - - correspondingExtendNode = extendNodes[idx]; - newParts = this._buildPartsMapFrom(correspondingExtendNode); - - $(correspondingExtendNode).empty(); - - this._overridePartsOf(container, newParts) - .replace(correspondingExtendNode); - - }, this); - - return toArray(templateContainer.childNodes); - }.bind(this)); - }, - - /** - * Builds parst map from HTML element by looking for all available override actions selectors. - * @param {HTMLElement} container - container to look up for new parts declarations - * @return {Object} - Map of parts to apply. E.g. { toolbar: { replace: [HTMLElement1, HTMLElement2], append: [HTMLElement3] } } - */ - _buildPartsMapFrom: function(container) { - var partsMap = {}, - actionNodes, - partSelector, - targetPart, - actions = overrides.getActions(); - - actions.forEach(function(action) { - partSelector = createActionSelectorFor(action); - actionNodes = toArray(container.querySelectorAll(partSelector)); - - actionNodes.forEach(function(node) { - targetPart = node.getAttribute('data-part-' + action); - - if (!partsMap[targetPart]) { - partsMap[targetPart] = {}; - } - - targetPart = partsMap[targetPart]; - - if (!targetPart[action]) { - targetPart[action] = []; - } - - targetPart[action].push(node); - }); - }); - - return partsMap; - }, - - /** - * Loops over newParts map and invokes override actions for each found. - * @param {HTMLElement} template - container to look for parts to be overrided by new ones. - * @param {Object} newParts - the result of _buildPartsMapFrom method. - * @return {Object} - */ - _overridePartsOf: function(template, newParts) { - var oldElement; - - _.each(newParts, function(actions, partName) { - _.each(actions, function(newElements, action) { - - oldElement = template.querySelector(createPartSelectorFor(partName)); - overrides[action]( - oldElement, - newElements - ); - - }); - }); - - return { - - /** - * Replaces extendNode with the result of overrides - * @param {HTMLElement} extendNode - initial container of new parts declarations - */ - replace: function(extendNode) { - $(extendNode).replaceWith(template.childNodes); - } - } + _parse: function (rawHtml) { + return _.toArray($.parseHTML(rawHtml)); } }; - - /** - * Extracts template path from node by [data-part-extend] attribute - * @param {HTMLElement} node - node to look up for [data-part-extend] attr - * @return {String} - value of [data-part-extend] attribute - */ - function extractTemplatePath(node) { - return node.getAttribute('data-template-extend'); - } - - /** - * Looks up for [data-template-extend] selector in container. - * @param {HTMLElement} container - node to lookup - * @return {Array} - array of found HTML elements - */ - function getExtendNodesFrom(container) { - return toArray(container.querySelectorAll('[data-template-extend]')) - } - - /** - * Checks if passed object has keys. - * @param {Object} object - target object - * @return {Boolean} - true, if object has no keys - */ - function isEmpty(object) { - return !Object.keys(object).length; - } - - /** - * Wraps nodes into container - * @param {Array} nodes - array of nodes - * @param {HTMLElement} container - target container - */ - function wrap(nodes, container) { - nodes.forEach(function (node) { - container.appendChild(node); - }); - } - - /** - * Creates action selector. - * @param {String} action - * @return {String} - Action selector - */ - function createActionSelectorFor(action) { - return '[data-part-' + action + ']'; - } - - /** - * Creates data-part selector. - * @param {String} part - * @return {String} - Part selector - */ - function createPartSelectorFor(part) { - return '[data-part="' + part + '"]'; - } - - /** - * Converts arrayLikeObject to array - * @param {Object|Array} arrayLikeObject - target - * @return {Array} - result array - */ - function toArray(arrayLikeObject) { - return Array.prototype.slice.call(arrayLikeObject); - } - - /** - * Waits for all items in passed array of promises to resolve. - * @param {Array} promises - array of promises - * @return {Deferred} - promise of promises to resolve - */ - function waitFor(promises) { - return $.when.apply(this, promises); - } -}); \ No newline at end of file +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/request_builder.js b/app/code/Magento/Ui/view/base/web/js/lib/request_builder.js deleted file mode 100644 index a70d13af32c6450cce6825bd10e81218db2a2055..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/request_builder.js +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -/** - * @returns {Function} Request builder function. - */ -define([ - 'Magento_Ui/js/lib/utils' -], function(utils) { - 'use strict'; - - /** - * @param {String} - name of params set - * @param {Object} - params to convert - * @returns {String} - concatenated name/params pairs by custom logic and separator - * @private - */ - function parseObject(name, value) { - var key, - result = []; - - for (key in value) { - result.push(name + '[' + key + ']' + '=' + value[key]) - } - - return result.join('&'); - } - - /** - * @param {String} - name of property - * @param {String} - corresponding value - * @returns {String} - concatenated params by separator "=" - * @private - */ - function parseValue(name, value) { - return name + '=' + value; - } - - /** - * Extracts sorting parameters from object and returns string representation of it. - * @param {Object} param - Sorting parameters object, e.g. { field: 'field_to_sort', dir: 'asc' }. - * @returns {String} - Chunk of url string that represents sorting params - * @private - */ - function extractSortParams(params) { - var result, - sorting = params.sorting; - - if (typeof sorting === 'undefined') { - return ''; - } - - result = '/sort/' + sorting.field + '/dir/' + sorting.direction; - - delete params.sorting; - - return result; - } - - /** - * Extracts pager parameters from an object and returns it's string representation. - * @param {Object} params which contains "paging" params object. - * @returns {String} - Chunk of url string that represents pager params - * @private - */ - function extractPagerParams(params) { - var result, - paging = params.paging; - - if (typeof paging === 'undefined') { - return ''; - } - - result = '/limit/' + paging.pageSize + '/page/' + paging.current; - - delete params.paging; - - return result; - } - - /** - * Formats filter data according to the type of it's value. - * @param {Object} filter - filter object to format. - * @returns {String} - Chunk of url string that represents filter's params - * @private - */ - function formatFilter(filter) { - var name = filter.field, - value = filter.value; - - return typeof value !== 'object' ? - parseValue(name, value) : - parseObject(name, value); - } - - /** - * Formats and assembles filter data. - * @param {Object} params - object containing "filter" array. - * @returns {String} - Chunk of url string that represents filters - * @private - */ - function extractFilterParams(params) { - var filters, - result; - - filters = params.filter; - - if (typeof filters === 'undefined' || !filters.length) { - return ''; - } - - result = filters.map(formatFilter).join('&'); - - result = '/filter/' + utils.btoa(encodeURI(result)); - - delete params.filter; - - return result; - } - - return function(root, params) { - var url, - lastChar; - - lastChar = root.charAt(root.length - 1); - - if (lastChar === '/') { - root = root.substr(0, root.length - 1); - } - - url = - root + - extractSortParams(params) + - extractPagerParams(params) + - extractFilterParams(params); - - return url; - }; - -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/rest.js b/app/code/Magento/Ui/view/base/web/js/lib/rest.js deleted file mode 100644 index 2c29c393ad314cc0ea2759fad20e0440a2c9d6f7..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/rest.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'underscore', - 'jquery', - 'Magento_Ui/js/lib/utils', - 'Magento_Ui/js/lib/class', - 'Magento_Ui/js/lib/events', - './request_builder' -], function(_, $, utils, Class, EventsBus, requestBuilder) { - 'use strict'; - - var defaults = { - ajax: { - dataType: 'json' - } - }; - - return Class.extend({ - initialize: function(config) { - $.extend(true, this.config = {}, defaults, config); - }, - - /** - * Sends ajax request using params and config passed to it and calls this.config.onRead when done. - * @param {Object} params - request body params - * @param {Object} config - config to build url from - */ - read: function(params, config) { - config = this.createConfig(params, config); - - $.ajax(config) - .done(this.onRead.bind(this)); - }, - - /** - * Creates config for ajax call. - * @param {Object} params - request body params - * @param {Object} config - config to build url from - * @returns {Object} - merged config for ajax call - */ - createConfig: function(params, config) { - var baseConf; - - config = config || {}; - params = params || {}; - - baseConf = { - url: requestBuilder(this.config.root, params), - data: params - }; - - return $.extend(true, baseConf, this.config.ajax, config); - }, - - /** - * Callback of ajax call. - * Parses results and triggers read event; - * @param {Object|*} result - Result of ajax call. - */ - onRead: function(result){ - result = typeof result === 'string' ? - JSON.parse(result) : - result; - - this.trigger('read', result); - }, - - /** - * Submits data using utils.submitAsForm - * @param {Object} config - object containing ajax options - */ - submit: function(config){ - var ajax = this.config.ajax, - data = ajax.data || {}; - - _.extend(config.data, data); - - utils.submitAsForm(config); - } - }, EventsBus); - -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/spinner.js b/app/code/Magento/Ui/view/base/web/js/lib/spinner.js index 4a9eae7d96340bd74c59b178025686c14f601723..a610c194333530d7706ceb4c15fb368807e6acc8 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/spinner.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/spinner.js @@ -7,8 +7,8 @@ define([ ], function ($) { 'use strict'; - var selector = '[data-role="spinner"]', - spinner = $(selector); + var selector = '[data-role="spinner"]', + spinner = $(selector); return { show: function () { @@ -22,5 +22,5 @@ define([ get: function (id) { return $(selector + '[data-component="' + id + '"]'); } - } -}); \ No newline at end of file + }; +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/storage/dump.js b/app/code/Magento/Ui/view/base/web/js/lib/storage/dump.js deleted file mode 100644 index 8c904764da3fde329e62aefac46849b762dc453e..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/storage/dump.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - './storage', - 'Magento_Ui/js/lib/deferred_events' -], function (Storage, DeferredEvents) { - return Storage.extend({}, DeferredEvents); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/storage/index.js b/app/code/Magento/Ui/view/base/web/js/lib/storage/index.js deleted file mode 100644 index ca58235fa19b4adbc060bc76bba9be29d4711b9e..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/storage/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -/** - * Assembles storages returning storage mapping - */ -define([ - './storage', - './meta', - './dump' -], function(Storage, MetaStorage, DumpStorage){ - 'use strict'; - - return { - meta: MetaStorage, - params: Storage, - config: Storage, - data: Storage, - dump: DumpStorage - } -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/storage/meta.js b/app/code/Magento/Ui/view/base/web/js/lib/storage/meta.js deleted file mode 100644 index d3cee2931c4d68da898f7dc461c23c0ce7c7e761..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/storage/meta.js +++ /dev/null @@ -1,186 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'underscore', - './storage' -], function(_, Storage) { - 'use strict'; - - /** - * Loops over first level of object looking for valueKey of typeof object values - * to be typeof object as well. Breaks loop on first entry on one. - * @param {Object} target - * @param {String} valueKey - complex to look for - * @return {Boolean} - */ - function hasComplexValue(target, valueKey) { - var result = false, - key, - object; - - - for (key in target) { - object = target[key]; - - if (typeof object === 'object' && typeof object[valueKey] === 'object') { - result = true; - break; - } - } - - return result; - } - - /** - * Recursively loops over object's properties and converts it to array ignoring keys. - * If typeof 'value' properties is 'object', creates 'items' property and assigns - * execution of nestedObjectToArray on 'value' to it. - * If typeof 'value' key is not an 'object', is simply writes an object itself to result array. - * @param {Object} obj - * @return {Array} result array - */ - function nestedObjectToArray(obj, valueKey) { - var target, - items = []; - - for (var prop in obj) { - - target = obj[prop]; - if (typeof target[valueKey] === 'object') { - - target.items = nestedObjectToArray(target[valueKey], valueKey); - delete target[valueKey]; - } - items.push(target); - } - - return items; - } - - return Storage.extend({ - - /** - * Initializes data prop based on data argument. - * Calls initFields and initColspan methods - * @param {Object} config - */ - initialize: function(data) { - this.data = data || {}; - - this.initFields() - .initColspan(); - }, - - /** - * Formats fields property to compatible format. - * Processes those. Assignes fiedls to data.fields. - * @return {Object} - reference to instance - */ - initFields: function(){ - var data = this.data, - fields = data.fields; - - fields = this._fieldsToArray(fields); - - fields.forEach(this._processField, this); - - data.fields = fields; - - return this; - }, - - /** - * Assigns data.colspan to this.getVisible().length - * @return {Object} - reference to instance - */ - initColspan: function(){ - var visible = this.getVisible(); - - this.data.colspan = visible.length; - - return this; - }, - - /** - * Assignes default params to field - * @param {Object} field - * @return {Object} reference to instance - */ - applyDefaults: function(field) { - var defaults = this.data.defaults; - - if (defaults) { - _.defaults(field, defaults); - } - - return this; - }, - - /** - * Format options based on those being nested - * @param {Object} field - * @return {Object} reference to instance - */ - formatOptions: function(field) { - var result, - options, - isNested; - - options = field.options; - - if (options) { - result = {}; - isNested = hasComplexValue(options, 'value'); - - if(isNested){ - result = nestedObjectToArray(options, 'value'); - } - else{ - _.each(options, function(option){ - result[option.value] = option.label; - }); - } - - field.options = result; - } - - return this; - }, - - /** - * Returns filted by visible property fields array. - * @return {Array} filted by visible property fields array - */ - getVisible: function(){ - var fields = this.data.fields; - - return fields.filter(function(field){ - return field.visible; - }); - }, - - /** - * Convertes fields object to array, assigning key to index property. - * @param {Object} fields - * @return {Array} array of fields - */ - _fieldsToArray: function(fields){ - return _.map(fields, function(field, id){ - field.index = id; - - return field; - }); - }, - - /** - * Calls applyDefaults and formatOptions on field - * @param {Object} field - */ - _processField: function(field){ - this.applyDefaults(field) - .formatOptions(field); - } - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/storage/storage.js b/app/code/Magento/Ui/view/base/web/js/lib/storage/storage.js deleted file mode 100644 index e0075c746b5466e8d48e247ea3e9dd9eea7e0588..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/storage/storage.js +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'underscore', - '../class', - '../events', - 'mage/utils' -], function(_, Class, EventsBus, utils) { - 'use strict'; - - return Class.extend({ - - /** - * Inits this.data to incoming data - * @param {Object} data - */ - initialize: function(data) { - this.data = data || {}; - }, - - /** - * If path specified, returnes this.data[path], else returns this.data - * @param {String} path - * @return {*} this.data[path] or simply this.data - */ - get: function(path) { - return utils.nested(this.data, path); - }, - - /** - * Sets value property to path and triggers update by path, passing result - * @param {String|*} path - * @param {String|*} value - * @return {Object} reference to instance - */ - set: function(path, value){ - var result = this._override.apply(this, arguments); - - value = result.value; - path = result.path; - - this.trigger('update', value); - - if (path) { - this.trigger('update:' + path, value); - } - - return this; - }, - - remove: function (path) { - utils.nestedRemove(this.data, path); - - return this; - }, - - /** - * Assignes props to this.data based on incoming params - * @param {String|*} path - * @param {*} value - * @return {Object} - */ - _override: function(path, value) { - if (arguments.length > 1) { - utils.nested(this.data, path, value); - } else { - value = path; - path = false; - - this.data = value; - } - - return { - path: path, - value: value - }; - } - - }, EventsBus); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/lib/utils.js b/app/code/Magento/Ui/view/base/web/js/lib/utils.js deleted file mode 100644 index dcc7c65e3255f6663273451b11916e8bc8c43f60..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/lib/utils.js +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'underscore', - 'mage/utils' -], function(_, utils) { - 'use strict'; - - var utils = {}, - atobSupport, - btoaSupport; - - atobSupport = typeof atob === 'function'; - btoaSupport = typeof btoa === 'function'; - - /** - * Base64 encoding/decoding methods. - * First check for native support. - */ - if( btoaSupport && atobSupport ){ - _.extend(utils, { - atob: function(input){ - return window.atob(input); - }, - - btoa: function(input){ - return window.btoa(input); - } - }); - } - else{ - _.extend(utils, { - atob: function(input){ - return Base64.decode(input) - }, - - btoa: function(input){ - return Base64.encode(input); - } - }); - } - - /** - * Submits specified data as a form object. - * @param {Object} params - Parameters of form. - */ - utils.submitAsForm = function(params){ - var form, - field; - - form = document.createElement('form'); - - form.setAttribute('method', params.method); - form.setAttribute('action', params.action); - - _.each(params.data, function(value, name){ - field = document.createElement('input'); - - if(typeof value === 'object'){ - value = JSON.stringify(value); - } - - field.setAttribute('name', name); - field.setAttribute('type', 'hidden'); - - field.value = value; - - form.appendChild(field); - }); - - document.body.appendChild(form); - - form.submit(); - }; - - return utils; -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter.js b/app/code/Magento/Ui/view/base/web/js/listing/filter.js deleted file mode 100644 index 95f58dde2c123d688562ca465e4973f51d57b909..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/listing/filter.js +++ /dev/null @@ -1,271 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'underscore', - 'Magento_Ui/js/lib/ko/scope', - 'Magento_Ui/js/lib/component' -], function(_, Scope, Component) { - 'use strict'; - - var BASE_PATH = 'Magento_Ui/js/listing/filter'; - - var defaults = { - types: { - filter_input: BASE_PATH + '/input', - filter_select: BASE_PATH + '/select', - filter_range: BASE_PATH + '/range', - filter_date: BASE_PATH + '/date' - } - }; - - var Filter = Scope.extend({ - /** - * Initializes instance properties - * @param {Object} config - Filter component configuration - */ - initialize: function(config) { - _.extend(this, config); - - this.initObservable() - .loadControls(); - }, - - /** - * Callback method that proceeds initialization of filter component. - */ - proceed: function () { - this.extractFields() - .initFilters(); - }, - - /** - * Initiates loading of filters constructors. - */ - loadControls: function () { - var coreTypes = defaults.types, - paths, - types; - - types = _.map(this.types, function (config, type) { - config.name = type; - - if(!config.control){ - config.control = coreTypes[type]; - } - - return config; - }); - - paths = _.pluck(types, 'control'); - - require(paths, this.onControlsLoaded.bind(this, types)); - }, - - /** - * Initializes observable properties of instance. - * @returns {Filter} Chainbale. - */ - initObservable: function(){ - this.observe({ - isVisible: false, - active: [], - filters: [] - }); - - return this; - }, - - /** - * Filters filterable fields and stores them to this.fields - * @returns {Filter} Chainbale. - */ - extractFields: function () { - var provider = this.provider.meta, - fields = provider.getVisible(); - - this.fields = fields.filter(function (field) { - return field.filterable; - }); - - return this; - }, - - /** - * Initializes filters by creating instances of - * corresponding classes found in controls by filter type. - * @returns {Filter} Chainbale. - */ - initFilters: function () { - var controls = this.types, - config, - type, - filters, - control; - - filters = this.fields.map(function (field) { - type = (field.filter_type || field.input_type); - config = controls && controls[type]; - control = config.constr; - - field.type = type; - field.module = config.module || 'ui'; - - return new control(field, config); - }, this); - - this.filters(filters); - - return this; - }, - - /** - * Extracts an array of non-empty filters. - * @returns {Array} Array of non-empty filters - */ - getNotEmpty: function(){ - return this.filters().filter(function(filter){ - return !filter.isEmpty(); - }); - }, - - /** - * Writes the result of getNotEmpty to active observable. - * @returns {Filter} Chainbale. - */ - findActive: function(){ - this.active(this.getNotEmpty()); - - return this; - }, - - /** - * Returns an array filters' data. - * @param {Boolean} [all=false] - - Whether to extract data from all of the filters - or from only the active ones. - * @returns {Array} Array of filters' data. - */ - getData: function(all){ - var filters; - - filters = all ? this.filters() : this.active(); - - return filters.map(function(filter){ - return filter.dump(); - }); - }, - - /** - * Clears data of all filters or of specified one. - * @param {Object} [filter] - If specified, clears data only of this filter. - * @returns {Filter} Chainbale. - */ - clearData: function(filter){ - var active = this.active; - - if(filter){ - filter.reset(); - - active.remove(filter); - } - else{ - this.filters().forEach(function (filter) { - filter.reset(); - }); - - active.removeAll(); - } - - return this; - }, - - /** - * Updates an array of active filters - * and reloads data provider with new filtering parameters. - * @returns {Filter} Chainbale. - */ - apply: function () { - this.findActive() - .reload(); - - return this; - }, - - /** - * Clears filters and updates data provider with new filtering parameters. - * @param {Object} [filter] - If specified then clears only this filter. - * @returns {Filter} Chainbale. - */ - reset: function(filter){ - this.clearData(filter) - .reload(); - - return this; - }, - - /** - * Sets set of params to storage. - * @param {*} action - data to set to storage params - * @returns {Filter} Chainbale. - */ - pushParams: function() { - var params = this.provider.params; - - params.set('filter', this.getData()); - - return this; - }, - - /** - * @description Toggles isVisible observable property - */ - toggle: function () { - this.isVisible(!this.isVisible()); - }, - - /** - * @description Sets isVisible observable property to false - */ - close: function () { - this.isVisible(false); - }, - - /** - * Resets specified filter using reset method - * @param {Object} filter - filter to reset - */ - onClear: function(filter) { - return this.reset.bind(this, filter); - }, - - /** - * Callback that fires when all of the filters constructors has been loaded. - * @param {Array} controlsMap - An array of availbale filter types and theirs configuration. - */ - onControlsLoaded: function (controlsMap) { - var controls = Array.prototype.slice.call(arguments, 1), - types = {}, - control; - - controls.forEach(function (constr, idx) { - control = controlsMap[idx]; - - delete control.control; - - control.constr = constr; - - types[control.name] = control; - }); - - this.types = types; - - this.proceed(); - } - }); - - return Component({ - constr: Filter - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/abstract.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/abstract.js deleted file mode 100644 index bf52c36dd9aa4478fa96a7cef7ce000e2bb82fe5..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/listing/filter/abstract.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'Magento_Ui/js/lib/ko/scope', - 'underscore' -], function (Scope, _) { - 'use strict'; - - return Scope.extend({ - - /** - * Extends instance with data passed. - * @param {Object} data - Item of "fields" array from grid configuration - * @param {Object} config - Filter configuration - */ - initialize: function (data, config) { - _.extend(this, data); - this.config = config; - - this.observe('output', ''); - }, - - isEmpty: function () {}, - - /** - * Returns alias for filter item template - * @return {String} - */ - getTemplate: function () { - return this.module + '/filter/' + this.type; - } - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/date.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/date.js deleted file mode 100644 index bff6c90fc63f7727483217c47ec08ddc1e88b964..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/listing/filter/date.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - './range' -], function (Range) { - 'use strict'; - - return Range; -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/filters.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/filters.js deleted file mode 100644 index 147b2b1d508e7a4d8c745fa7cf1bafd65880c0fd..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/listing/filter/filters.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -/** Assembles available filter controls and returns it's mapping. */ -define([ - './input', - './select', - './range' -], function (InputControl, SelectControl, RangeControl) { - 'use strict'; - - return { - input: InputControl, - select: SelectControl, - date: RangeControl, - range: RangeControl, - store: SelectControl - } -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/input.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/input.js deleted file mode 100644 index fdd6735151fff7d92e91d6755dcce103f63e10ab..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/listing/filter/input.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - './abstract', - 'underscore' -], function (AbstractControl, _) { - 'use strict'; - - return AbstractControl.extend({ - - /** - * Invokes initialize method of parent class and initializes observable properties of instance. - * @param {Object} data - Item of "fields" array from grid configuration - * @param {Object} config - Filter configuration - */ - initialize: function (data) { - this.constructor.__super__.initialize.apply(this, arguments); - - this.observe('value', ''); - }, - - /** - * Returnes true if this.value is falsy - * @return {Boolean} true if this.value is falsy, false otherwise - */ - isEmpty: function(){ - return !this.value(); - }, - - /** - * Returns this.value(). Is used for displaying on UI. - * @return {[type]} [description] - */ - display: function(){ - return this.value(); - }, - - /** - * Returns dump of instance's current state - * @returns {Object} - object which represents current state of instance - */ - dump: function () { - this.output( this.display() ); - - return { - field: this.index, - value: this.value() - }; - }, - - /** - * Resets state properties of instance and calls dump method. - * @returns {Object} - object which represents current state of instance - */ - reset: function () { - this.value(null); - - return this.dump(); - } - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/range.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/range.js deleted file mode 100644 index 69ac544fdb229f0581c28a51ba9bd9f77b9c9c67..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/listing/filter/range.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - './abstract', - 'underscore' -], function (AbstractControl, _) { - 'use strict'; - - return AbstractControl.extend({ - - /** - * Invokes initialize method of parent class and initializes observable properties of instance. - * @param {Object} data - Item of "fields" array from grid configuration - * @param {Object} config - Filter configuration - */ - initialize: function (data, config) { - this.constructor.__super__.initialize.apply(this, arguments); - - this.observe({ - from: '', - to: '' - }); - }, - - /** - * Creates dump copy of current state. - * @return {Object} dumped value object - */ - getValues: function(){ - var value = {}, - from = this.from(), - to = this.to(); - - if (from) { - value.from = from; - } - - if (to) { - value.to = to; - } - - return value; - }, - - /** - * Returns string value of current state for UI - * @return {String} - */ - display: function(){ - var values = this.getValues(); - - return _.map(values, function(value, name){ - return name + ': ' + value; - }).join(' '); - }, - - /** - * Checkes if current state is empty. - * @return {Boolean} - */ - isEmpty: function(){ - return ( !this.to() && !this.from() ); - }, - - /** - * Returns dump of instance's current state - * @returns {Object} - object which represents current state of instance - */ - dump: function () { - this.output( this.display() ); - - return { - field: this.index, - value: this.getValues() - }; - }, - - /** - * Resets state properties of instance and calls dump method. - * @returns {Object} - object which represents current state of instance - */ - reset: function () { - this.to(''); - this.from(''); - } - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/select.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/select.js deleted file mode 100644 index 128cc59eb53b84530fee7c39591ddceeedbfef79..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/listing/filter/select.js +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - './abstract', - 'underscore' -], function (AbstractControl, _) { - 'use strict'; - - return AbstractControl.extend({ - - /** - * Invokes initialize method of parent class and initializes properties of instance. - * @param {Object} data - Item of "fields" array from grid configuration - * @param {Object} config - Filter configuration - */ - initialize: function (data) { - this.constructor.__super__.initialize.apply(this, arguments); - - this.caption = 'Select...'; - - this.observe('selected', ''); - - this.options = this.options ? this.formatOptions(this.options) : []; - }, - - /** - * Checkes if current state is empty. - * @return {Boolean} - */ - isEmpty: function(){ - var selected = this.selected(); - - return !(selected && selected.value); - }, - - /** - * Formats options property of instance. - * @param {Object} options - object representing options - * @returns {Array} - Options, converted to array - */ - formatOptions: function (options) { - return _.map(options, function (value, key) { - return { value: key, label: value }; - }); - }, - - /** - * Returns string value of current state for UI - * @return {String} - */ - display: function(){ - var selected = this.selected(); - - return selected && selected.label; - }, - - /** - * Returns dump of instance's current state - * @returns {Object} - object which represents current state of instance - */ - dump: function () { - var selected = this.selected(); - - this.output( this.display() ); - - return { - field: this.index, - value: selected && selected.value - } - }, - - /** - * Resets state properties of instance and calls dump method. - * @returns {Object} - object which represents current state of instance - */ - reset: function () { - this.selected(null); - } - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/listing/grid.js b/app/code/Magento/Ui/view/base/web/js/listing/grid.js deleted file mode 100644 index e074902586342a9b8e7b80700eb565468462fcd2..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/listing/grid.js +++ /dev/null @@ -1,222 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'underscore', - 'Magento_Ui/js/lib/component', - 'Magento_Ui/js/lib/ko/scope', - 'Magento_Ui/js/lib/mixins/loader', -], function(_, Component, Scope, Loader) { - 'use strict'; - - var Listing = Scope.extend({ - - /** - * Extends instance with defaults and config, initializes observable properties. - * Updates provider with current state of instance. - * @param {Object} settings - */ - initialize: function(settings) { - _.extend(this, settings); - - this.initFields() - .initObservable() - .initListeners() - .updateItems(); - - this.unlock(); - }, - - /** - * Initializes raw properties - * @return {Object} reference to instance - */ - initFields: function(){ - this.meta = this.provider.meta; - this.fields = this.meta.getVisible(); - this.itemActionKey = this.meta.get('item_action'); - - return this; - }, - - /** - * Initializes observable properties of instance. - * @return {Object} - reference to instance - */ - initObservable: function() { - this.observe({ - rows: [], - isLocked: false, - colspan: this.meta.get('colspan'), - extenders: null, - templateExtenders: [] - }); - - return this; - }, - - /** - * Init instance's subscribtions - * @return {Object} - reference to instance - */ - initListeners: function() { - var provider = this.provider, - meta = provider.meta, - dump = provider.dump; - - _.bindAll(this, 'lock', 'onRefresh', 'updateExtenders', 'updateColspan'); - - provider.on({ - 'beforeRefresh': this.lock, - 'refresh': this.onRefresh - }); - - dump.when('update:extenders', this.updateExtenders); - meta.on('update:colspan', this.updateColspan); - - return this; - }, - - /** - * Is being called when some component pushed it's extender to global storage. - * Preprocesses incoming array of extenders and sets the results into extenders - * and templateExtenders observable arrays - * @param {Array} extenders - */ - updateExtenders: function (extenders) { - var adjusted = extenders.reduce(function (adjusted, extender) { - - adjusted[extender.as] = extender.name; - return adjusted; - - }, {}); - - this.extenders(adjusted); - - this.templateExtenders(extenders.map(this.adjustTemplateExtender, this)); - }, - - /** - * Fetches items from storage and stores it into rows observable array - * @return {Object} - reference to instance - */ - updateItems: function() { - var items = this.provider.data.get('items'); - - this.rows(items.map(this.formatItem, this)); - - return this; - }, - - formatItem: function (item) { - var actions = item.actions, - itemActionKey = this.itemActionKey, - itemAction; - - if (actions) { - itemAction = actions[itemActionKey]; - item.action_url = itemAction.href; - - if (itemAction.hidden) { - delete item.actions[itemActionKey]; - } - - item.actions = _.map(item.actions, function (action) { return action }); - } - - return item; - }, - - applyItemActionFor: function (item) { - return this.redirectTo.bind(this, item.action_url); - }, - - /** - * Returns extender by name of component which set it. - * @param {String} name - * @return {String} - Namespace string by which target component is registered in storage. - */ - getExtender: function(name) { - var extenders = this.extenders(); - - return extenders ? (this.parent_name + ':' + extenders[name]) : null; - }, - - /** - * Returns path to template for arbitrary field - * @param {String} field - * @return {String} - path to template - */ - getCellTemplateFor: function(field) { - return this.getRootTemplatePath() + '/cell/' + field.data_type; - }, - - /** - * Returns object which represents template bindings params - * @return {Object} - template binding params - */ - getTemplate: function() { - return { - name: this.getRootTemplatePath(), - extenders: this.templateExtenders() - }; - }, - - /** - * Generates template path for extender. - * @param {Object} extender - * @return {String} - extender's template path - */ - adjustTemplateExtender: function (extender) { - return this.getRootTemplatePath() + '/extender/' + extender.path; - }, - - /** - * Returns root template path for grid - * @return {String} - root template path - */ - getRootTemplatePath: function() { - return 'ui/listing/grid'; - }, - - /** - * Provider's refresh event's handler. - * Locks grid and updates items. - */ - onRefresh: function() { - this.unlock() - .updateItems(); - }, - - /** - * Updates colspan observable property - * @param {String} colspan - */ - updateColspan: function(colspan){ - this.colspan(colspan); - }, - - /** - * Sets location.href to target url - * @param {String} url - */ - redirectTo: function (url) { - if (url) { - window.location.href = url; - } - }, - - /** - * Indicates if rows observable array is empty - * @return {Boolean} [description] - */ - hasData: function(){ - return this.rows().length; - } - }, Loader); - - return Component({ - constr: Listing - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/listing/massaction.js b/app/code/Magento/Ui/view/base/web/js/listing/massaction.js deleted file mode 100644 index 2c559de58d1dc287e2c11a6309f19af27e29f105..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/listing/massaction.js +++ /dev/null @@ -1,414 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'jquery', - 'underscore', - 'Magento_Ui/js/lib/ko/scope', - 'Magento_Ui/js/lib/component', - 'mage/translate' -], function ($, _, Scope, Component) { - 'use strict'; - - function capitaliseFirstLetter(string) { - return string.charAt(0).toUpperCase() + string.slice(1); - } - - var defaults = { - actions: [], - deleteMsg: $.mage.__("Are you sure you want to delete these records?"), - notSelected: $.mage.__("You haven't selected any items!"), - selects: [ - { value: 'selectAll', label: 'Select all' }, - { value: 'deselectAll', label: 'Deselect all' }, - { value: 'selectPage', label: 'Select all on this page' }, - { value: 'deselectPage', label: 'Deselect all on this page' } - ], - selectableTemplate: 'selectable' - }; - - var MassActions = Scope.extend({ - - /** - * Extends instance with defaults and config, initializes observable properties. - * Updates storage with current state of instance. - * @param {Object} config - */ - initialize: function (config) { - _.extend(this, defaults, config); - - this.initObservable() - .initProperties() - .formatActions() - .attachTemplateExtender() - .initListeners() - .countPages(); - }, - - /** - * Initializes observable properties of instance. - * @returns {MassActions} Chainable. - */ - initObservable: function () { - this.observe({ - selected: this.selected || [], - excluded: [], - allSelected: this.allSelected || false, - actionsVisible: false, - menuVisible: false, - hasMultiplePages: '' - }); - - this.selected.subscribe(this.onSelectionsChange.bind(this)); - - return this; - }, - - /** - * Initializes instance properties - * @returns {MassActions} Chainable. - */ - initProperties: function () { - var provider = this.provider.meta; - - this.indexField = provider.get('index_field'); - - return this; - }, - - /** - * Convertes incoming optins to compatible format - * @returns {MassActions} Chainable. - */ - formatActions: function(){ - var actions = this.actions; - - if(!Array.isArray(actions)){ - - this.actions = _.map(actions, function(action, name){ - action.value = name; - - return action; - }); - } - - return this; - }, - - /** - * Attaches it's template to provider.dump's extenders - * @returns {MassActions} Chainable. - */ - attachTemplateExtender: function () { - var provider = this.provider, - dump = provider.dump, - meta = provider.meta, - colspan = meta.get('colspan'), - extenders = dump.get('extenders'); - - if(!this.selectableTemplate) { - return this; - } - - extenders.push({ - path: this.selectableTemplate, - name: this.name, - as: 'massaction' - }); - - dump.resolve('update:extenders', extenders); - meta.set('colspan', colspan + 1); - - return this; - }, - - /** - * Init instance's subscribtions - * @returns {MassActions} Chainable. - */ - initListeners: function(){ - this.provider.on('refresh', this.onRefresh.bind(this)); - - return this; - }, - - /** - * Prepares params object, which represents the current state of instance. - * @returns {Object} - params object - */ - buildParams: function () { - if (this.allSelected()) { - - return { - all_selected: true, - excluded: this.excluded() - }; - } - - return { - selected: this.selected() - }; - }, - - /** - * Toggles observable property based on area argument. - * @param {String} area - Name of the area to be toggled. - */ - toggle: function(area){ - var visible = this[area]; - - visible(!visible()); - }, - - /** - * Sets actionsVisible to false - */ - hideActions: function () { - this.actionsVisible(false); - }, - - /** - * Sets menuVisible to false - */ - hideMenu: function () { - this.menuVisible(false); - }, - - /** - * Updates storage's params by the current state of instance - * and hides dropdowns. - * @param {String} action - */ - setAction: function (action) { - return function(){ - this.submit(action) - .hideActions(); - }.bind(this); - }, - - /** - * Sends actions's data to server. - * @param {Object} action - An action object. - * @returns {MassActions} Chainable. - */ - submit: function(action) { - var client = this.provider.client, - value = action.value, - confirmed = true; - - if (!this.count) { - confirmed = false; - - alert(this.notSelected); - } else if (value === 'delete') { - confirmed = confirm(this.deleteMsg); - } - - if (confirmed) { - client.submit({ - method: 'post', - action: action.url, - data: { - massaction: this.buildParams() - } - }); - } - - return this; - }, - - /** - * Retrieve all id's from available records. - * @param {Boolean} [exclude] - Whether to exclude not selected ids' from result. - * @returns {Array} An array of ids'. - */ - getIds: function(exclude){ - var items = this.provider.data.get('items'), - ids = _.pluck(items, this.indexField); - - return exclude ? - _.difference(ids, this.excluded()) : - ids; - }, - - /** - * Sets isAllSelected observable to true and selects all items on current page. - */ - selectAll: function () { - this.allSelected(true); - - this.clearExcluded() - .selectPage(); - }, - - /** - * Sets isAllSelected observable to false and deselects all items on current page. - */ - deselectAll: function () { - this.allSelected(false); - this.deselectPage(); - }, - - /** - * Selects all items on current page, adding their ids to selected observable array - */ - selectPage: function () { - this.selected(this.getIds()); - }, - - /** - * Deselects all items on current page, emptying selected observable array - */ - deselectPage: function () { - this.selected.removeAll(); - }, - - updateExcluded: function(selected) { - var excluded = this.excluded(), - fromPage = _.difference(this.getIds(), selected); - - excluded = _.union(excluded, fromPage); - - excluded = _.difference(excluded, selected); - - this.excluded(excluded); - - return this; - }, - - /** - * Clears the array of not selected records. - * @returns {MassActions} Chainable. - */ - clearExcluded: function(){ - this.excluded.removeAll(); - - return this; - }, - - /** - * Returns handler for row click - * @param {String} url - * @return {Function} click handler - */ - redirectTo: function (url) { - - /** - * Sets location.href to target url - */ - return function () { - window.location.href = url; - } - }, - - /** - * Gets current pages count and assignes it's being more than one to - * hasMultiplePages observable. - * @returns {MassActions} Chainable. - */ - countPages: function() { - var provider = this.provider.data; - - this.pages = provider.get('pages'); - - this.hasMultiplePages(this.pages > 1); - - return this; - }, - - /** - * Counts number of 'selected' items. - * @returns {MassActions} Chainable. - */ - countSelect: function() { - var provider = this.provider, - total = provider.data.get('totalCount'), - excluded = this.excluded().length, - count = this.selected().length; - - if (this.allSelected()) { - count = total - excluded; - } - - provider.meta.set('selected', count); - - this.count = count; - - return this; - }, - - /** - * If isAllSelected is true, deselects all, else selects all - */ - toggleSelectAll: function () { - var isAllSelected = this.allSelected(); - - isAllSelected ? this.deselectAll() : this.selectAll(); - }, - - /** - * Looks up for corresponding to passed action checker method, - * and returnes it's result. If method not found, returnes true; - * @param {String} action - e.g. selectAll, deselectAll - * @returns {Boolean} should action be visible - */ - shouldBeVisible: function (action) { - var checker = this['should' + capitaliseFirstLetter(action) + 'BeVisible']; - - return checker ? checker.call(this) : true; - }, - - /** - * Checkes if selectAll action supposed to be visible - * @returns {Boolean} - */ - shouldSelectAllBeVisible: function () { - return !this.allSelected() && this.hasMultiplePages(); - }, - - /** - * Checkes if deselectAll action supposed to be visible - * @returns {Boolean} - */ - shouldDeselectAllBeVisible: function () { - return this.allSelected() && this.hasMultiplePages(); - }, - - onToggle: function(area){ - return this.toggle.bind(this, area); - }, - - /** - * Creates handler for applying action (e.g. selectAll) - * @param {String} action - * @returns {Function} - click handler - */ - onApplySelect: function (action) { - return function(){ - this.menuVisible(false); - this[action](); - }.bind(this); - }, - - /** - * Updates state according to changes of provider. - */ - onRefresh: function () { - if( this.allSelected() ){ - this.selected(this.getIds(true)); - } - - this.countPages(); - }, - - onSelectionsChange: function(selected){ - this.updateExcluded(selected) - .countSelect(); - } - }); - - return Component({ - constr: MassActions - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/listing/paging.js b/app/code/Magento/Ui/view/base/web/js/listing/paging.js deleted file mode 100644 index c32df63ed9b108c39bad296081b2e6abade4b1a2..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/listing/paging.js +++ /dev/null @@ -1,191 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'underscore', - '../lib/ko/scope', - '../lib/component' -], function(_, Scope, Component) { - 'use strict'; - - var defaults = { - sizes: [5, 10, 20, 30, 50, 100, 200], - params: { - dir: 'paging', - items: ['pageSize', 'current'] - } - }; - - var Paging = Scope.extend({ - - /** - * Extends instance with defaults and config, initializes observable properties. - * Updates storage with current state of instance. - * @param {Object} config - */ - initialize: function(config) { - _.extend(this, defaults, config); - - this.initObservable(config) - .initProvider() - .pushParams(); - }, - - /** - * Initializes observable properties of instance. - * @return {Object} - reference to instance - */ - initObservable: function(config) { - var data = this.provider.data.get(); - - this.observe({ - 'pages': data.pages || 1, - 'totalCount': data.totalCount, - 'current': this.current, - 'pageSize': this.pageSize, - 'selected': 0 - }); - - return this; - }, - - /** - * Subscribes on provider's events - * @returns {Paging} Chainable. - */ - initProvider: function(){ - var provider = this.provider, - params = provider.params, - meta = provider.meta; - - _.bindAll(this, 'drop', 'onRefresh', 'pullParams', 'updateSelected'); - - provider.on('refresh', this.onRefresh); - - meta.on('update:selected', this.updateSelected); - - params.on({ - 'update:filter': this.drop, - 'update:sorting': this.drop, - 'update:paging': this.pullParams - }); - - return this; - }, - - /** - * Increments current observable prop by val and call reload method - * @param {String} val - */ - go: function(val) { - var current = this.current; - - current(current() + val); - - this.reload(); - }, - - /** - * Calls go method with 1 as agrument - */ - next: function() { - this.go(1); - }, - - /** - * Calls go method with -1 as agrument - */ - prev: function() { - this.go(-1); - }, - - /** - * Compares current and pages observables and returns boolean result - * @return {Boolean} is current equal to pages property - */ - isLast: function() { - return this.current() === this.pages(); - }, - - /** - * Compares current observable to 1 - * @return {Boolean} is current page first - */ - isFirst: function() { - return this.current() === 1; - }, - - /** - * Returns closest existing page number to page argument - * @param {Number} page - * @return {Number} closest existing page number - */ - getInRange: function(page) { - return Math.min(Math.max(1, page), this.pages()); - }, - - /** - * Sets current observable to 1 and calls pushParams method - */ - drop: function() { - this.current(1); - - this.pushParams(); - }, - - /** - * Updates number of selected items. - * @param {Number} count - New number of selected items. - */ - updateSelected: function(count){ - this.selected(count); - }, - - /** - * Is being called on provider's refresh event. - * Updates totalCount and pages observables - */ - onRefresh: function() { - var data = this.provider.data.get(); - - this.totalCount(data.totalCount); - this.pages(data.pages || 1); - }, - - /** - * Is being triggered on user interaction with page size select. - * Resets current page to first if needed. - */ - onSizeChange: function() { - var size = this.pageSize(); - - if (size * this.current() > this.totalCount()) { - this.current(1); - } - - this.reload(); - }, - - /** - * Validates page change according to user's input. - * Sets current observable to result of validation. - * Calls reload method then. - */ - onPageChange: function() { - var current, - valid; - - current = +this.current(); - valid = !isNaN(current) ? this.getInRange(current) : 1; - - this.current(valid); - - this.reload(); - } - }); - - return Component({ - constr: Paging - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/js/listing/sorting.js b/app/code/Magento/Ui/view/base/web/js/listing/sorting.js deleted file mode 100644 index 31b9812713c32d285a76f33d1672d27bfbf0eaf3..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/js/listing/sorting.js +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'underscore', - 'Magento_Ui/js/lib/ko/scope', - 'Magento_Ui/js/lib/component' -], function(_, Scope, Component) { - 'use strict'; - - var defaults = { - dirs: { - asc: 'sort-arrow-asc', - desc: 'sort-arrow-desc' - }, - params: { - dir: 'sorting', - items: ['field', 'direction'] - }, - initialDir: 'asc', - noSort: 'not-sort', - templateExtender: 'sortable' - }; - - var Sorting = Scope.extend({ - - /** - * Extends instance with defaults and config, initializes observable properties. - * Updates storage with current state of instance. - * @param {Object} config - */ - initialize: function(config) { - _.extend(this, defaults, config); - - this.initObservable() - .attachTemplateExtender() - .pushParams(); - }, - - /** - * Initializes observable properties of instance. - * @returns {Sorting} Chainable. - */ - initObservable: function(){ - this.observe('field direction'); - - return this; - }, - - /** - * Attaches it's template to provider.dump's extenders - * @returns {Sorting} Chainable. - */ - attachTemplateExtender: function () { - var dump = this.provider.dump, - extenders = dump.get('extenders'); - - extenders.push({ - path: this.templateExtender, - name: this.name, - as: 'sorting' - }); - - dump.resolve('update:extenders', extenders); - - return this; - }, - - /** - * Generates css class for indicating sorting state for field. - * @param {String} id - identifier of field to be sorted - * @returns {String} - css class. - */ - setClass: function(id) { - return this.isSorted(id) ? - this.dirs[this.direction()] : - this.noSort; - }, - - /** - * Toggles observable dir property betweeen 'asc' and 'desc' values. - */ - toggleDirection: function() { - var dir = this.direction; - - dir(dir() === 'asc' ? 'desc' : 'asc'); - }, - - /** - * Sets currently sorted field and initial sorting type for it. - * @param {String} id - identifier of field to be sorted - */ - setSort: function(id) { - this.field(id); - this.direction(this.initialDir); - }, - - /** - * Sorts by field and reloads storage. - * @param {(String|Number)} id - Identifier of field to be sorted. - */ - sortBy: function(id) { - this.isSorted(id) ? - this.toggleDirection() : - this.setSort(id); - - this.reload(); - }, - - /** - * Checks if the field is currently sorted. - * @param {String} id - identifier of field to be sorted - * @returns {Boolean} true, if target field is sorted already, false otherwise - */ - isSorted: function(id) { - return id === this.field(); - }, - - /** - * Returns function to handle user's click (workaround for knockout.js). - * @param {Object} field - * @returns {Function} - click handler - */ - onClick: function(field) { - return this.sortBy.bind(this, field.index); - } - }); - - return Component({ - constr: Sorting - }); -}); \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/area.html b/app/code/Magento/Ui/view/base/web/templates/area.html index 867908c0f8eeda3b65128cfb31653bda3bea0aee..eee2d4a8c630dcf93ab48c1911ed1b0b7237de1b 100644 --- a/app/code/Magento/Ui/view/base/web/templates/area.html +++ b/app/code/Magento/Ui/view/base/web/templates/area.html @@ -4,7 +4,6 @@ * See COPYING.txt for license details. */ --> - <!-- ko if: wasActivated --> <div data-bind="visible: active"> <!-- ko foreach: elems --> diff --git a/app/code/Magento/Ui/view/base/web/templates/content/content.html b/app/code/Magento/Ui/view/base/web/templates/content/content.html index c3d84628b7721cfd63b07a65ab4e66e623b122c9..ad90f63cd4282170e5322957e7bda90ac42f2291 100644 --- a/app/code/Magento/Ui/view/base/web/templates/content/content.html +++ b/app/code/Magento/Ui/view/base/web/templates/content/content.html @@ -7,7 +7,7 @@ <div data-bind="html: content, attr: {class: element.cssclass ? element.cssclass : 'admin__scope-old'}"></div> <!--ko if: showSpinner --> -<div data-role="spinner" class="grid-loading-mask" data-bind="visible: loading"> - <div class="spinner"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div> +<div data-role="spinner" class="admin__data-grid-loading-mask" data-bind="visible: loading"> + <span class="grid-loader"></span> </div> <!-- /ko --> diff --git a/app/code/Magento/Ui/view/base/web/templates/filter.html b/app/code/Magento/Ui/view/base/web/templates/filter.html deleted file mode 100644 index 0f95ab6ae6e9cf87ce69cc39a9d99c3ed9d75f1b..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/filter.html +++ /dev/null @@ -1,42 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<div class="filters"> - <button class="action filters-toggle" data-bind="click: toggle, css: { active: isVisible }"> - <span data-bind="text: $t('Filter')"></span> - </button> - <div class="form filters-form" data-bind="visible: isVisible" data-part="filter-form"> - <fieldset class="filters-fieldset fieldset"> - <legend class="legend filters-legend"> - <span data-bind="text: $t('Advanced filter')"></span> - </legend><br /> - <!-- ko foreach: { data: filters, as: 'item' } --> - <!-- ko template: item.getTemplate() --><!-- /ko --> - <!-- /ko --> - </fieldset> - <div class="actions filters-actions"> - <button class="action secondary action-reset" data-bind="click: reset" type="button"><span data-bind="text: $t('Reset')"></span></button> - <button class="action primary action-apply" data-bind="click: apply" type="button"><span data-bind="text: $t('Apply')"></span></button> - <button class="action secondary action-close" data-bind="click: close" type="button"><span data-bind="text: $t('Close')"></span></button> - </div> - </div> - <div class="filters-current" data-bind="css: {active: active().length}"> - <ul class="filters-items items"> - <!-- ko foreach: { data: active, as: 'filter' } --> - - <li class="filters-item item"> - <strong class="item-label" data-bind="text: $t(filter.label)"></strong> - <span class="item-value" data-bind="text: $t(filter.output)"></span> - <button data-bind="click: $parent.onClear(filter)" type="button" class="action action-remove"><span data-bind="text: $t('Remove')"></span></button> - </li> - - <!-- /ko --> - </ul> - <button data-bind="click: reset" class="action action-clear"> - <span data-bind="text: $t('Clear all')"></span> - </button> - </div> -</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/filter/filter_date.html b/app/code/Magento/Ui/view/base/web/templates/filter/filter_date.html deleted file mode 100644 index 644aad7f8301f550f871700dbe25381e5b608b11..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/filter/filter_date.html +++ /dev/null @@ -1,27 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<fieldset class="field field-range field-date"> - <legend class="label"> - <span data-bind="text: label"></span> - </legend><br /> - <div class="control"> - <div class="fields group group-2"> - <div class="field field-range-from"> - <label class="label"><span data-bind="text: $t('From')"></span></label> - <div class="control"> - <input type="text" class="input-text no-changes" data-bind="datepicker: { storage: from, options: config }, attr: {placeholder: $t('From')}"> - </div> - </div> - <div class="field field-range-to"> - <label class="label"><span data-bind="text: $t('To')"></span></label> - <div class="control"> - <input type="text" class="input-text no-changes" data-bind="datepicker: { storage: to, options: config }, attr: {placeholder: $t('To')}"> - </div> - </div> - </div> - </div> -</fieldset> diff --git a/app/code/Magento/Ui/view/base/web/templates/filter/filter_input.html b/app/code/Magento/Ui/view/base/web/templates/filter/filter_input.html deleted file mode 100644 index 0550a3907fca34af7173d0b75d40e9edd0b64327..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/filter/filter_input.html +++ /dev/null @@ -1,14 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<div class="field"> - <label class="label" data-bind="attr: {for: index}"> - <span data-bind="text: label"></span> - </label> - <div class="control"> - <input data-bind="value: value, attr: {id: index}" class="input-text" type="text"> - </div> -</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/filter/filter_range.html b/app/code/Magento/Ui/view/base/web/templates/filter/filter_range.html deleted file mode 100644 index f34b97cb89bb854436ba71d072a0b520b8f88873..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/filter/filter_range.html +++ /dev/null @@ -1,27 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<fieldset class="field field-range"> - <legend class="label"> - <span data-bind="text: label"></span> - </legend><br /> - <div class="control"> - <div class="fields group group-2"> - <div class="field field-range-from"> - <label class="label"><span data-bind="text: $t('From')"></span></label> - <div class="control hide-picker"> - <input type="text" class="input-text no-changes" data-bind="value: from, attr: {placeholder: $t('From')}"> - </div> - </div> - <div class="field field-range-to"> - <label class="label"><span data-bind="text: $t('To')"></span></label> - <div class="control hide-picker"> - <input type="text" class="input-text no-changes" data-bind="value: to, attr: {placeholder: $t('To')}"> - </div> - </div> - </div> - </div> -</fieldset> diff --git a/app/code/Magento/Ui/view/base/web/templates/filter/filter_select.html b/app/code/Magento/Ui/view/base/web/templates/filter/filter_select.html deleted file mode 100644 index 22be5c2d159a35a11acc731c8d6fc61c641c4216..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/filter/filter_select.html +++ /dev/null @@ -1,14 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<div class="field"> - <label class="label" data-bind="attr: {for: index}"> - <span data-bind="text: label"></span> - </label> - <div class="control"> - <select data-bind="attr: {id: index}, options: options, value: selected, optionsText: 'label', optionsCaption: caption" class="select"></select> - </div> -</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html b/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html index 5fd7ccc4bfed8874636abd5fa9c154c65ffc6422..05234c4afad7ace8a0e7261599b03eddf7c26260 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html @@ -10,12 +10,12 @@ <!-- ko foreach: { data: element.elems, as: 'element' } --> <li class="address-list-item" data-bind="css: { 'ui-state-active': element.active }, click: activate"> <div class="address-list-item-actions"> - <button class="action-delete" type="button" data-bind="click: $parent.removeChild(element)"> + <button class="action-delete" type="button" data-bind="click: $parent.removeChild.bind($parent, element)"> <span data-bind="text: $parent.removeLabel"></span> </button> </div> <!-- ko template: previewTpl --><!-- /ko --> - <div data-bind="foreach: { data: element.head, as: 'element' }, stopPropagation: true"> + <div data-bind="foreach: { data: element.getRegion('head'), as: 'element' }, stopPropagation: true"> <!-- ko template: element.getTemplate() --><!-- /ko --> </div> </li> @@ -35,7 +35,7 @@ <span data-bind="text: $parent.label"></span> </legend> <br> - <!-- ko foreach: { data: element.body, as: 'element' } --> + <!-- ko foreach: { data: element.getRegion('body'), as: 'element' } --> <!-- ko template: element.getTemplate() --><!-- /ko --> <!-- /ko --> </fieldset> diff --git a/app/code/Magento/Ui/view/base/web/templates/form/components/collection/item.html b/app/code/Magento/Ui/view/base/web/templates/form/components/collection/item.html deleted file mode 100644 index f274c3fe90f9396d739d94618104f4c4a0f7755d..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/form/components/collection/item.html +++ /dev/null @@ -1,10 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<!-- ko foreach: { data: elems, as: 'element' } --> - <!-- ko template: element.getTemplate() --><!-- /ko --> -<!-- /ko --> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/form/components/collection/preview.html b/app/code/Magento/Ui/view/base/web/templates/form/components/collection/preview.html index eed7c6acc697fbc9ce46ac7e1b9392a2064ada52..96ac887a7fb4aa9d40b21aea255d860c71048313 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/components/collection/preview.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/components/collection/preview.html @@ -9,7 +9,7 @@ data: formatPreviews([ "prefix firstname middlename lastname suffix", "company", - "street", + "street_container", { items: "city region_id postcode", separator: ", " diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/checkbox.html b/app/code/Magento/Ui/view/base/web/templates/form/element/checkbox.html index 1f712a604aba029f64399a5063e0faf8e964a7a3..01dca8a5b9318157f562333f27546e07f3d0e081 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/element/checkbox.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/element/checkbox.html @@ -8,12 +8,7 @@ <input type="checkbox" class="admin__control-checkbox" data-bind="checked: value, attr: { id: uid, disabled: disabled, name: inputName }, hasFocus: focused"> <label class="admin__field-label" data-bind="checked: value, attr: { for: uid }"> - <!-- ko if: $parent.isSingle() --> - <span data-bind="text: description"></span> - <!-- /ko --> - <!-- ko if: !$parent.isSingle() --> - <span data-bind="text: description || label"></span> - <!-- /ko --> + <span data-bind="text: description || label"></span> </label> <!-- ko if: notice --> diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/textarea.html b/app/code/Magento/Ui/view/base/web/templates/form/element/textarea.html index 8aa979d0658994b3bb64d9f397e991f1bb4891bd..fa1f88ddc1fc2fdee3578b0799b5519c5ab2d8af 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/element/textarea.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/element/textarea.html @@ -4,6 +4,7 @@ * See COPYING.txt for license details. */ --> + <textarea class="admin__control-textarea" data-bind=" value: value, hasFocus: focused, diff --git a/app/code/Magento/Ui/view/base/web/templates/group/field.html b/app/code/Magento/Ui/view/base/web/templates/form/field.html similarity index 69% rename from app/code/Magento/Ui/view/base/web/templates/group/field.html rename to app/code/Magento/Ui/view/base/web/templates/form/field.html index e01470fa2aed8f7e15547bcc6c2e20f909bb9f69..8ba9dc8d3474a539de251007e8f994bb2e4e163f 100644 --- a/app/code/Magento/Ui/view/base/web/templates/group/field.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/field.html @@ -4,22 +4,22 @@ * See COPYING.txt for license details. */ --> -<div class="admin__field" data-bind="css: {'_required': element.required, '_disabled': element.disabled, '_error': element.error}"> +<div class="admin__field" data-bind="visible: visible, css: {'_required': element.required, '_disabled': element.disabled, '_error': element.error}"> <!-- ko if: element.label --> - <label class="admin__field-label" data-bind="attr: { for: element.uid }, css: {'_dublicated': element.label === $parent.label}"> + <label class="admin__field-label" data-bind="attr: { for: element.uid }"> <span data-bind="text: element.label"></span> </label> <!-- /ko --> <div class="admin__field-control"> <!-- ko ifnot: element.hasAddons() --> - <!-- ko template: element.getTemplate() --><!-- /ko --> + <!-- ko template: element.elementTmpl --><!-- /ko --> <!-- /ko --> <!-- ko if: element.hasAddons() --> <div class="admin__control-addon"> - <!-- ko template: element.getTemplate() --><!-- /ko --> + <!-- ko template: element.elementTmpl --><!-- /ko --> <!-- ko if: element.addbefore --> <label class="admin__addon-prefix" data-bind="attr: { for: element.uid }"><span data-bind="text: element.addbefore"></span></label> @@ -39,10 +39,9 @@ <div class="admin__field-note" data-bind="attr: { id: element.noticeId }"><span data-bind="text: element.notice"></span></div> <!-- /ko --> - <!-- ko if: $parent.isSingle() --> - <!-- ko if: element.error() && !element.hidden() --> - <label class="admin__field-error" data-bind="attr: { for: element.uid }, text: element.error"></label> - <!-- /ko --> + <!-- ko if: element.error() --> + <label class="admin__field-error" data-bind="attr: { for: element.uid }, text: element.error"></label> <!-- /ko --> </div> </div> +<!-- /ko --> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/fieldset/fieldset.html b/app/code/Magento/Ui/view/base/web/templates/form/fieldset.html similarity index 89% rename from app/code/Magento/Ui/view/base/web/templates/fieldset/fieldset.html rename to app/code/Magento/Ui/view/base/web/templates/form/fieldset.html index 7a5dc7460dc556de2f622e73d39f25f079d80126..159511ae9c30c14519ec7fc19a5978a7602b5402 100644 --- a/app/code/Magento/Ui/view/base/web/templates/fieldset/fieldset.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/fieldset.html @@ -4,9 +4,9 @@ * See COPYING.txt for license details. */ --> -<!-- ko if: elems --> + <div class="admin__fieldset-wrapper" data-bind="css: {'collapsable-wrapper': collapsible, 'opened': opened}"> - <div class="admin__fieldset-wrapper-title" tabindex="3" data-bind="click: onClick, keyboard: { 13: toggle }"> + <div class="admin__fieldset-wrapper-title" tabindex="3" data-bind="click: toggleOpened, keyboard: { 13: toggleOpened }"> <strong class="title"> <span data-bind="text: label"></span> </strong> @@ -19,4 +19,3 @@ </fieldset> </div> </div> -<!-- /ko --> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/actions.html b/app/code/Magento/Ui/view/base/web/templates/grid/actions.html new file mode 100644 index 0000000000000000000000000000000000000000..685936aa8430382b59ff1b065c74e244aadcd24a --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/actions.html @@ -0,0 +1,29 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<div class="col-xs-2"> + <div + class="action-select-wrap" + data-bind="css: {'_active': opened}, + click: toggleOpened, + outerClick: close"> + <button + class="action-select" + data-bind="title: $t('Select Items')"> + <span data-bind="text: $t('Actions')"></span> + </button> + <ul + class="action-menu" + data-bind="css: {'_active': opened}, + foreach: {data: actions, as: 'action'}"> + <li data-bind="click: $parent.applyAction.bind($parent, action)"> + <span + class="action-menu-item" + data-bind="text: label"></span> + </li> + </ul> + </div> +</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/cells/actions.html b/app/code/Magento/Ui/view/base/web/templates/grid/cells/actions.html new file mode 100644 index 0000000000000000000000000000000000000000..1ef5fc1177e73194f9bf29a7d27554c85de47a6f --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/cells/actions.html @@ -0,0 +1,30 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<td class="data-grid-actions-cell"> + <!-- ko if: getDisplayed(row[field.index]).length > 1 --> + <div class="action-select-wrap _active"> + <button class="action-select"> + <span data-bind="text: $t('Select')"></span> + </button> + <ul class="action-menu _active"> + <li> + <a + class="action-menu-item" + data-bind="attr: {href: displayed[0].href}, + text: displayed[0].label"></a> + </li> + </ul> + </div> + <!-- /ko --> + <!-- ko ifnot: getDisplayed(row[field.index]).length > 1 --> + <a + class="action-menu-item" + data-bind="attr: {href: displayed[0].href}, + text: displayed[0].label"></a> + <!-- /ko --> +</td> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/cells/multiselect.html b/app/code/Magento/Ui/view/base/web/templates/grid/cells/multiselect.html new file mode 100644 index 0000000000000000000000000000000000000000..81e6b2c5bc3706a042daf1f6e2b3725e84b681c4 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/cells/multiselect.html @@ -0,0 +1,18 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<td class="data-grid-checkbox-cell"> + <label class="data-grid-checkbox-cell-inner"> + <input + class="admin__control-checkbox" + type="checkbox" + data-bind="checked: selected, + value: row[indexField], + attr: {id: 'check' + row[indexField]}"> + <label data-bind="attr: {for: 'check' + row[indexField]}"></label> + </label> +</td> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/cells/text.html b/app/code/Magento/Ui/view/base/web/templates/grid/cells/text.html new file mode 100644 index 0000000000000000000000000000000000000000..aff66b7cc2c68a98579a076540dfe22a674c6654 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/cells/text.html @@ -0,0 +1,16 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<!-- ko if: isClickable(row) --> +<td + data-bind="click: redirect.bind($data, getClickUrl(row)), + html: getLabel(row[field.index])" + data-action="grid-row-edit"></td> +<!-- /ko --> +<!-- ko ifnot: isClickable(row) --> +<td data-bind="html: getLabel(row[field.index])"></td> +<!-- /ko --> diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/store.html b/app/code/Magento/Ui/view/base/web/templates/grid/columns/actions.html similarity index 52% rename from app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/store.html rename to app/code/Magento/Ui/view/base/web/templates/grid/columns/actions.html index c6e156ce8e99032c45c93a7c6992787a08785547..ff0980dbe37979d4568ec2b5b8d7d41e6772fb6d 100644 --- a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/store.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/columns/actions.html @@ -4,6 +4,7 @@ * See COPYING.txt for license details. */ --> -<td data-part="body.row.cell"> - <span data-bind="html: row[field.index]"></span> -</td> \ No newline at end of file + +<th class="data-grid-th data-grid-actions-cell"> + <span data-bind="text: label"></span> +</th> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html b/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html new file mode 100644 index 0000000000000000000000000000000000000000..8553c127d60cbe35ea144d206a96c5294e389cc0 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html @@ -0,0 +1,41 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<th class="data-grid-multiselect-cell"> + <div + class="action-multiselect-wrap" + data-bind="css: { '_active': menuVisible, '_disabled': !totalRecords()}, + outerClick: hideMenu"> + <input + id="mass-select-checkbox" + class="admin__control-checkbox" + type="checkbox" + data-bind="checked: allSelected, + event: { change: toggleSelectAll }, + css: { '_indeterminate': indetermine }, + enable: totalRecords"> + <label for="mass-select-checkbox"></label> + <button + class="action-multiselect-toggle" + data-toggle="dropdown" + data-bind="css: { '_active': menuVisible }, + click: toggleMenu, + enable: totalRecords"> + <span data-bind="text: $t('Options')"></span> + </button> + <ul + class="action-menu" + data-bind="click: hideMenu"> + <!-- ko foreach: actions --> + <li data-bind="click: $parent[value].bind($parent), + visible: $parent.isActionRelevant(value)"> + <span class="action-menu-item" data-bind="text: label"></span> + </li> + <!-- /ko --> + </ul> + </div> +</th> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/columns/text.html b/app/code/Magento/Ui/view/base/web/templates/grid/columns/text.html new file mode 100644 index 0000000000000000000000000000000000000000..9f708c21f093a5f8c4e9a6c53eddd3ee2adb04a5 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/columns/text.html @@ -0,0 +1,20 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<!-- ko if: sortable --> + <th + class="data-grid-th _sortable" + data-bind="css: sortClass, click: sort"> + <span data-bind="text: label"></span> + </th> +<!-- /ko --> + +<!-- ko ifnot: sortable --> + <th class="data-grid-th"> + <span data-bind="text: label"></span> + </th> +<!-- /ko --> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/controls/columns.html b/app/code/Magento/Ui/view/base/web/templates/grid/controls/columns.html new file mode 100644 index 0000000000000000000000000000000000000000..fafa87cfc8b505d1005959c03d513081ac382a7e --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/controls/columns.html @@ -0,0 +1,45 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<div data-bind="css: {_active: opened}, outerClick: close" class="admin__action-dropdown-wrap admin__data-grid-action-columns"> + <button + class="admin__action-dropdown" + type="button" + data-bind="click: toggleOpened" + data-toggle="dropdown" + aria-haspopup="true"> + <span class="admin__action-dropdown-text" data-bind="text: $t('Columns')"></span> + </button> + <div data-bind="css: {_overflow: hasOverflow()}" class="admin__action-dropdown-menu admin__data-grid-action-columns-menu"> + <div class="admin__action-dropdown-menu-header"> + <span data-bind="text: getHeaderMessage($t('<%- visible %> out of <%- total %> visible'))"></span> + </div> + <div class="admin__action-dropdown-menu-content"> + <!-- ko foreach: elems --> + <div class="admin__field-option"> + <input data-bind="attr: {id: 'grid-controls-columns-' + index}, disable: $parent.isDisabled($data), checked: visible" + class="admin__control-checkbox" type="checkbox"/> + <label data-bind="text: label, attr: {for: 'grid-controls-columns-' + index}" class="admin__field-label"></label> + </div> + <!-- /ko --> + </div> + <div class="admin__action-dropdown-menu-footer"> + <div class="admin__action-dropdown-footer-secondary-actions"> + <button data-bind="click: reset" class="action-tertiary" type="button"> + <span data-bind="text: $t('Reset')"></span> + </button> + </div> + <div class="admin__action-dropdown-footer-main-actions"> + <button data-bind="click: cancel" class="action-tertiary" type="button"> + <span data-bind="text: $t('Cancel')"></span> + </button> + <button data-bind="click: apply" class="action-secondary" type="button"> + <span data-bind="text: $t('Apply')"></span> + </button> + </div> + </div> + </div> +</div> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/controls/view.html b/app/code/Magento/Ui/view/base/web/templates/grid/controls/view.html new file mode 100644 index 0000000000000000000000000000000000000000..fc4e1bd8656b7687d787b082da6b1fe0f3d7e000 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/controls/view.html @@ -0,0 +1,60 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<div + class="admin__action-dropdown-wrap admin__data-grid-action-bookmarks _hide" + data-bind="css: {_active: opened, _disabled: !collapsible}, outerClick: close"> + <button + class="admin__action-dropdown" + type="button" + data-bind="click: toggleOpened" + data-toggle="dropdown" + aria-haspopup="true"> + <span class="admin__action-dropdown-text">Default View</span> + </button> + <ul class="admin__action-dropdown-menu"> + <!-- ko foreach: {data: sampleData, as: 'view'} --> + <li + data-bind="css: {_edit: false}"> + <div class="action-dropdown-menu-item-edit"> + <input + class="admin__control-text" + data-bind="value: view.label" + type="text"> + <button + class="action-submit" + type="button"> + <span>Submit</span> + </button> + <div class="action-dropdown-menu-item-actions"> + <button + class="action-delete" + type="button"> + <span>Delete</span> + </button> + </div> + </div> + <div class="action-dropdown-menu-item"> + <a + class="action-dropdown-menu-link" + href="" + data-bind="text: view.label"></a> + <div class="action-dropdown-menu-item-actions"> + <button + class="action-edit" + type="button"> + <span>Edit</span> + </button> + </div> + </div> + </li> + <!-- /ko --> + <li class="action-dropdown-menu-item-last"> + <a href="">Save Current View</a> + </li> + </ul> +</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/date.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/date.html new file mode 100644 index 0000000000000000000000000000000000000000..9fbd4a2b336d69242c5e00d56fa9ca247ebee274 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/date.html @@ -0,0 +1,27 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<div class="admin__form-field"> + <label + class="admin__form-field-label" + data-bind="attr: {for: uid}"> + <span data-bind="text: label"></span> + </label> + <div class="admin__form-field-control"> + <input + class="admin__control-text" + type="text" + data-bind="hasFocus: focused, + datepicker: { storage: value, options: options }, + attr: { + value: value, + name: inputName, + 'aria-describedby': noticeId, + disabled: disabled + }" /> + </div> +</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/group.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/group.html new file mode 100644 index 0000000000000000000000000000000000000000..a0374eb43cbacd05d18bc163641bd9198edc4b57 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/group.html @@ -0,0 +1,15 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<fieldset class="admin__form-field"> + <legend class="admin__form-field-legend"> + <span data-bind="text: label"></span> + </legend> + <!-- ko foreach: elems --> + <!-- ko template: getTemplate() --><!-- /ko --> + <!-- /ko --> +</fieldset> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/input.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/input.html new file mode 100644 index 0000000000000000000000000000000000000000..8e93919ff881319024fc23dea95dd2e17fc37635 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/input.html @@ -0,0 +1,27 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<div class="admin__form-field"> + <label + class="admin__form-field-label" + data-bind="attr: {for: uid}"> + <span data-bind="text: label"></span> + </label> + <div class="admin__form-field-control"> + <input + class="admin__control-text" + type="text" + data-bind="value: value, + hasFocus: focused, + attr: { + name: inputName, + 'aria-describedby': noticeId, + id: uid, + disabled: disabled + }" /> + </div> +</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/select.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/select.html new file mode 100644 index 0000000000000000000000000000000000000000..abd2502ba19b07f80d55f191ddd6bc587acedc61 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/select.html @@ -0,0 +1,31 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<div class="admin__form-field"> + <label + class="admin__form-field-label" + data-bind="attr: {for: uid}"> + <span data-bind="text: label"></span> + </label> + <div class="admin__field-control"> + <select + class="admin__control-select" + data-bind="attr: { + name: inputName, + id: uid, + disabled: disabled, + 'aria-describedby': noticeId, + placeholder: placeholder + }, + hasFocus: focused, + optgroup: options, + value: value, + optionsCaption: caption, + optionsValue: 'value', + optionsText: 'label'"/> + </div> +</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/filters.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/filters.html new file mode 100644 index 0000000000000000000000000000000000000000..ddda29706153af351d5faf217d1fc13459005783 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/filters.html @@ -0,0 +1,108 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<div class="data-grid-search-control-wrap"> + <input + class="admin__control-text data-grid-search-control" + placeholder="Search by keyword" + type="text"/> + <button + class="action-submit" + type="submit"><span data-bind="text: $t('Search')"></span></button> + <ul class="action-menu _active"> + <li> + <a class="action-menu-item" href>Lorem</a> + </li> + <li> + <a class="action-menu-item" href>Lorem 1</a> + </li> + <li> + <a class="action-menu-item" href>Lorem 2</a> + </li> + </ul> +</div> + +<div class="data-grid-filters-actions-wrap"> + <div class="data-grid-filters-action-wrap"> + <button + class="action-default _active" + data-action="grid-filter-expand" + data-bind="click: toggleOpened, css: { _active: opened }"> + <span data-bind="text: $t('Filters')"></span> + </button> + </div> +</div> + +<div + class="admin__data-grid-filters-current" + data-bind="css: {_show: active().length && !opened()}"> + <div class="admin__current-filters-title-wrap"> + <span + class="admin__current-filters-title" + data-bind="text: $t('Active filters:')"></span> + </div> + <div class="admin__current-filters-list-wrap"> + <ul class="admin__current-filters-list"> + <!-- ko foreach: previews --> + <li> + <span data-bind="text: label + ':'"></span> + <span data-bind="text: preview"></span> + <button + class="action-remove" + data-bind="click: $parent.reset.bind($parent, elem)" + type="button"> + <span data-bind="text: $t('Remove')"></span> + </button> + </li> + <!-- /ko --> + </ul> + </div> +</div> + +<div + class="admin__data-grid-filters-wrap" + data-bind="css: { _show: opened }" + data-part="filter-form"> + + <fieldset class="admin__fieldset admin__data-grid-filters"> + <legend class="admin__filters-legend"> + <span data-bind="text: $t('Advanced filter')"></span> + </legend> + <!-- ko foreach: elems --> + <!-- ko template: getTemplate() --><!-- /ko --> + <!-- /ko --> + </fieldset> + + <div class="admin__data-grid-filters-footer"> + <div class="admin__footer-secondary-actions"> + <button + class="action-tertiary" + type="button" + data-action="grid-filter-reset" + data-bind="click: reset"> + <span data-bind="text: $t('Reset')"></span> + </button> + </div> + <div class="admin__footer-main-actions"> + <button + class="action-tertiary" + type="button" + data-action="grid-filter-cancel" + data-bind="click: close"> + <span data-bind="text: $t('Cancel')"></span> + </button> + <button + class="action-secondary" + type="button" + data-action="grid-filter-apply" + data-bind="click: apply"> + <span data-bind="text: $t('Apply Filters')"></span> + </button> + </div> + </div> + +</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/listing.html b/app/code/Magento/Ui/view/base/web/templates/grid/listing.html new file mode 100644 index 0000000000000000000000000000000000000000..544a998a4dbc79e0dc08f0297b8d3821cf0d9fc1 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/listing.html @@ -0,0 +1,38 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<table class="data-grid"> + <thead data-part="head"> + <tr data-part="head.row"> + <!-- ko foreach: elems --> + <!-- ko if: visible --> + <!-- ko template: getHeader() --><!-- /ko --> + <!-- /ko --> + <!-- /ko --> + </tr> + </thead> + <tbody data-part="body"> + <!-- ko if: hasData() --> + <!-- ko foreach: { data: rows, as: 'row' } --> + <tr data-part="body.row"> + <!-- ko foreach: { data: $parent.elems, as: 'field' } --> + <!-- ko if: visible --> + <!-- ko template: getBody() --><!-- /ko --> + <!-- /ko --> + <!-- /ko --> + </tr> + <!-- /ko --> + <!-- /ko --> + + <!-- ko ifnot: hasData() --> + <tr class="data-grid-tr-no-data"> + <td data-bind="attr: { colspan: getColspan() }, + text: $t('We couldn\'t find any records.')"></td> + </tr> + <!-- /ko --> + </tbody> +</table> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/paging.html b/app/code/Magento/Ui/view/base/web/templates/grid/paging.html new file mode 100644 index 0000000000000000000000000000000000000000..9f4f5cc2fdcb5101d7e3969bf9e06ae1be8e0af9 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/paging.html @@ -0,0 +1,50 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<div class="col-xs-3"> + <div class="admin__control-support-text"> + <span data-bind="text: totalRecords"></span> records found + <!-- ko if: totalSelected --> + (<span data-bind="text: totalSelected"></span> selected) + <!-- /ko --> + </div> +</div> + +<div class="col-xs-7 admin__data-grid-pager-wrap"> + <select + id="perPage" + class="admin__control-select" + data-bind="options: options, + value: pageSize, + optionsValue: 'value', + optionsText: 'label'"></select> + <label class="admin__control-support-text" for="perPage">per page</label> + + <div class="admin__data-grid-pager"> + <button + class="action-previous" + type="button" + data-bind="css: { disabled: isFirst() }, + click: prev"> + <span>Previous page</span> + </button> + <input + id="pageCurrent" + class="admin__control-text" + data-bind="value: _current" + type="number" /> + <label class="admin__control-support-text" for="pageCurrent"> + of <span data-bind="text: pages"></span> + </label> + <button + class="action-next" + data-bind="css: { disabled: isLast() }, + click: next"> + <span>Next page</span> + </button> + </div> + +</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/toolbar.html b/app/code/Magento/Ui/view/base/web/templates/grid/toolbar.html new file mode 100644 index 0000000000000000000000000000000000000000..0812e3fe862d2fac42f48fdd80ead31355f23107 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/toolbar.html @@ -0,0 +1,24 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<div class="admin__data-grid-header"> + <div class="admin__data-grid-header-row"> + <div class="admin__data-grid-actions-wrap"> + <!-- ko foreach: getRegion('dataGridActions') --> + <!-- ko template: getTemplate() --><!-- /ko --> + <!-- /ko --> + </div> + <!-- ko foreach: getRegion('dataGridFilters') --> + <!-- ko template: getTemplate() --><!-- /ko --> + <!-- /ko --> + </div> + <div class="admin__data-grid-header-row row row-gutter"> + <!-- ko foreach: getRegion('bottom') --> + <!-- ko template: getTemplate() --><!-- /ko --> + <!-- /ko --> + </div> +</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/group/group.html b/app/code/Magento/Ui/view/base/web/templates/group/group.html index 519aefbcee9f2dae72e0db9fd75f74738d8aeba8..7db2db6edfd14dfb0de0a56abf7ccedc026d1a59 100644 --- a/app/code/Magento/Ui/view/base/web/templates/group/group.html +++ b/app/code/Magento/Ui/view/base/web/templates/group/group.html @@ -4,8 +4,6 @@ * See COPYING.txt for license details. */ --> - -<!-- ko if: element.isMultiple() --> <fieldset class="admin__field" data-bind="css: {'_required': element.required}"> <legend class="admin__field-label"> <span data-bind="text: element.label"></span> @@ -13,14 +11,14 @@ <div class="admin__field-control" data-bind="css: {'admin__control-fields': element.breakLine, 'admin__control-grouped': !element.breakLine}"> <!-- ko foreach: { data: elems, as: 'element' } --> - <!-- ko ifnot: element.hidden --> + <!-- ko if: element.visible() --> <!-- ko ifnot: (element.input_type == 'checkbox' || element.input_type == 'radio') --> <!-- ko template: $parent.fieldTemplate --><!-- /ko --> <!-- /ko --> <!-- ko if: (element.input_type == 'checkbox' || element.input_type == 'radio') --> - <!-- ko template: element.getTemplate() --><!-- /ko --> + <!-- ko template: element.elementTmpl --><!-- /ko --> <!-- /ko --> <!-- /ko --> @@ -28,20 +26,9 @@ <!-- /ko --> <!-- ko foreach: { data: elems, as: 'element' } --> - <!-- ko if: element.error() && !element.hidden() --> + <!-- ko if: element.error() && element.visible() --> <label class="admin__field-error" data-bind="attr: { for: uid }, text: element.error"></label> <!-- /ko --> <!-- /ko --> </div> </fieldset> -<!-- /ko --> - -<!-- ko if: element.isSingle() --> - - <!-- ko foreach: { data: elems, as: 'element' } --> - - <!-- ko template: $parent.fieldTemplate --><!-- /ko --> - - <!-- /ko --> - -<!-- /ko --> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid.html deleted file mode 100644 index 6349b6c08e146c12c320bd78e811d9d437fe739d..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/listing/grid.html +++ /dev/null @@ -1,36 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<div class="hor-scroll"> - <table class="data"> - <thead data-part="head"> - <tr class="headings" data-part="head.row"> - <!-- ko foreach: { data: fields, as: 'field' } --> - <th> - <span data-bind="text: field.label"></span> - </th> - <!-- /ko --> - </tr> - </thead> - <tbody data-part="body"> - <!-- ko if: hasData() --> - <!-- ko foreach: { data: rows, as: 'row' } --> - <tr data-part="body.row" class="even pointer" data-bind="click: $parent.applyItemActionFor(row)"> - <!-- ko foreach: { data: $parent.fields, as: 'field' } --> - <!-- ko template: $parents[1].getCellTemplateFor(field) --><!-- /ko --> - <!-- /ko --> - </tr> - <!-- /ko --> - <!-- /ko --> - - <!-- ko ifnot: hasData() --> - <tr class="even"> - <td class="empty-text" data-bind="attr: { colspan: colspan }, text: $t('We couldn\'t find any records.')"></td> - </tr> - <!-- /ko --> - </tbody> - </table> -</div> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/actions.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/actions.html deleted file mode 100644 index 0ebd67b45eecddff54c777e51ee68c6d63380e20..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/actions.html +++ /dev/null @@ -1,16 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<td data-part="body.row.cell" data-bind="stopPropagation: true"> - <div data-bind="if: window.Array.isArray(row[field.index])"> - <div data-bind="foreach: { data: row[field.index], as: 'action' }"> - <a target="_blank" data-bind="attr: { href: action.href }, text: action.label"></a> - </div> - </div> - <div data-bind="ifnot: window.Array.isArray(row[field.index])"> - <a target="_blank" data-bind="attr: { href: row[field.index].href }, text: row[field.index].label"></a> - </div> -</td> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/date.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/date.html deleted file mode 100644 index 0bed40dd404be7b7b11bc99a19b57225ec46f6ed..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/date.html +++ /dev/null @@ -1,9 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<td data-part="body.row.cell"> - <span data-bind="date: { value: row[field.index], format: field.date_format }"></span> -</td> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/text.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/text.html deleted file mode 100644 index 5ee35346b921d02384022322173b18ea8a0372bb..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/text.html +++ /dev/null @@ -1,14 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<td data-part="body.row.cell"> - <span data-bind="'if': 'options' in $data"> - <span data-bind="text: options[row[index]]"></span> - </span> - <span data-bind="ifnot: 'options' in $data"> - <span data-bind="text: row[field.index]"></span> - </span> -</td> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/selectable.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/selectable.html deleted file mode 100644 index b3a385c92b8fd62b2cdce54188fcecdb5dc15837..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/selectable.html +++ /dev/null @@ -1,38 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<table> - <thead> - <tr data-part-prepend="head.row"> - <th class="col-select col-massaction" data-bind="scope: $parent.getExtender('massaction')"> - <div class="mass-select" data-bind="outerClick: hideMenu, stopPropagation: true"> - <label class="field choice mass-select-field"> - <input type="checkbox" id="mass-select-checkbox" data-bind="checked: allSelected, event: { 'change': toggleSelectAll }"> - </label> - <button class="mass-select-toggle" data-toggle="dropdown" data-bind="css: { 'active': menuVisible }, click: onToggle('menuVisible')"> - <span data-bind="text: $t('Options')"></span> - </button> - <ul class="mass-select-menu" data-bind="css: { 'active': menuVisible } "> - <!-- ko foreach: { data: selects , as: 'action' } --> - <li data-bind="click: $parent.onApplySelect(action.value), visible: $parent.shouldBeVisible(action.value)"> - <span data-bind="text: $t(action.label)"></span> - </li> - <!-- /ko --> - </ul> - </div> - </th> - </tr> - </thead> - <tbody> - <tr data-part-prepend="body.row"> - <td class="col-select col-massaction" data-bind="scope: $parent.getExtender('massaction'), stopPropagation: true"> - <label class="select-box" data-bind="stopPropagation: true"> - <input type="checkbox" class="massaction-checkbox" data-bind="checked: selected, value: row[indexField]"> - </label> - </td> - </tr> - </tbody> -</table> diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/sortable.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/sortable.html deleted file mode 100644 index 10d0d3f92cd477c62943917ea3846024903d5ed6..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/sortable.html +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<table> - <thead data-part-replace="head" data-bind="scope: getExtender('sorting')"> - <tr class="headings" data-part="head.row"> - <!-- ko foreach: { data: $parent.fields, as: 'field' } --> - <th> - <!-- ko if: field.sortable --> - <span> - <a href="#" data-bind="text: field.label, css: $parent.setClass(field.index), click: $parent.onClick(field)"></a> - </span> - <!-- /ko --> - - <!-- ko ifnot: field.sortable --> - <span data-bind="text: field.label"></span> - <!-- /ko --> - </th> - <!-- /ko --> - </tr> - </thead> -</table> diff --git a/app/code/Magento/Ui/view/base/web/templates/massaction.html b/app/code/Magento/Ui/view/base/web/templates/massaction.html deleted file mode 100644 index 547c92de838807804ce6e2607c2f19b3f0b41dd1..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/massaction.html +++ /dev/null @@ -1,17 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<div title="Select Items" class="actions-split" data-bind="css: {'active': actionsVisible}, stopPropagation: true, outerClick: hideActions"> - <button title="Actions" class="action-default scalable add" data-bind="click: onToggle('actionsVisible')"> - <span data-bind="text: $t('Actions')"></span> - </button> - <button title="" class="action-toggle scalable add" data-toggle="dropdown" data-bind="click: onToggle('actionsVisible'), css: {active: actionsVisible}"> - <span data-bind="text: $t('Select')"></span> - </button> - <ul class="dropdown-menu" data-bind="css: {'active': actionsVisible}, foreach: {data: actions, as: 'action'}"> - <li data-bind="click: $parent.setAction(action)"><span class="item" data-bind="text: label"></span></li> - </ul> -</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/pageactions.html b/app/code/Magento/Ui/view/base/web/templates/pageactions.html deleted file mode 100644 index caf4d917fadfaaa6827f1a25cbd45682bbfa747d..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/pageactions.html +++ /dev/null @@ -1,26 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<div class="page-main-actions"> - <div class="page-actions-placeholder"></div> - <div data-mage-init='{"floatingHeader": {}}' class="page-actions" data-ui-id="page-actions-toolbar-content-header"> - <div class="page-actions-inner" data-title="Pages"> - <div class="page-actions-buttons"> - <!-- ko foreach: actions --> - <button data-bind=" - attr: {title: $t(label)}, - css: {primary: type === 'primary'}, - click: $parent.redirectTo(url)" - type="button" - class="action- scalable add" - data-ui-id="cms-page-add-button"> - <span data-bind="text: $t(label)"></span> - </button> - <!-- /ko --> - </div> - </div> - </div> -</div> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/pagination.html b/app/code/Magento/Ui/view/base/web/templates/pagination.html deleted file mode 100644 index 9046c0f4a1c4b063b7c0df6f04f22d846eae397b..0000000000000000000000000000000000000000 --- a/app/code/Magento/Ui/view/base/web/templates/pagination.html +++ /dev/null @@ -1,32 +0,0 @@ -<!-- -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<span data-part="left"> - <span class="pages-total-found"> - <strong data-bind="text: totalCount"></strong> records found - <!-- ko if: selected --> - (<strong data-bind="text: selected"></strong> selected) - <!-- /ko --> - </span> - <label class="view-pages"> - View - <select data-bind="options: sizes, value: pageSize, event: { change: onSizeChange}"></select> - per page. - </label> -</span> -<span data-part="right"> - <span data-bind="css: { disabled: isFirst() }, click: prev" class="action-previous"> - <span>Previous page</span> - </span> - <input data-bind="value: current, event: {change: onPageChange}" type="text" class="input-text page" /> - <span class="pages-total"> - of - <span data-bind="text: pages"></span> - </span> - <span data-bind="css: { disabled: isLast() }, click: next" class="action-next"> - <span>Next page</span> - </span> -</span> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/tab.html b/app/code/Magento/Ui/view/base/web/templates/tab.html index d2ff2cd5e890392506e6bae7d6455af70a97965c..8f11fa286ba637260a49d267c52f8f1690e48024 100644 --- a/app/code/Magento/Ui/view/base/web/templates/tab.html +++ b/app/code/Magento/Ui/view/base/web/templates/tab.html @@ -5,8 +5,8 @@ */ --> <div class="admin__page-nav"> - <div class="admin__page-nav-title" data-bind="css: { '_collapsible': collapsible, '_opened': opened() && collapsible }, click: toggle, click: onClick, keyboard: { 13: onClick }"> - <strong tabindex="1" data-bind="text: label, keyboard: { 13: toggle }"></strong> + <div class="admin__page-nav-title" data-bind="css: { '_collapsible': collapsible, '_opened': opened && collapsible }, click: toggleOpened, keyboard: { 13: toggleOpened }"> + <strong tabindex="1" data-bind="text: label, keyboard: { 13: toggleOpened }"></strong> </div> <ul class="admin__page-nav-items items" data-bind="visible: opened"> <!-- ko foreach: elems --> diff --git a/app/code/Magento/Ups/composer.json b/app/code/Magento/Ups/composer.json index 3fed6bdce1e18410c2fc17a53d32f8a93d940f78..d22db469d42c92b9f0b1f004872435abbcc3bf9b 100644 --- a/app/code/Magento/Ups/composer.json +++ b/app/code/Magento/Ups/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-shipping": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-shipping": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/UrlRewrite/composer.json b/app/code/Magento/UrlRewrite/composer.json index 1156b7cb79022a4f0caf8e293c1b752ecc4d0cef..b49e137af5d05c8943bcee48f4e13d54db8c4648 100644 --- a/app/code/Magento/UrlRewrite/composer.json +++ b/app/code/Magento/UrlRewrite/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-catalog-url-rewrite": "0.74.0-beta6", - "magento/module-cms": "0.74.0-beta6", - "magento/module-cms-url-rewrite": "0.74.0-beta6", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-catalog-url-rewrite": "0.74.0-beta7", + "magento/module-cms": "0.74.0-beta7", + "magento/module-cms-url-rewrite": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/User/composer.json b/app/code/Magento/User/composer.json index 1d387c17899055557bb811a7c3024d38b90ef587..6c4a9d182196217ea7a011ad8894f37a11884cb4 100644 --- a/app/code/Magento/User/composer.json +++ b/app/code/Magento/User/composer.json @@ -3,15 +3,15 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-authorization": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-integration": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-authorization": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-integration": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Usps/composer.json b/app/code/Magento/Usps/composer.json index 382961b5610b48750b1aa3e64d77e46433cae688..5e50dcbc46c23ff314332a4aabc477379b318927 100644 --- a/app/code/Magento/Usps/composer.json +++ b/app/code/Magento/Usps/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-shipping": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/module-config": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-shipping": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/module-config": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "lib-libxml": "*", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Variable/composer.json b/app/code/Magento/Variable/composer.json index ececb67d0ec8b20c51576dfe0b271f50a9c98015..87583d867fa2eec4500366d36c5b7cc4363f89cf 100644 --- a/app/code/Magento/Variable/composer.json +++ b/app/code/Magento/Variable/composer.json @@ -3,14 +3,14 @@ "description": "N/A", "require": { "php": "~5.4.11|~5.5.0|~5.6.0", - "magento/module-backend": "0.74.0-beta6", - "magento/module-email": "0.74.0-beta6", - "magento/module-store": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-backend": "0.74.0-beta7", + "magento/module-email": "0.74.0-beta7", + "magento/module-store": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Version/composer.json b/app/code/Magento/Version/composer.json index 7bb5e528673b62f88d0c668ab148cdae4dfbcd35..804db0bd8f4ec5d5119b4bfd830bb59eba08f679 100644 --- a/app/code/Magento/Version/composer.json +++ b/app/code/Magento/Version/composer.json @@ -3,11 +3,11 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Webapi/composer.json b/app/code/Magento/Webapi/composer.json index c2e4ec4dacb4f073ed7c35ac5a1a557e8c27db70..4097e63655d1654cbe39c0a5d767abaf613abbcf 100644 --- a/app/code/Magento/Webapi/composer.json +++ b/app/code/Magento/Webapi/composer.json @@ -3,18 +3,18 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-authorization": "0.74.0-beta6", - "magento/module-integration": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-authorization": "0.74.0-beta7", + "magento/module-integration": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-user": "0.74.0-beta6" + "magento/module-user": "0.74.0-beta7" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Weee/composer.json b/app/code/Magento/Weee/composer.json index 9b11852f84fd425b09a62737597c797ddcdd31d8..ba4b15374bad4320414343956952ec2ac5fd3000 100644 --- a/app/code/Magento/Weee/composer.json +++ b/app/code/Magento/Weee/composer.json @@ -3,20 +3,20 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-tax": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-directory": "0.74.0-beta6", - "magento/module-eav": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-quote": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-tax": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-directory": "0.74.0-beta7", + "magento/module-eav": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-quote": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Widget/composer.json b/app/code/Magento/Widget/composer.json index e1ebbafa7d489f3a823f28fee6e691289851c00b..3cf33ee5654bfca968013901005b5e9157b0abcc 100644 --- a/app/code/Magento/Widget/composer.json +++ b/app/code/Magento/Widget/composer.json @@ -3,17 +3,17 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-cms": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-variable": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-cms": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-variable": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Wishlist/Block/Adminhtml/WishlistTab.php b/app/code/Magento/Wishlist/Block/Adminhtml/WishlistTab.php index 2f393bf6d2c40e0d1e80974d5854187c8bd994df..6a6d83a1bdabef4d2d3f7d7c47b50a9c157b574a 100644 --- a/app/code/Magento/Wishlist/Block/Adminhtml/WishlistTab.php +++ b/app/code/Magento/Wishlist/Block/Adminhtml/WishlistTab.php @@ -5,17 +5,16 @@ */ namespace Magento\Wishlist\Block\Adminhtml; -use Magento\Backend\Block\Template\Context; -use Magento\Customer\Controller\RegistryConstants; use Magento\Framework\Registry; +use Magento\Backend\Block\Template\Context; use Magento\Ui\Component\Layout\Tabs\TabWrapper; +use Magento\Ui\Component\Layout\Tabs\TabInterface; +use Magento\Customer\Controller\RegistryConstants; /** * Class WishlistTab - * - * @package Magento\Wishlist\Block\Adminhtml */ -class WishlistTab extends TabWrapper +class WishlistTab extends TabWrapper implements TabInterface { /** * Core registry diff --git a/app/code/Magento/Wishlist/composer.json b/app/code/Magento/Wishlist/composer.json index 59eee0b1b1feb0c7ab6eccbe0a4563a729e34340..b5400d7ffae45854dde81421038bcb58547818b7 100644 --- a/app/code/Magento/Wishlist/composer.json +++ b/app/code/Magento/Wishlist/composer.json @@ -3,28 +3,28 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/module-store": "0.74.0-beta6", - "magento/module-customer": "0.74.0-beta6", - "magento/module-catalog": "0.74.0-beta6", - "magento/module-checkout": "0.74.0-beta6", - "magento/module-theme": "0.74.0-beta6", - "magento/module-catalog-inventory": "0.74.0-beta6", - "magento/module-rss": "0.74.0-beta6", - "magento/module-backend": "0.74.0-beta6", - "magento/module-sales": "0.74.0-beta6", - "magento/module-grouped-product": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", - "magento/module-ui": "0.74.0-beta6", + "magento/module-store": "0.74.0-beta7", + "magento/module-customer": "0.74.0-beta7", + "magento/module-catalog": "0.74.0-beta7", + "magento/module-checkout": "0.74.0-beta7", + "magento/module-theme": "0.74.0-beta7", + "magento/module-catalog-inventory": "0.74.0-beta7", + "magento/module-rss": "0.74.0-beta7", + "magento/module-backend": "0.74.0-beta7", + "magento/module-sales": "0.74.0-beta7", + "magento/module-grouped-product": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", + "magento/module-ui": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "suggest": { - "magento/module-configurable-product": "0.74.0-beta6", - "magento/module-downloadable": "0.74.0-beta6", - "magento/module-bundle": "0.74.0-beta6", - "magento/module-cookie": "0.74.0-beta6" + "magento/module-configurable-product": "0.74.0-beta7", + "magento/module-downloadable": "0.74.0-beta7", + "magento/module-bundle": "0.74.0-beta7", + "magento/module-cookie": "0.74.0-beta7" }, "type": "magento2-module", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Wishlist/view/adminhtml/layout/customer_form.xml b/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_edit.xml similarity index 90% rename from app/code/Magento/Wishlist/view/adminhtml/layout/customer_form.xml rename to app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_edit.xml index 778b395ef14f8086c8c826715669fc6e6d6b03f4..c2caa32651b3797fb91742ea16f9dc1e57eda4dc 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/layout/customer_form.xml +++ b/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_edit.xml @@ -7,7 +7,7 @@ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> <body> - <referenceBlock name="form"> + <referenceBlock name="customer_form"> <block class="Magento\Wishlist\Block\Adminhtml\WishlistTab" name="wishlist" /> </referenceBlock> </body> diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_footer.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_footer.less index c8333911914ef0b9074034bd5f189d17d516fe12..290056b3664b9ec988dec9870b94a528d4a54edc 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_footer.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_footer.less @@ -38,6 +38,10 @@ @_link-text-decoration-active: false ); } + .admin__control-select { + max-width: 52rem; + width: 100%; + } } .magento-version { diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_menu.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_menu.less index 28387dfa85d71e68b74c0ccc508c7b9e03e63ab4..2fe7569f06c995e426241930d01694c5fa15c438 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_menu.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_menu.less @@ -277,25 +277,16 @@ margin: -(@submenu-heading-group__indent-bottom) @submenu__padding-horizontal * 2 + @submenu-action-close__indent-right 3.8rem @submenu__padding-horizontal * 2; } - .submenu-close { - &:extend(.abs-action-reset all); + .action-close { padding: 2.4rem @submenu-action-close__indent-right; position: absolute; right: 0; top: 0; - &:active { - .scale(); - } &:before { - &:extend(.abs-icon all); color: @submenu-section-label__color; - content: @icon-close-mage__content; font-size: 1.7rem; - .transition(color); } &:hover { - cursor: pointer; - text-decoration: none; &:before { color: @color-white; } diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/_actions-group.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/_actions-group.less index c7c4a1d35bd596fe0f363e763fd50d2d006e5bcf..716248651a8add1391f46575e8323e20a1d7dbd9 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/_actions-group.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/_actions-group.less @@ -19,53 +19,7 @@ // Variables // --------------------------------------------- -@page-header-action__height: 3.4rem; -@page-header-action__color: @text__color; -@page-header-action__hover__color: darken(@page-header-action__color, 20%); -@page-header-action__background-color: @page-wrapper__background-color; -@page-header-action__active__border-color: @color-blue-pure; -@page-header-action__border-color: @color-light-gray; - -// -// Extends -// --------------------------------------------- - -.abs-page-header-action { - background-color: @page-header-action__background-color; - border: 1px solid transparent; - border-bottom: none; - color: @page-header-action__color; - display: inline-block; - height: @page-header-action__height; - position: relative; - transition: border-color @appering__transition-duration @apperaing__transition-timing-function; - &:hover { - color: @page-header-action__hover__color; - text-decoration: none; - } -} - -.abs-page-header-action-menu { - background-color: @page-header-action__background-color; - border: 1px solid @page-header-action__active__border-color; - box-shadow: @component__box-shadow__base; - margin-top: -1px; - opacity: 0; - position: absolute; - right: 0; - top: 100%; - transition: all @appering__transition-duration @apperaing__transition-timing-function; - visibility: hidden; - &:before { - content: ''; - position: absolute; - } - > li { - display: block; - > a { - } - } -} +@page-header-action__height: @action__height + .1rem; // diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less index fd094d1ee44c7d1516e6f1989fb7086ad5b5034b..8d88b1044fc973c63d5f191a9073b77a862de7f6 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less @@ -18,14 +18,14 @@ @notifications-action__padding-bottom: (@page-header-action__height - @notifications-action-icon__size) / 2 - .05rem; @notifications-action__padding-side: 2rem; @notifications-action__padding-top: (@page-header-action__height - @notifications-action-icon__size) / 2 + .05rem; -@notifications-action__hover__color: darken(@page-header-action__color, 20%); +@notifications-action__hover__color: darken(@action-dropdown__color, 20%); @notifications-action-icon__size: 1.9rem; @notifications-action-menu__z-index: @header__z-index; @notifications-close__color: @color-gray80; @notifications-counter__background-color: @color-tomato-brick; @notifications-entry__padding-top: .6rem; -@notifications-entry__hover__background-color: @color-blue-clear-sky; +@notifications-entry__hover__background-color: @action__hover__background-color; @notifications-list__width: 32rem; @notifications-title__color: @color-light-phoenix; @notifications-time__color: @color-very-dark-gray1; @@ -39,33 +39,41 @@ &.active { z-index: @notifications-action-menu__z-index; // Should be over global search when active .notifications-action { - border-color: @page-header-action__active__border-color; + border-color: @action-dropdown__active__border-color; box-shadow: @component__box-shadow__base; &:after { - background-color: @page-header-action__background-color; + border: none; + background-color: @action-dropdown__background-color; content: ''; + display: block; height: @component__shadow-size__base + 1; left: -(@component__shadow-size__base + 1); + margin-top: 0; position: absolute; right: 0; top: 100%; + width: auto; } } - .notifications-list { - opacity: 1; - visibility: visible; - } + } + // Notifications dropdown + .admin__action-dropdown-menu { + padding: 1rem 0 0; + width: @notifications-list__width; } } .notifications-action { - &:extend(.abs-page-header-action all); + height: @page-header-action__height; padding: @notifications-action__padding-top @notifications-action__padding-side @notifications-action__padding-bottom; - z-index: 2; + &:after { + display: none; + } &:before { &:extend(.abs-icon all); content: @icon-notification-02__content; font-size: @notifications-action-icon__size; + margin-right: 0; } &:active { &:before { @@ -89,21 +97,11 @@ } } -.notifications-list { - &:extend(.abs-page-header-action-menu all); - padding-top: 1rem; - width: @notifications-list__width; - z-index: 1; - &:before { - z-index: 2; - } -} - .notifications-entry { line-height: @line-height__base; padding: @notifications-entry__padding-top @notifications-action__padding-side .8rem; position: relative; - transition: background-color .2s linear; + transition: @smooth__background-color; &:hover { background-color: @notifications-entry__hover__background-color; } diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less index 8b733d549c46afbd5e8f133acc3ec51ee86b5515..27524d7d4d0854693596871cd21c5d8f05dd84b8 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less @@ -43,8 +43,8 @@ min-width: @search-global-field__width; &._active { .search-global-input { - background-color: @page-header-action__background-color; - border-color: @page-header-action__active__border-color; + background-color: @action-dropdown__background-color; + border-color: @action-dropdown__active__border-color; box-shadow: @component__box-shadow__base; padding-right: @search-global-input__active__padding-right; width: @search-global-input__active__width; @@ -70,7 +70,7 @@ width: @search-global-input__active__width; } .search-global-menu { - border: 1px solid @page-header-action__active__border-color; + border: 1px solid @action-dropdown__active__border-color; border-top-color: transparent; box-shadow: @component__box-shadow__base; left: 0; @@ -81,7 +81,7 @@ top: 100%; z-index: 2; &:after { - background-color: @page-header-action__background-color; + background-color: @action-dropdown__background-color; content: ''; height: @component__shadow-size__base; left: 0; @@ -90,8 +90,8 @@ top: -@component__shadow-size__base; } > li { - background-color: @page-header-action__background-color; - border-top: 1px solid @page-header-action__border-color; + background-color: @action-dropdown__background-color; + border-top: 1px solid @action-dropdown__border-color; display: block; font-size: @font-size__s; padding: @search-global-input__padding-top @search-global-input__padding-side @search-global-input__padding-bottom; @@ -120,7 +120,7 @@ } &:hover { &:before { - color: @page-header-action__hover__color; + color: @action-dropdown__hover__color; } } &:before { diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_user.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_user.less index 678ed4b2342689e39c6a8bc2e1e8b21288409102..e43ef98b27b22da4156f8e2427c6eab0bbd2ae4c 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_user.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_user.less @@ -11,8 +11,6 @@ // Variables // --------------------------------------------- -@user__font-size: round(@font-size__base - .1rem, 1); - @user-account__padding-bottom: .4rem; @user-account__padding-left: 4rem; @user-account__padding-top: .7rem; @@ -20,6 +18,8 @@ @user-account-menu__min-width: 20rem; @user-account-menu__z-index: @notifications-action-menu__z-index - 10; // Should be lower than notifications +@user-account-menu__hover__background-color: @action__hover__background-color; +@user-account-menu__active__background-color: darken(@color-blue-clear-sky, 5%); // @@ -27,102 +27,74 @@ float: right; line-height: @line-height__base; // ToDo UI: Delete with admin scope margin-left: .3rem; - position: relative; z-index: @user-account-menu__z-index; + &._active, &.active { - .admin-user-account { - border-color: @page-header-action__active__border-color; + // User account action + .admin__action-dropdown { + border-color: @action-dropdown__active__border-color; box-shadow: @component__box-shadow__base; } - .admin-user-account-text-wrapper { - &:after { - background-color: @page-header-action__background-color; - content: ''; - height: @component__shadow-size__base + 1; - left: -(@component__shadow-size__base + 1); - position: absolute; - right: 0; - top: 100%; + } + // User account action + .admin__action-dropdown { + .action-toggle-triangle( + @_dropdown__padding-right: @user-account__padding-right; + @_triangle__color: @action-dropdown__color; + @_triangle__hover__color: @action-dropdown__hover__color; + @_triangle__right: 1.3rem; + ); + height: @page-header-action__height; + padding-bottom: @user-account__padding-bottom; + padding-left: @user-account__padding-left; + padding-top: @user-account__padding-top; + &:before { + @_icon-user__size: 2rem; + + &:extend(.abs-icon all); + content: @icon-account__content; + font-size: @_icon-user__size; + left: 1.1rem; + margin-top: -(@_icon-user__size / 2) - .1rem; + position: absolute; + top: 50%; + } + } + // User account menu + .admin__action-dropdown-menu { + @_user-menu__indent-side: 1rem; + min-width: @user-account-menu__min-width; + padding-left: @_user-menu__indent-side; + padding-right: @_user-menu__indent-side; + > li { + > a { + padding-right: (@user-account__padding-right - @_user-menu__indent-side); + padding-left: .5em; + white-space: nowrap; + transition: @smooth__background-color; + &:hover { + background-color: @user-account-menu__hover__background-color; + color: @action-dropdown__color; + } + &:active { + background-color: @user-account-menu__active__background-color; + bottom: -1px; + position: relative; + } } } - .admin-user-menu { - opacity: 1; - visibility: visible; + .admin-user-name { + .text-overflow-ellipsis(); + display: inline-block; + max-width: @user-account-menu__min-width; + overflow: hidden; + vertical-align: top; } } } -.admin-user-account { - &:extend(.abs-page-header-action all); - .dropdown-triangle( - @_dropdown__padding-right: @user-account__padding-right; - @_triangle__color: @page-header-action__color; - @_triangle__hover__color: @page-header-action__hover__color; - @_triangle__right: 1.3rem; - ); - font-size: @user__font-size; - letter-spacing: .05em; - padding-bottom: @user-account__padding-bottom; - padding-left: @user-account__padding-left; - padding-top: @user-account__padding-top; - z-index: 2; - &:before { - @_icon-user__size: 2rem; - - &:extend(.abs-icon all); - content: @icon-account__content; - font-size: @_icon-user__size; - left: 1.1rem; - margin-top: -(@_icon-user__size / 2) - .1rem; - position: absolute; - top: 50%; - } -} - .admin-user-account-text { + .text-overflow-ellipsis(); display: inline-block; max-width: @user-account-menu__min-width - @user-account__padding-left - @user-account__padding-right - 2rem; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.admin-user-menu { - @_user-menu__inden-side: 1rem; - - &:extend(.abs-page-header-action-menu all); - line-height: @line-height__base; - min-width: @user-account-menu__min-width; - padding: .5em @_user-menu__inden-side; - z-index: 1; - &:before { - z-index: 1; - } - > li { - > a { - color: @page-header-action__color; - display: block; - padding: .6rem (@user-account__padding-right - @_user-menu__inden-side) .6rem .5em; - text-decoration: none; - transition: background-color .1s linear; - white-space: nowrap; - &:hover { - background-color: @dropdown-menu__hover__background-color; - color: @page-header-action__color; - } - &:active { - background-color: @dropdown-menu__active__background-color; - bottom: -1px; - position: relative; - } - } - } - .admin-user-name { - display: inline-block; - max-width: @user-account-menu__min-width; - overflow: hidden; - text-overflow: ellipsis; - vertical-align: text-top; - white-space: nowrap; - } } diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less index 8fc37b9a87900f1e8bfb4187f9c6573cb30fd66b..1e410484253ff275204b387310b92fe406181c64 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less @@ -12,7 +12,7 @@ // Components // --------------------------------------------- -@import 'actions_bar/_store-switcher.less'; +@import 'actions-bar/_store-switcher.less'; // // Variables @@ -34,7 +34,7 @@ } .page-main-actions { - margin: 0 0 2rem; + margin: 0 0 @indent__l; } // @@ -52,15 +52,13 @@ z-index: @page-actions__fixed__z-index; .page-actions-inner { &:before { + .text-overflow-ellipsis(); color: @page-title__color; content: attr(data-title); float: left; font-size: @page-title__font-size; margin-top: .3rem; max-width: 50%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; } } } @@ -105,6 +103,7 @@ } } .actions-split { + &:extend(.abs-actions-split-xl all); float: right; margin-left: @_page-action__indent; .vendor-prefix-order(2); diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions_bar/_store-switcher.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less similarity index 98% rename from app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions_bar/_store-switcher.less rename to app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less index 3e699e2172984de88021448463571bcd9f5f87e1..99527ea22ca0b8ea743dc380f30360a5e6f02dd3 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions_bar/_store-switcher.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less @@ -13,9 +13,10 @@ color: @text__color; // ToDo UI: Delete with admin scope float: left; font-size: round(@font-size__base - .1rem, 1); - margin-top: 1.1rem; + margin-top: .7rem; .admin__action-dropdown { margin-left: .5em; + background-color: @page-main-actions__background-color; } .dropdown { .dropdown( diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_login.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_login.less index 7ba168e1ab2333553e3416ff40e09f404872faac..bf9bfec974326847996124b11b68fa4867defb75 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_login.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_login.less @@ -18,12 +18,12 @@ // Admin user auth pages layout // --------------------------------------------- -// Header +// Header .login-header { margin: 0 0 3rem; } -// Login box +// Login box .page-layout-admin-login { align-items: center; .vendor-prefix-display(flex); @@ -38,6 +38,7 @@ margin: auto; max-width: @login-box__max-width; min-height: @login-box__min-height; + min-width: 0; padding: 40px 80px 50px; position: relative; width: 100%; diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module.less new file mode 100644 index 0000000000000000000000000000000000000000..6ab7104603ae2c6e9a7f1bfbbe30ef029520c508 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module.less @@ -0,0 +1,6 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +@import 'module/_data-grid.less'; diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module.less index 6d1cdd4c54a3d3db423a4740e016c242f7fd7e84..3e1c86ab7f8b8dbd8cd4cbcecc88cf50ae9d5af0 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module.less +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module.less @@ -3,13 +3,15 @@ // * See COPYING.txt for license details. // */ -//colors +// +// Variables +// --------------------------------------------- + @admin__color1: #adadad; @admin__color2: #d3d3d3; @admin__color3: #e0e0e0; @admin__color4: #666; -//Spacing @spacing__base: 10px; @spacing-xs: @spacing__base; @spacing-s: @spacing__base; @@ -17,7 +19,6 @@ @spacing-l: @spacing__base; @spacing-xl: @spacing__base; -//Fonts @size__base: 1rem; @size-xs: @size__base; @size-s: @size__base; @@ -27,6 +28,8 @@ @field-date-icon--color: #514943; +// + [class*="tab-nav-item"]:not(ul):active, [class*="tab-nav-item"]:not(ul):focus { box-shadow: none; @@ -125,53 +128,51 @@ } .listing-tiles { - overflow: hidden; - margin-top: -10px; - margin-left: -10px; - - .listing-tile { - background-color: #f2ebde; - display: block; - width: 238px; - height: 200px; - float: left; - border: 1px solid #676056; - margin-top: 10px; - margin-left: 10px; - border-radius: 4px; - text-align: center; - - &.disabled { - border-color: red; - } + overflow: hidden; + margin-top: -10px; + margin-left: -10px; + + .listing-tile { + background-color: #f2ebde; + display: block; + width: 238px; + height: 200px; + float: left; + border: 1px solid #676056; + margin-top: 10px; + margin-left: 10px; + border-radius: 4px; + text-align: center; + + &.disabled { + border-color: red; + } - &.enabled { - border-color: green; + &.enabled { + border-color: green; + } } - } } .listing { - .disabled { - color: red; - } - .enabled { - color: green; - } + .disabled { + color: red; + } + .enabled { + color: green; + } } .pager { text-align: left; padding-bottom: 10px; .clearfix(); - [data-part=left] { display: inline-block; width: 45%; float: left; text-align: left; } - [data-part=right] { display: inline-block; width: 45%; @@ -182,44 +183,30 @@ -ms-user-select: none; // use in 11 IE user-select: none; } - - .action-next{ + .action-next { cursor: pointer; } - - .action-previous{ + .action-previous { cursor: pointer; } } -.pager { - text-align: left; -} -.pager [data-part=left] { - display: inline-block; - width: 45%; - text-align: left; -} -.pager [data-part=right] { - display: inline-block; - width: 45%; - text-align: right; - float: right; -} -.grid .col-title { - min-width: 90px; - text-align: center; -} -.grid-actions [data-part=search] { - display: inline-block; - margin: 0 30px; -} -.grid-actions [data-part=search] input[type=text] { - vertical-align: bottom; - width: 460px; +.grid-actions { + [data-part=search] { + display: inline-block; + margin: 0 30px; + input[type=text] { + vertical-align: bottom; + width: 460px; + } + } } .grid { + .col-title { + min-width: 90px; + text-align: center; + } .actions-split { .clearfix(); display: inline-block; @@ -292,274 +279,6 @@ } } -.filters { - &-toggle { - .button( - @_button-margin: 3px, - @_button-icon-use: true, - @_button-font-content: @icon-pointer-down, - @_button-icon-font-size: 30px, - @_button-icon-font-line-height: 15px, - @_button-icon-font-text-hide: false, - @_button-icon-font-position: after - ); - .button-reset(); - &:after { - margin-top: 2px; - margin-left: -3px; - } - &.active { - &:after { - content: @icon-pointer-up; - } - } - } - &-current { - padding: 10px 0; - display: none; - &.active{ - display: block; - } - } - &-items { - .list-reset-styles(); - display: inline; - } - &-item { - display: inline-block; - margin:0 5px 5px 0; - padding: 2px 2px 2px 4px; - border-radius: 3px; - background: #f7f3eb; - .item-label { - font-weight: 600; - &:after { - content: ": " - } - } - .action-remove { - .button( - @_button-margin: 3px, - @_button-icon-use: true, - @_button-font-content: @icon-remove, - @_button-icon-font-size: 16px, - @_button-icon-font-line-height: 16px, - @_button-icon-font-text-hide: true - ); - padding: 0; - //.button-reset(); - } - } - &-form { - position: relative; - z-index: 1; - margin: 14px 0; - background: #fff; - border: 1px solid #bbb; - box-shadow: 0 3px 3px rgba(0, 0, 0, .15); - .action-close { - position: absolute; - top: 3px; - right: 7px; - .button( - @_button-margin: 3px, - @_button-icon-use: true, - @_button-font-content: @icon-remove, - @_button-icon-font-size: 42px, - @_button-icon-font-line-height: 42px, - @_button-icon-font-text-hide: true - ); - .button-reset(); - } - } - &-actions { - margin: 18px; - text-align: right; - } - &-fieldset { - padding-bottom: 0; - .field { - border: 0; - .form-field( - @_type: inline, - @_column: true, - @_column-number: 3, - @_type-inline-label-width: 35%, - @_type-inline-control-width: 65% - ); - .label { - .style2(); - margin: 0; - } - } - } - .field-date .group { - .hasDatepicker { - width: 100%; - padding-right: 30px; - - & + .ui-datepicker-trigger { - img { - display: none; - } - .button-reset(); - .icon-font( - @icon-calendar, - @_icon-font-size: 35px, - @_icon-font-line-height: 30px, - @_icon-font-text-hide: true, - @_icon-font-position: after, - @_icon-font-color: @field-date-icon--color - ); - margin-left: -33px; - display: inline-block; - width: 30px; - } - } - } - .field-range .group{ - .field { - margin-bottom: 0; - } - .label { - &:extend(.visually-hidden all); - } - .control { - width: 100%; - box-sizing: border-box; - padding-right: 0; - position: relative; - z-index: 1; - } - } - -} - -/* [data-part=filter-form] { - width: 650px; - left: 150px; - - background: #fff; - border: 1px solid #bbb; - position: absolute; - z-index: 100; - box-shadow: 0 3px 3px rgba(0, 0, 0, .15); - margin-top: 4px; - - .title { - position: relative; - padding: 5px 18px; - - .close { - position: absolute; - font-size: .8em; - right: 10px; - top: 12px; - cursor: pointer; - - &:hover, - &:active { - text-decoration: underline; - } - } - } - - > .actions { - padding: 5px 18px 36px; - } -} */ - -.mass-select { - position: relative; - margin: -6px -10px; - padding: 6px 2px 6px 10px; - z-index: 1; - white-space: nowrap; - &.active { - background: rgba(0,0,0,.2); - } - &-toggle { - .button( - @_button-margin: 3px, - @_button-icon-use: true, - @_button-font-content: @icon-pointer-down, - @_button-icon-font-size: 30px, - @_button-icon-font-line-height: 15px, - @_button-icon-font-text-hide: true - ); - .button-reset(); - &:before { - margin-top: -2px; - text-indent: -5px; - color: #fff; - } - &:hover:before { - color: #fff; - } - &:active, - &.active { - &:before { - content: @icon-pointer-up; - } - } - } - &-field { - .label { - &:extend(.visually-hidden all); - } - display: inline; - } - &-menu { - display: none; - position: absolute; top: 100%; left: 0; - text-align: left; - .list-reset-styles(); - background: #fff; - border: 1px solid #bbb; - min-width: 175px; - box-shadow: 0 3px 3px rgba(0, 0, 0, .15); - li { - margin: 0; - padding: 4px 15px; - border-bottom: 1px solid #e5e5e5; - } - li:hover { - background: #e8e8e8; - cursor: pointer; - } - span { - font-weight: normal; - font-size: 13px; - color: #645d53; - } - &.active { - display: block; - } - } -} - -.grid-loading-mask{ - position: absolute; - left: 0; - top: 0; - right: 0; - bottom: 0; - background: rgba(255, 255, 255, .5); - z-index: 100; - - .grid-loader{ - position: absolute; - margin: auto; - left: 0; - top: 0; - right: 0; - bottom: 0; - width: 218px; - height: 149px; - background: url('@{baseDir}images/loader-2.gif') 50% 50% no-repeat; - } -} - // // Form Component // @@ -581,20 +300,20 @@ } .field-price.addon { - direction: rtl; + direction: rtl; } .field-price.addon > * { - direction: ltr; + direction: ltr; } .field-price.addon .addafter { - border-width: 1px 0 1px 1px; - border-radius: 2px 0 0 2px; + border-width: 1px 0 1px 1px; + border-radius: 2px 0 0 2px; } .field-price.addon input:first-child { - border-radius: 0 2px 2px 0; + border-radius: 0 2px 2px 0; } .field-price input[type="text"] { @@ -602,21 +321,21 @@ } .field-price input ~ label.addafter strong { - margin-left: 2px; - margin-right: -2px; + margin-left: 2px; + margin-right: -2px; } .field-price.addon > input { - width: 99px; - float: left; + width: 99px; + float: left; } .field-price .control { - position: relative; + position: relative; } .field-price label.mage-error { - position: absolute; - left: 0; - top: 30px; + position: absolute; + left: 0; + top: 30px; } diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less new file mode 100644 index 0000000000000000000000000000000000000000..d01685e141655100c6a45d8a9115fcf4ae3d7abf --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less @@ -0,0 +1,313 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// UI -> Data Grid +// _____________________________________________ + +// +// Components +// --------------------------------------------- + +@import 'data-grid/_data-grid-header.less'; + +// +// Variables +// --------------------------------------------- + +@data-grid__font-size: 1.3rem; + +@data-grid-tr__active__background-color: @action__hover__background-color; +@data-grid-tr__hover__background-color: lighten(@action__hover__background-color, 1%); + +@data-grid-cell__border-width: .1rem; +@data-grid-cell__padding-horizontal: 1rem; +@data-grid-cell__padding-vertical: 1rem; + +@data-grid-td__border-color: @color-gray84; +@data-grid-td__border-inner-style: dashed; +@data-grid-td__border-outer-style: solid; +@data-grid-td__even__background-color: @color-white-smoke; +@data-grid-td__odd__background-color: @page__background-color; + +@data-grid-th__border-color: @color-darkie-gray; +@data-grid-th__border-style: solid; +@data-grid-th__background-color: @color-brownie; +@data-grid-th__color: @color-white; +@data-grid-th__padding-horizontal: @data-grid-cell__padding-horizontal; +@data-grid-th__padding-vertical: @data-grid-cell__padding-vertical; +@data-grid-th__hover__background-color: lighten(@data-grid-th__background-color, 5%); + +@data-grid-th-marker__width: .7rem; + +@data-grid-checkbox-cell-inner__padding-top: 1.1rem; +@data-grid-checkbox-cell-inner__padding-horizontal: 1.8rem; + +@data-grid-row-parent-marker__size: 1rem; + +// + +.admin__data-grid-wrap { + padding-top: 0; + position: relative; +} + +.admin__data-grid-loading-mask { + background: rgba(255, 255, 255, .5); + bottom: 0; + left: 0; + right: 0; + top: 0; + position: absolute; + z-index: @overlay__z-index; + + .grid-loader { + background: url('@{baseDir}images/loader-2.gif') 50% 50% no-repeat; + bottom: 0; + height: 149px; + left: 0; + margin: auto; + position: absolute; + right: 0; + top: 0; + width: 218px; + } +} + +.data-grid { + border-bottom: @data-grid-cell__border-width @data-grid-td__border-outer-style @data-grid-td__border-color; + border-left: none; + border-right: none; + border-top: none; + font-size: @data-grid__font-size; + margin-bottom: 2rem; + max-width: 100%; + width: 100%; + thead { + background-color: transparent; // ToDo UI: Rewrite old styles. Should be deleted afterwards + color: @text__color; // ToDo UI: Rewrite old styles. Should be deleted afterwards + } + tr { + &:nth-child(even) { + td { + background-color: @data-grid-td__even__background-color; + } + } + &:active { + td { + background-color: @data-grid-tr__active__background-color; + } + } + &:hover { + td { + background-color: @data-grid-tr__hover__background-color; + cursor: pointer; + } + } + &.data-grid-tr-no-data { + &:hover { + td { + cursor: default; + background-color: @data-grid-td__odd__background-color; + } + } + } + } + th, + td { + font-size: @data-grid__font-size; // ToDo UI: Rewrite old styles. Should be deleted afterwards + line-height: @line-height__base; + transition: @smooth__background-color; + vertical-align: top; + } + td { + background-color: @data-grid-td__odd__background-color; + border-left: @data-grid-cell__border-width @data-grid-td__border-inner-style @data-grid-td__border-color; + border-right: @data-grid-cell__border-width @data-grid-td__border-inner-style @data-grid-td__border-color; + color: @table__color; + padding: @data-grid-cell__padding-vertical @data-grid-cell__padding-horizontal; + &:first-child { + border-left-style: @data-grid-td__border-outer-style; + } + &:last-child { + border-right-style: @data-grid-td__border-outer-style; + } + // Action select data grid styles (can be action-select-secondary in future) + .action-select { + .link-pattern(); + background-color: transparent; + border: none; + font-size: @data-grid__font-size; + padding: 0 3rem 0 0; + &:hover { + &:after { + border-color: @link__hover__color transparent transparent transparent; + } + } + &:after { + border-color: @link__color transparent transparent transparent; + } + &:before { + display: none; + } + } + .action-menu { + left: auto; + z-index: 1; + } + } + th { + background-color: @data-grid-th__background-color; + border: @data-grid-cell__border-width @data-grid-th__border-style @data-grid-th__border-color; + border-left-color: transparent; + color: @data-grid-th__color; + font-weight: @font-weight__semibold; + padding: 0; + text-align: left; + &:first-child { + border-left-color: @data-grid-th__border-color; + } + } + .data-grid-th { + color: @data-grid-th__color; + padding: @data-grid-th__padding-vertical @data-grid-th__padding-horizontal; + &._sortable { + cursor: pointer; + padding-right: @data-grid-th__padding-horizontal * 2 + @data-grid-th-marker__width; + position: relative; + transition: @smooth__background-color; + &:focus, + &:hover { + background-color: @data-grid-th__hover__background-color; + } + &:active { + padding-bottom: @data-grid-th__padding-vertical - .1rem; + padding-top: @data-grid-th__padding-vertical + .1rem; + } + } + } + .data-grid-checkbox-cell { + padding: 0; + &:hover { + cursor: default; + } + } + .data-grid-multiselect-cell { + padding: @data-grid-th__padding-horizontal @data-grid-th__padding-vertical @data-grid-th__padding-horizontal - .1rem; + text-align: center; + width: @control-checkbox-radio__size + @data-grid-checkbox-cell-inner__padding-horizontal * 2; + } + .data-grid-actions-cell { + padding-left: @data-grid-cell__padding-horizontal * 2; + padding-right: @data-grid-cell__padding-horizontal * 2; + width: 1%; + } + // Nested rows + .data-grid-row-parent { + &._active { + > td { + background-color: @color-lazy-sunny; + border-bottom: @data-grid-cell__border-width @data-grid-td__border-outer-style @data-grid-td__border-color; + border-left-color: transparent; + border-right-color: transparent; + border-top: @data-grid-cell__border-width @data-grid-td__border-outer-style @data-grid-td__border-color; + &:first-child { + border-left-color: @data-grid-td__border-color; + } + &:last-child { + border-right-color: @data-grid-td__border-color; + } + } + } + } + .data-grid-row-child { + display: none; + &._active { + display: table-row; + + tr { + &:not(.data-grid-row-child) { + td { + border-top: @data-grid-cell__border-width @data-grid-td__border-outer-style @data-grid-td__border-color; + } + } + } + } + } + .data-grid-row-child, + .data-grid-row-parent ~ .data-grid-row-child { + td { + background-color: @color-lazy-sun-white; + border-color: transparent; + &:first-child { + border-left-color: @data-grid-td__border-color; + } + &:last-child { + border-right-color: @data-grid-td__border-color; + } + } + } +} + +// Ascend & Descend sort marker +.data-grid-th { + &._sortable { + &._ascend, + &._descend { + &:before { + position: absolute; + right: @data-grid-th__padding-horizontal; + top: @data-grid-th__padding-vertical - .1rem; + } + } + &._ascend { + &:before { + content: '\2193'; + } + } + &._descend { + &:before { + content: '\2191'; + } + } + } +} + +// Checkbox actions column +.data-grid-checkbox-cell-inner { + display: block; + padding: @data-grid-checkbox-cell-inner__padding-top @data-grid-checkbox-cell-inner__padding-horizontal .9rem; + text-align: right; + &:hover { + cursor: pointer; + } +} + +// Nested rows +.data-grid-row-parent { + &._active { + > td { + .data-grid-checkbox-cell-inner { + &:before { + content: @icon-caret-up__content; + } + } + } + } + > td { + .data-grid-checkbox-cell-inner { + padding-left: (@data-grid-checkbox-cell-inner__padding-horizontal * .75) * 2 + @data-grid-row-parent-marker__size; + position: relative; + &:before { + &:extend(.abs-icon all); + content: @icon-caret-down__content; + font-size: @data-grid-row-parent-marker__size; + font-weight: @font-weight__bold; + left: @data-grid-checkbox-cell-inner__padding-horizontal * .75; + position: absolute; + top: @data-grid-checkbox-cell-inner__padding-top + (@data-grid-row-parent-marker__size / 2); + } + } + } +} diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/_data-grid-header.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/_data-grid-header.less new file mode 100644 index 0000000000000000000000000000000000000000..6d5ecd492f8b61b3727d2aea729e31e3cce18dbb --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/_data-grid-header.less @@ -0,0 +1,96 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// UI -> Data Grid -> Header +// _____________________________________________ + +// +// Components +// --------------------------------------------- + +@import 'data-grid-header/_data-grid-filters.less'; +@import 'data-grid-header/_data-grid-pager.less'; +// Actions group +@import 'data-grid-header/_data-grid-action-bookmarks.less'; +@import 'data-grid-header/_data-grid-action-columns.less'; + +// +// Variables +// --------------------------------------------- + +@data-grid-header-add-indent__bottom: .9rem; +@data-grid-header-add-indent__top: .5rem; + +@data-grid-header-row__margin-bottom: @indent__base; + +@data-grid-action__z-index: @data-grid-header__z-index - 10; + +// + +.admin__data-grid-header { + font-size: @font-size__base; // ToDo UI: should be deleted, added to prevent fz override with .grid + position: relative; + z-index: @data-grid-header__z-index - 1; +} + +.admin__data-grid-header-row { + &:extend(.abs-clearfix all); + margin-bottom: @data-grid-header-row__margin-bottom; + &:first-child { + margin-bottom: @data-grid-header-row__margin-bottom - @data-grid-header-add-indent__bottom; + } + .action-select-wrap { + display: block; + } + .action-select { + width: 100%; + } +} + +// +// Data grid Header Actions group +// --------------------------------------------- + +.admin__data-grid-actions-wrap { + float: right; + margin-left: 1.1rem; + margin-top: -@data-grid-header-add-indent__top; + text-align: right; + .admin__action-dropdown-wrap { + position: relative; + text-align: left; + &._active, + &._active + .admin__action-dropdown-wrap, // ToDo UI: remove after bookmarks ready + &._hide + .admin__action-dropdown-wrap, + &:first-child { + &:after { + display: none; + } + } + &._active { + .admin__action-dropdown, + .admin__action-dropdown-menu { + border-color: @action__border-color; + } + } + &:after { + border-left: 1px solid @color-gray80; + content: ''; + height: @action__height; + left: 0; + position: absolute; + top: @data-grid-header-add-indent__top; + z-index: 3; + } + } + .admin__action-dropdown { + padding-bottom: @action-dropdown__padding-bottom + @data-grid-header-add-indent__bottom; + padding-top: @action-dropdown__padding-top + @data-grid-header-add-indent__top; + &:after { + margin-top: -.4rem; + } + } +} diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-action-bookmarks.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-action-bookmarks.less new file mode 100644 index 0000000000000000000000000000000000000000..6e3be82858c0933375b870d9c25d4ccbf986e401 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-action-bookmarks.less @@ -0,0 +1,160 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// UI -> Data Grid -> Header -> Action Default View +// _____________________________________________ + +// +// Variables +// --------------------------------------------- + +@action-dropdown-menu__font-size: 1.3rem; + +@action-dropdown-menu-item__background-color: @page-wrapper__background-color; +@action-dropdown-menu-item__padding-vertical: 1rem; +@action-dropdown-menu-item__padding-left: 2rem; +@action-dropdown-menu-item__hover__background-color: @color-gray89; + +@action-dropdown-menu-item-actions__size: 1.7rem; +@action-dropdown-menu-item-actions__width: 5rem; + +@action-dropdown-menu-item-action-icon__padding-horizontal: 1.4rem; +@action-dropdown-menu-item-action-icon__padding-vertical: .6rem; + +// + +.admin__data-grid-action-bookmarks { + .admin__action-dropdown-menu__align(right); + opacity: @component-modal__opacity; + &._hide { + display: none; + } + &._active { + z-index: @data-grid-action__z-index; + } + .admin__action-dropdown { + &:before { + &:extend(.abs-icon all); + content: @icon-views__content; + } + } + .admin__action-dropdown-menu { + font-size: @action-dropdown-menu__font-size; + left: 0; + padding: 1rem 0 0; + right: auto; + > li { + padding: 0 @action-dropdown-menu-item-actions__width 0 0; + position: relative; + white-space: nowrap; + &:not(.action-dropdown-menu-item-last) { + transition: @smooth__background-color; + &:hover { + background-color: @action-dropdown-menu-item__hover__background-color; + } + } + } + .action-dropdown-menu-item { + max-width: 23rem; + min-width: 18rem; + white-space: normal; + word-break: break-all; + } + .action-dropdown-menu-item-edit { + display: none; + padding-bottom: @action-dropdown-menu-item__padding-vertical; + padding-left: @action-dropdown-menu-item__padding-left / 2; + padding-top: @action-dropdown-menu-item__padding-vertical; + .action-dropdown-menu-item-actions { + padding-bottom: @action-dropdown-menu-item__padding-vertical; + padding-top: @action-dropdown-menu-item__padding-vertical; + } + } + // Save action + .action-dropdown-menu-item-last { + padding-bottom: @action-dropdown-menu-item__padding-vertical; + padding-left: @action-dropdown-menu-item__padding-left / 2; + padding-top: @action-dropdown-menu-item__padding-vertical; + > a { + .link-pattern(); + display: inline-block; + padding-left: 1.1rem; + } + } + // Edit state + ._edit { + .action-dropdown-menu-item { + display: none; + } + .action-dropdown-menu-item-edit { + display: block; + } + } + // Edit item + .admin__control-text { + font-size: @action-dropdown-menu__font-size; + min-width: 15rem; + width: ~'calc(100% - 4rem)'; + .ie9 & { + width: 15rem; + } + } + .action-dropdown-menu-item-actions { + border-left: 1px solid @action-dropdown-menu-item__background-color; + bottom: 0; + position: absolute; + right: 0; + top: 0; + width: @action-dropdown-menu-item-actions__width; + } + .action-dropdown-menu-link { + .action-dropdown-menu-link-pattern(); + padding: @action-dropdown-menu-item__padding-vertical 1rem @action-dropdown-menu-item__padding-vertical @action-dropdown-menu-item__padding-left + .1rem; + } + } + // Icon actions + .action-submit, + .action-delete, + .action-edit { + .action-reset(); + vertical-align: top; + &:before { + &:extend(.abs-icon all); + font-size: @action-dropdown-menu-item-actions__size; + } + > span { + .hidden(); + } + } + .action-delete, + .action-edit { + padding: @action-dropdown-menu-item-action-icon__padding-vertical @action-dropdown-menu-item-action-icon__padding-horizontal; + &:active { + .scale(); + } + } + .action-submit { + padding: @action-dropdown-menu-item-action-icon__padding-vertical 1rem @action-dropdown-menu-item-action-icon__padding-vertical .8rem; + &:active { + position: relative; + right: -1px; + } + &:before { + content: @icon-arrow-right__content; + } + } + .action-delete { + &:before { + content: @icon-delete__content; + } + } + .action-edit { + padding-top: @action-dropdown-menu-item-action-icon__padding-vertical + .2rem; + &:before { + content: @icon-edit__content; + } + } +} diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-action-columns.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-action-columns.less new file mode 100644 index 0000000000000000000000000000000000000000..e4148e87f4dbb11469b2e3ecb97513defca1e363 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-action-columns.less @@ -0,0 +1,94 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// UI -> Data Grid -> Header -> Action Columns +// _____________________________________________ + +// +// Variables +// --------------------------------------------- + +@data-grid-action-columns-menu__padding-horizontal: 3.5rem; + +@data-grid-action-columns-menu-item__column: 3; +@data-grid-action-columns-menu-item__margin-bottom: 1.5rem; +@data-grid-action-columns-menu-item__width: 15.8rem; +@data-grid-action-columns-menu-item__height: round((@font-size__base * @line-height__base), 1); + +@data-grid-action-columns-menu-items-to-scroll: 18; +@data-grid-action-columns-menu-scroll__width: 1.8rem; + +// + +.admin__data-grid-action-columns { + &._active { + opacity: @component-modal__opacity; + z-index: @data-grid-action__z-index; + } + .admin__action-dropdown { + &:before { + &:extend(.abs-icon all); + content: @icon-systems__content; + font-size: 1.8rem; // Static + left: .3rem; + margin-right: .7rem; + vertical-align: top; + } + } +} + +.admin__data-grid-action-columns-menu { + color: @color-very-dark-gray-black; + font-size: 1.3rem; + overflow: hidden; + padding: 2.2rem @data-grid-action-columns-menu__padding-horizontal 1rem; + z-index: 1; + // State with scroll when .admin__field-option > @data-grid-action-columns-menu-items-to-scroll + &._overflow { + .admin__action-dropdown-menu-header { + border-bottom: 1px solid @border-color__base; + } + .admin__action-dropdown-menu-content { + width: @data-grid-action-columns-menu-item__width * @data-grid-action-columns-menu-item__column + @data-grid-action-columns-menu-scroll__width; + } + .admin__action-dropdown-menu-footer { + border-top: 1px solid @border-color__base; + padding-top: 2.5rem; + } + } + .admin__action-dropdown-menu-content { + .extend__clearfix(); + max-height: (@data-grid-action-columns-menu-items-to-scroll / @data-grid-action-columns-menu-item__column) * (@data-grid-action-columns-menu-item__height + @data-grid-action-columns-menu-item__margin-bottom) + (@data-grid-action-columns-menu-item__height / 2 + @data-grid-action-columns-menu-item__margin-bottom); + overflow-y: auto; + padding-top: 1.5rem; + width: @data-grid-action-columns-menu-item__width * @data-grid-action-columns-menu-item__column; + } + .admin__field-option { + height: @data-grid-action-columns-menu-item__height; + float: left; + margin-bottom: @data-grid-action-columns-menu-item__margin-bottom; + padding: 0 1rem 0 0; + width: @data-grid-action-columns-menu-item__width; + } + .admin__field-label { + .text-overflow-ellipsis(); + display: block; + } + .admin__action-dropdown-menu-header { + padding-bottom: 1.5rem; + } + .admin__action-dropdown-menu-footer { + padding: 1rem 0 2rem; + } + .admin__action-dropdown-footer-main-actions { + margin-left: 25%; + text-align: right; + } + .admin__action-dropdown-footer-secondary-actions { + float: left; + margin-left: -@button__padding-horizontal; + } +} diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-filters.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-filters.less new file mode 100644 index 0000000000000000000000000000000000000000..66df9bda92aaebd8b110229fdbcb6adefc9b2e79 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-filters.less @@ -0,0 +1,320 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// UI -> Data Grid -> Header -> Filters +// _____________________________________________ + +// +// Variables +// --------------------------------------------- + +@data-grid-search-action__size: 2rem; + +@data-grid-filters__font-size: 1.3rem; +@data-grid-filters__background-color: @page-wrapper__background-color; + +@data-grid-filters-fieldset__inner-side: 4rem; +@data-grid-filters-fieldset__columns: 4; + +@data-grid-filters-label__width: 25%; + +@data-grid-filters-action__padding-right: 2.1rem; +@data-grid-filters-action__padding-left: 1.7rem; +@data-grid-filters-action__active__border-color: @color-gray80; +@data-grid-filters-action__active__color: @color-phoenix; + +@data-grid-filters-current-action-remove__background-color: @color-gray68; +@data-grid-filters-current-action-remove__hover__background-color: darken(@data-grid-filters-current-action-remove__background-color, 10%); +@data-grid-filters-current-action-remove__size: 1.6rem; + +// +// Filter action & search +// --------------------------------------------- + +.data-grid-filters-actions-wrap { + float: right; +} + +// Data Grid Search +.data-grid-search-control-wrap { + display: none; + float: left; + max-width: 45.5rem; + position: relative; + width: 50%; + :-ms-input-placeholder { + font-style: italic; + } + ::-webkit-input-placeholder { + font-style: italic; + } + ::-moz-placeholder { + font-style: italic; + } + // Submit/search icon + .action-submit { + .action-reset(); + padding: .6rem 2rem .2rem; + position: absolute; + right: 0; + top: 1px; + &:active { + .scale(); + } + &:hover { + &:before { + color: darken(@text__color, 10%); + } + } + &:focus { + box-shadow: @focus__box-shadow; + } + &:before { + &:extend(.abs-icon all); + content: @icon-search__content; + font-size: @data-grid-search-action__size; + transition: @smooth__color; + } + > span { + .hidden(); + } + } + .action-menu { + z-index: 1; + } +} + +.data-grid-search-control { + padding-right: @data-grid-search-action__size + 2rem * 2; + width: 100%; +} + +// Action +.data-grid-filters-action-wrap { + float: left; + padding-left: @indent__base; + .action-default { + font-size: @data-grid-filters__font-size; + padding-left: @data-grid-filters-action__padding-left; + padding-right: @data-grid-filters-action__padding-right; + padding-top: @action__padding-top + .1rem; + &._active { + background-color: @data-grid-filters__background-color; + border-bottom-color: @data-grid-filters__background-color; + border-right-color: @data-grid-filters-action__active__border-color; + font-weight: @font-weight__semibold; + margin-left: 0; + margin-right: 0; + margin-top: -.1rem; + padding-bottom: 1.9rem; + padding-top: @action__padding-top + .2rem; + position: relative; + z-index: 4; + &:after { + background-color: @data-grid-filters-action__active__color; + bottom: 100%; + content: ''; + height: 3px; + left: -1px; + position: absolute; + right: -1px; + } + } + &:before { + &:extend(.abs-icon all); + content: @icon-filter__content; + font-size: 1.8rem; + margin-right: .4rem; + position: relative; + top: -1px; + vertical-align: top; + } + } +} + +// +// Filters content +// --------------------------------------------- + +.admin__data-grid-filters-wrap { + .appearing__off(); + clear: both; + font-size: @data-grid-filters__font-size; + max-height: 0; + transition: opacity .3s ease, padding .3s ease; + &._show { + .appearing__on(); + border-bottom: 1px solid @data-grid-filters-action__active__border-color; + border-top: 1px solid @data-grid-filters-action__active__border-color; + margin-bottom: .7rem; + max-height: 50rem; + padding: 3.6rem 0 3rem; + position: relative; + top: -1px; + z-index: 3; + .admin__data-grid-filters-footer, + .admin__data-grid-filters { + display: block; + } + } + // Field labels + .admin__form-field-legend, + .admin__form-field-label { + display: block; + font-weight: bold; + margin: 0 0 .3rem; + text-align: left; + } + // First level field + .admin__form-field { + float: left; + margin-bottom: 2em; + margin-left: 0; + padding-left: @data-grid-filters-fieldset__inner-side / 2; + padding-right: @data-grid-filters-fieldset__inner-side / 2; + width: 100% / @data-grid-filters-fieldset__columns; + &:nth-child(5n + 1) { + clear: both; + } + // Inner fields + .admin__form-field { + float: none; + margin-bottom: 1.5rem; + padding-left: 0; + padding-right: 0; + width: auto; + &:last-child { + margin-bottom: 0; + } + // Inner field labels + .admin__form-field-label { + border: @field-control__border-width solid transparent; + float: left; + font-weight: normal; + line-height: @field-control__line-height; + margin-bottom: 0; + padding-bottom: @field-control__padding-bottom; + padding-right: 1em; + padding-top: @field-control__padding-top; + width: @data-grid-filters-label__width; + } + .admin__form-field-control { + margin-left: @data-grid-filters-label__width; + } + } + } + .admin__form-field-label, + .admin__control-text, + .admin__control-select { + font-size: @data-grid-filters__font-size; + } + .admin__control-select { + padding-top: @action__padding-top - .1rem; + height: @action__height - .1rem; + } + // Date control + .admin__control-text.hasDatepicker, + .admin__control-select { + width: 100%; + } +} + +// Filters content wrap +.admin__data-grid-filters { + &:extend(.abs-clearfix all); + display: none; + margin-left: -(@data-grid-filters-fieldset__inner-side / 2); + margin-right: -(@data-grid-filters-fieldset__inner-side / 2); +} + +.admin__filters-legend { + .hidden(); +} + +// Filters footer +.admin__data-grid-filters-footer { + &:extend(.abs-clearfix all); + display: none; + font-size: @font-size__base; + .admin__footer-main-actions { + margin-left: 25%; + text-align: right; + } + .admin__footer-secondary-actions { + float: left; + width: 50%; + } +} + +// +// Chips +// --------------------------------------------- + +// Current chips +.admin__data-grid-filters-current { + border-bottom: 1px solid @data-grid-filters-action__active__border-color; + border-top: 1px solid @data-grid-filters-action__active__border-color; + display: none; + font-size: @data-grid-filters__font-size; + margin-bottom: .9rem; + padding-bottom: .8rem; + padding-top: 1.1rem; + width: 100%; + &._show { + display: table; + } +} + +.admin__current-filters-list-wrap, +.admin__current-filters-title-wrap { + display: table-cell; + vertical-align: top; +} + +.admin__current-filters-title { + margin-right: 1em; + white-space: nowrap; +} + +.admin__current-filters-list-wrap { + width: 100%; +} + +.admin__current-filters-list { + margin-bottom: 0; + > li { + display: inline-block; + font-weight: @font-weight__semibold; + margin: 0 1rem .5rem; + padding-right: @data-grid-filters-current-action-remove__size + 1rem; + position: relative; + } + .action-remove { + .action-reset(); + line-height: 1; + position: absolute; + right: 0; + top: 1px; + &:hover { + &:before { + color: @data-grid-filters-current-action-remove__hover__background-color; + } + } + &:active { + .scale(); + } + &:before { + &:extend(.abs-icon all); + color: @data-grid-filters-current-action-remove__background-color; + content: @icon-remove-small__content; + font-size: @data-grid-filters-current-action-remove__size; + transition: @smooth__color; + } + > span { + .hidden(); + } + } +} diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-pager.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-pager.less new file mode 100644 index 0000000000000000000000000000000000000000..a30087cb5a6972ca99f7636d3a4fe26e9ee59219 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-pager.less @@ -0,0 +1,63 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// UI -> Data Grid -> Header -> Pager +// _____________________________________________ + +// +// Variables +// --------------------------------------------- + +@data-grid-pager-action__width: 4.4rem; + +// + +.admin__data-grid-pager-wrap { + text-align: right; +} + +.admin__data-grid-pager { + display: inline-block; + margin-left: @content__indent; + .admin__control-text::-webkit-outer-spin-button, + .admin__control-text::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + .admin__control-text { + -moz-appearance: textfield; + text-align: center; + width: @data-grid-pager-action__width; + } +} + +.action-previous, +.action-next { + width: @data-grid-pager-action__width; + &:before { + &:extend(.abs-icon all); + font-weight: @font-weight__bold; + } + > span { + .hidden(); + } +} + +.action-previous { + margin-right: 2.5rem; + text-indent: -.25em; + &:before { + content: @icon-caret-left__content; + } +} + +.action-next { + margin-left: 1.5rem; + text-indent: .1em; + &:before { + content: @icon-caret-right__content; + } +} diff --git a/app/design/adminhtml/Magento/backend/composer.json b/app/design/adminhtml/Magento/backend/composer.json index 8ae2687dac7e5d03b2248d8dff711c8d8fd8a1c9..a0fc76610568403a31ae8e6e3184977f90c6cce9 100644 --- a/app/design/adminhtml/Magento/backend/composer.json +++ b/app/design/adminhtml/Magento/backend/composer.json @@ -3,11 +3,11 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-theme", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_actions.less b/app/design/adminhtml/Magento/backend/web/css/source/_actions.less index e9b6e173f1df976ffec6b1317f9153200343edc7..0353568d0e94abea48be8579cb2adcf6d3f1dcf9 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/_actions.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/_actions.less @@ -7,7 +7,10 @@ // Imports // _____________________________________________ +@import 'actions/_actions-dropdown.less'; @import 'actions/_actions-split.less'; +@import 'actions/_actions-select.less'; +@import 'actions/_actions-multiselect.less'; // // Variables @@ -15,12 +18,15 @@ // Base button @button__background-color: @color-gray89; -@button__border-color: @color-gray68; +@button__border-color: @action__border-color; +@button__border-size: 1px; +@button__border-style: solid; @button__color: @color-brownie; @button__font-family: @font-family__base; -@button__font-size: @font-size__base; -@button__padding-top: .5em; -@button__padding-bottom: .57em; +@button__font-size: @action__font-size; +@button__line-height: @action__line-height; +@button__padding-top: @action__padding-top; +@button__padding-bottom: @action__padding-bottom; @button__padding-horizontal: 1em; @button__padding-vertical__l: .6875em; @@ -46,11 +52,18 @@ @button-secondary__active__background-color: @color-very-dark-gray-black2; @button-secondary__hover__background-color: @color-very-dark-gray-black2; +// Triangle marker +@button-marker-triangle__height: .5rem; +@button-marker-triangle__width: .8rem; + +@button-marker-triangle__height__xl: .9rem; +@button-marker-triangle__width__xl: 1.2rem; + // // Utilities // _____________________________________________ -.action-reset () { +.action-reset() { background-color: transparent; border: none; border-radius: 0; @@ -64,6 +77,47 @@ } } +// Used in action dropdown, actions split & all other actions with triangle marker +.action-toggle-triangle ( + @_dropdown__padding-right: 3rem; + @_triangle__height: @button-marker-triangle__height; + @_triangle__width: @button-marker-triangle__width; + @_triangle__color: @color-black; + @_triangle__hover__color: darken(@_triangle__color, 10%); + @_triangle__right: (@_dropdown__padding-right / 2) - (@_triangle__width / 2); +) { + padding-right: @_dropdown__padding-right; + &._active, + &.active { + &:after { + transform: rotate(180deg); + } + } + &:after { + border-color: @_triangle__color transparent transparent transparent; + border-style: solid; + border-width: @_triangle__height @_triangle__width / 2 0 @_triangle__width / 2; + content: ''; + height: 0; + margin-top: -((@_triangle__width / 2) / 2); + position: absolute; + right: @_triangle__right; + top: 50%; + transition: all .2s linear; + width: 0; + ._active &, + .active & { + transform: rotate(180deg); + } + } + &:hover { + &:after { + border-color: @_triangle__hover__color transparent transparent transparent; + } + } +} + + // // Extends // _____________________________________________ @@ -73,15 +127,16 @@ } .abs-action-pattern { - border: 1px solid; + border: @button__border-size @button__border-style; border-radius: 0; // ToDo UI: Delete with admin scope display: inline-block; font-family: @button__font-family; font-size: @button__font-size; font-weight: @font-weight__semibold; + line-height: @button__line-height; padding: @button__padding-top @button__padding-horizontal @button__padding-bottom; text-align: center; - vertical-align: baseline; // ToDo UI: Delete with admin scope + vertical-align: baseline; &[disabled], &.disabled { cursor: default; @@ -140,6 +195,10 @@ .action-quaternary(); } +.abs-action-menu { + .action-menu(); +} + // // Default action // --------------------------------------------- @@ -245,6 +304,89 @@ button { } } +// +// Specific actions +// --------------------------------------------- + +.action-close { + > span { + .hidden(); + } + &:extend(.abs-action-reset all); + &:active { + .scale(); + } + &:before { + &:extend(.abs-icon all); + content: @icon-close-mage__content; + .transition(color); + } + &:hover { + cursor: pointer; + text-decoration: none; + } +} + +// +// Action menu +// --------------------------------------------- + +// Used in actions split, action select and all other simple (one line) action menu list +.action-menu { + .appearing__off(); + background-color: @page-wrapper__background-color; + border: 1px solid @action__active__border-color; + border-radius: 1px; + box-shadow: @component__box-shadow__base; + color: @text__color; + display: block; // ToDo UI: Should be deleted with old styles + font-weight: @font-weight__regular; + left: 0; + list-style: none; + margin: 2px 0 0; // Action box-shadow + 1px indent + min-width: 0; // ToDo UI: Should be deleted with old styles + padding: 0; + position: absolute; + right: 0; + top: 100%; + transition: opacity @appearing__transition-duration @apperaing__transition-timing-function; + &._active { + .appearing__on(); + } + > li { + display: block; + border: none; // ToDo UI: Should be deleted with old styles + padding: 0; + transition: background-color .1s linear; + > a { + &:hover { + text-decoration: none; + } + } + &:hover { + background-color: @action-menu__hover__background-color; + } + &:active { + background-color: darken(@action-menu__hover__background-color, 10%); + } + } + .item, + .action-menu-item { + display: block; + padding: .6875em 1em; + cursor: pointer; + } + a { + &.action-menu-item { + color: @text__color; + &:focus { + background-color: @action-menu__hover__background-color; + box-shadow: none; + } + } + } +} + // // ToDo UI: Button migration // _____________________________________________ diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_classes.less b/app/design/adminhtml/Magento/backend/web/css/source/_classes.less new file mode 100644 index 0000000000000000000000000000000000000000..2b420d0e88ff98160f00b6af5ae2953665a61568 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/web/css/source/_classes.less @@ -0,0 +1,16 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// Helper cross js and styles classes +// _____________________________________________ + +// Can be used for disabled elements, equal disabled='disabled' attribute +._disabled { + .disabled(); + &:hover { + .disabled(); + } +} diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_forms.less b/app/design/adminhtml/Magento/backend/web/css/source/_forms.less index 131ae92ae03dee1b4e619d4a5939357de56fa86b..624092c1068bb181bf7e9e60329e41e13c0f4f8a 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/_forms.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/_forms.less @@ -7,4 +7,4 @@ @import 'forms/_fields.less'; @import 'forms/_tooltip.less'; @import 'forms/_temp.less'; -@import 'forms/_dropdown.less'; +@import 'forms/_checkbox-radio.less'; diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_grid.less b/app/design/adminhtml/Magento/backend/web/css/source/_grid.less index f139356abfa2948d91e01fa63dffde477b7067de..4a7856af7947c918231a4d19f46be1f279336daa 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/_grid.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/_grid.less @@ -65,9 +65,8 @@ .row-gutter { margin-left: -(@content__indent / 2); margin-right: -(@content__indent / 2); - .col-gutter { + > [class*='col-'] { padding-left: @content__indent / 2; padding-right: @content__indent / 2; } } - diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_sources.less b/app/design/adminhtml/Magento/backend/web/css/source/_sources.less index 82de6e8fd0d1b023a6739df8b85ab07b820f1724..197d0d89a271cb453c4048d7a02099dbd23ba63b 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/_sources.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/_sources.less @@ -11,8 +11,8 @@ @import '_utilities.less'; @import '_reset.less'; @import '_typography.less'; -@import '_icons.less'; @import '_lists.less'; +@import '_icons.less'; @import '_forms.less'; @import '_actions.less'; @import '_tables.less'; diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_structure.less b/app/design/adminhtml/Magento/backend/web/css/source/_structure.less index f971e04756ee517f8ded56eaf5346c5cf1726c81..f7e0dbde07ca8958b2778f02d9811eb077738ae8 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/_structure.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/_structure.less @@ -29,6 +29,7 @@ body { .page-wrapper { background-color: @page-wrapper__background-color; + min-width: 102.4rem; padding-left: @page-wrapper__indent-left; } diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_typography.less b/app/design/adminhtml/Magento/backend/web/css/source/_typography.less index 476415b15756aca49c23ba1c8218a3cc679666a6..ef2beb554b5a79d5a0512720366d68cc6787b81b 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/_typography.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/_typography.less @@ -3,6 +3,19 @@ // * See COPYING.txt for license details. // */ +// +// Utilities +// --------------------------------------------- + +.link-pattern() { + color: @link__color; + text-decoration: none; + &:hover { + color: @link__hover__color; + text-decoration: underline; + } +} + .font-face( @family-name: @font-family-name__base, @font-path: '@{baseDir}fonts/opensans/light/opensans-300', @@ -31,6 +44,8 @@ @font-style: normal ); +// + html, body { height: 100%; @@ -109,10 +124,5 @@ small { // Links a { - color: @link__color; - text-decoration: none; - &:hover { - color: @link__hover__color; - text-decoration: underline; - } + .link-pattern(); } diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_utilities.less b/app/design/adminhtml/Magento/backend/web/css/source/_utilities.less index 5182c77ed22e5463c2e377a7d09b17f0a12f3820..84a014a902f9bdc18a9e1f99330fc50891985d80 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/_utilities.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/_utilities.less @@ -7,3 +7,32 @@ @import 'utilities/_grid.less'; @import 'utilities/_animations.less'; @import 'utilities/_spinner.less'; + +.hidden() { + clip: rect(0, 0, 0, 0); + overflow: hidden; + position: absolute; +} + +.disabled() { + box-shadow: none; + cursor: default; + opacity: .5; + outline: 0; +} + +.text-overflow-ellipsis() { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.appearing__off() { + opacity: 0; + visibility: hidden; +} + +.appearing__on() { + opacity: 1; + visibility: visible; +} diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_variables.less b/app/design/adminhtml/Magento/backend/web/css/source/_variables.less index a18ebc40b4799ca255df30f31ef303b596f8665c..191918c389c231300ce085f212628874acc1bc6d 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/_variables.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/_variables.less @@ -10,6 +10,7 @@ @import 'variables/_colors.less'; @import 'variables/_typography.less'; @import 'variables/_icons.less'; +@import 'variables/_actions.less'; @import 'variables/_forms.less'; @import 'variables/_structure.less'; @import 'variables/_animations.less'; \ No newline at end of file diff --git a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-dropdown.less b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-dropdown.less new file mode 100644 index 0000000000000000000000000000000000000000..6f89fefaf392a88cc9042ddb7d1070e5fb3dfc09 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-dropdown.less @@ -0,0 +1,164 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// Forms -> Dropdown element +// _____________________________________________ + +// +// Variables +// --------------------------------------------- + +@action-dropdown__color: @text__color; +@action-dropdown__background-color: @page-wrapper__background-color; +@action-dropdown__border-color: @color-light-gray; +@action-dropdown__font-size: round(@font-size__base - .1rem, 1); +@action-dropdown__height: @action__height; +@action-dropdown__padding-top: .7rem; +@action-dropdown__padding-bottom: .8rem; +@action-dropdown__padding-horizontal: 1.5rem; +@action-dropdown__padding-right: @action-dropdown__padding-horizontal + @action-dropdown-menu__padding-horizontal + @button-marker-triangle__width; +@action-dropdown__active__border-color: @color-blue-pure; +@action-dropdown__hover__color: darken(@action-dropdown__color, 20%); + +@action-dropdown-menu__padding-vertical: .5rem; +@action-dropdown-menu__padding-horizontal: 1rem; + +@action-dropdown-menu-link__padding-vertical: .6rem; +@action-dropdown-menu-link__padding-horizontal: @action-dropdown__padding-horizontal - @action-dropdown-menu__padding-horizontal; + +// +// Utilities +// --------------------------------------------- + +.admin__action-dropdown-menu__align( + @_align +) when (@_align = left) { + .admin__action-dropdown-text { + &:after { + left: -(@component__shadow-size__base + 1); + right: 0; + } + } + .admin__action-dropdown-menu { + left: auto; + right: 0; + } +} + +.admin__action-dropdown-menu__align( + @_align +) when (@_align = right) { + .admin__action-dropdown-text { + &:after { + right: -(@component__shadow-size__base + 1); + left: 0; + } + } + .admin__action-dropdown-menu { + left: 0; + right: auto; + } +} + +.action-dropdown-menu-link-pattern() { + color: @action-dropdown__color; + display: block; + text-decoration: none; +} + +// + +.admin__action-dropdown-wrap { + .admin__action-dropdown-menu__align(left); + display: inline-block; + position: relative; + &.active, + &._active { + .admin__action-dropdown { + border-color: @action-dropdown__active__border-color; + box-shadow: @component__box-shadow__base; + } + // Dropdown helper to prevent box shadow unnecessary appearing + .admin__action-dropdown-text { + &:after { + background-color: @action-dropdown__background-color; + content: ''; + height: @component__shadow-size__base + 1; + position: absolute; + top: 100%; + } + } + .admin__action-dropdown-menu { + .appearing__on(); + } + } + &._disabled { + .admin__action-dropdown { + cursor: default; + } + &:hover { + .admin__action-dropdown { + color: @action-dropdown__color; + } + } + } +} + +.admin__action-dropdown { + .action-toggle-triangle( + @_dropdown__padding-right: @action-dropdown__padding-right; + ); + box-shadow: none; + background-color: @action-dropdown__background-color; + border: 1px solid transparent; + border-bottom: none; + border-radius: 0; + color: @action-dropdown__color; + display: inline-block; + font-size: @action-dropdown__font-size; + font-weight: @font-weight__regular; + letter-spacing: -.025em; + padding: @action-dropdown__padding-top @action-dropdown__padding-right @action-dropdown__padding-bottom @action-dropdown__padding-horizontal; + position: relative; + transition: border-color @appearing__transition-duration @apperaing__transition-timing-function; + vertical-align: baseline; + z-index: 2; + &:hover { + color: @action-dropdown__hover__color; + background-color: @action-dropdown__background-color; + text-decoration: none; + } + // Triangle + &:after { + right: @action-dropdown__padding-horizontal; + } + // Icon + &:before { + margin-right: 1rem; + } +} + +.admin__action-dropdown-menu { + .appearing__off(); + background-color: @action-dropdown__background-color; + border: 1px solid @action-dropdown__active__border-color; + box-shadow: @component__box-shadow__base; + line-height: @line-height__base; + margin-top: -1px; + min-width: 120%; + padding: @action-dropdown-menu__padding-vertical @action-dropdown-menu__padding-horizontal; + position: absolute; + top: 100%; + transition: all @appearing__transition-duration @apperaing__transition-timing-function; + z-index: 1; + > li { + display: block; + > a { + .action-dropdown-menu-link-pattern(); + padding: @action-dropdown-menu-link__padding-vertical @action-dropdown-menu-link__padding-horizontal; + } + } +} diff --git a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-multiselect.less b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-multiselect.less new file mode 100644 index 0000000000000000000000000000000000000000..597a73358d82bb119a8329b8c2d5a435339f1e0d --- /dev/null +++ b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-multiselect.less @@ -0,0 +1,84 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// Actions -> Actions multiselect +// _____________________________________________ + +// Action multiselect is a combining of checkbox and dropdown elements + +.action-multiselect-wrap { + &:extend(.abs-clearfix all); + display: inline-block; + padding-top: 1px; + position: relative; + height: @control-checkbox-radio__size; + z-index: @action-multiselect__z-index; + &:hover { + .admin__control-checkbox + label:before, + .action-multiselect-toggle { + border-color: @field-control__hover__border-color; + } + } + &._active { + .admin__control-checkbox + label:before, + .action-multiselect-toggle { + border-color: @action__active__border-color; + } + .action-menu { + .appearing__on(); + } + } + &._disabled { + .admin__control-checkbox { + + label { + &:before { + background-color: @control-checkbox-radio__background-color; + } + } + } + .admin__control-checkbox + label:before, + .action-multiselect-toggle { + border-color: @field-control__border-color; + opacity: 1; + } + } + .admin__control-checkbox, + .admin__control-checkbox + label, + .action-multiselect-toggle { + float: left; + } + .action-multiselect-toggle { + .action-toggle-triangle( + @_triangle__height: @button-marker-triangle__height; + @_triangle__width: @button-marker-triangle__width; + ); + border-radius: 0 1px 1px 0; + height: @control-checkbox-radio__size; + margin-left: -1px; + padding: 0; + position: relative; + transition: @smooth__border-color; + width: @control-checkbox-radio__size; + &:focus { + border-color: @action__active__border-color; + } + &:after { + right: .3rem; + } + > span { + .visually-hidden(); + } + } + .action-menu { + left: -(@data-grid-cell__padding-horizontal + @data-grid-cell__border-width + .1rem); + right: auto; + text-align: left; + margin-top: 1px; + } + .action-menu-item { + white-space: nowrap; + } +} diff --git a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-select.less b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-select.less new file mode 100644 index 0000000000000000000000000000000000000000..496f6269e8b3ddff1ae01efaf405ea41e37aa979 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-select.less @@ -0,0 +1,64 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// Actions -> Action select +// _____________________________________________ + +// Action select have the same visual styles and functionality as native <select> +.action-select-wrap { + @_action-select__border-color: @button__border-color; + @_action-select__active__border-color: @action__active__border-color; + @_action-select-toggle__size: @action__height; + + display: inline-block; + position: relative; + .action-select { + .action-toggle-triangle( + @_dropdown__padding-right: @_action-select-toggle__size; + @_triangle__height: @button-marker-triangle__height; + @_triangle__width: @button-marker-triangle__width; + ); + .text-overflow-ellipsis(); + background-color: @color-white; + font-weight: @font-weight__regular; + text-align: left; + &:hover { + border-color: @field-control__hover__border-color; + &:before { + border-color: @field-control__hover__border-color; + } + } + // Toggle action + &:before { + background-color: @button__background-color; + border: @button__border-size @button__border-style @_action-select__border-color; + bottom: 0; + content: ''; + position: absolute; + right: 0; + top: 0; + width: @_action-select-toggle__size; + } + &._active { + border-color: @_action-select__active__border-color; + &:before { + border-color: @_action-select__active__border-color; + border-left-color: @_action-select__border-color; + } + } + } + &._active { + .action-select { + border-color: @field-control__active__border-color; + &:before { + border-color: @field-control__active__border-color; + } + &:after { + transform: rotate(180deg); + } + } + } +} diff --git a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-split.less b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-split.less index 050e9bf71fbfc21c19218280971f16cf0169695f..402bd4b223727a8e437a3ce7dd66a6f09c898885 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-split.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-split.less @@ -7,15 +7,42 @@ // Actions -> Actions split // _____________________________________________ +// Actions split is a button aggregator with dropdown element + +// +// Extends +// --------------------------------------------- + +.abs-actions-split-xl { + @_dropdown__padding-right: 4rem; + @_action-toggle__width: @_dropdown__padding-right; + + @_triangle__height: @button-marker-triangle__height__xl; + @_triangle__right: (@_dropdown__padding-right / 2) - (@_triangle__width / 2); + @_triangle__width: @button-marker-triangle__width__xl; + + .action-default { + margin-right: @_action-toggle__width; + } + .action-toggle { + padding-right: @_dropdown__padding-right; + &:after { + border-width: @_triangle__height @_triangle__width / 2 0 @_triangle__width / 2; + margin-top: -((@_triangle__width / 2) / 2); + right: @_triangle__right; + } + } +} + +// Double button action .actions-split { @_action-split__min-width: @_action-toggle__width + @_action-default__min-width; - @_action-split-dropdown__hover__background-color: @color-gray89; @_action-default__min-width: 9.3rem; - @_action-toggle__width: 4rem; + @_action-toggle__width: @action__height; .extend__clearfix(); position: relative; - z-index: @split-button__z-index; + z-index: @actions-split__z-index; &.active, &._active, &:hover { @@ -31,8 +58,7 @@ } } .dropdown-menu { - opacity: 1; - visibility: visible; + .appearing__on(); } } .action-toggle, @@ -50,10 +76,10 @@ min-width: @_action-default__min-width; } .action-toggle { - .dropdown-triangle( + .action-toggle-triangle( @_dropdown__padding-right: @_action-toggle__width; - @_triangle__height: .9rem; - @_triangle__width: 1.2rem; + @_triangle__height: @button-marker-triangle__height; + @_triangle__width: @button-marker-triangle__width; ); border-left-color: rgba(0, 0, 0, .2); bottom: 0; @@ -61,13 +87,13 @@ position: absolute; right: 0; top: 0; - // Disable triangle rotation - &._active, - &.active { - &:after { - transform: none; - } - } + // Disable triangle rotation + // &._active, + // &.active { + // &:after { + // transform: none; + // } + // } &.action-secondary, &.secondary, &.action-primary, @@ -77,36 +103,11 @@ } } > span { - .visually-hidden(); + .hidden(); } } - .dropdown-menu { - background-color: @page-wrapper__background-color; - border: 1px solid @button__hover__border-color; - border-radius: 1px; - box-shadow: @component__box-shadow__base; - display: block; // ToDo UI: Should be deleted with old styles - left: 0; - list-style: none; - margin: 2px 0 0; // Action box-shadow + 1px indent - min-width: 0; // ToDo UI: Should be deleted with old styles - opacity: 0; - padding: 0; - position: absolute; - right: 0; - top: 100%; - transition: opacity @appering__transition-duration @apperaing__transition-timing-function; - visibility: hidden; - > li { - border: none; // ToDo UI: Should be deleted with old styles - padding: .6875em; - &:hover { - background-color: @_action-split-dropdown__hover__background-color; - cursor: pointer; - } - &:active { - background-color: darken(@_action-split-dropdown__hover__background-color, 10%); - } - } + .dropdown-menu, + .action-menu { + &:extend(.abs-action-menu all); } } diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less index 5e59707575f588a5996565b8c7931c0efc2ae9e4..621b01524dceea3fea33932b967c26b0dabf851b 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less @@ -16,32 +16,35 @@ @ui-datepicker__border: 1px solid #007dbd; @ui-datepicker__indent: 3px; @ui-datepicker__padding: 20px; -@ui-datepicker__shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.3); +@ui-datepicker__shadow: @component__box-shadow__base; // // Datepicker control // --------------------------------------------- -.admin__control-text.hasDatepicker { - width: 15rem; -} - .admin__control-text { + &.hasDatepicker { + width: 15rem; + } + .ui-datepicker-trigger { .button-reset(); .icon-font( - @icon-calendar, - @_icon-font-size: 3.8rem, - @_icon-font-line-height: 33px, + @_icon-font-content: @icon-calendar__content, + @_icon-font: @icons-admin__font-name, + @_icon-font-size: 2.1rem, + @_icon-font-line-height: @action__height, @_icon-font-text-hide: true, @_icon-font-position: after, @_icon-font-color: @ui-datepicker-icon__color ); - height: 3.3rem; + height: @action__height; overflow: hidden; vertical-align: top; - margin-left: -4rem; + margin-left: -@action__height; display: inline-block; + &:active { + .scale(.975); + } } } @@ -52,6 +55,7 @@ .ui-datepicker { box-sizing: border-box; display: none; + opacity: @component-modal__opacity; padding: @ui-datepicker__padding + @ui-datepicker__indent @ui-datepicker__padding; width: auto; z-index: 999999 !important; diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_popups.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_popups.less index 918ce1cec2d1c6fd8c740c21eab8c342d573ba99..b6d5c27d02ce0a54374c1c8cfed44aa9b979dbcc 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/components/_popups.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_popups.less @@ -33,18 +33,16 @@ // _____________________________________________ .ui-dialog { + .appearing__off(); background: @popup__background-color; min-width: 40%; - opacity: 0; transform: scale(0.7); transition: all 0.3s; - visibility: hidden; width: 75%; &.ui-dialog-active { + .appearing__on(); transform: scale(1); - opacity: 1; - visibility: visible; } &.ui-draggable { diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_tooltip-temp.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_tooltip-temp.less deleted file mode 100644 index 94e7125551a0a7cc3c696a2c5e618a7d052ef4fb..0000000000000000000000000000000000000000 --- a/app/design/adminhtml/Magento/backend/web/css/source/components/_tooltip-temp.less +++ /dev/null @@ -1,78 +0,0 @@ -// /** -// * Copyright © 2015 Magento. All rights reserved. -// * See COPYING.txt for license details. -// */ - -// -// Main elements -> Tooltip -// _____________________________________________ - -// ToDo UI: Consist old styles, should be changed with new design - -//.tooltip { -// display: inline-block; -// margin-left: 5px; -// .help span, -// .help a { -// position: relative; -// z-index: 2; -// width: 22px; -// height: 22px; -// display: inline-block; -// vertical-align: middle; -// cursor: pointer; -// &:before { -// content: "?"; -// font-weight: 500; -// font-size: 18px; -// display: inline-block; -// overflow: hidden; -// height: 22px; -// border-radius: 11px; -// line-height: 22px; -// width: 22px; -// text-align: center; -// color: #ffffff; -// background-color: #514943; -// } -// span { -// .visually-hidden(); -// } -// } -// // TODO Tooltips -// .tooltip-content { -// display: none; -// position: absolute; -// max-width: 200px; -// margin-top: 10px; -// margin-left: -19px; -// padding: 4px 8px; -// border-radius: 3px; -// background: #000; -// background: rgba(49, 48, 43, .8); -// color: #fff; -// text-shadow: none; -// z-index: 20; -// &:before { -// content: ''; -// position: absolute; -// width: 0; -// height: 0; -// top: -5px; -// left: 20px; -// border-left: 5px solid transparent; -// border-right: 5px solid transparent; -// border-bottom: 5px solid #000; -// opacity: .8; -// } -// &.loading { -// position: absolute; -// &:before { -// border-bottom-color: rgba(0, 0, 0, .3); -// } -// } -// } -// &:hover > .tooltip-content { -// display: block; -// } -//} diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_checkbox-radio.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_checkbox-radio.less new file mode 100644 index 0000000000000000000000000000000000000000..4ce5832e7c6e9ac8e913303c2d9008f4e8b3c7cb --- /dev/null +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_checkbox-radio.less @@ -0,0 +1,173 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// Variables +// _____________________________________________ + +@control-checkbox-radio__size: 1.6rem; +@control-checkbox-radio__background-color: @color-white; +@control-checkbox-radio-mark__color: @color-brownie; + +// Checkbox & radio +.admin__control-radio, +.admin__control-checkbox { + cursor: pointer; + opacity: 0.01; // hack for successful selenium tests + overflow: hidden; + position: absolute; + vertical-align: top; + &:after { // ToDo UI: Should be deleted with old styles that generate styles for this element + display: none; + } + + label { + cursor: pointer; + display: inline-block; + &:before { + &:extend(.abs-icon all); + background-color: @control-checkbox-radio__background-color; + border: 1px solid @field-control__border-color; + color: transparent; + float: left; + height: @control-checkbox-radio__size; + text-align: center; + vertical-align: top; + width: @control-checkbox-radio__size; + } + } + // Label with text content + + .admin__field-label { + padding-left: @control-checkbox-radio__size + @field-label__indent; + &:before { + margin: 1px @field-label__indent 0 -(@control-checkbox-radio__size + @field-label__indent); + } + } + // Checked state + &:checked { + + label { + &:before { + color: @control-checkbox-radio-mark__color; + } + } + } + // Disabled state + &.disabled, + &[disabled] { + + label { + cursor: default; + &:before { + background-color: @field-control__disabled__background-color; + border-color: @field-control__border-color; + cursor: default; + } + color: @field-control__color; + opacity: .5; + } + } + &:not([disabled]), + &:not(.disabled) { + // Focus state + &:focus { + + label { + &:before { + ._keyfocus & { + border-color: @field-control__focus__border-color; + } + } + } + } + // Hover state + &:hover { + + label { + &:before { + border-color: @field-control__hover__border-color; + } + } + } + } +} + +// Radio +.admin__control-radio { + + label { + &:before { + border-radius: @control-checkbox-radio__size; + content: @icon-enable__content; + font-size: 1rem; + transition: @smooth__border-color, color .1s ease-in; + } + } + // Discard extend line-height 1, to fix animation + &.admin__control-radio { + + label { + &:before { + line-height: 140%; + } + } + } + // Radio checked state + &:checked { + &:not([disabled]), + &:not(.disabled) { + // Prevent hover effects for checked radio + &:hover { + cursor: default; + + label { + cursor: default; + &:before { + border-color: @field-control__border-color; + } + } + } + } + } +} + +// Checkbox +.admin__control-checkbox { + + label { + &:before { + border-radius: 1px; + content: ''; + font-size: 0; + transition: font-size .1s ease-out, color .1s ease-out, @smooth__border-color; + } + } + &:checked { + + label { + &:before { + content: @icon-check-mage__content; + font-size: 1.1rem; + line-height: 125%; + } + } + } + &:not(:checked) { + &._indeterminate, + &:indeterminate { + + label { + &:before { + color: @control-checkbox-radio-mark__color; + content: '-'; + font-family: @font-family__base; + font-size: @font-size__base; + font-weight: @font-weight__bold; + } + } + } + } +} + +// +// ToDo UI: Delete with old scope +// --------------------------------------------- + +input[type="checkbox"], +input[type="radio"] { + &.admin__control-checkbox { + position: absolute; + margin: 0; + } +} diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less index 6d6619c82ef5dc131ba6596b9cb36cf025615906..3c8edc32869948f9627bc02df3ba11f8db67a89d 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less @@ -11,16 +11,27 @@ // _____________________________________________ @field-control__background-color: @color-white; -@field-control__border-color: @color-gray68; +@field-control__border-color: @action__border-color; +@field-control__border-radius: 1px; +@field-control__border-width: .1rem; @field-control__color: @color-very-dark-gray-black; -@field-control__font-size: 1.4rem; -@field-control__height: 3.3rem; +@field-control__font-size: @action__font-size; +@field-control__line-height: @action__line-height; +@field-control__height: @action__height; +@field-control__padding-top: @action__padding-top; +@field-control__padding-horizontal: 1rem; +@field-control__padding-bottom: @action__padding-bottom; + +@field-control__active__border-color: @field-control__focus__border-color; +@field-control__hover__border-color: @action__hover__border-color; +@field-control__focus__border-color: @color-blue-pure; +@field-control__disabled__background-color: @color-lighter-gray; + @field-control-addon__color: @color-gray52; + @field-control-option-label__padding-left: 26px; -// States -@field-control__disabled__background-color: @color-lighter-gray; -@field-control__focus__border-color: @color-blue-pure; +@field-label__indent: 1rem; @field-label__disabled__color: @color-gray60; @field-label__required__color: @color-phoenix; @@ -32,26 +43,32 @@ // Common // --------------------------------------------- -.__form-control-styles() { +.__form-control-pattern() { background-color: @field-control__background-color; - border-radius: .1rem; - border: 1px solid @field-control__border-color; + border-radius: @field-control__border-radius; + border: @field-control__border-width solid @field-control__border-color; color: @field-control__color; font-size: @field-control__font-size; font-weight: @font-weight__regular; - height: @field-control__height; - max-width: 100%; - padding: 0 1rem; - transition: border-color .1s ease-in; + line-height: @field-control__line-height; + height: auto; + width: auto; + padding: @field-control__padding-top @field-control__padding-horizontal @field-control__padding-bottom; + transition: @smooth__border-color; + vertical-align: baseline; +} + +.__form-control-pattern__hover() { + border-color: @field-control__hover__border-color; } -.__form-control-styles__focus() { +.__form-control-pattern__focus() { border-color: @field-control__focus__border-color; box-shadow: none; outline: 0; } -.__form-control-styles__disabled() { +.__form-control-pattern__disabled() { background-color: @field-control__disabled__background-color; border-color: @field-control__border-color; color: @field-control__color; @@ -61,14 +78,12 @@ // Input text styles .admin__control-text { - .extend__form-control-styles(); - line-height: @field-control__height; - width: 100%; + &:extend(.abs-form-control-pattern all); } // Select styles .admin__control-select { - .extend__form-control-styles(); + &:extend(.abs-form-control-pattern all); .css(appearance, none, 1); background-repeat: no-repeat; @@ -84,7 +99,14 @@ background-position+: ~'calc(100% - 33px)' 0; background-size+: 1px 100%; + height: @field-control__height; padding-right: 4.4rem; // Distance between select switch and inner text + transition: @smooth__border-color; + + &:hover { + border-color: @field-control__hover__border-color; + cursor: pointer; + } &:focus { background-image+: url('../images/arrows-bg.svg'); @@ -95,12 +117,14 @@ background-image+: linear-gradient(@field-control__focus__border-color, @field-control__focus__border-color); background-position+: ~'calc(100% - 33px)' 0; + border-color: @field-control__focus__border-color; } &::-ms-expand { display: none; } .ie9 & { - padding-right: 0; + background-image: none; + padding-right: @field-control__padding-horizontal; } } @@ -115,7 +139,7 @@ option:empty { // Multiple select .admin__control-multiselect { - .extend__form-control-styles(); + &:extend(.abs-form-control-pattern all); height: auto; padding: .6rem 1rem; } @@ -128,20 +152,22 @@ option:empty { z-index: 1; } -.admin__control-file-label:before { - &:extend(.__form-control-styles); - content:''; - left: 0; - position: absolute; - top: 0; - width: 100%; - z-index: 0; - .admin__control-file:active + &, - .admin__control-file:focus + & { - &:extend(.__form-control-styles:focus); - } - .admin__control-file[disabled] + & { - &:extend(.__form-control-styles[disabled]); +.admin__control-file-label { + :before { + &:extend(.abs-form-control-pattern); + content:''; + left: 0; + position: absolute; + top: 0; + width: 100%; + z-index: 0; + .admin__control-file:active + &, + .admin__control-file:focus + & { + &:extend(.abs-form-control-pattern:focus); + } + .admin__control-file[disabled] + & { + &:extend(.abs-form-control-pattern[disabled]); + } } } @@ -153,94 +179,35 @@ option:empty { width: auto; } -// Textarea -.admin__control-textarea { - .extend__form-control-styles(); - height: 8.48rem; - line-height: 1.18; - padding-top: .8rem; - resize: vertical; - width: 100%; -} +// +// Support text. Can be used on label or plain text to align controls & actions +// --------------------------------------------- -// Checkboxes and radios -.admin__control-radio, -.admin__control-checkbox { - cursor: pointer; - margin: .3rem 0 0; - opacity: 0.01; // hack for successful selenium tests - overflow: hidden; - position: absolute; - vertical-align: top; - + label { - cursor: pointer; - display: inline-block; - padding-left: @field-control-option-label__padding-left; - - &:before { - background: @field-control__background-color; - border-radius: .2rem; - border: 1px solid @field-control__border-color; - color: transparent; - content: @icon-check-mage__content; - float: left; - font: 0/14px @icons-admin__font-name; - height: 1.6rem; - margin: 1px 10px 0 -26px; - text-align: center; - transition: border-color .1s ease-in, color .1s ease-in, font-size .1s ease-in; - vertical-align: top; - width: 1.6rem; - } - } - &:focus { - + label { - ._keyfocus & { - &:extend(._keyfocus *:focus); - } - &:before { - border-color: @field-control__focus__border-color; - } - } - } - &[disabled] { - + label { - &:before { - background-color: @field-control__disabled__background-color; - border-color: @field-control__border-color; - } - color: @field-control__color; - opacity: @disabled__opacity; - } - } +.admin__control-support-text { // ToDo UI: should be renamed to .admin__control-text + border: @field-control__border-width solid transparent; + display: inline-block; + font-size: @field-control__font-size; + line-height: @field-control__line-height; + padding-top: @field-control__padding-top; + padding-bottom: @field-control__padding-bottom; } -.admin__control-radio { - + label { - &:before { - border-radius: .8rem; - content: @icon-enable__content; - } - } - &:checked { - + label { - &:before { - color: @color-brownie; - font-size: 1rem; - } - } +[class*='admin__control-'] { + + .admin__control-support-text { + margin-left: .7rem; } } -.admin__control-checkbox { - &:checked { - + label { - &:before { - color: @color-brownie; - font-size: 1.1rem; - } - } - } +// +// Textarea +// --------------------------------------------- + +.admin__control-textarea { + &:extend(.abs-form-control-pattern all); + height: 8.48rem; + line-height: 1.18; + padding-top: .8rem; + resize: vertical; } // Control with additional prefix or suffix label @@ -283,7 +250,7 @@ option:empty { } } & + [class*='admin__addon-']:before { - &:extend(.__form-control-styles); + &:extend(.abs-form-control-pattern); bottom: 0; box-sizing: border-box; content: ''; @@ -294,10 +261,10 @@ option:empty { z-index: 0; } &[disabled] + [class*='admin__addon-']:before { - &:extend(.__form-control-styles[disabled]); + &:extend(.abs-form-control-pattern[disabled]); } &:focus + [class*='admin__addon-']:before { - &:extend(.__form-control-styles:focus); + &:extend(.abs-form-control-pattern:focus); } } } @@ -325,6 +292,7 @@ option:empty { order: 0; } } + .ie9 { .admin__control-addon { &:after { diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_dropdown.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_dropdown.less deleted file mode 100644 index 47fec57d10e088af1bf6aaa03f602f389199accb..0000000000000000000000000000000000000000 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_dropdown.less +++ /dev/null @@ -1,68 +0,0 @@ -// /** -// * Copyright © 2015 Magento. All rights reserved. -// * See COPYING.txt for license details. -// */ - -// -// Forms -> Dropdown element -// _____________________________________________ - -// -// Variables -// --------------------------------------------- - -@dropdown__color: @text__color; - -@dropdown-menu__hover__background-color: @color-blue-clear-sky; -@dropdown-menu__active__background-color: darken(@color-blue-clear-sky, 5%); - -// -// Mixins -// --------------------------------------------- - -.dropdown-triangle ( - @_dropdown__padding-right: 3rem; - @_triangle__width: .8rem; - @_triangle__height: .5rem; - @_triangle__color: @color-black; - @_triangle__hover__color: darken(@_triangle__color, 10%); - @_triangle__right: (@_dropdown__padding-right / 2) - (@_triangle__width / 2); -) { - padding-right: @_dropdown__padding-right; - &._active, - &.active { - &:after { - transform: rotate(180deg); - } - } - &:after { - border-color: @_triangle__color transparent transparent transparent; - border-style: solid; - border-width: @_triangle__height @_triangle__width / 2 0 @_triangle__width / 2; - content: ''; - height: 0; - margin-top: -((@_triangle__width / 2) / 2); - position: absolute; - right: @_triangle__right; - top: 50%; - transition: all .2s linear; - width: 0; - ._active &, - .active & { - transform: rotate(180deg); - } - } - &:hover { - &:after { - border-color: @_triangle__hover__color transparent transparent transparent; - } - } -} - -// - -.admin__action-dropdown { - .action-reset(); - .dropdown-triangle(); - color: @dropdown__color; -} \ No newline at end of file diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_extends.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_extends.less index 699c2ba354eeb9fdf97406c9211242490823a08a..0a883946949c2fa22cdbdd52c5fd05a6a6d46934 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_extends.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_extends.less @@ -7,23 +7,16 @@ // Extend common form control styles // --------------------------------------------- -.extend__form-control-styles() { - &:extend(.__form-control-styles); - &:focus { - &:extend(.__form-control-styles:focus); - } - &[disabled] { - &:extend(.__form-control-styles[disabled]); +.abs-form-control-pattern { + .__form-control-pattern(); + &:hover { + .__form-control-pattern__hover(); } -} - -.__form-control-styles { - .__form-control-styles(); &:focus { - .__form-control-styles__focus(); + .__form-control-pattern__focus(); } &[disabled] { - .__form-control-styles__disabled(); + .__form-control-pattern__disabled(); } } @@ -34,6 +27,7 @@ .extend__field-rows() { &:extend(.abs-field-rows all); } + .abs-field-rows[class] { > .admin__field-control { float: none; diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less index f5ae9614e8a91894ab3da0d2197abc17a2893db9..def207f2a0bb7dab63a8eca3eab4cfd38b2e9652 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less @@ -28,13 +28,15 @@ // Form Fields // _____________________________________________ +// // Fieldset +// --------------------------------------------- + .admin__fieldset { border: 0; margin: 0; min-width: 0; padding: 0; - > .admin__field { border: 0; margin: 0; @@ -54,7 +56,24 @@ } } +.admin__form-field { + border: 0; + margin: 0; + padding: 0; +} + +.admin__form-field-control, +.admin__field-control { + .admin__control-text, + .admin__control-textarea { + width: 100%; + } +} + +// // Label +// --------------------------------------------- + .admin__field-label { color: @field-label__color; margin: 0; @@ -64,7 +83,7 @@ display: none; } - [class]:not(.admin__field-option) > & { + .admin__field:not(.admin__field-option) > & { font-family: @font-family__base; font-size: @field-label__font-size; font-weight: @font-weight__semibold; @@ -74,11 +93,10 @@ word-wrap: break-word; &:before { + .appearing__off(); content: '.'; margin-left: -7px; overflow: hidden; - visibility: hidden; - width: 0; } span { @@ -109,7 +127,10 @@ } } +// // Field +// --------------------------------------------- + .admin__field { margin-bottom: 0; @@ -163,13 +184,16 @@ } } } - .admin__field-control { & + & { margin-top: 1.5rem; } } +// +// Field messages +// --------------------------------------------- + // Field error message .admin__field-error { background: @field-error-message__background-color; diff --git a/app/design/adminhtml/Magento/backend/web/css/source/variables/_actions.less b/app/design/adminhtml/Magento/backend/web/css/source/variables/_actions.less new file mode 100644 index 0000000000000000000000000000000000000000..6cb821a11a68f5e895607cd5a8c21224807ad21f --- /dev/null +++ b/app/design/adminhtml/Magento/backend/web/css/source/variables/_actions.less @@ -0,0 +1,22 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// Actions +// _____________________________________________ + +@action__border-color: @color-gray68; +@action__font-size: @font-size__base; +@action__line-height: @line-height__base; +@action__padding-top: round(((@field-control__height - @field-control__font-size * @field-control__line-height - @field-control__border-width * 2) / 2), 1); +@action__padding-bottom: @field-control__padding-top; +@action__height: 3.3rem; + +@action__active__border-color: @color-blue-pure; // Not the same as @button__hover__border-color +@action__hover__background-color: @color-blue-clear-sky; +@action__hover__border-color: darken(@action__border-color, 15%); + +// Actions menu +@action-menu__hover__background-color: @color-gray89; diff --git a/app/design/adminhtml/Magento/backend/web/css/source/variables/_animations.less b/app/design/adminhtml/Magento/backend/web/css/source/variables/_animations.less index 1284a440a9e5229d53ec39b228c23ea3d3f15d64..986647aefd2700ca241759e9b6b238288270a7b9 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/variables/_animations.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/variables/_animations.less @@ -7,5 +7,9 @@ // Transitions // _____________________________________________ -@appering__transition-duration: .15s; +@appearing__transition-duration: .15s; @apperaing__transition-timing-function: ease; + +@smooth__color: color .1s linear; +@smooth__background-color: background-color .1s linear; +@smooth__border-color: border-color .1s linear; diff --git a/app/design/adminhtml/Magento/backend/web/css/source/variables/_colors.less b/app/design/adminhtml/Magento/backend/web/css/source/variables/_colors.less index 61823ceffe0be26f3e8d9bea2908fee156846cc2..80492cbd3cd378486cdda5de768ebb8eb4152145 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/variables/_colors.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/variables/_colors.less @@ -21,6 +21,7 @@ @color-very-dark-gray1: #777; @color-brownie-vanilla: #736963; @color-dark-gray: #808080; +@color-darkie-gray: #8a837f; @color-gray65: #a6a6a6; @color-gray65-almost: #a79d95; @color-gray65-lighten: #aaa6a0; @@ -38,6 +39,7 @@ @color-very-light-gray: #fcfcfc; @color-ivory: #f7f3eb; @color-white-fog2: #f1f1f1; +@color-lazy-sun-white: #fffbe6; @color-lazy-sun: #fffbbb; @color-lazy-sunny: #fff1ad; diff --git a/app/design/adminhtml/Magento/backend/web/css/source/variables/_structure.less b/app/design/adminhtml/Magento/backend/web/css/source/variables/_structure.less index 2e081b044437fa866129b1d5b83ac9b6e736bf24..65feb808800fdab0b5f6636f193159003226bf11 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/variables/_structure.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/variables/_structure.less @@ -33,8 +33,12 @@ @z-index-9: 900; @z-index-10: 1000; +// z-index 2 +@actions-split__z-index: @z-index-2; +@action-multiselect__z-index: @z-index-2; + // z-index 3 -@split-button__z-index: @z-index-3; +@data-grid-header__z-index: @z-index-3; // z-index 4 @header__z-index: @z-index-4; @@ -63,3 +67,5 @@ @component__shadow-size__base: 5px; @component__box-shadow__base: 1px 1px @component__shadow-size__base rgba(0, 0, 0, .5); + +@component-modal__opacity: .98; diff --git a/app/design/adminhtml/Magento/backend/web/css/styles-old.less b/app/design/adminhtml/Magento/backend/web/css/styles-old.less index 55ff2a07a82998541813d953643dbdbe4414b600..77fb1698576b0de4f3115cf7906241a6e82e5e9e 100644 --- a/app/design/adminhtml/Magento/backend/web/css/styles-old.less +++ b/app/design/adminhtml/Magento/backend/web/css/styles-old.less @@ -2013,13 +2013,9 @@ input.no-display, } } - .col-2-left-layout, - .col-1-layout { + .col-2-left-layout { margin: 0 auto; position: relative; - } - - .col-2-left-layout { &:before { position: absolute; content: ""; diff --git a/app/design/adminhtml/Magento/backend/web/css/styles.less b/app/design/adminhtml/Magento/backend/web/css/styles.less index 8b9bd439e270c0f7b8b660df3c255c3b3478f761..f4f585880c7d9d1ce9db56cf76d391b57063fb40 100644 --- a/app/design/adminhtml/Magento/backend/web/css/styles.less +++ b/app/design/adminhtml/Magento/backend/web/css/styles.less @@ -22,12 +22,11 @@ //@magento_import "source/_module.less"; // import theme styles - // // Temporary // --------------------------------------------- -// ToDo UI: Hiding menu (should be fixed in layouts) +// ToDo UI: Hiding menu (should be fixed in layouts) .attribute-popup { .page-wrapper { margin-left: 0; @@ -39,7 +38,17 @@ } } -// ToDo UI: Temporary. Should be changed +[class*='admin__'] { + + label, + + label:after, + + label:before, + &:before, + &:after { + box-sizing: border-box; + } +} + +// ToDo UI: Temporary. Should be changed @import 'source/components/_calendar-temp.less'; // diff --git a/app/design/adminhtml/Magento/backend/web/mui/styles/table.less b/app/design/adminhtml/Magento/backend/web/mui/styles/table.less index 22032decb2c9868ecfab36e87e49684a33dc0416..574b9f0754306f96ac3c0950e8ae82bd2c74a046 100644 --- a/app/design/adminhtml/Magento/backend/web/mui/styles/table.less +++ b/app/design/adminhtml/Magento/backend/web/mui/styles/table.less @@ -67,23 +67,9 @@ table { } // -// Grid table header filters and settings -//-------------------------------------- +// Table Filters +// -------------------------------------- -.grid-actions, -.pager, -.massaction, -.filter { - .input-text, - select, - .select { - margin: 0 10px 0 0; - } -} - -// -// Table Filters -//-------------------------------------- .filter { input.input-text { width: 99%; diff --git a/app/design/frontend/Magento/blank/composer.json b/app/design/frontend/Magento/blank/composer.json index 2a04bfacb343d811febc36cc9be67b7254e3eb41..f4cade65a82198127de39ab5b9f923dc8cb046ca 100644 --- a/app/design/frontend/Magento/blank/composer.json +++ b/app/design/frontend/Magento/blank/composer.json @@ -3,11 +3,11 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/framework": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-theme", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/design/frontend/Magento/luma/composer.json b/app/design/frontend/Magento/luma/composer.json index 8fa8ad3aa9e7c50206b59568b7faff068e12c61b..a402aecdcb5bc449edca9a7263e1b4043526b036 100644 --- a/app/design/frontend/Magento/luma/composer.json +++ b/app/design/frontend/Magento/luma/composer.json @@ -3,12 +3,12 @@ "description": "N/A", "require": { "php": "~5.5.0|~5.6.0", - "magento/theme-frontend-blank": "0.74.0-beta6", - "magento/framework": "0.74.0-beta6", + "magento/theme-frontend-blank": "0.74.0-beta7", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-theme", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/etc/di.xml b/app/etc/di.xml index 10095a200e3bc10329a48f6a95c1fd40faa49012..c461dc254c841721a21146ff4010a00f848f1124 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -400,7 +400,7 @@ <argument name="readers" xsi:type="array"> <item name="container" xsi:type="string">Magento\Framework\View\Layout\Reader\Container</item> <item name="block" xsi:type="string">Magento\Framework\View\Layout\Reader\Block</item> - <item name="ui_component" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item> + <item name="uiComponent" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item> </argument> </arguments> </virtualType> @@ -416,7 +416,7 @@ <item name="block" xsi:type="string">Magento\Framework\View\Layout\Reader\Block</item> <item name="move" xsi:type="string">Magento\Framework\View\Layout\Reader\Move</item> <item name="remove" xsi:type="string">Magento\Framework\View\Layout\Reader\Remove</item> - <item name="ui_component" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item> + <item name="uiComponent" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item> </argument> </arguments> </virtualType> @@ -440,7 +440,7 @@ <item name="block" xsi:type="string">Magento\Framework\View\Layout\Reader\Block</item> <item name="move" xsi:type="string">Magento\Framework\View\Layout\Reader\Move</item> <item name="remove" xsi:type="string">Magento\Framework\View\Layout\Reader\Remove</item> - <item name="ui_component" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item> + <item name="uiComponent" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item> </argument> </arguments> </virtualType> @@ -459,7 +459,7 @@ <item name="block" xsi:type="string">Magento\Framework\View\Layout\Reader\Block</item> <item name="move" xsi:type="string">Magento\Framework\View\Layout\Reader\Move</item> <item name="remove" xsi:type="string">Magento\Framework\View\Layout\Reader\Remove</item> - <item name="ui_component" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item> + <item name="uiComponent" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item> </argument> </arguments> </virtualType> @@ -476,7 +476,7 @@ <item name="block" xsi:type="string">Magento\Framework\View\Layout\Reader\Block</item> <item name="move" xsi:type="string">Magento\Framework\View\Layout\Reader\Move</item> <item name="remove" xsi:type="string">Magento\Framework\View\Layout\Reader\Remove</item> - <item name="ui_component" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item> + <item name="uiComponent" xsi:type="string">Magento\Framework\View\Layout\Reader\UiComponent</item> </argument> </arguments> </virtualType> @@ -501,7 +501,7 @@ <item name="body" xsi:type="object">Magento\Framework\View\Page\Config\Generator\Body</item> <item name="block" xsi:type="object">Magento\Framework\View\Layout\Generator\Block</item> <item name="container" xsi:type="object">Magento\Framework\View\Layout\Generator\Container</item> - <item name="ui_component" xsi:type="object">Magento\Framework\View\Layout\Generator\UiComponent</item> + <item name="uiComponent" xsi:type="object">Magento\Framework\View\Layout\Generator\UiComponent</item> </argument> </arguments> </type> @@ -512,7 +512,7 @@ <item name="body" xsi:type="object">Magento\Framework\View\Page\Config\Generator\Body</item> <item name="block" xsi:type="object">Magento\Framework\View\Layout\Generator\Block</item> <item name="container" xsi:type="object">Magento\Framework\View\Layout\Generator\Container</item> - <item name="ui_component" xsi:type="object">Magento\Framework\View\Layout\Generator\UiComponent</item> + <item name="uiComponent" xsi:type="object">Magento\Framework\View\Layout\Generator\UiComponent</item> </argument> </arguments> </virtualType> diff --git a/app/i18n/magento/de_de/composer.json b/app/i18n/magento/de_de/composer.json index 3348716f124bbb1283aca8365bee6dc1653f53b6..d1331eacdfd3c24651ca62a9c24998294c5fef7f 100644 --- a/app/i18n/magento/de_de/composer.json +++ b/app/i18n/magento/de_de/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-de_de", "description": "German (Germany) language", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/app/i18n/magento/en_us/composer.json b/app/i18n/magento/en_us/composer.json index 54427d660fa30d9bae85106145c1486e6e04189d..7ba926a7e7f131d32dcc6970e6a8e5354f1b9de0 100644 --- a/app/i18n/magento/en_us/composer.json +++ b/app/i18n/magento/en_us/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-en_us", "description": "English (United States) language", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/app/i18n/magento/es_es/composer.json b/app/i18n/magento/es_es/composer.json index de93f29f35665cc28056a6bd9d273ac9a85cf89c..7499abd7c6c5e1e7f99c0aafa4db0235b5313dd5 100644 --- a/app/i18n/magento/es_es/composer.json +++ b/app/i18n/magento/es_es/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-es_es", "description": "Spanish (Spain) language", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/app/i18n/magento/fr_fr/composer.json b/app/i18n/magento/fr_fr/composer.json index 57c2be2ed896269ff4140ad4c4970cb450ba2b67..17a7589ee6a23fde6f076caba6a050244d4be4d3 100644 --- a/app/i18n/magento/fr_fr/composer.json +++ b/app/i18n/magento/fr_fr/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-fr_fr", "description": "French (France) language", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/app/i18n/magento/nl_nl/composer.json b/app/i18n/magento/nl_nl/composer.json index 12c4f56f07432845832714823d15a4f34d8e4b10..38bd3b93c1f0670ba4cc1bcddfd8411834492f4a 100644 --- a/app/i18n/magento/nl_nl/composer.json +++ b/app/i18n/magento/nl_nl/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-nl_nl", "description": "Dutch (Netherlands) language", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/app/i18n/magento/pt_br/composer.json b/app/i18n/magento/pt_br/composer.json index cc1a364b3dde8fba1615b23368ee82f4041da639..240415c9b81456f5a57fdb00cafcabcb1a312639 100644 --- a/app/i18n/magento/pt_br/composer.json +++ b/app/i18n/magento/pt_br/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-pt_br", "description": "Portuguese (Brazil) language", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/app/i18n/magento/zh_cn/composer.json b/app/i18n/magento/zh_cn/composer.json index 1088c0e650ce72ad7a50a07957c4571f156913f2..28227ddf118f2d71115548176e258f08116a2f0c 100644 --- a/app/i18n/magento/zh_cn/composer.json +++ b/app/i18n/magento/zh_cn/composer.json @@ -1,13 +1,13 @@ { "name": "magento/language-zh_cn", "description": "Chinese (China) language", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { - "magento/framework": "0.74.0-beta6", + "magento/framework": "0.74.0-beta7", "magento/magento-composer-installer": "*" }, "type": "magento2-language", diff --git a/composer.json b/composer.json index e99f901fde5affb0c5023710e7e9d788421aa9d0..4424cb729baf30a8a1b65ed83e644d65296a9e96 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "magento/magento2ce", "description": "Magento 2 (Community Edition)", "type": "project", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/composer.lock b/composer.lock index a4498fe8e6dc972a67cd464639b3f4a7619783fd..1458a41878a67fefec425b795aad2b31fbfde8ab 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "ff2c069b557199903bafc88e8abe0cea", + "hash": "eb32c28075b2f343240b21d18a62385e", "packages": [ { "name": "composer/composer", diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php index 8b04e6bd56c8408b7af23580dd19600adae5d53e..d805ea841654d68eed204e683be0d18bf194b5d1 100644 --- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php +++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php @@ -11,8 +11,7 @@ use Magento\Mtf\Client\Locator; use Magento\Mtf\Client\ElementInterface; /** - * Class ConditionsElement - * Typified element class for conditions + * Typified element class for conditions. * * Format value. * Add slash to symbols: "{", "}", "[", "]", ":". @@ -39,77 +38,110 @@ use Magento\Mtf\Client\ElementInterface; class ConditionsElement extends SimpleElement { /** - * Main condition + * Count for trying fill condition element. + */ + const TRY_COUNT = 3; + + /** + * Main condition. * * @var string */ protected $mainCondition = './/ul[contains(@id,"__1__children")]/..'; /** - * Identification for chooser grid + * Identification for chooser grid. * * @var string */ protected $chooserLocator = '.rule-chooser-trigger'; /** - * Button add condition + * Button add condition. * * @var string */ protected $addNew = './/*[contains(@class,"rule-param-new-child")]/a'; /** - * Button remove condition + * Button remove condition. * * @var string */ protected $remove = './/*/a[@class="rule-param-remove"]'; /** - * New condition + * New condition. * * @var string */ protected $newCondition = './ul/li/span[contains(@class,"rule-param-new-child")]/..'; /** - * Type of new condition + * Type of new condition. * * @var string */ protected $typeNew = './/*[@class="element"]/select'; /** - * Created condition + * Created condition. * * @var string */ protected $created = './ul/li[span[contains(@class,"rule-param-new-child")]]/preceding-sibling::li[1]'; /** - * Children condition + * Children condition. * * @var string */ protected $children = './/ul[contains(@id,"conditions__")]'; /** - * Parameter of condition + * Parameter of condition. * * @var string */ protected $param = './span[span[*[substring(@id,(string-length(@id)-%d+1))="%s"]]]'; /** - * Key of last find param + * Rule param wait locator. + * + * @var string + */ + protected $ruleParamWait = './/*[@class="rule-param-wait"]'; + + /** + * Rule param input selector. + * + * @var string + */ + protected $ruleParamInput = '[name^="rule"]'; + + /** + * Apply rule param link. + * + * @var string + */ + protected $applyRuleParam = './/*[@class="rule-param-apply"]'; + + /** + * Chooser grid locator. + * + * @var string + */ + protected $chooserGridLocator = 'div[id*=chooser]'; + + /** + * Key of last find param. * * @var int */ protected $findKeyParam = 0; /** - * Map of parameters + * Map of parameters. * * @var array */ @@ -122,7 +154,7 @@ class ConditionsElement extends SimpleElement ]; /** - * Map encode special chars + * Map encode special chars. * * @var array */ @@ -135,7 +167,7 @@ class ConditionsElement extends SimpleElement ]; /** - * Map decode special chars + * Map decode special chars. * * @var array */ @@ -148,34 +180,22 @@ class ConditionsElement extends SimpleElement ]; /** - * Rule param wait locator - * - * @var string - */ - protected $ruleParamWait = './/*[@class="rule-param-wait"]'; - - /** - * Chooser grid locator - * - * @var string - */ - protected $chooserGridLocator = 'div[id*=chooser]'; - - /** - * Rule param input selector. + * Latest occurred exception. * - * @var string + * @var \Exception */ - protected $ruleParamInput = '.element [name^="rule"]'; + protected $exception; /** - * Set value to conditions + * Set value to conditions. * * @param string $value * @return void */ public function setValue($value) { + $this->eventManager->dispatchEvent(['set_value'], [__METHOD__, $this->getAbsoluteSelector()]); + $conditions = $this->decodeValue($value); $context = $this->find($this->mainCondition, Locator::SELECTOR_XPATH); $this->clear(); @@ -183,7 +203,7 @@ class ConditionsElement extends SimpleElement } /** - * Add condition combination + * Add conditions combination. * * @param string $condition * @param ElementInterface $context @@ -192,15 +212,7 @@ class ConditionsElement extends SimpleElement protected function addConditionsCombination($condition, ElementInterface $context) { $condition = $this->parseCondition($condition); - - $this->driver->selectWindow(); - $newCondition = $context->find($this->newCondition, Locator::SELECTOR_XPATH); - $newCondition->find($this->addNew, Locator::SELECTOR_XPATH)->click(); - - $this->driver->selectWindow(); - $typeNewCondition = $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'select'); - $typeNewCondition->setValue($condition['type']); - + $this->addCondition($condition['type'], $context); $createdCondition = $context->find($this->created, Locator::SELECTOR_XPATH); $this->waitForCondition($createdCondition); if (!empty($condition['rules'])) { @@ -210,7 +222,7 @@ class ConditionsElement extends SimpleElement } /** - * Add conditions + * Add conditions. * * @param array $conditions * @param ElementInterface $context @@ -229,7 +241,7 @@ class ConditionsElement extends SimpleElement } /** - * Add single Condition + * Add single Condition. * * @param string $condition * @param ElementInterface $context @@ -238,36 +250,55 @@ class ConditionsElement extends SimpleElement protected function addSingleCondition($condition, ElementInterface $context) { $condition = $this->parseCondition($condition); + $this->addCondition($condition['type'], $context); + $createdCondition = $context->find($this->created, Locator::SELECTOR_XPATH); + $this->waitForCondition($createdCondition); + $this->fillCondition($condition['rules'], $createdCondition); + } - $this->driver->selectWindow(); + /** + * Click to add condition button and set type. + * + * @param string $type + * @param ElementInterface $context + * @return void + * @throws \Exception + */ + protected function addCondition($type, ElementInterface $context) + { $newCondition = $context->find($this->newCondition, Locator::SELECTOR_XPATH); - $newCondition->find($this->addNew, Locator::SELECTOR_XPATH)->click(); - - $typeNew = $this->typeNew; - $newCondition->waitUntil( - function () use ($newCondition, $typeNew) { - $element = $newCondition->find($typeNew, Locator::SELECTOR_XPATH, 'select'); - if ($element->isVisible()) { - return true; - } - $this->driver->selectWindow(); - return null; + $count = 0; + + do { + $newCondition->find($this->addNew, Locator::SELECTOR_XPATH)->click(); + + try { + $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'select')->setValue($type); + $isSetType = true; + } catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) { + $isSetType = false; + $this->exception = $e; + $this->eventManager->dispatchEvent(['exception'], [__METHOD__, $this->getAbsoluteSelector()]); } - ); - $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'select')->setValue($condition['type']); + $count++; + } while (!$isSetType && $count < self::TRY_COUNT); - $createdCondition = $context->find($this->created, Locator::SELECTOR_XPATH); - $this->waitForCondition($createdCondition); - $this->fillCondition($condition['rules'], $createdCondition); + if (!$isSetType) { + $exception = $this->exception ? $this->exception : (new \Exception("Can not add condition: {$type}")); + throw $exception; + } } /** - * Fill single condition + * Fill single condition. * * @param array $rules * @param ElementInterface $element * @return void * @throws \Exception + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function fillCondition(array $rules, ElementInterface $element) { @@ -275,52 +306,117 @@ class ConditionsElement extends SimpleElement foreach ($rules as $rule) { /** @var ElementInterface $param */ $param = $this->findNextParam($element); + $isSet = false; + $count = 0; + + do { + try { + $openParamLink = $param->find('a'); + if ($openParamLink->isVisible()) { + $openParamLink->click(); + } + $this->waitUntil(function () use ($param) { + return $param->find($this->ruleParamInput)->isVisible() ? true : null; + }); + + if ($this->fillGrid($rule, $param)) { + $isSet = true; + } elseif ($this->fillSelect($rule, $param)) { + $isSet = true; + } elseif ($this->fillText($rule, $param)) { + $isSet = true; + } + } catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) { + $isSet = false; + $this->exception = $e; + $this->eventManager->dispatchEvent(['exception'], [__METHOD__, $this->getAbsoluteSelector()]); + } + $count++; + } while (!$isSet && $count < self::TRY_COUNT); - $this->driver->selectWindow(); - $param->find('a')->click(); - - if (preg_match('`%(.*?)%`', $rule, $chooserGrid)) { - $chooserConfig = explode('#', $chooserGrid[1]); - $param->find($this->chooserLocator)->click(); - $rule = preg_replace('`%(.*?)%`', '', $rule); - $grid = ObjectManager::getInstance()->create( - str_replace('/', '\\', $chooserConfig[0]), - [ - 'element' => $this->find($this->chooserGridLocator) - ] - ); - $grid->searchAndSelect([$chooserConfig[1] => $rule]); - continue; + if (!$isSet) { + $exception = $this->exception ? $this->exception : (new \Exception('Can not set value: ' . $rule)); + throw $exception; } - $input = $this->ruleParamInput; - $param->waitUntil( - function () use ($param, $input) { - $element = $param->find($input); - return $element->isVisible() ? true : null; - } + } + } + + /** + * Fill grid element. + * + * @param string $rule + * @param ElementInterface $param + * @return bool + */ + protected function fillGrid($rule, ElementInterface $param) + { + if (preg_match('`%(.*?)%`', $rule, $chooserGrid)) { + $chooserConfig = explode('#', $chooserGrid[1]); + $rule = preg_replace('`%(.*?)%`', '', $rule); + + $param->find($this->chooserLocator)->click(); + $grid = ObjectManager::getInstance()->create( + str_replace('/', '\\', $chooserConfig[0]), + [ + 'element' => $this->find($this->chooserGridLocator) + ] ); - $value = $param->find('select', Locator::SELECTOR_TAG_NAME, 'select'); - if ($value->isVisible()) { - $value->setValue($rule); - $this->click(); - continue; + $grid->searchAndSelect([$chooserConfig[1] => $rule]); + + $apply = $param->find($this->applyRuleParam, Locator::SELECTOR_XPATH); + if ($apply->isVisible()) { + $apply->click(); } - $value = $param->find('input', Locator::SELECTOR_TAG_NAME); - if ($value->isVisible()) { - $value->setValue($rule); - $apply = $param->find('.//*[@class="rule-param-apply"]', Locator::SELECTOR_XPATH); - if ($apply->isVisible()) { - $apply->click(); - } - continue; + return true; + } + return false; + } + + /** + * Fill select element. + * + * @param string $rule + * @param ElementInterface $param + * @return bool + */ + protected function fillSelect($rule, ElementInterface $param) + { + $value = $param->find('select', Locator::SELECTOR_TAG_NAME, 'select'); + if ($value->isVisible()) { + $value->setValue($rule); + $this->click(); + + return true; + } + return false; + } + + /** + * Fill text element. + * + * @param string $rule + * @param ElementInterface $param + * @return bool + */ + protected function fillText($rule, ElementInterface $param) + { + $value = $param->find('input', Locator::SELECTOR_TAG_NAME); + if ($value->isVisible()) { + $value->setValue($rule); + + $apply = $param->find('.//*[@class="rule-param-apply"]', Locator::SELECTOR_XPATH); + if ($apply->isVisible()) { + $apply->click(); } - throw new \Exception('Undefined type of value '); + + return true; } + return false; } /** - * Decode value + * Decode value. * * @param string $value * @return array @@ -344,7 +440,7 @@ class ConditionsElement extends SimpleElement } /** - * Parse condition + * Parse condition. * * @param string $condition * @return array @@ -366,7 +462,7 @@ class ConditionsElement extends SimpleElement } /** - * Find next param of condition for fill + * Find next param of condition for fill. * * @param ElementInterface $context * @return ElementInterface @@ -387,7 +483,7 @@ class ConditionsElement extends SimpleElement } /** - * Reset key of last find param + * Reset key of last find param. * * @return void */ @@ -397,25 +493,21 @@ class ConditionsElement extends SimpleElement } /** - * Param wait loader + * Param wait loader. * - * @return void + * @param ElementInterface $element */ protected function waitForCondition(ElementInterface $element) { $this->waitUntil( function () use ($element) { - if ($element->getAttribute('class') == 'rule-param-wait') { - $this->driver->selectWindow(); - return null; - } - return true; + return $element->getAttribute('class') == 'rule-param-wait' ? null : true; } ); } /** - * Clear conditions + * Clear conditions. * * @return void */ @@ -429,7 +521,7 @@ class ConditionsElement extends SimpleElement } /** - * Get value from conditions + * Get value from conditions. * * @return null */ diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/LiselectstoreElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/LiselectstoreElement.php index 5d3f79b515b8d7c140a7221c49b7977cbafeef82..5df3f333d46ed0297873f0c650ab387ab7f660ff 100644 --- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/LiselectstoreElement.php +++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/LiselectstoreElement.php @@ -65,7 +65,7 @@ class LiselectstoreElement extends SimpleElement public function setValue($value) { $this->eventManager->dispatchEvent(['set_value'], [__METHOD__, $this->getAbsoluteSelector()]); - $this->driver->find($this->toggleSelector)->click(); + $this->context->find($this->toggleSelector)->click(); $value = explode('/', $value); $optionSelector = []; @@ -88,7 +88,7 @@ class LiselectstoreElement extends SimpleElement */ protected function getLiElements() { - $this->driver->find($this->toggleSelector)->click(); + $this->find($this->toggleSelector)->click(); $elements = $this->driver->getElements($this, 'li', Locator::SELECTOR_TAG_NAME); $dropdownData = []; foreach ($elements as $element) { diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Page/Header.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Page/Header.php index 6685ac3f6f7877ecd19204061077d4ce1e2ce2c3..cbe0c75b7d923176473dc55456345d4fee719b1f 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Page/Header.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Page/Header.php @@ -20,7 +20,7 @@ class Header extends Block * * @var string */ - protected $adminAccountLink = '.admin-user-account'; + protected $adminAccountLink = '.admin-user-account-text'; /** * Selector for Log Out Link. diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/PageActions.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/PageActions.php index 8ed2b6a7bfb7acdadf0b2fd106939052fb7de5d2..2dbbdd6fe04c8e4a7b57f1fc71316dd4e1c85023 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/PageActions.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/PageActions.php @@ -23,7 +23,7 @@ class PageActions extends AbstractPageActions * * @var string */ - protected $scopeSelector = '.actions.dropdown'; + protected $scopeSelector = '.store-switcher .actions.dropdown'; /** * Select store @@ -41,7 +41,7 @@ class PageActions extends AbstractPageActions } /** - * Check if store visible in scope dropdown + * Check if store is visible in scope dropdown * * @param Store $store * @return bool diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php index 59a11f436051b6e190f286e7c9f1feb12fa2e50b..40d04bc0fd76f92725a84952a1c143dc8fee50b9 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php @@ -32,7 +32,7 @@ abstract class Grid extends Block * * @var string */ - protected $searchButton = '[title=Search][class*=action]'; + protected $searchButton = '[data-action="grid-filter-apply"]'; /** * Locator for 'Sort' link @@ -46,7 +46,7 @@ abstract class Grid extends Block * * @var string */ - protected $resetButton = '.action-reset'; + protected $resetButton = '[data-action="grid-filter-reset"]'; /** * The first row in grid. For this moment we suggest that we should strictly define what we are going to search @@ -137,21 +137,14 @@ abstract class Grid extends Block * * @var string */ - protected $filterButton = '.action.filters-toggle'; + protected $filterButton = '[data-action="grid-filter-expand"]'; /** * Active class * * @var string */ - protected $active = '.active'; - - /** - * Base part of row locator template for getRow() method - * - * @var string - */ - protected $location = '//div[@class="grid"]//tr['; + protected $active = '[class=*_active]'; /** * Secondary part of row locator template for getRow() method @@ -381,16 +374,12 @@ abstract class Grid extends Block if ($isSearchable) { $this->search($filter); } - $location = '//div[@class="grid"]//tr['; - $rowTemplate = 'td[contains(.,normalize-space("%s"))]'; - if ($isStrict) { - $rowTemplate = 'td[text()[normalize-space()="%s"]]'; - } + $rowTemplate = ($isStrict) ? $this->rowTemplateStrict : $this->rowTemplate; $rows = []; foreach ($filter as $value) { $rows[] = sprintf($rowTemplate, $value); } - $location = $location . implode(' and ', $rows) . ']'; + $location = '//tr[' . implode(' and ', $rows) . ']'; return $this->_rootElement->find($location, Locator::SELECTOR_XPATH); } @@ -428,7 +417,6 @@ abstract class Grid extends Block */ public function isRowVisible(array $filter, $isSearchable = true, $isStrict = true) { - $this->openFilterBlock(); return $this->getRow($filter, $isSearchable, $isStrict)->isVisible(); } @@ -457,14 +445,14 @@ abstract class Grid extends Block { $this->getTemplateBlock()->waitForElementNotVisible($this->loader); - $button = $this->_rootElement->find($this->filterButton); - if ($button->isVisible() && !$this->_rootElement->find($this->filterButton . $this->active)->isVisible()) { - $button->click(); + $toggleFilterButton = $this->_rootElement->find($this->filterButton); + $searchButton = $this->_rootElement->find($this->searchButton); + if ($toggleFilterButton->isVisible() && !$searchButton->isVisible()) { + $toggleFilterButton->click(); $browser = $this->_rootElement; - $selector = $this->searchButton; $browser->waitUntil( - function () use ($browser, $selector) { - return $browser->find($selector)->isVisible() ? true : null; + function () use ($searchButton) { + return $searchButton->isVisible() ? true : null; } ); } diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php index 19ee690cba1cf208e20885459ea8fd11e32ffbf6..b262b81e09c0ebfdcef2d6ff555e9d756713aa8e 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php @@ -38,7 +38,7 @@ class AdminAuthLogin extends Page * * @var string */ - protected $messagesBlock = '.messages .message'; + protected $messagesBlock = '.messages'; /** * Constructor. diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php index 535cc6ef859eaa1d2a01df74a95d2625b8025b21..c4a1925081da60591b258109dcc11ed13326b030 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php @@ -23,6 +23,13 @@ class ListProduct extends Block */ protected $productItem = './/*[contains(@class,"product-item-link") and normalize-space(text())="%s"]/ancestor::li'; + /** + * Locator for product item link. + * + * @var string + */ + protected $productItemLink = '.product-item-link'; + /** * Sorter dropdown selector. * @@ -46,6 +53,23 @@ class ListProduct extends Block ); } + /** + * Get product names list. + * + * @return array + */ + public function getProductNames() + { + $itemLinks = $this->_rootElement->getElements($this->productItemLink); + $productNames = []; + + foreach ($itemLinks as $itemLink) { + $productNames[] = trim($itemLink->getText()); + } + + return $productNames; + } + /** * Get all terms used in sort. * diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php index e684946a46f47f152fdd1d4373f31a31b1142dd4..bd7a938684dd27bf7d38724ecc1f6cd046788381 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php @@ -6,6 +6,7 @@ namespace Magento\Catalog\Test\Handler\Category; +use Magento\Catalog\Test\Fixture\Category; use Magento\Mtf\Fixture\FixtureInterface; use Magento\Mtf\Handler\Curl as AbstractCurl; use Magento\Mtf\Util\Protocol\CurlInterface; @@ -58,20 +59,24 @@ class Curl extends AbstractCurl implements CategoryInterface * * @param FixtureInterface|null $fixture [optional] * @return array + * @throws \Exception */ public function persist(FixtureInterface $fixture = null) { $data = $this->prepareData($fixture); - $url = $_ENV['app_backend_url'] . 'catalog/category/save/store/0/parent/' . $data['general']['parent_id'] . '/'; $curl = new BackendDecorator(new CurlTransport(), $this->_configuration); $curl->write(CurlInterface::POST, $url, '1.0', [], $data); $response = $curl->read(); $curl->close(); + if (!strpos($response, 'data-ui-id="messages-message-success"')) { + $this->_eventManager->dispatchEvent(['curl_failed'], [$response]); + throw new \Exception('Category creation by curl handler was not successful!'); + } + preg_match('#http://.+/id/(\d+).+store/#m', $response, $matches); $id = isset($matches[1]) ? (int)$matches[1] : null; - return ['id' => $id]; } @@ -83,12 +88,16 @@ class Curl extends AbstractCurl implements CategoryInterface */ protected function prepareData(FixtureInterface $fixture) { - $data['general'] = $this->replaceMappingData($fixture->getData()); - $data['is_anchor'] = isset($data['is_anchor']) ? $data['is_anchor'] : 0; + $data = ['general' => $this->replaceMappingData($fixture->getData())]; + $data['general']['is_anchor'] = isset($data['general']['is_anchor']) ? $data['general']['is_anchor'] : 0; + if ($fixture->hasData('landing_page')) { $data['general']['landing_page'] = $this->getBlockId($fixture->getLandingPage()); } + $data['category_products'] = $this->prepareCategoryProducts($fixture); + unset($data['general']['category_products']); + $diff = array_diff($this->dataUseConfig, array_keys($data['general'])); if (!empty($diff)) { $data['use_config'] = $diff; @@ -97,6 +106,28 @@ class Curl extends AbstractCurl implements CategoryInterface return $data; } + /** + * Prepare category products data for curl. + * + * @param FixtureInterface $category + * @return array + */ + protected function prepareCategoryProducts(FixtureInterface $category) + { + $categoryProducts = []; + $defaultPosition = 0; + + /** @var Category $category */ + if ($category->hasData('category_products')) { + $products = $category->getDataFieldConfig('category_products')['source']->getProducts(); + foreach ($products as $product) { + $categoryProducts[$product->getId()] = $defaultPosition; + } + } + + return json_encode($categoryProducts); + } + /** * Getting block id by name. * diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml index 392a1ff131e7fbee4246d32285458c1c4d086030..45839712e35c673123d36d46d33b1aaa8b869979 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml @@ -8,7 +8,6 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> <page name="CatalogCategoryView" area="Category" mca="catalog/category/view" module="Magento_Catalog"> <block name="titleBlock" class="Magento\Theme\Test\Block\Html\Title" locator=".page-title-wrapper h1.page-title .base" strategy="css selector"/> - <block name="layeredNavigationBlock" class="Magento\LayeredNavigation\Test\Block\Navigation" locator=".block.filter" strategy="css selector"/> <block name="widgetView" class="Magento\Widget\Test\Block\WidgetView" locator=".widget" strategy="css selector"/> <block name="viewBlock" class="Magento\Catalog\Test\Block\Category\View" locator="#maincontent" strategy="css selector"/> <block name="listProductBlock" class="Magento\Catalog\Test\Block\Product\ListProduct" locator=".products.wrapper.grid" strategy="css selector"/> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml index 4998c9d9604744c84511a07a10c321a6cc29bd02..c4ae2d72fde4dc62c6c352172b7510b3a237138e 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml @@ -65,6 +65,31 @@ </field> </dataset> + <dataset name="product_20_dollar"> + <field name="attribute_set_id" xsi:type="array"> + <item name="dataSet" xsi:type="string">default</item> + </field> + <field name="name" xsi:type="string">product_20_dollar %isolation%</field> + <field name="sku" xsi:type="string">sku_product_20_dollar_%isolation%</field> + <field name="is_virtual" xsi:type="string">No</field> + <field name="weight" xsi:type="string">1</field> + <field name="quantity_and_stock_status" xsi:type="array"> + <item name="qty" xsi:type="string">1000</item> + <item name="is_in_stock" xsi:type="string">In Stock</item> + </field> + <field name="price" xsi:type="array"> + <item name="value" xsi:type="string">20</item> + </field> + <field name="tax_class_id" xsi:type="array"> + <item name="dataSet" xsi:type="string">taxable_goods</item> + </field> + <field name="website_ids" xsi:type="array"> + <item name="0" xsi:type="string">Main Website</item> + </field> + <field name="visibility" xsi:type="string">Catalog, Search</field> + <field name="url_key" xsi:type="string">product-20-dollar-%isolation%</field> + </dataset> + <dataset name="product_with_url_key"> <field name="name" xsi:type="string">Simple Product %isolation%</field> <field name="sku" xsi:type="string">sku_simple_product_%isolation%</field> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml index b4b2da10a3d7350c0a210b8c9d4bdf3b67c8ec64..83d80113af0ae3d885bd6e2f706b904a39164dfd 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml @@ -69,7 +69,6 @@ <data name="category/data/available_product_listing_config" xsi:type="string">Yes</data> <data name="category/data/default_product_listing_config" xsi:type="string">Yes</data> <data name="category/data/use_config_price_range" xsi:type="string">Yes</data> - <data name="category/data/category_products_data/preset" xsi:type="string">default</data> <data name="category/data/category_products/dataSet" xsi:type="string">catalogProductSimple::default,catalogProductSimple::default</data> <constraint name="Magento\Catalog\Test\Constraint\AssertCategorySaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForm" /> @@ -97,7 +96,6 @@ <data name="category/data/default_sort_by" xsi:type="string">Price</data> <data name="category/data/use_config_price_range" xsi:type="string">No</data> <data name="category/data/layered_navigation_price_step" xsi:type="string">50</data> - <data name="category/data/category_products_data/preset" xsi:type="string">default</data> <data name="category/data/category_products/dataSet" xsi:type="string">catalogProductSimple::default,catalogProductSimple::default</data> <constraint name="Magento\Catalog\Test\Constraint\AssertCategorySaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForm" /> diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/AbstractCatalogRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/AbstractCatalogRuleEntityTest.php index 8c2ab9474a2c002767159584ba680781934ade83..8cc2bbcd11900b03ac123fee638555e84de93a19 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/AbstractCatalogRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/AbstractCatalogRuleEntityTest.php @@ -38,13 +38,6 @@ abstract class AbstractCatalogRuleEntityTest extends Injectable */ protected $adminCache; - /** - * Fixture CatalogRule. - * - * @var array - */ - protected $catalogRules = []; - /** * Fixture factory. * @@ -80,12 +73,6 @@ abstract class AbstractCatalogRuleEntityTest extends Injectable */ public function tearDown() { - foreach ($this->catalogRules as $catalogRule) { - $filter = ['name' => $catalogRule->getName()]; - $this->catalogRuleIndex->open(); - $this->catalogRuleIndex->getCatalogRuleGrid()->searchAndOpen($filter); - $this->catalogRuleNew->getFormPageActions()->delete(); - } - $this->catalogRules = []; + $this->objectManager->create('\Magento\CatalogRule\Test\TestStep\DeleteAllCatalogRulesStep')->run(); } } diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplySeveralCatalogPriceRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplySeveralCatalogPriceRuleEntityTest.php index 84f9cd923b6ef87fa44b77d82c0874529f0362fa..1ef4e30a3e542de934a5f0b55e214460b385c8a5 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplySeveralCatalogPriceRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplySeveralCatalogPriceRuleEntityTest.php @@ -9,17 +9,15 @@ namespace Magento\CatalogRule\Test\TestCase; use Magento\Catalog\Test\Fixture\CatalogProductSimple; /** - * Test Creation for Apply several CatalogPriceRuleEntity - * - * Test Flow: * Preconditions: - * 1. Execute before each variation: - * - Delete all active catalog price rules - * - Create catalog price rule from dataSet using Curl + * 1. Execute before each variation: + * - Delete all active catalog price rules + * - Create catalog price rule from dataSet using Curl + * * Steps: - * 1. Apply all created rules - * 2. Create simple product - * 3. Perform all assertions + * 1. Apply all created rules. + * 2. Create simple product. + * 3. Perform all assertions. * * @group Catalog_Price_Rules_(MX) * @ZephyrId MAGETWO-24780 @@ -32,7 +30,7 @@ class ApplySeveralCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTe /* end tags */ /** - * Apply several catalog price rules + * Apply several catalog price rules. * * @param array $catalogRulesOriginal * @return array @@ -44,15 +42,15 @@ class ApplySeveralCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTe if ($catalogPriceRule == '-') { continue; } - $this->catalogRules[$key] = $this->fixtureFactory->createByCode( + $catalogRules[$key] = $this->fixtureFactory->createByCode( 'catalogRule', ['dataSet' => $catalogPriceRule] ); - $this->catalogRules[$key]->persist(); + $catalogRules[$key]->persist(); $filter = [ - 'name' => $this->catalogRules[$key]->getName(), - 'rule_id' => $this->catalogRules[$key]->getId(), + 'name' => $catalogRules[$key]->getName(), + 'rule_id' => $catalogRules[$key]->getId(), ]; $this->catalogRuleIndex->getCatalogRuleGrid()->searchAndOpen($filter); $this->catalogRuleNew->getFormPageActions()->saveAndApply(); diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php index 20ddb3397e1a54e507e8dd9893b587a79caea588..be62cb21448e54bfb45f6d86c18f3019b485a66a 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php @@ -9,15 +9,13 @@ namespace Magento\CatalogRule\Test\TestCase; use Magento\CatalogRule\Test\Fixture\CatalogRule; /** - * Test Creation for Create CatalogPriceRuleEntity - * - * Test Flow: + * Steps: * 1. Log in as default admin user. - * 2. Go to Marketing > Catalog Price Rules - * 3. Press "+" button to start create new catalog price rule - * 4. Fill in all data according to data set - * 5. Save rule - * 6. Perform appropriate assertions + * 2. Go to Marketing > Catalog Price Rules. + * 3. Press "+" button to start create new catalog price rule. + * 4. Fill in all data according to data set. + * 5. Save rule. + * 6. Perform appropriate assertions. * * @group Catalog_Price_Rules_(MX) * @ZephyrId MAGETWO-24341 @@ -42,8 +40,5 @@ class CreateCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTest $this->catalogRuleIndex->getGridPageActions()->addNew(); $this->catalogRuleNew->getEditForm()->fill($catalogPriceRule); $this->catalogRuleNew->getFormPageActions()->save(); - - // Prepare data for tear down - $this->catalogRules[] = $catalogPriceRule; } } diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogRuleTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogRuleTest.php index 6649d45ba0e6312653b5c6766ab1727f20786aed..18815f160fa7f9f1b2ea52a6b64a8b28ad32c568 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogRuleTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogRuleTest.php @@ -12,18 +12,16 @@ use Magento\Catalog\Test\Fixture\CatalogProductSimple; use Magento\Customer\Test\Fixture\CustomerGroupInjectable; /** - * Test Coverage for Create Catalog Rule - * - * Test Flow: + * Steps: * 1. Log in as default admin user. - * 2. Go to Marketing > Catalog Price Rules - * 3. Press "+" button to start create new catalog price rule - * 4. Fill in all data according to data set - * 5. Save rule - * 6. Apply newly created catalog rule - * 7. Create simple product - * 8. Clear cache - * 9. Perform all assertions + * 2. Go to Marketing > Catalog Price Rules. + * 3. Press "+" button to start create new catalog price rule. + * 4. Fill in all data according to data set. + * 5. Save rule. + * 6. Apply newly created catalog rule. + * 7. Create simple product. + * 8. Clear cache. + * 9. Perform all assertions. * * @ticketId MAGETWO-23036 */ @@ -37,7 +35,7 @@ class CreateCatalogRuleTest extends AbstractCatalogRuleEntityTest /* end tags */ /** - * Create Catalog Price Rule + * Create Catalog Price Rule. * * @param CatalogRule $catalogPriceRule * @param Customer $customer @@ -70,9 +68,6 @@ class CreateCatalogRuleTest extends AbstractCatalogRuleEntityTest $this->catalogRuleNew->getEditForm()->fill($catalogPriceRule, null, $replace); $this->catalogRuleNew->getFormPageActions()->save(); - // Prepare data for tear down - $this->catalogRules[] = $catalogPriceRule; - // Apply Catalog Price Rule $this->catalogRuleIndex->getGridPageActions()->applyRules(); diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php index 29339f794b99555a85bd92961ac02a638902d344..fd30614dd24abfbdd239882132548305f5199cd0 100755 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php @@ -11,19 +11,17 @@ use Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds; use Magento\CatalogRule\Test\Fixture\CatalogRule; /** - * Test Creation for UpdateCatalogPriceRuleEntity - * - * Test Flow: * Preconditions: - * 1. Catalog Price Rule is created + * 1. Catalog Price Rule is created. + * * Steps: - * 1. Login to backend - * 2. Navigate to MARKETING > Catalog Price Rules - * 3. Click Catalog Price Rule from grid - * 4. Edit test value(s) according to dataSet - * 5. Click 'Save'/ 'Apply' button - * 6. Create simple product with category - * 7. Perform all asserts + * 1. Login to backend. + * 2. Navigate to MARKETING > Catalog Price Rules. + * 3. Click Catalog Price Rule from grid. + * 4. Edit test value(s) according to dataSet. + * 5. Click 'Save'/ 'Apply' button. + * 6. Create simple product with category. + * 7. Perform all asserts. * * @group Catalog_Price_Rules_(MX) * @ZephyrId MAGETWO-25187 @@ -37,7 +35,7 @@ class UpdateCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTest /* end tags */ /** - * Update catalog price rule + * Update catalog price rule. * * @param CatalogRule $catalogPriceRule * @param CatalogRule $catalogPriceRuleOriginal @@ -81,9 +79,6 @@ class UpdateCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTest $this->catalogRuleNew->getEditForm()->fill($catalogPriceRule, null, $replace); $this->catalogRuleNew->getFormPageActions()->$saveAction(); - // Prepare data for tear down - $this->catalogRules[] = $catalogPriceRule; - // Create simple product with category $productSimple->persist(); diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestStep/DeleteAllCatalogRulesStep.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestStep/DeleteAllCatalogRulesStep.php index a30825ebf60af09f0a09ddd652c6d9c7af830cb5..dcc06c224c0baafb2d9429ba256b7d922cbb6136 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestStep/DeleteAllCatalogRulesStep.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestStep/DeleteAllCatalogRulesStep.php @@ -51,6 +51,7 @@ class DeleteAllCatalogRulesStep implements TestStepInterface public function run() { $this->catalogRuleIndex->open(); + $this->catalogRuleIndex->getCatalogRuleGrid()->resetFilter(); while ($this->catalogRuleIndex->getCatalogRuleGrid()->isFirstRowVisible()) { $this->catalogRuleIndex->getCatalogRuleGrid()->openFirstRow(); $this->catalogRuleNew->getFormPageActions()->delete(); diff --git a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestStep/DeleteAllTermsEntityStep.php b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestStep/DeleteAllTermsEntityStep.php index f57baf78acc59aed8fce6d8dfae84cc00ce924ed..3599882b174c192c6f0638b491a86937e7e39c8c 100644 --- a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestStep/DeleteAllTermsEntityStep.php +++ b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestStep/DeleteAllTermsEntityStep.php @@ -52,6 +52,7 @@ class DeleteAllTermsEntityStep implements TestStepInterface public function run() { $this->agreementIndex->open(); + $this->agreementIndex->getAgreementGridBlock()->resetFilter(); while ($this->agreementIndex->getAgreementGridBlock()->isFirstRowVisible()) { $this->agreementIndex->getAgreementGridBlock()->openFirstRow(); $this->agreementNew->getPageActionsBlock()->delete(); diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Block/CmsGrid.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Block/CmsGrid.php index df52dfb3a70cb31a819d4cb0aa9f95248b82536e..99fe29e6517c8fe34fb3a6bc2e4113d5ff161955 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Block/CmsGrid.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Block/CmsGrid.php @@ -20,25 +20,23 @@ class CmsGrid extends Grid */ protected $filters = [ 'title' => [ - 'selector' => '#title', + 'selector' => '[name="params[filters][title]"]', ], 'identifier' => [ - 'selector' => '#identifier', + 'selector' => '[name="params[filters][identifier]"]', ], 'is_active' => [ - 'selector' => '#is_active', + 'selector' => '[name="params[filters][is_active]"]', 'input' => 'select', ], 'creation_time_from' => [ - 'selector' => '(//span[.="Created"]/following::input[contains(@placeholder,"From")])[1]', - 'strategy' => 'xpath', + 'selector' => '[name="params[filters][creation_time][from]"]', ], 'update_time_from' => [ - 'selector' => '(//span[.="Created"]/following::input[contains(@placeholder,"From")])[2]', - 'strategy' => 'xpath', + 'selector' => '[name="params[filters][update_time][from]"]', ], 'store_id' => [ - 'selector' => 'label[for="store_id"] + div > select', + 'selector' => '[name="params[filters][store_id]"]', 'input' => 'selectstore' ], ]; @@ -48,19 +46,19 @@ class CmsGrid extends Grid * * @var string */ - protected $searchButton = '.action-apply'; + protected $searchButton = '[data-action="grid-filter-apply"]'; /** * Locator value for 'Reset' button. * * @var string */ - protected $resetButton = '.action-reset'; + protected $resetButton = '[data-action="grid-filter-reset"]'; /** * Locator value for link in action column. * * @var string */ - protected $editLink = 'td[data-part="body.row.cell"]'; + protected $editLink = '.action-menu-item'; } diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Grid.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Grid.php index b58dfde4c16cb99902cfcb46a600a58cb00436b3..b111912748e06fee7328c8dc50c3e8baea2a0f36 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Grid.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Grid.php @@ -19,21 +19,21 @@ class Grid extends ParentGrid * * @var string */ - protected $searchButton = '.action.primary.action-apply'; + protected $searchButton = '[data-action="grid-filter-apply"]'; /** * Locator value for 'Reset' button. * * @var string */ - protected $resetButton = '.action.secondary.action-reset'; + protected $resetButton = '[data-action="grid-filter-reset"]'; /** * Locator value for link in action column. * * @var string */ - protected $editLink = 'td[data-part="body.row.cell"]'; + protected $editLink = '[data-action="grid-row-edit"]'; /** * 'Preview' cms page link. @@ -49,7 +49,7 @@ class Grid extends ParentGrid */ protected $filters = [ 'title' => [ - 'selector' => '#title', + 'selector' => '[name="params[filters][title]"]', ], ]; diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml index b62397be96d8a79f01c43bb426b4d8c9a521e79b..7f0434e5c657330fc233047676a40e399944d953 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml @@ -6,9 +6,9 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> - <page name="CmsBlockIndex" area="Adminhtml" mca="cms/block" module="Magento_Cms"> - <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator="#messages" strategy="css selector" /> + <page name="CmsBlockIndex" area="Adminhtml" mca="cms/block/index" module="Magento_Cms"> + <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator=".messages .message" strategy="css selector" /> <block name="gridPageActions" class="Magento\Backend\Test\Block\GridPageActions" locator=".page-main-actions" strategy="css selector" /> - <block name="cmsBlockGrid" class="Magento\Cms\Test\Block\Adminhtml\Block\CmsGrid" locator=".grid" strategy="css selector" /> + <block name="cmsBlockGrid" class="Magento\Cms\Test\Block\Adminhtml\Block\CmsGrid" locator=".admin__data-grid-wrap" strategy="css selector" /> </page> </config> diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml index 6c567cc3013ddba21ed268b8e4f537502a69fa06..44247cb0b215791070dcc32cf16d3d632a3c00b2 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> <page name="CmsPageIndex" area="Adminhtml" mca="cms/page/index" module="Magento_Cms"> <block name="pageActionsBlock" class="Magento\Backend\Test\Block\GridPageActions" locator=".page-main-actions" strategy="css selector" /> - <block name="cmsPageGridBlock" class="Magento\Cms\Test\Block\Adminhtml\Page\Grid" locator=".grid" strategy="css selector" /> + <block name="cmsPageGridBlock" class="Magento\Cms\Test\Block\Adminhtml\Page\Grid" locator=".admin__data-grid-wrap" strategy="css selector" /> <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator=".messages .message" strategy="css selector" /> </page> </config> diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/MainPageActions.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/MainPageActions.php deleted file mode 100644 index 14f7bf7af1bbeb49f34f4d68fe6e2bfa046039cd..0000000000000000000000000000000000000000 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/MainPageActions.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency; - -use Magento\Backend\Test\Block\PageActions; - -/** - * Class MainPageActions - * Main page actions on the SystemCurrencyIndex page - */ -class MainPageActions extends PageActions -{ - /** - * "Save Currency Rates" button locator - * - * @var string - */ - protected $saveCurrentRate = '[data-ui-id="page-actions-toolbar-save-button"]'; - - /** - * Save Currency Rates - * - * @return void - */ - public function saveCurrentRate() - { - $this->_rootElement->find($this->saveCurrentRate)->click(); - } -} diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/CurrencyRateForm.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/CurrencyRateForm.php new file mode 100644 index 0000000000000000000000000000000000000000..d5d1c887a484c6d4c46a641cacb4213f5d4e4a58 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/CurrencyRateForm.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\Rate; + +use Magento\Mtf\Block\Form; +use Magento\Mtf\Fixture\FixtureInterface; +use Magento\Mtf\Client\Element\SimpleElement; + +/** + * Currency Rate form. + */ +class CurrencyRateForm extends Form +{ + /** + * Fill currency rate form. + * + * @param FixtureInterface $fixture + * @param SimpleElement|null $element + * @return $this + */ + public function fill(FixtureInterface $fixture, SimpleElement $element = null) + { + /** @var \Magento\Directory\Test\Fixture\CurrencyRate $fixture */ + $this->placeholders['currency_from'] = $fixture->getCurrencyFrom(); + $this->placeholders['currency_to'] = $fixture->getCurrencyTo(); + $this->applyPlaceholders(); + + return parent::fill($fixture, $element); + } +} diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/CurrencyRateForm.xml b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/CurrencyRateForm.xml new file mode 100644 index 0000000000000000000000000000000000000000..4ffc8f05740d4454c14ded3bdc171699a7d93c1c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/CurrencyRateForm.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" ?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<mapping strict="0"> + <wrapper>rate</wrapper> + <fields> + <rate> + <selector>input[name="rate[%currency_from%][%currency_to%]"]</selector> + </rate> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/FormPageActions.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/FormPageActions.php new file mode 100644 index 0000000000000000000000000000000000000000..3c911026ad68cfce9ae4fd9f86caa607863ebe96 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/FormPageActions.php @@ -0,0 +1,22 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\Rate; + +use Magento\Backend\Test\Block\FormPageActions as ParentFormPageActions; + +/** + * Form page actions on the SystemCurrencyIndex page. + */ +class FormPageActions extends ParentFormPageActions +{ + /** + * "Save Currency Rates" button locator. + * + * @var string + */ + protected $saveButton = '.save'; +} diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/GridPageActions.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/GridPageActions.php similarity index 68% rename from dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/GridPageActions.php rename to dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/GridPageActions.php index f50f9a58386a4aa4ccada29a5115324aad6e4e57..ee7d3fcc6411632c646c08eaec8ab6ee8aa0d904 100644 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/GridPageActions.php +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Block/Adminhtml/System/Currency/Rate/GridPageActions.php @@ -4,10 +4,9 @@ * See COPYING.txt for license details. */ -namespace Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency; +namespace Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\Rate; use Magento\Backend\Test\Block\PageActions; -use Magento\Backend\Test\Block\Messages; /** * Grid page actions on the SystemCurrencyIndex page. @@ -47,21 +46,5 @@ class GridPageActions extends PageActions return $message->isVisible() ? true : null; } ); - if ($this->getMessageBlock()->isVisibleMessage('warning')) { - throw new \Exception($this->getMessageBlock()->getWarningMessages()); - } - } - - /** - * Get message block. - * - * @return Messages - */ - protected function getMessageBlock() - { - return $this->blockFactory->create( - 'Magento\Backend\Test\Block\Messages', - ['element' => $this->_rootElement->find($this->message)] - ); } } diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Page/Adminhtml/SystemCurrencyIndex.xml b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Page/Adminhtml/SystemCurrencyIndex.xml index 2ab90fb8688ebec958d8c4d8f30b9c643370e1db..efcc314043ecb2c455c908f3bc051697e7a85d42 100644 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Page/Adminhtml/SystemCurrencyIndex.xml +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Page/Adminhtml/SystemCurrencyIndex.xml @@ -7,7 +7,9 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> <page name="SystemCurrencyIndex" area="Adminhtml" mca="admin/system_currency/index" module="Magento_CurrencySymbol"> - <block name="gridPageActions" class="Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\GridPageActions" locator=".grid-actions" strategy="css selector"/> - <block name="mainPageActions" class="Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\MainPageActions" locator=".page-main-actions" strategy="css selector"/> + <block name="gridPageActions" class="Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\Rate\GridPageActions" locator=".grid-actions" strategy="css selector"/> + <block name="formPageActions" class="Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\Rate\FormPageActions" locator=".page-main-actions" strategy="css selector"/> + <block name="currencyRateForm" class="Magento\CurrencySymbol\Test\Block\Adminhtml\System\Currency\Rate\CurrencyRateForm" locator="#rate-form" strategy="css selector"/> + <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator="#messages" strategy="css selector"/> </page> -</config> \ No newline at end of file +</config> diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Repository/ConfigData.xml index 1d7fabcdeb20a6b5c12d4fd33bb4e929bf7066bb..17373832ad976111b47b2f57bbcf04f48f9b54a4 100644 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Repository/ConfigData.xml +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/Repository/ConfigData.xml @@ -137,5 +137,27 @@ <item name="value" xsi:type="string">USD</item> </field> </dataset> + + <dataset name="config_currency_symbols_usd_and_eur"> + <field name="currency/options/allow" xsi:type="array"> + <item name="scope" xsi:type="string">currency</item> + <item name="scope_id" xsi:type="number">1</item> + <item name="value" xsi:type="array"> + <item name="US Dollar" xsi:type="string">USD</item> + <item name="Euro" xsi:type="string">EUR</item> + </item> + </field> + </dataset> + + <dataset name="config_currency_symbols_usd_and_gbp"> + <field name="currency/options/allow" xsi:type="array"> + <item name="scope" xsi:type="string">currency</item> + <item name="scope_id" xsi:type="number">1</item> + <item name="value" xsi:type="array"> + <item name="US Dollar" xsi:type="string">USD</item> + <item name="British Pound Sterling" xsi:type="string">GBP</item> + </item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php new file mode 100644 index 0000000000000000000000000000000000000000..157b6dae2e1a1be571d2e7cbd7b3adcbbed1981e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CurrencySymbol\Test\TestCase; + +use Magento\Mtf\Fixture\FixtureFactory; +use Magento\Mtf\TestCase\Injectable; +use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencyIndex; +use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencySymbolIndex; + +/** + * Abstract class for currency symbol tests. + */ +abstract class AbstractCurrencySymbolEntityTest extends Injectable +{ + /** + * System Currency Symbol grid page. + * + * @var SystemCurrencySymbolIndex + */ + protected $currencySymbolIndex; + + /** + * System currency index page. + * + * @var SystemCurrencyIndex + */ + protected $currencyIndex; + + /** + * Fixture Factory. + * + * @var FixtureFactory + */ + protected $fixtureFactory; + + /** + * Create simple product and inject pages. + * + * @param SystemCurrencySymbolIndex $currencySymbolIndex + * @param SystemCurrencyIndex $currencyIndex + * @param FixtureFactory $fixtureFactory + * @return array + */ + public function __inject( + SystemCurrencySymbolIndex $currencySymbolIndex, + SystemCurrencyIndex $currencyIndex, + FixtureFactory $fixtureFactory + ) { + $this->currencySymbolIndex = $currencySymbolIndex; + $this->currencyIndex = $currencyIndex; + $this->fixtureFactory = $fixtureFactory; + $product = $this->fixtureFactory->createByCode( + 'catalogProductSimple', + ['dataSet' => 'product_with_category'] + ); + $product->persist(); + + return ['product' => $product]; + } + + /** + * Import currency rates. + * + * @param string $configData + * @return void + * @throws \Exception + */ + protected function importCurrencyRate($configData) + { + $this->objectManager->getInstance()->create( + 'Magento\Config\Test\TestStep\SetupConfigurationStep', + ['configData' => $configData] + )->run(); + + // Import Exchange Rates for currencies + $this->currencyIndex->open(); + $this->currencyIndex->getGridPageActions()->clickImportButton(); + if ($this->currencyIndex->getMessagesBlock()->isVisibleMessage('warning')) { + throw new \Exception($this->currencyIndex->getMessagesBlock()->getWarningMessages()); + } + $this->currencyIndex->getFormPageActions()->save(); + } + + /** + * Disabling currency which has been added. + * + * @return void + */ + public function tearDown() + { + $this->objectManager->getInstance()->create( + 'Magento\Config\Test\TestStep\SetupConfigurationStep', + ['configData' => 'config_currency_symbols_usd'] + )->run(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php index 5d2cc6badaa78bc22e0cec669393579f8e72e42f..c1597a1fbc4e6be9be827097c659276072d8c6ab 100644 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php @@ -6,12 +6,8 @@ namespace Magento\CurrencySymbol\Test\TestCase; -use Magento\Mtf\TestCase\Injectable; -use Magento\Mtf\Fixture\FixtureFactory; use Magento\Catalog\Test\Fixture\CatalogProductSimple; use Magento\CurrencySymbol\Test\Fixture\CurrencySymbolEntity; -use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencyIndex; -use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencySymbolIndex; /** * Preconditions: @@ -27,53 +23,13 @@ use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencySymbolIndex; * @group Currency_(PS) * @ZephyrId MAGETWO-26600 */ -class EditCurrencySymbolEntityTest extends Injectable +class EditCurrencySymbolEntityTest extends AbstractCurrencySymbolEntityTest { /* tags */ const MVP = 'no'; const DOMAIN = 'PS'; /* end tags */ - /** - * System Currency Symbol grid page. - * - * @var SystemCurrencySymbolIndex - */ - protected $currencySymbolIndex; - - /** - * System currency index page. - * - * @var SystemCurrencyIndex - */ - protected $currencyIndex; - - /** - * Create simple product and inject pages. - * - * @param SystemCurrencySymbolIndex $currencySymbolIndex - * @param SystemCurrencyIndex $currencyIndex, - * @param FixtureFactory $fixtureFactory - * @return array - */ - public function __inject( - SystemCurrencySymbolIndex $currencySymbolIndex, - SystemCurrencyIndex $currencyIndex, - FixtureFactory $fixtureFactory - ) { - $this->currencySymbolIndex = $currencySymbolIndex; - $this->currencyIndex = $currencyIndex; - - /**@var CatalogProductSimple $catalogProductSimple */ - $product = $fixtureFactory->createByCode( - 'catalogProductSimple', - ['dataSet' => 'product_with_category'] - ); - $product->persist(); - - return ['product' => $product]; - } - /** * Edit Currency Symbol Entity test. * @@ -91,36 +47,4 @@ class EditCurrencySymbolEntityTest extends Injectable $this->currencySymbolIndex->getCurrencySymbolForm()->fill($currencySymbol); $this->currencySymbolIndex->getPageActions()->save(); } - - /** - * Import currency rates. - * - * @param string $configData - * @return void - */ - protected function importCurrencyRate($configData) - { - $this->objectManager->getInstance()->create( - 'Magento\Config\Test\TestStep\SetupConfigurationStep', - ['configData' => $configData] - )->run(); - - // Import Exchange Rates for currencies - $this->currencyIndex->open(); - $this->currencyIndex->getGridPageActions()->clickImportButton(); - $this->currencyIndex->getMainPageActions()->saveCurrentRate(); - } - - /** - * Disabling currency which has been added. - * - * @return void - */ - public function tearDown() - { - $this->objectManager->getInstance()->create( - 'Magento\Config\Test\TestStep\SetupConfigurationStep', - ['configData' => 'config_currency_symbols_usd'] - )->run(); - } } diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php index f64c407f6aefffb4f76ccf351282c38556b079ca..96537d399ce8770887994dd6a6b7f9268f3e40f4 100644 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php @@ -6,12 +6,8 @@ namespace Magento\CurrencySymbol\Test\TestCase; -use Magento\Mtf\TestCase\Injectable; -use Magento\Mtf\Fixture\FixtureFactory; use Magento\Catalog\Test\Fixture\CatalogProductSimple; use Magento\CurrencySymbol\Test\Fixture\CurrencySymbolEntity; -use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencyIndex; -use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencySymbolIndex; /** * Preconditions: @@ -28,77 +24,13 @@ use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencySymbolIndex; * @group Currency_(PS) * @ZephyrId MAGETWO-26638 */ -class ResetCurrencySymbolEntityTest extends Injectable +class ResetCurrencySymbolEntityTest extends AbstractCurrencySymbolEntityTest { /* tags */ const MVP = 'no'; const DOMAIN = 'PS'; /* end tags */ - /** - * System currency symbol grid page. - * - * @var SystemCurrencySymbolIndex - */ - protected $currencySymbolIndex; - - /** - * System currency index page. - * - * @var SystemCurrencyIndex - */ - protected $currencyIndex; - - /** - * Currency symbol entity fixture. - * - * @var CurrencySymbolEntity - */ - protected $currencySymbolDefault; - - /** - * Fixture Factory. - * - * @var FixtureFactory - */ - protected $fixtureFactory; - - /** - * Prepare data. Create simple product. - * - * @param FixtureFactory $fixtureFactory - * @return array - */ - public function __prepare(FixtureFactory $fixtureFactory) - { - $this->fixtureFactory = $fixtureFactory; - $product = $this->fixtureFactory->createByCode( - 'catalogProductSimple', - ['dataSet' => 'product_with_category'] - ); - $product->persist(); - - return ['product' => $product]; - } - - /** - * Injection data. - * - * @param SystemCurrencySymbolIndex $currencySymbolIndex - * @param SystemCurrencyIndex $currencyIndex - * @param CurrencySymbolEntity $currencySymbolDefault - * @return array - */ - public function __inject( - SystemCurrencySymbolIndex $currencySymbolIndex, - SystemCurrencyIndex $currencyIndex, - CurrencySymbolEntity $currencySymbolDefault - ) { - $this->currencySymbolIndex = $currencySymbolIndex; - $this->currencyIndex = $currencyIndex; - $this->currencySymbolDefault = $currencySymbolDefault; - } - /** * Reset Currency Symbol Entity test. * @@ -135,36 +67,4 @@ class ResetCurrencySymbolEntityTest extends Injectable ) ]; } - - /** - * Import currency rates. - * - * @param string $configData - * @return void - */ - protected function importCurrencyRate($configData) - { - $this->objectManager->getInstance()->create( - 'Magento\Config\Test\TestStep\SetupConfigurationStep', - ['configData' => $configData] - )->run(); - - // Import Exchange Rates for currencies - $this->currencyIndex->open(); - $this->currencyIndex->getGridPageActions()->clickImportButton(); - $this->currencyIndex->getMainPageActions()->saveCurrentRate(); - } - - /** - * Disabling currency which has been added. - * - * @return void - */ - public function tearDown() - { - $this->objectManager->getInstance()->create( - 'Magento\Config\Test\TestStep\SetupConfigurationStep', - ['configData' => 'config_currency_symbols_usd'] - )->run(); - } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/CustomerForm.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/CustomerForm.xml index d8722814679701ed50ae1f70c49025d042738519..bc70891ffa44c1c7dc73bdc6469b37fcd113c886 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/CustomerForm.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/CustomerForm.xml @@ -8,9 +8,9 @@ <tabs> <account_information> <class>\Magento\Backend\Test\Block\Widget\Tab</class> - <selector>#tab_account</selector> + <selector>#tab_customer</selector> <strategy>css selector</strategy> - <wrapper>account</wrapper> + <wrapper>data[customer]</wrapper> <fields> <website_id> <input>select</input> @@ -28,7 +28,7 @@ </account_information> <addresses> <class>\Magento\Customer\Test\Block\Adminhtml\Edit\Tab\Addresses</class> - <selector>#tab_customer_address</selector> + <selector>#tab_address</selector> <strategy>css selector</strategy> </addresses> </tabs> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml index efef4933c1b7421defaf380157ce9b53cf53e66e..b50ddc0ff54a605085e89611fd4e168a93fe35be 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml @@ -70,11 +70,11 @@ <strategy>css selector</strategy> </vat_id> <default_billing> - <selector>#address_list [aria-selected="true"] [name^="account"][name$="[default_billing]"]</selector> + <selector>.ui-state-active [name$="[default_billing]"]</selector> <input>checkbox</input> </default_billing> <default_shipping> - <selector>#address_list [aria-selected="true"] [name^="account"][name$="[default_shipping]"]</selector> + <selector>.ui-state-active [name$="[default_shipping]"]</selector> <input>checkbox</input> </default_shipping> </fields> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Curl.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Curl.php index 67d98b313afe2c576d620daed3c0dfd392d40315..fb1030c3143f16e5496bd47354f74826ed2c457c 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Curl.php @@ -34,6 +34,10 @@ class Curl extends AbstractCurl implements CustomerInterface 'United States' => 'US', 'United Kingdom' => 'GB' ], + 'gender' => [ + 'Male' => 1, + 'Female' => 2, + ], 'region_id' => [ 'California' => 12, 'New York' => 43, @@ -47,14 +51,15 @@ class Curl extends AbstractCurl implements CustomerInterface * @var array */ protected $curlMapping = [ - 'account' => [ + 'customer' => [ 'group_id', 'firstname', 'lastname', 'email', 'dob', 'taxvat', - 'gender' + 'gender', + 'entity_id', ] ]; @@ -77,12 +82,11 @@ class Curl extends AbstractCurl implements CustomerInterface */ public function persist(FixtureInterface $customer = null) { - $address = []; - $result = []; /** @var Customer $customer */ - $url = $_ENV['app_frontend_url'] . 'customer/account/createpost/?nocookie=true'; $data = $customer->getData(); $data['group_id'] = $this->getCustomerGroup($customer); + $address = []; + $url = $_ENV['app_frontend_url'] . 'customer/account/createpost/?nocookie=true'; if ($customer->hasData('address')) { $address = $customer->getAddress(); @@ -98,15 +102,14 @@ class Curl extends AbstractCurl implements CustomerInterface throw new \Exception("Customer entity creating by curl handler was not successful! Response: $response"); } - $result['id'] = $this->getCustomerId($customer->getEmail()); - $data['customer_id'] = $result['id']; + $data['entity_id'] = $this->getCustomerId($customer->getEmail()); if (!empty($address)) { $data['address'] = $address; } $this->updateCustomer($data); - return $result; + return ['id' => $data['entity_id']]; } /** @@ -167,19 +170,19 @@ class Curl extends AbstractCurl implements CustomerInterface } unset($data['password'], $data['password_confirmation']); - $curlData = $this->replaceMappingData(array_merge($curlData, $data)); + $curlData = $this->replaceMappingData(array_replace_recursive($curlData, $data)); if (!empty($data['address'])) { $curlData = $this->prepareAddressData($curlData); } - $url = $_ENV['app_backend_url'] . 'customer/index/save/id/' . $data['customer_id']; + $url = $_ENV['app_backend_url'] . 'customer/index/save/id/' . $curlData['customer']['entity_id']; $curl = new BackendDecorator(new CurlTransport(), $this->_configuration); $curl->write(CurlInterface::POST, $url, '1.0', [], $curlData); $response = $curl->read(); $curl->close(); if (!strpos($response, 'data-ui-id="messages-message-success"')) { - $this->_eventManager->dispatchEvent(['curl_failed', [$response]]); + $this->_eventManager->dispatchEvent(['curl_failed'], [$response]); throw new \Exception('Failed to update customer!'); } } @@ -200,7 +203,6 @@ class Curl extends AbstractCurl implements CustomerInterface $curlData['address'][$key]['street'] = []; $curlData['address'][$key]['street'][] = $street; } - $newKey = 'new_' . ($key); if (isset($curlData['address'][$key]['default_billing'])) { $value = $curlData['address'][$key]['default_billing'] === 'Yes' ? 'true' : 'false'; $curlData['address'][$key]['default_billing'] = $value; @@ -209,9 +211,7 @@ class Curl extends AbstractCurl implements CustomerInterface $value = $curlData['address'][$key]['default_shipping'] === 'Yes' ? 'true' : 'false'; $curlData['address'][$key]['default_shipping'] = $value; } - $curlData['account']['customer_address'][$newKey] = $curlData['address'][$key]; } - unset($curlData['address']); return $curlData; } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml index 783fa1ad4e1b476da685d85db7e08281163d7256..57cf9a355142c53bce686233fd8ccbf588296f45 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml @@ -6,8 +6,8 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/pages.xsd"> - <page name="CustomerAccountCreate" mca="customer/account/create" module="Magento_Customer"> - <block name="registerForm" class="Magento\Customer\Test\Block\Form\Register" locator="#form-validate" strategy="css selector"/> - <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator=".page.messages" strategy="css selector"/> - </page> + <page name="CustomerAccountCreate" mca="customer/account/create" module="Magento_Customer"> + <block name="registerForm" class="Magento\Customer\Test\Block\Form\Register" locator="#form-validate[novalidate='novalidate']" strategy="css selector" /> + <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator=".page.messages" strategy="css selector" /> + </page> </config> diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Constraint/AssertCurrencyRateAppliedOnCatalogPage.php b/dev/tests/functional/tests/app/Magento/Directory/Test/Constraint/AssertCurrencyRateAppliedOnCatalogPage.php new file mode 100644 index 0000000000000000000000000000000000000000..05cd0245e1a759d6162a5dca748479844cb551c8 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Constraint/AssertCurrencyRateAppliedOnCatalogPage.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Directory\Test\Constraint; + +use Magento\Cms\Test\Page\CmsIndex; +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Catalog\Test\Page\Category\CatalogCategoryView; +use Magento\CurrencySymbol\Test\Fixture\CurrencySymbolEntity; + +/** + * Assert currency rate applied on catalog page. + */ +class AssertCurrencyRateAppliedOnCatalogPage extends AbstractConstraint +{ + /** + * Assert currency rate applied on catalog page. + * + * @param CmsIndex $cmsIndex + * @param CatalogCategoryView $catalogCategoryView + * @param CatalogProductSimple $product + * @param CurrencySymbolEntity $currencySymbol + * @param string $basePrice + * @param string $convertedPrice + * @return void + */ + public function processAssert( + CmsIndex $cmsIndex, + CatalogCategoryView $catalogCategoryView, + CatalogProductSimple $product, + CurrencySymbolEntity $currencySymbol, + $basePrice, + $convertedPrice + ) { + $categoryName = $product->getCategoryIds()[0]; + $cmsIndex->open(); + $cmsIndex->getTopmenu()->selectCategoryByName($categoryName); + $priceBlock = $catalogCategoryView->getListProductBlock()->getProductItem($product)->getPriceBlock(); + $actualPrice = $priceBlock->getPrice(''); + + \PHPUnit_Framework_Assert::assertEquals( + $basePrice, + $actualPrice, + 'Wrong price is displayed on Category page.' + ); + + $cmsIndex->getCurrencyBlock()->switchCurrency($currencySymbol); + $cmsIndex->getTopmenu()->selectCategoryByName($categoryName); + $actualPrice = $priceBlock->getPrice(''); + + \PHPUnit_Framework_Assert::assertEquals( + $convertedPrice, + $actualPrice, + 'Wrong price is displayed on Category page.' + ); + } + + /** + * Returns a string representation of successful assertion. + * + * @return string + */ + public function toString() + { + return "Currency rate has been applied correctly on Catalog page."; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Constraint/AssertCurrencyRateSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Directory/Test/Constraint/AssertCurrencyRateSuccessSaveMessage.php new file mode 100644 index 0000000000000000000000000000000000000000..3a9f7e82a3943e73ece72d72fbefb3bc2e720ca5 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Constraint/AssertCurrencyRateSuccessSaveMessage.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Directory\Test\Constraint; + +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencyIndex; + +/** + * Assert that success message is displayed. + */ +class AssertCurrencyRateSuccessSaveMessage extends AbstractConstraint +{ + const SUCCESS_MESSAGE = 'All valid rates have been saved.'; + + /** + * Assert that success message is displayed after currency rate saved. + * + * @param SystemCurrencyIndex $currencyIndexPage + * @return void + */ + public function processAssert(SystemCurrencyIndex $currencyIndexPage) + { + $actualMessage = $currencyIndexPage->getMessagesBlock()->getSuccessMessages(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $actualMessage, + 'Wrong success message is displayed.' + . "\nExpected: " . self::SUCCESS_MESSAGE + . "\nActual: " . $actualMessage + ); + } + + /** + * Returns a string representation of successful assertion. + * + * @return string + */ + public function toString() + { + return 'Currency rate success create message is present.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Fixture/CurrencyRate.xml b/dev/tests/functional/tests/app/Magento/Directory/Test/Fixture/CurrencyRate.xml new file mode 100644 index 0000000000000000000000000000000000000000..70fcf15c962980ade05464ff3e6a8cebb9b66c85 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Fixture/CurrencyRate.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd"> + <fixture name="currencyRate" module="Magento_Directory" type="flat" entity_type="directory_currency_rate" collection="Magento\Directory\Model\Resource\Currency" identifier="" repository_class="Magento\Directory\Test\Repository\CurrencyRate" handler_interface="Magento\Directory\Test\Handler\CurrencyRate\CurrencyRateInterface" class="Magento\Directory\Test\Fixture\CurrencyRate"> + <dataset name="default"> + <field name="currency_from" xsi:type="string">USD</field> + <field name="currency_to" xsi:type="string">EUR</field> + <field name="rate" xsi:type="number">0.8</field> + </dataset> + + <field name="currency_from" is_required="1" /> + <field name="currency_to" is_required="1" /> + <field name="rate" is_required="1" /> + </fixture> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Handler/CurrencyRate/Curl.php b/dev/tests/functional/tests/app/Magento/Directory/Test/Handler/CurrencyRate/Curl.php new file mode 100644 index 0000000000000000000000000000000000000000..cc6fbf9895588b3ae58c5dd75779c97e54c6a7ce --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Handler/CurrencyRate/Curl.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Directory\Test\Handler\CurrencyRate; + +use Magento\Mtf\Fixture\FixtureInterface; +use Magento\Mtf\Handler\Curl as AbstractCurl; +use Magento\Mtf\Util\Protocol\CurlInterface; +use Magento\Mtf\Util\Protocol\CurlTransport; +use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator; + +/** + * Curl handler for setting currency rates. + */ +class Curl extends AbstractCurl implements CurrencyRateInterface +{ + /** + * Post request for setting currency rate. + * + * @param FixtureInterface $fixture [optional] + * @return mixed|string + * @throws \Exception + */ + public function persist(FixtureInterface $fixture = null) + { + $data = $this->prepareData($fixture); + + $url = $_ENV['app_backend_url'] . 'admin/system_currency/saveRates/'; + $curl = new BackendDecorator(new CurlTransport(), $this->_configuration); + $curl->write(CurlInterface::POST, $url, '1.0', [], $data); + $response = $curl->read(); + $curl->close(); + + if (!strpos($response, 'data-ui-id="messages-message-success"')) { + throw new \Exception("Currency rates setting by curl handler was not successful! Response:\n" . $response); + } + } + + /** + * Prepare data for POST request. + * + * @param FixtureInterface $fixture + * @return array + */ + protected function prepareData(FixtureInterface $fixture) + { + $result = []; + $data = $fixture->getData(); + $result['rate'][$data['currency_from']][$data['currency_to']] = $data['rate']; + + return $result; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Handler/CurrencyRate/CurrencyRateInterface.php b/dev/tests/functional/tests/app/Magento/Directory/Test/Handler/CurrencyRate/CurrencyRateInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..99cc0f552b190d49268024a33dfa0501e97f8cc7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Handler/CurrencyRate/CurrencyRateInterface.php @@ -0,0 +1,17 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Directory\Test\Handler\CurrencyRate; + +use Magento\Mtf\Handler\HandlerInterface; + +/** + * Interface CurrencyRateInterface + */ +interface CurrencyRateInterface extends HandlerInterface +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/Repository/CurrencyRate.xml b/dev/tests/functional/tests/app/Magento/Directory/Test/Repository/CurrencyRate.xml new file mode 100644 index 0000000000000000000000000000000000000000..c1b6dc96e3cbb79862eb959f0325f551cb12acf2 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Directory/Test/Repository/CurrencyRate.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" ?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd"> + <repository class="Magento\Directory\Test\Repository\CurrencyRate"> + <dataset name="usd_chf_rate_0_9"> + <field name="currency_from" xsi:type="string">USD</field> + <field name="currency_to" xsi:type="string">CHF</field> + <field name="rate" xsi:type="number">0.9</field> + </dataset> + + <dataset name="usd_gbp_rate_0_6"> + <field name="currency_from" xsi:type="string">USD</field> + <field name="currency_to" xsi:type="string">GBP</field> + <field name="rate" xsi:type="number">0.6</field> + </dataset> + </repository> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php new file mode 100644 index 0000000000000000000000000000000000000000..04aa6c4ca73d61e4ef01e61ac9929d9a225d2b59 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Directory\Test\TestCase; + +use Magento\Config\Test\Fixture\ConfigData; +use Magento\Mtf\TestCase\Injectable; +use Magento\Directory\Test\Fixture\CurrencyRate; +use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencyIndex; + +/** + * Preconditions: + * 1. Create Simple product and assign it to the category. + * 2. Configure allowed Currencies Options. + * + * Steps: + * 1. Login to backend. + * 2. Go to Stores > Currency > Currency Rates. + * 3. Fill currency rate according to dataSet. + * 4. Click on 'Save Currency Rates' button. + * 5. Perform assertions. + * + * @group Localization_(PS) + * @ZephyrId MAGETWO-12427, MAGETWO-36824 + */ +class CreateCurrencyRateTest extends Injectable +{ + /* tags */ + const TEST_TYPE = 'acceptance_test'; + const DOMAIN = 'PS'; + /* end tags */ + + /** + * Currency rate index page. + * + * @var SystemCurrencyIndex + */ + protected $currencyIndexPage; + + /** + * Inject data. + * + * @param SystemCurrencyIndex $currencyIndexPage + * @return void + */ + public function __inject(SystemCurrencyIndex $currencyIndexPage) + { + $this->currencyIndexPage = $currencyIndexPage; + } + + /** + * Create currency rate test. + * + * @param CurrencyRate $currencyRate + * @param CatalogProductSimple $product + * @param $config + * @return void + */ + public function test(CurrencyRate $currencyRate, CatalogProductSimple $product, ConfigData $config) + { + // Preconditions: + $product->persist(); + $config->persist(); + + // Steps: + $this->currencyIndexPage->open(); + $this->currencyIndexPage->getCurrencyRateForm()->fill($currencyRate); + $this->currencyIndexPage->getFormPageActions()->save(); + } + + /** + * Reset currency config to default values. + * + * @return void + */ + public function tearDown() + { + $this->objectManager->create( + 'Magento\Config\Test\TestStep\SetupConfigurationStep', + ['configData' => 'config_currency_symbols_usd'] + )->run(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.xml b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..561f9307ff07f058b79e7873e4e7ed15ceb67632 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> + <testCase name="Magento\Directory\Test\TestCase\CreateCurrencyRateTest"> + <variation name="CreateCurrencyRateTestVariation1"> + <data name="currencyRate/data/currency_from" xsi:type="string">USD</data> + <data name="currencyRate/data/currency_to" xsi:type="string">EUR</data> + <data name="currencyRate/data/rate" xsi:type="number">0.8</data> + <data name="currencySymbol/dataSet" xsi:type="string">currency_symbols_eur</data> + <data name="product/dataSet" xsi:type="string">simple_10_dollar</data> + <data name="config/dataSet" xsi:type="string">config_currency_symbols_usd_and_eur</data> + <data name="basePrice" xsi:type="string">$10.00</data> + <data name="convertedPrice" xsi:type="string">€8.00</data> + <data name="tag" xsi:type="string">test_type:acceptance_test</data> + <constraint name="Magento\Directory\Test\Constraint\AssertCurrencyRateSuccessSaveMessage"/> + <constraint name="Magento\Directory\Test\Constraint\AssertCurrencyRateAppliedOnCatalogPage"/> + </variation> + </testCase> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Directory/Test/etc/curl/di.xml new file mode 100644 index 0000000000000000000000000000000000000000..0962d9ed807d9206fb6e31b641e4fa133588097c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Directory/Test/etc/curl/di.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" ?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> + <preference for="\Magento\Directory\Test\Handler\CurrencyRate\CurrencyRateInterface" type="\Magento\Directory\Test\Handler\CurrencyRate\Curl" /> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.php index 64d1aab3f990b7d1a043a6cce9bd2bc7bd890403..774f85d7772f4f9fdd76ca895448e8045d0a2c1c 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.php @@ -3,6 +3,7 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable; use Magento\Mtf\Block\Form; @@ -19,7 +20,7 @@ class LinkRow extends Form * * @var string */ - protected $deleteButton = '.action-remove'; + protected $deleteButton = '.action-delete'; /** * Fill item link diff --git a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Block/Adminhtml/Order/Create/Items/ItemProduct.php b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Block/Adminhtml/Order/Create/Items/ItemProduct.php index 3627d161b35ab583e5f5c7ab4a1c919d473c2c6c..77d38c0eb97743553753d2f5d1ae8ba9aa75bbeb 100644 --- a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Block/Adminhtml/Order/Create/Items/ItemProduct.php +++ b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Block/Adminhtml/Order/Create/Items/ItemProduct.php @@ -29,11 +29,11 @@ class ItemProduct extends \Magento\Sales\Test\Block\Adminhtml\Order\Create\Items protected $giftMessageForm = './/*[@role="dialog"][*[@id="gift_options_configure"]]'; /** - * Magento varienLoader.js loader. + * Magento loader. * * @var string */ - protected $loadingMask = '//*[@id="loading-mask"]/*[@id="loading_mask_loader"]'; + protected $loader = '[data-role="loader"]'; /** * Fill GiftMessage form. @@ -58,10 +58,11 @@ class ItemProduct extends \Magento\Sales\Test\Block\Adminhtml\Order\Create\Items ['element' => $this->browser->find($this->giftMessageForm, Locator::SELECTOR_XPATH)] ); $giftMessageForm->fill($giftMessage); - $loadingMask = $this->browser->find($this->loadingMask, Locator::SELECTOR_XPATH); + $loader = $this->loader; $this->browser->waitUntil( - function () use ($loadingMask) { - return !$loadingMask->isVisible() ? true : null; + function () use ($browser, $loader) { + $element = $this->browser->find($loader); + return $element->isVisible() == false ? true : null; } ); } diff --git a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/etc/testcase.xml index 3ce7af8e5be7e87a8a7173565d2b67e0740afa88..de5469059a9b89883c6210b648f0783b8af43fd8 100644 --- a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/etc/testcase.xml +++ b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/etc/testcase.xml @@ -22,15 +22,9 @@ <step name="placeOrder" module="Magento_Checkout" /> </scenario> <scenario name="CreateGiftMessageOnBackendTest" firstStep="setupConfiguration"> - <step name="setupConfiguration" module="Magento_Config" next="createProducts"> - <item name="configData" value="cashondelivery, enable_gift_messages" /> - </step> + <step name="setupConfiguration" module="Magento_Config" next="createProducts" /> <step name="createProducts" module="Magento_Catalog" next="createCustomer" /> - <step name="createCustomer" module="Magento_Customer" next="openSalesOrders"> - <item name="customer"> - <item name="dataSet" value="johndoe_with_addresses" /> - </item> - </step> + <step name="createCustomer" module="Magento_Customer" next="openSalesOrders" /> <step name="openSalesOrders" module="Magento_Sales" next="createNewOrder" /> <step name="createNewOrder" module="Magento_Sales" next="selectCustomerOrder" /> <step name="selectCustomerOrder" module="Magento_Sales" next="selectStore" /> diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct/CheckoutData.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct/CheckoutData.php index 5c45ad254c0b02f4444547e1b95ebba7fedf2727..2871ec912db01ef8020b14699f62d95c6f7299ac 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct/CheckoutData.php +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct/CheckoutData.php @@ -57,39 +57,6 @@ class CheckoutData extends \Magento\Catalog\Test\Fixture\CatalogProductSimple\Ch ], ], ], - 'three_simple_products_default_qty' => [ - 'options' => [ - [ - 'name' => 'product_key_0', - 'qty' => 17, - ], - [ - 'name' => 'product_key_1', - 'qty' => 36 - ], - [ - 'name' => 'product_key_2', - 'qty' => 20 - ], - ], - 'cartItem' => [ - 'price' => [ - 'product_key_0' => 560, - 'product_key_1' => 40, - 'product_key_2' => 100, - ], - 'qty' => [ - 'product_key_0' => 17, - 'product_key_1' => 36, - 'product_key_2' => 20, - ], - 'subtotal' => [ - 'product_key_0' => 9520.00, - 'product_key_1' => 1440.00, - 'product_key_2' => 2000.00, - ], - ], - ], ]; return isset($presets[$name]) ? $presets[$name] : null; } diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml index fbf4305699a447b37e9a8d1bd756caec8f1f569e..cd0bc02b3df4ccab18c34b1876eef98e775af553 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml @@ -117,34 +117,5 @@ <item name="preset" xsi:type="string">three_simple_products</item> </field> </dataset> - - <dataset name="three_simple_products_default_qty"> - <field name="name" xsi:type="string">Grouped product %isolation%</field> - <field name="sku" xsi:type="string">grouped_product_%isolation%</field> - <field name="category_ids" xsi:type="array"> - <item name="presets" xsi:type="string">default</item> - </field> - <field name="associated" xsi:type="array"> - <item name="preset" xsi:type="string">three_simple_products</item> - </field> - <field name="status" xsi:type="string">Product online</field> - <field name="visibility" xsi:type="string">Catalog, Search</field> - <field name="tax_class_id" xsi:type="array"> - <item name="dataSet" xsi:type="string">taxable_goods</item> - </field> - <field name="url_key" xsi:type="string">test-grouped-product-%isolation%</field> - <field name="quantity_and_stock_status" xsi:type="array"> - <item name="is_in_stock" xsi:type="string">In Stock</item> - </field> - <field name="website_ids" xsi:type="array"> - <item name="0" xsi:type="string">Main Website</item> - </field> - <field name="attribute_set_id" xsi:type="array"> - <item name="dataSet" xsi:type="string">default</item> - </field> - <field name="checkout_data" xsi:type="array"> - <item name="preset" xsi:type="string">three_simple_products_default_qty</item> - </field> - </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php index 41376ef7a3735d1af8d8dd8531397518f7f5b0a9..4dfa6dd2122c10aa6a7344210cd47d10985551c0 100644 --- a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php @@ -3,13 +3,14 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\LayeredNavigation\Test\Block; use Magento\Mtf\Block\Block; use Magento\Mtf\Client\Locator; /** - * Catalog layered navigation view block + * Catalog layered navigation view block. */ class Navigation extends Block { @@ -20,20 +21,6 @@ class Navigation extends Block */ protected $clearAll = '.action.clear'; - /** - * Price range. - * - * @var string - */ - protected $priceRange = "[href$='?price=%s']"; - - /** - * Attribute option. - * - * @var string - */ - protected $attributeOption = "//a[contains(text(), '%s')]"; - /** * Attribute option title selector. * @@ -42,11 +29,11 @@ class Navigation extends Block protected $optionTitle = '.filter-options-title'; /** - * Attribute option content selector. + * Filter link locator. * * @var string */ - protected $optionContent = '.filter-options-content'; + protected $filterLink = './/dt[contains(text(),"%s")]/following-sibling::dd//a'; /** * Click on 'Clear All' link. @@ -58,28 +45,6 @@ class Navigation extends Block $this->_rootElement->find($this->clearAll, locator::SELECTOR_CSS)->click(); } - /** - * Select product price range. - * - * @param string $range - * @return void - */ - public function selectPriceRange($range) - { - $this->_rootElement->find(sprintf($this->priceRange, $range))->click(); - } - - /** - * Select attribute option. - * - * @param string $optionName - * @return void - */ - public function selectAttributeOption($optionName) - { - $this->_rootElement->find(sprintf($this->attributeOption, $optionName), Locator::SELECTOR_XPATH)->click(); - } - /** * Get array of available filters. * @@ -94,4 +59,25 @@ class Navigation extends Block } return $data; } + + /** + * Click filter link. + * + * @param string $filter + * @param string $linkPattern + * @return void + * @throws \Exception + */ + public function clickFilterLink($filter, $linkPattern) + { + $links = $this->_rootElement->getElements(sprintf($this->filterLink, $filter), Locator::SELECTOR_XPATH); + + foreach ($links as $link) { + if (preg_match($linkPattern, trim($link->getText()))) { + $link->click(); + return; + } + } + throw new \Exception("Can't find {$filter} filter link by pattern: {$linkPattern}"); + } } diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Constraint/AssertFilterProductList.php b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Constraint/AssertFilterProductList.php new file mode 100644 index 0000000000000000000000000000000000000000..e2b384a26611026f3c353fd7d8f7185ecab99143 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Constraint/AssertFilterProductList.php @@ -0,0 +1,90 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\LayeredNavigation\Test\Constraint; + +use Magento\Catalog\Test\Fixture\Category; +use Magento\Catalog\Test\Page\Category\CatalogCategoryView; +use Magento\Cms\Test\Page\CmsIndex; +use Magento\Mtf\Constraint\AbstractConstraint; + +/** + * Check whether products can be filtered in the Frontend via layered navigation. + */ +class AssertFilterProductList extends AbstractConstraint +{ + /** + * Available products list. + * + * @var array + */ + protected $products; + + /** + * Assertion that filtered product list via layered navigation are displayed correctly. + * + * @param Category $category + * @param CmsIndex $cmsIndex + * @param CatalogCategoryView $catalogCategoryView + * @param array $layeredNavigation + * @return void + */ + public function processAssert( + Category $category, + CmsIndex $cmsIndex, + CatalogCategoryView $catalogCategoryView, + array $layeredNavigation + ) { + $this->products = $category->getDataFieldConfig('category_products')['source']->getProducts(); + $cmsIndex->open(); + $cmsIndex->getTopmenu()->selectCategoryByName($category->getName()); + + foreach ($layeredNavigation as $filters) { + foreach ($filters as $filter) { + $catalogCategoryView->getLayeredNavigationBlock()->clickFilterLink( + $filter['title'], + $filter['linkPattern'] + ); + + $productNames = $this->getProductNames($filter['products']); + sort($productNames); + $pageProductNames = $catalogCategoryView->getListProductBlock()->getProductNames(); + sort($pageProductNames); + \PHPUnit_Framework_Assert::assertEquals($productNames, $pageProductNames); + } + $catalogCategoryView->getLayeredNavigationBlock()->clearAll(); + } + } + + /** + * Get product names list by keys. + * + * @param string $productKeys + * @return array + */ + protected function getProductNames($productKeys) + { + $keys = array_map('trim', explode(',', $productKeys)); + $productNames = []; + + foreach ($keys as $key) { + $key = str_replace('product_', '', $key); + $productNames[] = $this->products[$key]->getName(); + } + + return $productNames; + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Filtered product list via layered navigation are displayed correctly.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Page/Category/CatalogCategoryView.xml b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Page/Category/CatalogCategoryView.xml new file mode 100644 index 0000000000000000000000000000000000000000..c3b68e9dd74ccab2655d9d8f307cb4c634e93dfd --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Page/Category/CatalogCategoryView.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> + <page name="CatalogCategoryView" area="Category" mca="catalog/category/view" module="Magento_Catalog"> + <block name="layeredNavigationBlock" class="Magento\LayeredNavigation\Test\Block\Navigation" locator=".block.filter" strategy="css selector"/> + </page> +</config> diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Repository/ConfigData.xml new file mode 100644 index 0000000000000000000000000000000000000000..2005dd8bf0cef056edf502e01fd9554e68cb8e23 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Repository/ConfigData.xml @@ -0,0 +1,45 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd"> + <repository class="Magento\Config\Test\Repository\ConfigData"> + <dataset name="layered_navigation_manual_range_10"> + <field name="catalog/layered_navigation/display_product_count" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" label="Yes" xsi:type="string">1</item> + </field> + <field name="catalog/layered_navigation/price_range_calculation" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" label="Manual" xsi:type="string">manual</item> + </field> + <field name="catalog/layered_navigation/price_range_step" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" xsi:type="string">10</item> + </field> + <field name="catalog/layered_navigation/price_range_max_intervals" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" xsi:type="string">10</item> + </field> + </dataset> + <dataset name="layered_navigation_manual_range_10_rollback"> + <field name="catalog/layered_navigation/display_product_count" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" label="Yes" xsi:type="string">1</item> + </field> + <field name="catalog/layered_navigation/price_range_calculation" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" label="Automatic (equalize price ranges)" xsi:type="string">auto</item> + </field> + </dataset> + </repository> +</config> diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php new file mode 100644 index 0000000000000000000000000000000000000000..dea532e69cf26dfe81ce7bb3fa281bf26a077dd8 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php @@ -0,0 +1,73 @@ +<?php + +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\LayeredNavigation\Test\TestCase; + +use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Catalog\Test\Fixture\Category; +use Magento\Mtf\TestCase\Injectable; + +/** + * Preconditions: + * 1. Setup Layered Navigation configuration. + * + * Steps: + * 1. Create category. + * 2. Create product with created category. + * 3. Perform all assertions. + * + * @group Layered_Navigation_(MX) + * @ZephyrId MAGETWO-12419 + */ +class FilterProductListTest extends Injectable +{ + /* tags */ + const DOMAIN = 'MX'; + const TEST_TYPE = 'acceptance_test'; + /* end tags */ + + /** + * Configuration setting. + * + * @var string + */ + protected $configData; + + /** + * Filtering product in the Frontend via layered navigation. + * + * @param string $configData + * @param Category $category + * @return array + */ + public function test($configData, Category $category) + { + $this->configData = $configData; + + // Preconditions + $this->objectManager->create( + 'Magento\Config\Test\TestStep\SetupConfigurationStep', + ['configData' => $this->configData] + )->run(); + + // Steps + $category->persist(); + } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->objectManager->create( + 'Magento\Config\Test\TestStep\SetupConfigurationStep', + ['configData' => $this->configData, 'rollback' => true] + )->run(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..4cfbc8d6397ff7d52133d0a2c70d129c06825b01 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> + <testCase name="Magento\LayeredNavigation\Test\TestCase\FilterProductListTest"> + <variation name="FilterProductListTestVariation1"> + <data name="configData" xsi:type="string">layered_navigation_manual_range_10</data> + <data name="category/dataSet" xsi:type="string">default_anchor_subcategory</data> + <data name="category/data/category_products/dataSet" xsi:type="string">catalogProductSimple::product_20_dollar, configurableProduct::filterable_two_options_with_zero_price</data> + <data name="layeredNavigation" xsi:type="array"> + <item name="filters_0" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">Price</item> + <item name="linkPattern" xsi:type="string">`^.+10\.00 - .+19\.99 1$`m</item> + <item name="products" xsi:type="string">product_1</item> + </item> + </item> + <item name="filters_1" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">attribute_dropdown</item> + <item name="linkPattern" xsi:type="string">`^option_0_[0-9]+ 1$`m</item> + <item name="products" xsi:type="string">product_1</item> + </item> + </item> + </data> + <data name="tag" xsi:type="string">test_type:acceptance_test</data> + <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForAssignedProducts" /> + <constraint name="Magento\LayeredNavigation\Test\Constraint\AssertFilterProductList" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/CustomerForm.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/CustomerForm.xml index c7a99a1c233ca0d32fb2e2703edf7b4c7f502484..32892c7138a7989b8d85d8c1092b80464054946c 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/CustomerForm.xml +++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/CustomerForm.xml @@ -8,7 +8,7 @@ <tabs> <product_reviews> <class>\Magento\Review\Test\Block\Adminhtml\Customer\Edit\Tab\Reviews</class> - <selector>#tab_reviews</selector> + <selector>#tab_block_reviews</selector> <strategy>css selector</strategy> </product_reviews> </tabs> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Coupons.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Coupons.php index e118bac1958fb0b3c9d0906bdafe181e157a9a7b..0a350725839b9e8833b90dda8003c051b0c7293c 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Coupons.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Coupons.php @@ -7,7 +7,7 @@ namespace Magento\Sales\Test\Block\Adminhtml\Order\Create; use Magento\Backend\Test\Block\Widget\Form; -use Magento\SalesRule\Test\Fixture\SalesRuleInjectable; +use Magento\SalesRule\Test\Fixture\SalesRule; use Magento\Mtf\Client\Locator; /** @@ -32,10 +32,10 @@ class Coupons extends Form /** * Enter discount code and click apply button. * - * @param SalesRuleInjectable $code + * @param SalesRule $code * @return void */ - public function applyCouponCode(SalesRuleInjectable $code) + public function applyCouponCode(SalesRule $code) { $this->_rootElement->find($this->couponCode)->setValue($code->getCouponCode()); $this->_rootElement->find($this->applyButton, Locator::SELECTOR_XPATH)->click(); diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Fixture/OrderInjectable/CouponCode.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Fixture/OrderInjectable/CouponCode.php index b3d081c56d4c759fe4728523de1732c42f1477d0..0a28aff4f63e99585c420f30ca03fcd9031e1a4e 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Fixture/OrderInjectable/CouponCode.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Fixture/OrderInjectable/CouponCode.php @@ -6,7 +6,7 @@ namespace Magento\Sales\Test\Fixture\OrderInjectable; -use Magento\SalesRule\Test\Fixture\SalesRuleInjectable; +use Magento\SalesRule\Test\Fixture\SalesRule; use Magento\Mtf\Fixture\FixtureFactory; use Magento\Mtf\Fixture\DataSource; @@ -24,12 +24,12 @@ class CouponCode extends DataSource public function __construct(FixtureFactory $fixtureFactory, array $data, array $params = []) { $this->params = $params; - if (isset($data['value']) && $data['value'] instanceof SalesRuleInjectable) { + if (isset($data['value']) && $data['value'] instanceof SalesRule) { $this->data = $data['value']; return; } if (isset($data['dataSet'])) { - $salesRule = $fixtureFactory->createByCode('salesRuleInjectable', ['dataSet' => $data['dataSet']]); + $salesRule = $fixtureFactory->createByCode('salesRule', ['dataSet' => $data['dataSet']]); $salesRule->persist(); $this->data = $salesRule; } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Handler/OrderInjectable/Curl.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Handler/OrderInjectable/Curl.php index e98f4ba0afff567f479384c0c7eaecef6543505d..7d993cb5f0094f6f9c9982314b44c83240402f88 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Handler/OrderInjectable/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Handler/OrderInjectable/Curl.php @@ -11,7 +11,7 @@ use Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct; use Magento\Customer\Test\Fixture\Customer; use Magento\Downloadable\Test\Fixture\DownloadableProduct; use Magento\Sales\Test\Fixture\OrderInjectable; -use Magento\SalesRule\Test\Fixture\SalesRuleInjectable; +use Magento\SalesRule\Test\Fixture\SalesRule; use Magento\Mtf\Fixture\FixtureInterface; use Magento\Mtf\Handler\Curl as AbstractCurl; use Magento\Mtf\Util\Protocol\CurlInterface; @@ -111,10 +111,10 @@ class Curl extends AbstractCurl implements OrderInjectableInterface /** * Prepare coupon data. * - * @param SalesRuleInjectable $data + * @param SalesRule $data * @return array */ - protected function prepareCouponCode(SalesRuleInjectable $data) + protected function prepareCouponCode(SalesRule $data) { return ['order' => ['coupon' => ['code' => $data->getCouponCode()]]]; } diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleApplying.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleApplying.php index 1b573901d93ca029d529bf6c812e436b43d0ee05..a9307ce8132134ef2b9fde5dd5aa3e2f43aaffdd 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleApplying.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleApplying.php @@ -15,7 +15,7 @@ use Magento\Customer\Test\Fixture\Address; use Magento\Customer\Test\Fixture\Customer; use Magento\Customer\Test\Page\CustomerAccountLogin; use Magento\Customer\Test\Page\CustomerAccountLogout; -use Magento\SalesRule\Test\Fixture\SalesRuleInjectable; +use Magento\SalesRule\Test\Fixture\SalesRule; use Magento\Mtf\Constraint\AbstractConstraint; /** @@ -121,8 +121,8 @@ abstract class AssertCartPriceRuleApplying extends AbstractConstraint * @param CatalogCategoryView $catalogCategoryView * @param CatalogProductView $catalogProductView * @param Customer $customer - * @param SalesRuleInjectable $salesRule - * @param SalesRuleInjectable $salesRuleOrigin + * @param SalesRule $salesRule + * @param SalesRule $salesRuleOrigin * @param array $productQuantity * @param CatalogProductSimple $productForSalesRule1 * @param CatalogProductSimple $productForSalesRule2 @@ -141,8 +141,8 @@ abstract class AssertCartPriceRuleApplying extends AbstractConstraint CatalogCategoryView $catalogCategoryView, CatalogProductView $catalogProductView, Customer $customer, - SalesRuleInjectable $salesRule, - SalesRuleInjectable $salesRuleOrigin, + SalesRule $salesRule, + SalesRule $salesRuleOrigin, array $productQuantity, CatalogProductSimple $productForSalesRule1, CatalogProductSimple $productForSalesRule2 = null, diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php index ccd77f877ced270b43d7bcc9f2081422676f0b58..d8a6445267051487c7f813a13dc62be1c8fd6981 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php @@ -6,7 +6,7 @@ namespace Magento\SalesRule\Test\Constraint; -use Magento\SalesRule\Test\Fixture\SalesRuleInjectable; +use Magento\SalesRule\Test\Fixture\SalesRule; use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteEdit; use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteIndex; use Magento\Mtf\Constraint\AbstractConstraint; @@ -34,15 +34,15 @@ class AssertCartPriceRuleForm extends AbstractConstraint * * @param PromoQuoteIndex $promoQuoteIndex * @param PromoQuoteEdit $promoQuoteEdit - * @param SalesRuleInjectable $salesRule - * @param SalesRuleInjectable $salesRuleOrigin + * @param SalesRule $salesRule + * @param SalesRule $salesRuleOrigin * @return void */ public function processAssert( PromoQuoteIndex $promoQuoteIndex, PromoQuoteEdit $promoQuoteEdit, - SalesRuleInjectable $salesRule, - SalesRuleInjectable $salesRuleOrigin = null + SalesRule $salesRule, + SalesRule $salesRuleOrigin = null ) { $filter = [ 'name' => $salesRule->hasData('name') ? $salesRule->getName() : $salesRuleOrigin->getName(), diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleIsNotPresentedInGrid.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleIsNotPresentedInGrid.php index 4c2fd8856a08fdd1af69c5594124fef9443166f4..a0914721420c86595f74dd6b16a487175e935d74 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleIsNotPresentedInGrid.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleIsNotPresentedInGrid.php @@ -6,7 +6,7 @@ namespace Magento\SalesRule\Test\Constraint; -use Magento\SalesRule\Test\Fixture\SalesRuleInjectable; +use Magento\SalesRule\Test\Fixture\SalesRule; use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteIndex; use Magento\Mtf\Constraint\AbstractConstraint; @@ -19,10 +19,10 @@ class AssertCartPriceRuleIsNotPresentedInGrid extends AbstractConstraint * Assert that sales rule is not present in cart price rules grid. * * @param PromoQuoteIndex $promoQuoteIndex - * @param SalesRuleInjectable $salesRule + * @param SalesRule $salesRule * @return void */ - public function processAssert(PromoQuoteIndex $promoQuoteIndex, SalesRuleInjectable $salesRule) + public function processAssert(PromoQuoteIndex $promoQuoteIndex, SalesRule $salesRule) { \PHPUnit_Framework_Assert::assertFalse( $promoQuoteIndex->getPromoQuoteGrid()->isRowVisible(['name' => $salesRule->getName()]), diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRuleInjectable.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRule.xml similarity index 90% rename from dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRuleInjectable.xml rename to dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRule.xml index 25f432794e8432456a08e315988cfe84f60525fb..9008a93b8a36b6f82c5115afc176f113495742bc 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRuleInjectable.xml +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRule.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd"> - <fixture name="salesRuleInjectable" module="Magento_SalesRule" type="flat" entity_type="salesrule" collection="Magento\SalesRule\Model\Resource\Rule\Collection" repository_class="Magento\SalesRule\Test\Repository\SalesRuleInjectable" handler_interface="Magento\SalesRule\Test\Handler\SalesRuleInjectable\SalesRuleInjectableInterface" class="Magento\SalesRule\Test\Fixture\SalesRuleInjectable"> + <fixture name="salesRule" module="Magento_SalesRule" type="flat" entity_type="salesrule" collection="Magento\SalesRule\Model\Resource\Rule\Collection" repository_class="Magento\SalesRule\Test\Repository\SalesRule" handler_interface="Magento\SalesRule\Test\Handler\SalesRule\SalesRuleInterface" class="Magento\SalesRule\Test\Fixture\SalesRule"> <dataset name="default"> <field name="name" xsi:type="string">Default price rule %isolation%</field> <field name="is_active" xsi:type="string">Active</field> @@ -36,7 +36,7 @@ <field name="is_active" group="rule_information"> <default_value xsi:type="string">Active</default_value> </field> - <field name="conditions_serialized" group="conditions" source="Magento\SalesRule\Test\Fixture\SalesRuleInjectable\ConditionsSerialized" /> + <field name="conditions_serialized" group="conditions" source="Magento\SalesRule\Test\Fixture\SalesRule\ConditionsSerialized" /> <field name="actions_serialized" group="actions" /> <field name="stop_rules_processing" group="actions"> <default_value xsi:type="string">1</default_value> diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRuleInjectable/ConditionsSerialized.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRule/ConditionsSerialized.php similarity index 94% rename from dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRuleInjectable/ConditionsSerialized.php rename to dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRule/ConditionsSerialized.php index 4d9c65cff5333e179f7dc06f72f857f5da9baf54..d323abf4b46bd36de6a57e976c5bf1f7c8fa384d 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRuleInjectable/ConditionsSerialized.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Fixture/SalesRule/ConditionsSerialized.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\SalesRule\Test\Fixture\SalesRuleInjectable; +namespace Magento\SalesRule\Test\Fixture\SalesRule; use Magento\Mtf\Fixture\DataSource; diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRuleInjectable/Curl.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/Curl.php similarity index 97% rename from dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRuleInjectable/Curl.php rename to dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/Curl.php index 2543ccdf8197195b9cdbdc2bdb6444ef5903a784..d1c4bdee2f717d441fa26222e1eeea5045072894 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRuleInjectable/Curl.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/Curl.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\SalesRule\Test\Handler\SalesRuleInjectable; +namespace Magento\SalesRule\Test\Handler\SalesRule; use Magento\Backend\Test\Handler\Conditions; use Magento\Mtf\Fixture\FixtureInterface; @@ -15,7 +15,7 @@ use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator; /** * Curl handler for creating sales rule. */ -class Curl extends Conditions implements SalesRuleInjectableInterface +class Curl extends Conditions implements SalesRuleInterface { /** * Map of type parameter. diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRuleInjectable/SalesRuleInjectableInterface.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/SalesRuleInterface.php similarity index 61% rename from dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRuleInjectable/SalesRuleInjectableInterface.php rename to dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/SalesRuleInterface.php index 0a9c2598e8c49b16841c1efd0fda60e4d1d1d248..d638e854cf27339db2118d4ea9c9f5980ce3139b 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRuleInjectable/SalesRuleInjectableInterface.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/SalesRuleInterface.php @@ -4,14 +4,14 @@ * See COPYING.txt for license details. */ -namespace Magento\SalesRule\Test\Handler\SalesRuleInjectable; +namespace Magento\SalesRule\Test\Handler\SalesRule; use Magento\Mtf\Handler\HandlerInterface; /** * Interface SalesRuleInterface. */ -interface SalesRuleInjectableInterface extends HandlerInterface +interface SalesRuleInterface extends HandlerInterface { // } diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRuleInjectable.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml similarity index 99% rename from dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRuleInjectable.xml rename to dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml index 02d81f565a253de17ec04662a14bf162c330b256..897aa57c1bf7ff47a3b61b9d51e4b8782966a8ee 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRuleInjectable.xml +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd"> - <repository class="Magento\SalesRule\Test\Repository\SalesRuleInjectable"> + <repository class="Magento\SalesRule\Test\Repository\SalesRule"> <dataset name="active_sales_rule_with_percent_price_discount_coupon"> <field name="name" xsi:type="string">Shopping Cart Price Rule with Specific Coupon %isolation%</field> <field name="description" xsi:type="string">Description for Cart Price Rule</field> diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php index 24bafea36fbe42b87673f83accf39b5a70ddc666..e82c3e9bcc2c216a1185d1cb3c77f0ac9d5d6124 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php @@ -6,7 +6,7 @@ namespace Magento\SalesRule\Test\TestCase; -use Magento\SalesRule\Test\Fixture\SalesRuleInjectable; +use Magento\SalesRule\Test\Fixture\SalesRule; use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteEdit; use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteIndex; use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteNew; @@ -115,10 +115,10 @@ class CreateSalesRuleEntityTest extends Injectable /** * Create Sales Rule Entity. * - * @param SalesRuleInjectable $salesRule + * @param SalesRule $salesRule * @return void */ - public function testCreateSalesRule(SalesRuleInjectable $salesRule) + public function testCreateSalesRule(SalesRule $salesRule) { // Preconditions $this->salesRuleName = $salesRule->getName(); diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php index 49f3e7655790d8cf6ec4842d2861cc55692e5a72..3dcf7ad8e3a6df646e81ade107440b57c8587887 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php @@ -6,7 +6,7 @@ namespace Magento\SalesRule\Test\TestCase; -use Magento\SalesRule\Test\Fixture\SalesRuleInjectable; +use Magento\SalesRule\Test\Fixture\SalesRule; use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteEdit; use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteIndex; use Magento\Mtf\TestCase\Injectable; @@ -63,10 +63,10 @@ class DeleteSalesRuleEntityTest extends Injectable /** * Delete Sales Rule Entity. * - * @param SalesRuleInjectable $salesRule + * @param SalesRule $salesRule * @return void */ - public function testDeleteSalesRule(SalesRuleInjectable $salesRule) + public function testDeleteSalesRule(SalesRule $salesRule) { // Preconditions $salesRule->persist(); diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php index ed72d923f05b1911611a38244d9f5e2b79c5d669..93e0e862805255e0f86bb8ccd131382acc2c280f 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php @@ -6,7 +6,7 @@ namespace Magento\SalesRule\Test\TestCase; -use Magento\SalesRule\Test\Fixture\SalesRuleInjectable; +use Magento\SalesRule\Test\Fixture\SalesRule; use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteEdit; use Magento\SalesRule\Test\Page\Adminhtml\PromoQuoteIndex; use Magento\Mtf\Fixture\FixtureFactory; @@ -92,13 +92,13 @@ class UpdateSalesRuleEntityTest extends Injectable /** * Update Sales Rule Entity. * - * @param SalesRuleInjectable $salesRule - * @param SalesRuleInjectable $salesRuleOrigin + * @param SalesRule $salesRule + * @param SalesRule $salesRuleOrigin * @return void */ public function testUpdateSalesRule( - SalesRuleInjectable $salesRule, - SalesRuleInjectable $salesRuleOrigin + SalesRule $salesRule, + SalesRule $salesRuleOrigin ) { // Preconditions $salesRuleOrigin->persist(); diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnBackendStep.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnBackendStep.php index 7e193a4d0ab1cc570bbbebad6dedda8c57946c6d..709e2c1644b71675224dc3941c2e4d7a1bc3ff7e 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnBackendStep.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnBackendStep.php @@ -7,7 +7,7 @@ namespace Magento\SalesRule\Test\TestStep; use Magento\Sales\Test\Page\Adminhtml\OrderCreateIndex; -use Magento\SalesRule\Test\Fixture\SalesRuleInjectable; +use Magento\SalesRule\Test\Fixture\SalesRule; use Magento\Mtf\TestStep\TestStepInterface; /** @@ -25,16 +25,16 @@ class ApplySalesRuleOnBackendStep implements TestStepInterface /** * SalesRule fixture. * - * @var SalesRuleInjectable + * @var SalesRule */ protected $salesRule; /** * @constructor * @param OrderCreateIndex $orderCreateIndex - * @param SalesRuleInjectable $salesRule + * @param SalesRule $salesRule */ - public function __construct(OrderCreateIndex $orderCreateIndex, SalesRuleInjectable $salesRule = null) + public function __construct(OrderCreateIndex $orderCreateIndex, SalesRule $salesRule = null) { $this->orderCreateIndex = $orderCreateIndex; $this->salesRule = $salesRule; diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnFrontendStep.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnFrontendStep.php index 6bff54ec11dee9b17a78f52478fff86e8652457d..49fedf0d5d16dd7b214105d42fb4cab24e55aaa8 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnFrontendStep.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/ApplySalesRuleOnFrontendStep.php @@ -7,7 +7,7 @@ namespace Magento\SalesRule\Test\TestStep; use Magento\Checkout\Test\Page\CheckoutCart; -use Magento\SalesRule\Test\Fixture\SalesRuleInjectable; +use Magento\SalesRule\Test\Fixture\SalesRule; use Magento\Mtf\TestStep\TestStepInterface; /** @@ -25,16 +25,16 @@ class ApplySalesRuleOnFrontendStep implements TestStepInterface /** * SalesRule fixture. * - * @var SalesRuleInjectable + * @var SalesRule */ protected $salesRule; /** * @constructor * @param CheckoutCart $checkoutCart - * @param SalesRuleInjectable $salesRule + * @param SalesRule $salesRule */ - public function __construct(CheckoutCart $checkoutCart, SalesRuleInjectable $salesRule = null) + public function __construct(CheckoutCart $checkoutCart, SalesRule $salesRule = null) { $this->checkoutCart = $checkoutCart; $this->salesRule = $salesRule; diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/CreateSalesRuleStep.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/CreateSalesRuleStep.php index c458bed8659ad8e8b3d2d381a1601ecfade3e163..bda908faf26778fa05dfb90b4dac909a3d6d4902 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/CreateSalesRuleStep.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/CreateSalesRuleStep.php @@ -51,7 +51,7 @@ class CreateSalesRuleStep implements TestStepInterface $result['salesRule'] = null; if ($this->salesRule !== null) { $salesRule = $this->fixtureFactory->createByCode( - 'salesRuleInjectable', + 'salesRule', ['dataSet' => $this->salesRule] ); $salesRule->persist(); diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/DeleteAllSalesRuleStep.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/DeleteAllSalesRuleStep.php index 0141a0506fd6e926987234027c894c7462c01245..98bf51e84f7c37fa0c7cf86af5024e0f7ceefe72 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/DeleteAllSalesRuleStep.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestStep/DeleteAllSalesRuleStep.php @@ -50,6 +50,7 @@ class DeleteAllSalesRuleStep implements TestStepInterface public function run() { $this->promoQuoteIndex->open(); + $this->promoQuoteIndex->getPromoQuoteGrid()->resetFilter(); while ($this->promoQuoteIndex->getPromoQuoteGrid()->isFirstRowVisible()) { $this->promoQuoteIndex->getPromoQuoteGrid()->openFirstRow(); $this->promoQuoteEdit->getFormPageActions()->delete(); diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/curl/di.xml index 2591249e9e02850c5123b9c66a0652a7bd5cfa00..3416929d0ab44031cbb7bef4b0d3ac7628cf9139 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/curl/di.xml +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/curl/di.xml @@ -6,5 +6,5 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> - <preference for="Magento\SalesRule\Test\Handler\SalesRuleInjectable\SalesRuleInjectableInterface" type="\Magento\SalesRule\Test\Handler\SalesRuleInjectable\Curl" /> + <preference for="Magento\SalesRule\Test\Handler\SalesRule\SalesRuleInterface" type="\Magento\SalesRule\Test\Handler\SalesRule\Curl" /> </config> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleApplying.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleApplying.php index b5631910c0d44a00f93df89cc540b56734348c1a..51476690a8897b2f9b745dc46fbab9c4a12a1955 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleApplying.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleApplying.php @@ -11,15 +11,12 @@ use Magento\Catalog\Test\Page\Product\CatalogProductView; use Magento\Checkout\Test\Page\CheckoutCart; use Magento\Customer\Test\Fixture\Address; use Magento\Customer\Test\Fixture\Customer; -use Magento\Customer\Test\Page\CustomerAccountLogin; -use Magento\Customer\Test\Page\CustomerAccountLogout; use Magento\Tax\Test\Fixture\TaxRule; use Magento\Mtf\Client\BrowserInterface; use Magento\Mtf\Constraint\AbstractConstraint; use Magento\Mtf\Fixture\FixtureFactory; /** - * Class AssertTaxRuleApplying * Abstract class for implementing assert applying */ abstract class AssertTaxRuleApplying extends AbstractConstraint @@ -82,8 +79,6 @@ abstract class AssertTaxRuleApplying extends AbstractConstraint * * @param FixtureFactory $fixtureFactory * @param TaxRule $taxRule - * @param CustomerAccountLogin $customerAccountLogin - * @param CustomerAccountLogout $customerAccountLogout * @param Customer $customer * @param CatalogProductView $catalogProductView * @param CheckoutCart $checkoutCart @@ -92,14 +87,10 @@ abstract class AssertTaxRuleApplying extends AbstractConstraint * @param BrowserInterface $browser * @param TaxRule $initialTaxRule * @return void - * - * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function processAssert( FixtureFactory $fixtureFactory, TaxRule $taxRule, - CustomerAccountLogin $customerAccountLogin, - CustomerAccountLogout $customerAccountLogout, Customer $customer, CatalogProductView $catalogProductView, CheckoutCart $checkoutCart, @@ -134,9 +125,10 @@ abstract class AssertTaxRuleApplying extends AbstractConstraint ); $this->productSimple->persist(); // Customer login - $customerAccountLogout->open(); - $customerAccountLogin->open(); - $customerAccountLogin->getLoginBlock()->login($customer); + $this->objectManager->create( + 'Magento\Customer\Test\TestStep\LoginCustomerOnFrontendStep', + ['customer' => $customer] + )->run(); // Clearing shopping cart and adding product to shopping cart $checkoutCart->open()->getCartBlock()->clearShoppingCart(); $browser->open($_ENV['app_frontend_url'] . $this->productSimple->getUrlKey() . '.html'); diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ddfd3ab0508cc3a90986eada1db016a526ba921e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php @@ -0,0 +1,75 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Tax\Test\TestCase; + +use Magento\Mtf\TestCase\Scenario; +use Magento\Mtf\ObjectManager; + +/** + * Steps: + * 1. Log in as default admin user. + * 2. Go to Stores > Taxes > Tax Rules. + * 3. Click 'Add New Tax Rule' button. + * 4. Assign default rates to rule. + * 5. Save Tax Rate. + * 6. Go to Products > Catalog. + * 7. Add new product. + * 8. Fill data according to dataset. + * 9. Save product. + * 10. Go to Stores > Configuration. + * 11. Fill Tax configuration according to data set. + * 12. Save tax configuration. + * 13. Perform all assertions. + * + * @group Tax_(CS) + * @ZephyrId MAGETWO-27809 + */ +class TaxCalculationTest extends Scenario +{ + /* tags */ + const MVP = 'yes'; + const DOMAIN = 'CS'; + /* end tags */ + + /** + * Skip failed tests. + * + * @return void + */ + public static function setUpBeforeClass() + { + self::markTestIncomplete("Epic: MAGETWO-30073"); + } + + /** + * Runs tax calculation test. + * + * @return void + */ + public function test() + { + $this->executeScenario(); + } + + /** + * Tear down after each test. + * + * @return void + */ + public function tearDown() + { + $this->objectManager->create('\Magento\Tax\Test\TestStep\DeleteAllTaxRulesStep')->run(); + $this->objectManager->create('\Magento\SalesRule\Test\TestStep\DeleteAllSalesRuleStep')->run(); + $this->objectManager->create('\Magento\CatalogRule\Test\TestStep\DeleteAllCatalogRulesStep')->run(); + + // TODO: Move set default configuration to "tearDownAfterClass" method after fix bug MAGETWO-29331 + $this->objectManager->create( + 'Magento\Config\Test\TestStep\SetupConfigurationStep', + ['configData' => 'default_tax_configuration'] + )->run(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..9891afcdf2d0fa727302f3c047f08bea83beb05f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml @@ -0,0 +1,301 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> + <testCase name="Magento\Tax\Test\TestCase\TaxCalculationTest"> + <variation name="TaxCalculationTestVariation1"> + <data name="description" xsi:type="string">Simple product tier price with sales rule, customer tax equals store tax and catalog price including tax</data> + <data name="configData" xsi:type="string">row_cat_incl_ship_excl_after_disc_on_excl, display_excluding_including_tax</data> + <data name="product" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_category</data> + <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data> + <data name="catalogRule" xsi:type="string">-</data> + <data name="taxRule" xsi:type="string">customer_equals_store_rate</data> + <data name="customer/dataSet" xsi:type="string">johndoe_unique</data> + <data name="qty" xsi:type="string">3</data> + <data name="prices/category_price_excl_tax" xsi:type="string">277.14</data> + <data name="prices/category_price_incl_tax" xsi:type="string">300.00</data> + <data name="prices/product_view_price_excl_tax" xsi:type="string">277.14</data> + <data name="prices/product_view_price_incl_tax" xsi:type="string">300.00</data> + <data name="prices/cart_item_price_excl_tax" xsi:type="string">13.86</data> + <data name="prices/cart_item_price_incl_tax" xsi:type="string">15.00</data> + <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">41.57</data> + <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">45.00</data> + <data name="prices/subtotal_excl_tax" xsi:type="string">41.57</data> + <data name="prices/subtotal_incl_tax" xsi:type="string">45.00</data> + <data name="prices/discount" xsi:type="string">20.79</data> + <data name="prices/shipping_excl_tax" xsi:type="string">15.00</data> + <data name="prices/shipping_incl_tax" xsi:type="string">16.24</data> + <data name="prices/tax" xsi:type="string">3.09</data> + <data name="prices/grand_total_excl_tax" xsi:type="string">37.36</data> + <data name="prices/grand_total_incl_tax" xsi:type="string">40.45</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> + </variation> + <variation name="TaxCalculationTestVariation2"> + <data name="description" xsi:type="string">Simple product group price with sales rule, customer tax greater than store tax and catalog price excluding tax</data> + <data name="configData" xsi:type="string">row_cat_excl_ship_incl_before_disc_on_incl, display_excluding_including_tax</data> + <data name="product" xsi:type="string">catalogProductSimple::simple_with_group_price_and_category</data> + <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data> + <data name="catalogRule" xsi:type="string">-</data> + <data name="taxRule" xsi:type="string">customer_greater_store_rate</data> + <data name="customer/dataSet" xsi:type="string">johndoe_unique</data> + <data name="qty" xsi:type="string">3</data> + <data name="prices/category_price_excl_tax" xsi:type="string">90.99</data> + <data name="prices/category_price_incl_tax" xsi:type="string">98.61</data> + <data name="prices/product_view_price_excl_tax" xsi:type="string">90.99</data> + <data name="prices/product_view_price_incl_tax" xsi:type="string">98.61</data> + <data name="prices/cart_item_price_excl_tax" xsi:type="string">90.99</data> + <data name="prices/cart_item_price_incl_tax" xsi:type="string">98.61</data> + <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">272.97</data> + <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">295.83</data> + <data name="prices/subtotal_excl_tax" xsi:type="string">272.97</data> + <data name="prices/subtotal_incl_tax" xsi:type="string">295.83</data> + <data name="prices/discount" xsi:type="string">147.92</data> + <data name="prices/shipping_excl_tax" xsi:type="string">13.86</data> + <data name="prices/shipping_incl_tax" xsi:type="string">15.02</data> + <data name="prices/tax" xsi:type="string">24.02</data> + <data name="prices/grand_total_excl_tax" xsi:type="string">138.91</data> + <data name="prices/grand_total_incl_tax" xsi:type="string">162.93</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> + </variation> + <variation name="TaxCalculationTestVariation3"> + <data name="description" xsi:type="string">Simple product group price with sales rule, customer tax less than store tax and catalog price excluding tax</data> + <data name="configData" xsi:type="string">total_cat_excl_ship_incl_after_disc_on_excl, display_excluding_including_tax</data> + <data name="product" xsi:type="string">catalogProductSimple::simple_with_group_price_and_category</data> + <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data> + <data name="catalogRule" xsi:type="string">-</data> + <data name="taxRule" xsi:type="string">customer_less_store_rate</data> + <data name="customer/dataSet" xsi:type="string">johndoe_unique</data> + <data name="qty" xsi:type="string">3</data> + <data name="prices/category_price_excl_tax" xsi:type="string">90.99</data> + <data name="prices/category_price_incl_tax" xsi:type="string">98.50</data> + <data name="prices/product_view_price_excl_tax" xsi:type="string">90.99</data> + <data name="prices/product_view_price_incl_tax" xsi:type="string">98.50</data> + <data name="prices/cart_item_price_excl_tax" xsi:type="string">90.99</data> + <data name="prices/cart_item_price_incl_tax" xsi:type="string">98.50</data> + <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">272.97</data> + <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">295.49</data> + <data name="prices/subtotal_excl_tax" xsi:type="string">272.97</data> + <data name="prices/subtotal_incl_tax" xsi:type="string">295.49</data> + <data name="prices/discount" xsi:type="string">136.49</data> + <data name="prices/shipping_excl_tax" xsi:type="string">13.84</data> + <data name="prices/shipping_incl_tax" xsi:type="string">14.98</data> + <data name="prices/tax" xsi:type="string">12.40</data> + <data name="prices/grand_total_excl_tax" xsi:type="string">150.32</data> + <data name="prices/grand_total_incl_tax" xsi:type="string">162.72</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> + </variation> + <variation name="TaxCalculationTestVariation4"> + <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax less than store tax and catalog price including tax</data> + <data name="configData" xsi:type="string">row_cat_incl_ship_excl_before_disc_on_incl, display_excluding_including_tax</data> + <data name="product" xsi:type="string">catalogProductSimple::product_with_special_price_and_category</data> + <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data> + <data name="catalogRule" xsi:type="string">-</data> + <data name="taxRule" xsi:type="string">customer_less_store_rate</data> + <data name="customer/dataSet" xsi:type="string">johndoe_unique</data> + <data name="qty" xsi:type="string">3</data> + <data name="prices/category_price_excl_tax" xsi:type="string">83.05</data> + <data name="prices/category_price_incl_tax" xsi:type="string">89.90</data> + <data name="prices/product_view_price_excl_tax" xsi:type="string">83.05</data> + <data name="prices/product_view_price_incl_tax" xsi:type="string">89.90</data> + <data name="prices/cart_item_price_excl_tax" xsi:type="string">83.05</data> + <data name="prices/cart_item_price_incl_tax" xsi:type="string">89.90</data> + <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">249.15</data> + <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">269.70</data> + <data name="prices/subtotal_excl_tax" xsi:type="string">249.15</data> + <data name="prices/subtotal_incl_tax" xsi:type="string">269.70</data> + <data name="prices/discount" xsi:type="string">134.85</data> + <data name="prices/shipping_excl_tax" xsi:type="string">15.00</data> + <data name="prices/shipping_incl_tax" xsi:type="string">16.24</data> + <data name="prices/tax" xsi:type="string">21.79</data> + <data name="prices/grand_total_excl_tax" xsi:type="string">129.30</data> + <data name="prices/grand_total_incl_tax" xsi:type="string">151.09</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> + </variation> + <variation name="TaxCalculationTestVariation5"> + <data name="description" xsi:type="string">Simple product tier price with sales rule, customer tax less than store tax and catalog price including tax</data> + <data name="configData" xsi:type="string">unit_cat_incl_ship_incl_before_disc_on_incl, display_excluding_including_tax</data> + <data name="product" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_category</data> + <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data> + <data name="catalogRule" xsi:type="string">-</data> + <data name="taxRule" xsi:type="string">customer_less_store_rate</data> + <data name="customer/dataSet" xsi:type="string">johndoe_unique</data> + <data name="qty" xsi:type="string">3</data> + <data name="prices/category_price_excl_tax" xsi:type="string">276.81</data> + <data name="prices/category_price_incl_tax" xsi:type="string">299.65</data> + <data name="prices/product_view_price_excl_tax" xsi:type="string">276.81</data> + <data name="prices/product_view_price_incl_tax" xsi:type="string">299.65</data> + <data name="prices/cart_item_price_excl_tax" xsi:type="string">13.84</data> + <data name="prices/cart_item_price_incl_tax" xsi:type="string">14.98</data> + <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">41.52</data> + <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">44.94</data> + <data name="prices/subtotal_excl_tax" xsi:type="string">41.52</data> + <data name="prices/subtotal_incl_tax" xsi:type="string">44.94</data> + <data name="prices/discount" xsi:type="string">22.47</data> + <data name="prices/shipping_excl_tax" xsi:type="string">13.84</data> + <data name="prices/shipping_incl_tax" xsi:type="string">14.98</data> + <data name="prices/tax" xsi:type="string">4.56</data> + <data name="prices/grand_total_excl_tax" xsi:type="string">32.89</data> + <data name="prices/grand_total_incl_tax" xsi:type="string">37.45</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> + </variation> + <variation name="TaxCalculationTestVariation6"> + <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax equals store tax and catalog price excluding tax</data> + <data name="configData" xsi:type="string">total_cat_excl_ship_incl_before_disc_on_incl, display_excluding_including_tax</data> + <data name="product" xsi:type="string">catalogProductSimple::product_with_special_price_and_category</data> + <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data> + <data name="catalogRule" xsi:type="string">-</data> + <data name="taxRule" xsi:type="string">customer_equals_store_rate</data> + <data name="customer/dataSet" xsi:type="string">johndoe_unique</data> + <data name="qty" xsi:type="string">3</data> + <data name="prices/category_price_excl_tax" xsi:type="string">90.00</data> + <data name="prices/category_price_incl_tax" xsi:type="string">97.43</data> + <data name="prices/product_view_price_excl_tax" xsi:type="string">90.00</data> + <data name="prices/product_view_price_incl_tax" xsi:type="string">97.43</data> + <data name="prices/cart_item_price_excl_tax" xsi:type="string">90.00</data> + <data name="prices/cart_item_price_incl_tax" xsi:type="string">97.43</data> + <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">270.00</data> + <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">292.28</data> + <data name="prices/subtotal_excl_tax" xsi:type="string">270.00</data> + <data name="prices/subtotal_incl_tax" xsi:type="string">292.28</data> + <data name="prices/discount" xsi:type="string">146.15</data> + <data name="prices/shipping_excl_tax" xsi:type="string">13.86</data> + <data name="prices/shipping_incl_tax" xsi:type="string">15.00</data> + <data name="prices/tax" xsi:type="string">23.42</data> + <data name="prices/grand_total_excl_tax" xsi:type="string">137.71</data> + <data name="prices/grand_total_incl_tax" xsi:type="string">161.13</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> + </variation> + <variation name="TaxCalculationTestVariation7"> + <data name="description" xsi:type="string">Simple product group price with sales rule, customer tax equals store tax and catalog price excluding tax</data> + <data name="configData" xsi:type="string">unit_cat_excl_ship_excl_after_disc_on_excl, display_excluding_including_tax</data> + <data name="product" xsi:type="string">catalogProductSimple::simple_with_group_price_and_category</data> + <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data> + <data name="catalogRule" xsi:type="string">-</data> + <data name="taxRule" xsi:type="string">customer_equals_store_rate</data> + <data name="customer/dataSet" xsi:type="string">johndoe_unique</data> + <data name="qty" xsi:type="string">3</data> + <data name="prices/category_price_excl_tax" xsi:type="string">90.99</data> + <data name="prices/category_price_incl_tax" xsi:type="string">98.50</data> + <data name="prices/product_view_price_excl_tax" xsi:type="string">90.99</data> + <data name="prices/product_view_price_incl_tax" xsi:type="string">98.50</data> + <data name="prices/cart_item_price_excl_tax" xsi:type="string">90.99</data> + <data name="prices/cart_item_price_incl_tax" xsi:type="string">98.50</data> + <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">272.97</data> + <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">295.50</data> + <data name="prices/subtotal_excl_tax" xsi:type="string">272.97</data> + <data name="prices/subtotal_incl_tax" xsi:type="string">295.50</data> + <data name="prices/discount" xsi:type="string">136.49</data> + <data name="prices/shipping_excl_tax" xsi:type="string">15.00</data> + <data name="prices/shipping_incl_tax" xsi:type="string">16.24</data> + <data name="prices/tax" xsi:type="string">12.49</data> + <data name="prices/grand_total_excl_tax" xsi:type="string">151.48</data> + <data name="prices/grand_total_incl_tax" xsi:type="string">163.97</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> + </variation> + <variation name="TaxCalculationTestVariation8"> + <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax greater than store tax and catalog price including tax</data> + <data name="configData" xsi:type="string">total_cat_incl_ship_excl_before_disc_on_excl, display_excluding_including_tax</data> + <data name="product" xsi:type="string">catalogProductSimple::simple_with_group_price_and_category</data> + <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data> + <data name="catalogRule" xsi:type="string">-</data> + <data name="taxRule" xsi:type="string">customer_greater_store_rate</data> + <data name="customer/dataSet" xsi:type="string">johndoe_unique</data> + <data name="qty" xsi:type="string">3</data> + <data name="prices/category_price_excl_tax" xsi:type="string">84.06</data> + <data name="prices/category_price_incl_tax" xsi:type="string">91.10</data> + <data name="prices/product_view_price_excl_tax" xsi:type="string">84.06</data> + <data name="prices/product_view_price_incl_tax" xsi:type="string">91.10</data> + <data name="prices/cart_item_price_excl_tax" xsi:type="string">84.06</data> + <data name="prices/cart_item_price_incl_tax" xsi:type="string">91.10</data> + <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">252.18</data> + <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">273.30</data> + <data name="prices/subtotal_excl_tax" xsi:type="string">252.18</data> + <data name="prices/subtotal_incl_tax" xsi:type="string">273.30</data> + <data name="prices/discount" xsi:type="string">126.09</data> + <data name="prices/shipping_excl_tax" xsi:type="string">15.00</data> + <data name="prices/shipping_incl_tax" xsi:type="string">16.26</data> + <data name="prices/tax" xsi:type="string">22.38</data> + <data name="prices/grand_total_excl_tax" xsi:type="string">141.09</data> + <data name="prices/grand_total_incl_tax" xsi:type="string">163.47</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> + </variation> + <variation name="TaxCalculationTestVariation9"> + <data name="description" xsi:type="string">Simple product tier price with sales rule, customer tax greater than store tax and catalog price excluding tax</data> + <data name="configData" xsi:type="string">total_cat_excl_ship_incl_after_disc_on_incl, display_excluding_including_tax</data> + <data name="product" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_category</data> + <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data> + <data name="catalogRule" xsi:type="string">-</data> + <data name="taxRule" xsi:type="string">customer_greater_store_rate</data> + <data name="customer/dataSet" xsi:type="string">johndoe_unique</data> + <data name="qty" xsi:type="string">3</data> + <data name="prices/category_price_excl_tax" xsi:type="string">300.00</data> + <data name="prices/category_price_incl_tax" xsi:type="string">325.13</data> + <data name="prices/product_view_price_excl_tax" xsi:type="string">300.00</data> + <data name="prices/product_view_price_incl_tax" xsi:type="string">325.13</data> + <data name="prices/cart_item_price_excl_tax" xsi:type="string">15.00</data> + <data name="prices/cart_item_price_incl_tax" xsi:type="string">16.26</data> + <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">45.00</data> + <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">48.77</data> + <data name="prices/subtotal_excl_tax" xsi:type="string">45.00</data> + <data name="prices/subtotal_incl_tax" xsi:type="string">48.77</data> + <data name="prices/discount" xsi:type="string">24.39</data> + <data name="prices/shipping_excl_tax" xsi:type="string">13.86</data> + <data name="prices/shipping_incl_tax" xsi:type="string">15.02</data> + <data name="prices/tax" xsi:type="string">2.89</data> + <data name="prices/grand_total_excl_tax" xsi:type="string">34.47</data> + <data name="prices/grand_total_incl_tax" xsi:type="string">37.36</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> + </variation> + <variation name="TaxCalculationTestVariation10"> + <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax greater than store tax and catalog price excluding tax</data> + <data name="configData" xsi:type="string">unit_cat_excl_ship_incl_after_disc_on_excl, display_excluding_including_tax</data> + <data name="product" xsi:type="string">catalogProductSimple::product_with_special_price_and_category</data> + <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data> + <data name="catalogRule" xsi:type="string">-</data> + <data name="taxRule" xsi:type="string">customer_greater_store_rate</data> + <data name="customer/dataSet" xsi:type="string">johndoe_unique</data> + <data name="qty" xsi:type="string">3</data> + <data name="prices/category_price_excl_tax" xsi:type="string">90.00</data> + <data name="prices/category_price_incl_tax" xsi:type="string">97.54</data> + <data name="prices/product_view_price_excl_tax" xsi:type="string">90.00</data> + <data name="prices/product_view_price_incl_tax" xsi:type="string">97.54</data> + <data name="prices/cart_item_price_excl_tax" xsi:type="string">90.00</data> + <data name="prices/cart_item_price_incl_tax" xsi:type="string">97.54</data> + <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">270.00</data> + <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">292.62</data> + <data name="prices/subtotal_excl_tax" xsi:type="string">270.00</data> + <data name="prices/subtotal_incl_tax" xsi:type="string">292.62</data> + <data name="prices/discount" xsi:type="string">135.00</data> + <data name="prices/shipping_excl_tax" xsi:type="string">13.86</data> + <data name="prices/shipping_incl_tax" xsi:type="string">15.02</data> + <data name="prices/tax" xsi:type="string">12.47</data> + <data name="prices/grand_total_excl_tax" xsi:type="string">148.86</data> + <data name="prices/grand_total_incl_tax" xsi:type="string">161.33</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxCalculationAfterCheckoutExcludingIncludingTax" /> + <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b67edd7a4c1787025b0b0b45b126f3c3996427e4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php @@ -0,0 +1,160 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Tax\Test\TestCase; + +use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\CatalogRule\Test\Fixture\CatalogRule; +use Magento\Customer\Test\Fixture\Customer; +use Magento\SalesRule\Test\Fixture\SalesRule; +use Magento\Mtf\Fixture\FixtureFactory; +use Magento\Mtf\TestCase\Injectable; + +/** + * Steps: + * 1. Log in as default admin user. + * 2. Go to Stores > Taxes > Tax Rules. + * 3. Click 'Add New Tax Rule' button. + * 4. Assign 3 different rates for different addresses + * 5. Save Tax Rate. + * 6. Go to Products > Catalog. + * 7. Add new product. + * 8. Fill data according to dataset. + * 9. Save product. + * 10. Go to Stores > Configuration. + * 11. Fill Tax configuration according to data set. + * 12. Save tax configuration. + * 13. Register two customers on front end that will match two different rates + * 14. Login with each customer and verify prices + * + * @group Tax_(CS) + * @ZephyrId MAGETWO-29052 + */ +class TaxWithCrossBorderTest extends Injectable +{ + /* tags */ + const MVP = 'yes'; + const DOMAIN = 'CS'; + /* end tags */ + + /** + * Fixture SalesRule. + * + * @var SalesRule + */ + protected $salesRule; + + /** + * Fixture CatalogRule. + * + * @var CatalogRule + */ + protected $catalogRule; + + /** + * Fixture factory. + * + * @var FixtureFactory + */ + protected $fixtureFactory; + + /** + * Prepare data. + * + * @param FixtureFactory $fixtureFactory + * @return array + */ + public function __prepare(FixtureFactory $fixtureFactory) + { + $this->fixtureFactory = $fixtureFactory; + + return ['customers' => $this->createCustomers()]; + } + + /** + * Injection data. + * + * @return void + */ + public function __inject() + { + // TODO: Move test set up to "__prepare" method after fix bug MAGETWO-29331 + $taxRule = $this->fixtureFactory->createByCode('taxRule', ['dataSet' => 'cross_border_tax_rule']); + $taxRule->persist(); + } + + /** + * Create customers. + * + * @return array $customers + */ + protected function createCustomers() + { + $customersData = ['johndoe_unique_TX', 'johndoe_unique']; + $customers = []; + foreach ($customersData as $customerData) { + $customer = $this->fixtureFactory->createByCode('customer', ['dataSet' => $customerData]); + $customer->persist(); + $customers[] = $customer; + } + return $customers; + } + + /** + * Test product prices with tax. + * + * @param CatalogProductSimple $product + * @param string $configData + * @param SalesRule $salesRule [optional] + * @param CatalogRule $catalogRule [optional] + * @return void + */ + public function test( + CatalogProductSimple $product, + $configData, + SalesRule $salesRule = null, + CatalogRule $catalogRule = null + ) { + //Preconditions + if ($salesRule !== null) { + $salesRule->persist(); + $this->salesRule = $salesRule; + } + if ($catalogRule !== null) { + $catalogRule->persist(); + $this->catalogRule = $catalogRule; + } + $this->objectManager->create( + 'Magento\Config\Test\TestStep\SetupConfigurationStep', + ['configData' => $configData] + )->run(); + $product->persist(); + } + + /** + * Tear down after test. + * + * @return void + */ + public function tearDown() + { + if (isset($this->salesRule)) { + $this->objectManager->create('Magento\SalesRule\Test\TestStep\DeleteAllSalesRuleStep')->run(); + $this->salesRule = null; + } + if (isset($this->catalogRule)) { + $this->objectManager->create('\Magento\CatalogRule\Test\TestStep\DeleteAllCatalogRulesStep')->run(); + $this->catalogRule = null; + } + + // TODO: Move set default configuration to "tearDownAfterClass" method after fix bug MAGETWO-29331 + $this->objectManager->create('Magento\Tax\Test\TestStep\DeleteAllTaxRulesStep')->run(); + $this->objectManager->create( + 'Magento\Config\Test\TestStep\SetupConfigurationStep', + ['configData' => 'default_tax_configuration'] + )->run(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..82218491cf409382415251e998b235429a4364c5 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> + <testCase name="Magento\Tax\Test\TestCase\TaxWithCrossBorderTest"> + <variation name="TaxWithCrossBorderTestVariation1"> + <data name="product/dataSet" xsi:type="string">with_one_custom_option_and_category</data> + <data name="configData" xsi:type="string">cross_border_enabled_price_incl_tax, display_excluding_including_tax</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxWithCrossBorderApplied" /> + </variation> + <variation name="TaxWithCrossBorderTestVariation2"> + <data name="product/dataSet" xsi:type="string">product_with_category</data> + <data name="salesRule/dataSet" xsi:type="string">cart_rule</data> + <data name="configData" xsi:type="string">cross_border_enabled_price_incl_tax, display_excluding_including_tax</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxWithCrossBorderApplied" /> + </variation> + <variation name="TaxWithCrossBorderTestVariation3"> + <data name="product/dataSet" xsi:type="string">product_with_category</data> + <data name="catalogRule/dataSet" xsi:type="string">catalog_price_rule_priority_0</data> + <data name="configData" xsi:type="string">cross_border_enabled_price_incl_tax, display_excluding_including_tax</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxWithCrossBorderApplied" /> + </variation> + <variation name="TaxWithCrossBorderTestVariation4"> + <data name="product/dataSet" xsi:type="string">product_with_special_price_and_category</data> + <data name="configData" xsi:type="string">cross_border_enabled_price_incl_tax, display_excluding_including_tax</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxWithCrossBorderApplied" /> + </variation> + <variation name="TaxWithCrossBorderTestVariation5"> + <data name="product/dataSet" xsi:type="string">product_with_category</data> + <data name="configData" xsi:type="string">cross_border_enabled_price_excl_tax, display_excluding_including_tax</data> + <constraint name="Magento\Tax\Test\Constraint\AssertTaxWithCrossBorderNotApplied" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestStep/DeleteAllTaxRulesStep.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestStep/DeleteAllTaxRulesStep.php index 69b0cb8e48754397a8a3d56873fcc721f7e6269a..d24b2ca4c4de8cd5cb362704b3c78c2ad4905fb4 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestStep/DeleteAllTaxRulesStep.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestStep/DeleteAllTaxRulesStep.php @@ -51,6 +51,7 @@ class DeleteAllTaxRulesStep implements TestStepInterface public function run() { $this->taxRuleIndexPage->open(); + $this->taxRuleIndexPage->getTaxRuleGrid()->resetFilter(); while ($this->taxRuleIndexPage->getTaxRuleGrid()->isFirstRowVisible()) { $this->taxRuleIndexPage->getTaxRuleGrid()->openFirstRow(); $this->taxRuleNewPage->getFormPageActions()->delete(); diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/testcase.xml new file mode 100644 index 0000000000000000000000000000000000000000..c47afe1a6a889a0df215473b24539396e0ff8b77 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/testcase.xml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/TestCase/etc/testcase.xsd"> + <scenario name="TaxCalculationTest" firstStep="setupConfiguration"> + <step name="setupConfiguration" module="Magento_Config" next="createSalesRule" /> + <step name="createSalesRule" module="Magento_SalesRule" next="createCatalogRule" /> + <step name="createCatalogRule" module="Magento_CatalogRule" next="createTaxRule" /> + <step name="createTaxRule" module="Magento_Tax" next="createProduct" /> + <step name="createProduct" module="Magento_Catalog" next="createCustomer" /> + <step name="createCustomer" module="Magento_Customer" next="loginCustomerOnFrontend" /> + <step name="loginCustomerOnFrontend" module="Magento_Customer" /> + </scenario> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Ups/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Ups/Test/Repository/ConfigData.xml index 5351224a4f52e4bc04b92617f30d0190b5963fb3..f6c7bd8341526c7fa4e6f48a79f020fb5830b2b8 100644 --- a/dev/tests/functional/tests/app/Magento/Ups/Test/Repository/ConfigData.xml +++ b/dev/tests/functional/tests/app/Magento/Ups/Test/Repository/ConfigData.xml @@ -1,4 +1,4 @@ -<?xml version="1.0"?> +<?xml version="1.0" ?> <!-- /** * Copyright © 2015 Magento. All rights reserved. diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Adminhtml/Edit/CustomerForm.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Adminhtml/Edit/CustomerForm.xml index c00338cd02750df3c73fca736d49307814d8e286..d6a8abbf78b151df64f7fee7e5dcd34d1674c15a 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Adminhtml/Edit/CustomerForm.xml +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Adminhtml/Edit/CustomerForm.xml @@ -8,7 +8,7 @@ <tabs> <wishlist> <class>\Magento\Wishlist\Test\Block\Adminhtml\Customer\Edit\Tab\Wishlist</class> - <selector>#tab_wishlist</selector> + <selector>#tab_block_wishlist</selector> <strategy>css selector</strategy> </wishlist> </tabs> diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml index 1cf13be71e2cd00324fbc5303d2a6bd31230fa33..d88f6d3054641ffa76b70d4b5593bcd59f3aede1 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml @@ -27,7 +27,7 @@ <constraint name="Magento\Wishlist\Test\Constraint\AssertWishlistIsEmpty" /> </variation> <variation name="AddProductsToCartFromCustomerWishlistOnFrontendTestVariation4"> - <data name="products" xsi:type="string">groupedProduct::three_simple_products_default_qty</data> + <data name="products" xsi:type="string">groupedProduct::three_simple_products</data> <data name="qty" xsi:type="string">-</data> <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductsIsAbsentInWishlist" /> diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php index cce7949f993f63e0312573a558e50510fee1fc84..2b96619bcae14f8186d73bd61782a213238bd33e 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php @@ -11,34 +11,26 @@ use Magento\Catalog\Test\Page\Product\CatalogProductView; use Magento\Cms\Test\Page\CmsIndex; use Magento\Customer\Test\Fixture\Customer; use Magento\Customer\Test\Page\CustomerAccountIndex; -use Magento\Customer\Test\Page\CustomerAccountLogin; -use Magento\Customer\Test\Page\CustomerAccountLogout; use Magento\Wishlist\Test\Page\WishlistIndex; use Magento\Wishlist\Test\Page\WishlistShare; use Magento\Mtf\Client\BrowserInterface; use Magento\Mtf\TestCase\Injectable; /** - * Test Creation for ShareWishlistEntity - * - * Test Flow: - * * Preconditions: - * 1. Create Customer Account - * 2. Create product + * 1. Create Customer Account. + * 2. Create product. * * Steps: - * 1. Login to frontend as a Customer - * 2. Add product to Wish List - * 3. Click "Share Wish List" button - * 4. Fill in all data according to data set - * 5. Click "Share Wishlist" button - * 6. Perform all assertions + * 1. Login to frontend as a Customer. + * 2. Add product to Wish List. + * 3. Click "Share Wish List" button. + * 4. Fill in all data according to data set. + * 5. Click "Share Wishlist" button. + * 6. Perform all assertions. * * @group Wishlist_(CS) * @ZephyrId MAGETWO-23394 - * - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ShareWishlistEntityTest extends Injectable { @@ -49,56 +41,42 @@ class ShareWishlistEntityTest extends Injectable /* end tags */ /** - * Cms index page + * Cms index page. * * @var CmsIndex */ protected $cmsIndex; /** - * Customer login page - * - * @var CustomerAccountLogin - */ - protected $customerAccountLogin; - - /** - * Customer account index page + * Customer account index page. * * @var CustomerAccountIndex */ protected $customerAccountIndex; /** - * Product view page + * Product view page. * * @var CatalogProductView */ protected $catalogProductView; /** - * Page CustomerAccountLogout - * - * @var CustomerAccountLogout - */ - protected $customerAccountLogout; - - /** - * Wishlist index page + * Wishlist index page. * * @var WishlistIndex */ protected $wishlistIndex; /** - * Wishlist share page + * Wishlist share page. * * @var WishlistShare */ protected $wishlistShare; /** - * Prepare data + * Prepare data. * * @param Customer $customer * @param CatalogProductSimple $product @@ -118,12 +96,10 @@ class ShareWishlistEntityTest extends Injectable } /** - * Injection data + * Inject pages. * * @param CmsIndex $cmsIndex - * @param CustomerAccountLogin $customerAccountLogin * @param CustomerAccountIndex $customerAccountIndex - * @param CustomerAccountLogout $customerAccountLogout * @param CatalogProductView $catalogProductView * @param WishlistIndex $wishlistIndex * @param WishlistShare $wishlistShare @@ -131,24 +107,20 @@ class ShareWishlistEntityTest extends Injectable */ public function __inject( CmsIndex $cmsIndex, - CustomerAccountLogin $customerAccountLogin, CustomerAccountIndex $customerAccountIndex, - CustomerAccountLogout $customerAccountLogout, CatalogProductView $catalogProductView, WishlistIndex $wishlistIndex, WishlistShare $wishlistShare ) { $this->cmsIndex = $cmsIndex; - $this->customerAccountLogin = $customerAccountLogin; $this->customerAccountIndex = $customerAccountIndex; - $this->customerAccountLogout = $customerAccountLogout; $this->catalogProductView = $catalogProductView; $this->wishlistIndex = $wishlistIndex; $this->wishlistShare = $wishlistShare; } /** - * Share wish list + * Share wish list. * * @param BrowserInterface $browser * @param Customer $customer @@ -174,27 +146,16 @@ class ShareWishlistEntityTest extends Injectable } /** - * Login customer + * Login customer. * * @param Customer $customer * @return void */ protected function loginCustomer(Customer $customer) { - $this->cmsIndex->open(); - if (!$this->cmsIndex->getLinksBlock()->isLinkVisible('Log Out')) { - $this->cmsIndex->getLinksBlock()->openLink("Log In"); - $this->customerAccountLogin->getLoginBlock()->login($customer); - } - } - - /** - * Log out after test - * - * @return void - */ - public function tearDown() - { - $this->customerAccountLogout->open(); + $this->objectManager->create( + 'Magento\Customer\Test\TestStep\LoginCustomerOnFrontendStep', + ['customer' => $customer] + )->run(); } } diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.xml index 59dccc42d293c1a3a1259565da59e9408c390de5..8dd654cf89bbd1065185ba2a345c5fe44f3cf65f 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.xml @@ -6,11 +6,11 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> - <testCase name="Magento\Wishlist\Test\TestCase\ShareWishlistEntityTest"> - <variation name="ShareWishlistEntityTestVariation1"> - <data name="sharingInfo/emails" xsi:type="string">JohnDoe123456789@example.com,JohnDoe987654321@example.com,JohnDoe123456abc@example.com</data> - <data name="sharingInfo/message" xsi:type="string">Sharing message.</data> - <constraint name="Magento\Wishlist\Test\Constraint\AssertWishlistShareMessage"/> - </variation> - </testCase> + <testCase name="Magento\Wishlist\Test\TestCase\ShareWishlistEntityTest"> + <variation name="ShareWishlistEntityTestVariation1"> + <data name="sharingInfo/emails" xsi:type="string">JohnDoe123456789@example.com,JohnDoe987654321@example.com,JohnDoe123456abc@example.com</data> + <data name="sharingInfo/message" xsi:type="string">Sharing message.</data> + <constraint name="Magento\Wishlist\Test\Constraint\AssertWishlistShareMessage" /> + </variation> + </testCase> </config> diff --git a/dev/tests/functional/utils/config/ee_modules.yml.dist b/dev/tests/functional/utils/config/ee_modules.yml.dist deleted file mode 100644 index 33bd56450a7a26ceb8241a97495dbc1c23675c6e..0000000000000000000000000000000000000000 --- a/dev/tests/functional/utils/config/ee_modules.yml.dist +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright © 2015 Magento. All rights reserved. -# See COPYING.txt for license details. -- Magento_Backend -- Magento_Catalog -- Magento_Customer \ No newline at end of file diff --git a/dev/tests/functional/utils/config/generator_config.yml.dist b/dev/tests/functional/utils/config/generator_config.yml.dist deleted file mode 100644 index 14dffd2306b796de983017366d6b6b26e2f863e9..0000000000000000000000000000000000000000 --- a/dev/tests/functional/utils/config/generator_config.yml.dist +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright © 2015 Magento. All rights reserved. -# See COPYING.txt for license details. -# Generator running options, in case "generate_specified_modules" is set to "yes" then specified file is used -generate_specified_modules: no -specified_modules: dev\tests\functional\utils\config\ee_modules.yml.dist - -# Fallback path configurations -tests_fallback: - 1: - path: tests/app - -# Handler priority configuration -handler_fallback: - 1: Curl - 2: Direct - 3: Ui \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php index b3c578e46cfa26069c1c93c07ac1b15bc3ea59e7..da3a723a0db759702ecd505510159f614a9b5105 100755 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php @@ -102,7 +102,7 @@ class IndexTest extends \Magento\Backend\Utility\Controller public function testSaveActionWithInvalidCustomerAddressData() { $post = [ - 'account' => [ + 'customer' => [ 'middlename' => 'test middlename', 'group_id' => 1, 'website_id' => 0, @@ -110,8 +110,8 @@ class IndexTest extends \Magento\Backend\Utility\Controller 'lastname' => 'test lastname', 'email' => 'example@domain.com', 'default_billing' => '_item1', - 'customer_address' => ['_item1' => []], ], + 'address' => ['_item1' => []], ]; $this->getRequest()->setPostValue($post); $this->dispatch('backend/customer/index/save'); @@ -141,7 +141,7 @@ class IndexTest extends \Magento\Backend\Utility\Controller $objectManager = Bootstrap::getObjectManager(); $post = [ - 'account' => [ + 'customer' => [ 'middlename' => 'test middlename', 'group_id' => 1, 'website_id' => 0, @@ -150,17 +150,17 @@ class IndexTest extends \Magento\Backend\Utility\Controller 'email' => 'example@domain.com', 'default_billing' => '_item1', 'password' => 'password', - 'customer_address' => [ - '_item1' => [ - 'firstname' => 'test firstname', - 'lastname' => 'test lastname', - 'street' => ['test street'], - 'city' => 'test city', - 'country_id' => 'US', - 'postcode' => '01001', - 'telephone' => '+7000000001', - 'default_billing' => 'true', - ], + ], + 'address' => [ + '_item1' => [ + 'firstname' => 'test firstname', + 'lastname' => 'test lastname', + 'street' => ['test street'], + 'city' => 'test city', + 'country_id' => 'US', + 'postcode' => '01001', + 'telephone' => '+7000000001', + 'default_billing' => 'true', ], ], ]; @@ -218,8 +218,8 @@ class IndexTest extends \Magento\Backend\Utility\Controller public function testSaveActionExistingCustomerAndExistingAddressData() { $post = [ - 'customer_id' => '1', - 'account' => [ + 'customer' => [ + 'entity_id' => '1', 'middlename' => 'test middlename', 'group_id' => 1, 'website_id' => 1, @@ -232,39 +232,38 @@ class IndexTest extends \Magento\Backend\Utility\Controller 'created_at' => '2000-01-01 00:00:00', 'default_shipping' => '_item1', 'default_billing' => 1, - 'customer_address' => [ - '1' => [ - 'firstname' => 'update firstname', - 'lastname' => 'update lastname', - 'street' => ['update street'], - 'city' => 'update city', - 'country_id' => 'US', - 'postcode' => '01001', - 'telephone' => '+7000000001', - 'default_billing' => 'true', - ], - '_item1' => [ - 'firstname' => 'new firstname', - 'lastname' => 'new lastname', - 'street' => ['new street'], - 'city' => 'new city', - 'country_id' => 'US', - 'postcode' => '01001', - 'telephone' => '+7000000001', - 'default_shipping' => 'true', - ], - '_template_' => [ - 'firstname' => '', - 'lastname' => '', - 'street' => [], - 'city' => '', - 'country_id' => 'US', - 'postcode' => '', - 'telephone' => '', - ], + ], + 'address' => [ + '1' => [ + 'firstname' => 'update firstname', + 'lastname' => 'update lastname', + 'street' => ['update street'], + 'city' => 'update city', + 'country_id' => 'US', + 'postcode' => '01001', + 'telephone' => '+7000000001', + 'default_billing' => 'true', + ], + '_item1' => [ + 'firstname' => 'new firstname', + 'lastname' => 'new lastname', + 'street' => ['new street'], + 'city' => 'new city', + 'country_id' => 'US', + 'postcode' => '01001', + 'telephone' => '+7000000001', + 'default_shipping' => 'true', + ], + '_template_' => [ + 'firstname' => '', + 'lastname' => '', + 'street' => [], + 'city' => '', + 'country_id' => 'US', + 'postcode' => '', + 'telephone' => '', ], ], - 'subscription' => '', ]; $this->getRequest()->setPostValue($post); @@ -330,7 +329,7 @@ class IndexTest extends \Magento\Backend\Utility\Controller $this->assertEquals(1, $subscriber->getStatus()); $post = [ - 'customer_id' => $customerId, + 'customer' => ['entity_id' => $customerId], ]; $this->getRequest()->setPostValue($post); $this->getRequest()->setParam('id', 1); @@ -360,7 +359,7 @@ class IndexTest extends \Magento\Backend\Utility\Controller public function testSaveActionCoreException() { $post = [ - 'account' => [ + 'customer' => [ 'middlename' => 'test middlename', 'group_id' => 1, 'website_id' => 1, @@ -477,7 +476,7 @@ class IndexTest extends \Magento\Backend\Utility\Controller { $customerData = [ 'customer_id' => 0, - 'account' => [ + 'customer' => [ 'created_in' => false, 'disable_auto_group_change' => false, 'email' => false, @@ -887,8 +886,8 @@ class IndexTest extends \Magento\Backend\Utility\Controller public function testValidateCustomerWithAddressSuccess() { $customerData = [ - 'id' => '1', - 'account' => [ + 'customer' => [ + 'entity_id' => '1', 'middlename' => 'new middlename', 'group_id' => 1, 'website_id' => 1, @@ -943,8 +942,8 @@ class IndexTest extends \Magento\Backend\Utility\Controller public function testValidateCustomerWithAddressFailure() { $customerData = [ - 'id' => '1', - 'account' => [ + 'customer' => [ + 'entity_id' => '1', 'middlename' => 'new middlename', 'group_id' => 1, 'website_id' => 1, @@ -955,30 +954,30 @@ class IndexTest extends \Magento\Backend\Utility\Controller 'new_password' => 'auto', 'sendemail_store_id' => '1', 'sendemail' => '1', - 'customer_address' => [ - '1' => [ - 'firstname' => '', - 'lastname' => '', - 'street' => ['update street'], - 'city' => 'update city', - 'postcode' => '01001', - 'telephone' => '', - ], - '_template_' => [ - 'lastname' => '', - 'street' => [], - 'city' => '', - 'country_id' => 'US', - 'postcode' => '', - 'telephone' => '', - ], + ], + 'address' => [ + '1' => [ + 'firstname' => '', + 'lastname' => '', + 'street' => ['update street'], + 'city' => 'update city', + 'postcode' => '01001', + 'telephone' => '', + ], + '_template_' => [ + 'lastname' => '', + 'street' => [], + 'city' => '', + 'country_id' => 'US', + 'postcode' => '', + 'telephone' => '', ], ], ]; /** * set customer data */ - $this->getRequest()->setParams($customerData); + $this->getRequest()->setPostValue($customerData); $this->dispatch('backend/customer/index/validate'); $body = $this->getResponse()->getBody(); diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/StoreTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/StoreTest.php index 8fbdd0f346d4b0c410bd35387dd45564504b61f8..a84b46c3c2981e420d24a251db6a0b46cc332eee 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/StoreTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/StoreTest.php @@ -451,7 +451,8 @@ class StoreTest extends \PHPUnit_Framework_TestCase [true, ['HTTPS' => 'on']], [true, ['SSL_OFFLOADED' => 'https']], [true, ['HTTP_SSL_OFFLOADED' => 'https']], - [true, ['SERVER_PORT' => 80]], + [true, ['HTTPS' => 'on', 'SERVER_PORT' => 80]], + [false, ['SERVER_PORT' => 80]], [false, []], ]; } diff --git a/dev/tests/integration/testsuite/Magento/ToolkitFramework/_files/small.xml b/dev/tests/integration/testsuite/Magento/ToolkitFramework/_files/small.xml index 4c0292a8c2f0d5fd009882546a65c9258892e66c..911f2482ebcec61f1d6bf914463511ffd1252359 100644 --- a/dev/tests/integration/testsuite/Magento/ToolkitFramework/_files/small.xml +++ b/dev/tests/integration/testsuite/Magento/ToolkitFramework/_files/small.xml @@ -61,7 +61,7 @@ <value>0</value> </config> <config> - <path>system/full_page_cache/varnish/access_lis</path> + <path>system/full_page_cache/varnish/access_list</path> <scope>default</scope> <scopeId>0</scopeId> <value>localhost</value> diff --git a/dev/tests/js/jasmine/assets/apply/templates/node.html b/dev/tests/js/jasmine/assets/apply/templates/node.html index 3c6895d98c381b7d64f7210dd5b83b5e04235255..f694083783e00922b7faa63eecb5155251cc0f5a 100644 --- a/dev/tests/js/jasmine/assets/apply/templates/node.html +++ b/dev/tests/js/jasmine/assets/apply/templates/node.html @@ -5,6 +5,6 @@ */ --> <div id="<%= containerId %>"> - <div id="<%= nodeId %>" + <div id="<%= nodeId %>"> <%= dataAttr %>='<%= JSON.stringify(nodeData) %>'></div> </div> \ No newline at end of file diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js new file mode 100644 index 0000000000000000000000000000000000000000..0d68a9dcfa145676d90bd99803fe11ece671d5b0 --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js @@ -0,0 +1,150 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'underscore', + 'Magento_Ui/js/grid/columns/multiselect' +], function (_, Multiselect) { + 'use strict'; + + describe('ui/js/grid/columns/multiselect', function () { + var multiSelect; + + beforeEach(function () { + multiSelect = new Multiselect({ + rows: [], + index: 'index', + name: 'name', + indexField: 'id', + dataScope: 'scope', + provider: 'provider' + }); + multiSelect.source = { + set: function () {} + }; + spyOn(multiSelect.source, 'set'); + }); + + afterEach(function () { + }); + + it('Default state - Select no rows', function () { + multiSelect.rows.push({id:1}); + multiSelect.rows.push({id:2}); + multiSelect.rows.push({id:3}); + + expect(multiSelect.allSelected()).toBeFalsy(); + expect(multiSelect.excluded()).toEqual([]); + expect(multiSelect.selected()).toEqual([]); + multiSelect.exportSelections(); + //expect(multiSelect.source.set).toHaveBeenCalledWith([]); + expect(multiSelect.source.set.calls.argsFor(1)) + .toEqual([]); + }); + + it('Select specific several rows on several pages', function () { + multiSelect.selected.push(4); + multiSelect.selected.push(5); + + expect(multiSelect.allSelected()).toBeFalsy(); + expect(multiSelect.excluded()).toEqual([]); + expect(multiSelect.selected()).toEqual([4,5]); + }); + + it('Select all rows on several pages', function () { + multiSelect.rows([ + {id:1}, + {id:2} + ]); + multiSelect.selectPage(); + multiSelect.rows([ + {id:3}, + {id:4} + ]); + multiSelect.selectPage(); + + expect(multiSelect.allSelected()).toBeFalsy(); + expect(multiSelect.excluded()).toEqual([]); + expect(multiSelect.selected()).toEqual([1,2,3,4]); + }); + + it('Select all rows on current page with some specific rows on another page', function () { + multiSelect.rows([ + {id:1}, + {id:2} + ]); + multiSelect.rows([ + {id:3}, + {id:4} + ]); + multiSelect.selectPage(); + multiSelect.rows([ + {id:5}, + {id:6} + ]); + multiSelect.selected.push(6); + + expect(multiSelect.allSelected()).toBeFalsy(); + expect(multiSelect.excluded()).toEqual([]); + expect(multiSelect.selected()).toEqual([3,4,6]); + }); + + it('Select all rows on several pages without some specific rows', function () { + multiSelect.rows([ + {id:1}, + {id:2} + ]); + multiSelect.rows([ + {id:3}, + {id:4} + ]); + multiSelect.selectPage(); + multiSelect.selected.remove(4); // remove second + + expect(multiSelect.allSelected()).toBeFalsy(); + expect(multiSelect.excluded()).toEqual([]); + expect(multiSelect.selected()).toEqual([3]); + }); + + it('Select all rows all over the Grid', function () { + multiSelect.rows([ + {id:1}, + {id:2} + ]); + multiSelect.selectAll(); + multiSelect.rows([ + {id:3}, + {id:4} + ]); + + expect(multiSelect.allSelected()).toBeFalsy(); + expect(multiSelect.excluded()).toEqual([]); + expect(multiSelect.selected()).toEqual([1,2]); + }); + + it('Select all rows all over the Grid without all rows on current page but with specific rows on another page', function () { + multiSelect.rows([ + {id:1}, + {id:2} + ]); + multiSelect.rows([ + {id:3}, + {id:4} + ]); + multiSelect.selectAll(); + multiSelect.deselectPage(); + multiSelect.rows([ + {id:5}, + {id:6} + ]); + multiSelect.selected.push(6); + + expect(multiSelect.allSelected()).toBeFalsy(); + expect(multiSelect.excluded()).toEqual([]); + expect(multiSelect.selected()).toEqual([6]); + }); + + }); +}); \ No newline at end of file diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/columns.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/columns.test.js new file mode 100644 index 0000000000000000000000000000000000000000..e01b4eb1d22910908e2540a6e8b71a7a4dad7414 --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/columns.test.js @@ -0,0 +1,64 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'underscore', + 'Magento_Ui/js/grid/controls/columns' +], function (_, Columns) { + 'use strict'; + + describe('ui/js/grid/controls/columns', function () { + var columnsInstance, + FakeElement; + + beforeEach(function () { + columnsInstance = new Columns({ + elems: [], + index: 'index', + name: 'name', + indexField: 'id', + dataScope: 'scope', + provider: 'provider' + }); + FakeElement = function(){ + return this; + }; + FakeElement.prototype.visible = function(){ + return true; + }; + }); + + it('hasOverflow method', function () { + columnsInstance.viewportSize = 2; + columnsInstance.elems.push({id:1}); + columnsInstance.elems.push({id:2}); + + expect(columnsInstance.hasOverflow()).toBeFalsy(); + + columnsInstance.elems.push({id:3}); + expect(columnsInstance.hasOverflow()).toBeTruthy(); + }); + + it('isDisabled method', function () { + columnsInstance.viewportMaxSize = 4; + columnsInstance.elems.push(new FakeElement()); + expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeTruthy(); + + columnsInstance.elems.push(new FakeElement()); + expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeFalsy(); + + columnsInstance.elems.push(new FakeElement()); + expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeFalsy(); + + columnsInstance.elems.push(new FakeElement()); + expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeFalsy(); + + columnsInstance.elems.push(new FakeElement()); + expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeTruthy(); + expect(columnsInstance.isDisabled(columnsInstance.elems()[3])).toBeTruthy(); + }); + + }); +}); \ No newline at end of file diff --git a/dev/tools/Magento/Tools/I18n/Pack/Generator.php b/dev/tools/Magento/Tools/I18n/Pack/Generator.php index fce8d3d556b94dd830e63641ebd09fc5b61ac2f2..bc257a637ace6c67ebb2fe1575e88915bc7ea9fa 100644 --- a/dev/tools/Magento/Tools/I18n/Pack/Generator.php +++ b/dev/tools/Magento/Tools/I18n/Pack/Generator.php @@ -100,7 +100,7 @@ class Generator /** @var \Magento\Tools\I18n\Dictionary\Phrase $phrase */ $phrase = $phrases[0]; $error .= sprintf( - "The phrase \"%s\" is translated differently in %d places.\n", + "The phrase \"%s\" is translated in %d places.\n", $phrase->getPhrase(), count($phrases) ); diff --git a/dev/tools/Magento/Tools/I18n/Test/Unit/Pack/GeneratorTest.php b/dev/tools/Magento/Tools/I18n/Test/Unit/Pack/GeneratorTest.php index e5a4f9bd2442c606aafa7c058e372d0922a43af7..4ca23c946a99bd976d17deee464cf886ffe5ff8c 100644 --- a/dev/tools/Magento/Tools/I18n/Test/Unit/Pack/GeneratorTest.php +++ b/dev/tools/Magento/Tools/I18n/Test/Unit/Pack/GeneratorTest.php @@ -110,8 +110,8 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase public function testGenerateWithNotAllowedDuplicatesAndDuplicatesExist() { $error = "Duplicated translation is found, but it is not allowed.\n" - . "The phrase \"phrase1\" is translated differently in 1 places.\n" - . "The phrase \"phrase2\" is translated differently in 1 places.\n"; + . "The phrase \"phrase1\" is translated in 1 places.\n" + . "The phrase \"phrase2\" is translated in 1 places.\n"; $this->setExpectedException('\RuntimeException', $error); $allowDuplicates = false; diff --git a/dev/tools/performance-toolkit/fixtures/cart_price_rules.php b/dev/tools/performance-toolkit/fixtures/cart_price_rules.php index 8bb9287c3fa521d3a2560a32d8fab920ef1c9abb..93a95e98c9f8c0dea21fa21426549d27f5a2d0ab 100644 --- a/dev/tools/performance-toolkit/fixtures/cart_price_rules.php +++ b/dev/tools/performance-toolkit/fixtures/cart_price_rules.php @@ -20,7 +20,10 @@ class CartPriceRulesFixture extends \Magento\ToolkitFramework\Fixture public function execute() { $this->application->resetObjectManager(); - $cartPriceRulesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('cart_price_rules', 9); + $cartPriceRulesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('cart_price_rules', 0); + if (!$cartPriceRulesCount) { + return; + } $cartPriceRulesProductsFloor = \Magento\ToolkitFramework\Config::getInstance()->getValue( 'cart_price_rules_floor', 3 diff --git a/dev/tools/performance-toolkit/fixtures/catalog_price_rules.php b/dev/tools/performance-toolkit/fixtures/catalog_price_rules.php index 8956c18ecaacee3caf98b1ba25c49b47ff6e338a..8ccf546687232358a9dff1a053c2c4e496314953 100644 --- a/dev/tools/performance-toolkit/fixtures/catalog_price_rules.php +++ b/dev/tools/performance-toolkit/fixtures/catalog_price_rules.php @@ -19,7 +19,10 @@ class CatalogPriceRulesFixture extends \Magento\ToolkitFramework\Fixture */ public function execute() { - $catalogPriceRulesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('catalog_price_rules', 3); + $catalogPriceRulesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('catalog_price_rules', 0); + if (!$catalogPriceRulesCount) { + return; + } $this->application->resetObjectManager(); /** @var \Magento\Store\Model\StoreManager $storeManager */ diff --git a/dev/tools/performance-toolkit/fixtures/categories.php b/dev/tools/performance-toolkit/fixtures/categories.php index b6bc39d83f34ad25bb0d25fd3619741549aa57fc..75b2444ff38d4ff279d7a8f4f517058f669fdf20 100644 --- a/dev/tools/performance-toolkit/fixtures/categories.php +++ b/dev/tools/performance-toolkit/fixtures/categories.php @@ -19,7 +19,10 @@ class CategoriesFixture extends \Magento\ToolkitFramework\Fixture */ public function execute() { - $categoriesNumber = \Magento\ToolkitFramework\Config::getInstance()->getValue('categories', 18); + $categoriesNumber = \Magento\ToolkitFramework\Config::getInstance()->getValue('categories', 0); + if (!$categoriesNumber) { + return; + } $maxNestingLevel = \Magento\ToolkitFramework\Config::getInstance()->getValue('categories_nesting_level', 3); $this->application->resetObjectManager(); diff --git a/dev/tools/performance-toolkit/fixtures/configs_apply.php b/dev/tools/performance-toolkit/fixtures/configs_apply.php index 99c62d1233a11370c69f1c49a2781cb18a265544..0317935fa3bd895085435defe78d68eb4140f066 100644 --- a/dev/tools/performance-toolkit/fixtures/configs_apply.php +++ b/dev/tools/performance-toolkit/fixtures/configs_apply.php @@ -20,6 +20,9 @@ class ConfigsApplyFixture extends \Magento\ToolkitFramework\Fixture public function execute() { $configs = \Magento\ToolkitFramework\Config::getInstance()->getValue('configs', array()); + if (empty($configs)) { + return; + } $this->application->resetObjectManager(); foreach ($configs['config'] as $config) { diff --git a/dev/tools/performance-toolkit/fixtures/configurable_products.php b/dev/tools/performance-toolkit/fixtures/configurable_products.php index a3aa8f8ba8d244eba56a8ca2e184be05f7cdbbce..4184c3c49ea9e5bca14cfa73f534de2a7efbb7a0 100644 --- a/dev/tools/performance-toolkit/fixtures/configurable_products.php +++ b/dev/tools/performance-toolkit/fixtures/configurable_products.php @@ -820,7 +820,10 @@ class ConfigurableProductsFixture extends \Magento\ToolkitFramework\Fixture */ public function execute() { - $configurablesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('configurable_products', 90); + $configurablesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('configurable_products', 0); + if (!$configurablesCount) { + return; + } $this->application->resetObjectManager(); /** @var \Magento\Store\Model\StoreManager $storeManager */ diff --git a/dev/tools/performance-toolkit/fixtures/customers.php b/dev/tools/performance-toolkit/fixtures/customers.php index df42bc283a2211b50db2b6a0b2c27dad1a0f095c..9a11fb93ac9ed3268b90499a72db32d78be495f3 100644 --- a/dev/tools/performance-toolkit/fixtures/customers.php +++ b/dev/tools/performance-toolkit/fixtures/customers.php @@ -19,7 +19,10 @@ class CustomersFixture extends \Magento\ToolkitFramework\Fixture */ public function execute() { - $customersNumber = \Magento\ToolkitFramework\Config::getInstance()->getValue('customers', 10); + $customersNumber = \Magento\ToolkitFramework\Config::getInstance()->getValue('customers', 0); + if (!$customersNumber) { + return; + } $this->application->resetObjectManager(); /** @var \Magento\Store\Model\StoreManager $storeManager */ diff --git a/dev/tools/performance-toolkit/fixtures/eav_variations.php b/dev/tools/performance-toolkit/fixtures/eav_variations.php index 2d2fbc89517432b2f96afbb19655fc0c425742a4..5587ab258b6a050324bb2f957dbcdedc24a6e236 100644 --- a/dev/tools/performance-toolkit/fixtures/eav_variations.php +++ b/dev/tools/performance-toolkit/fixtures/eav_variations.php @@ -21,6 +21,10 @@ class EavVariationsFixture extends \Magento\ToolkitFramework\Fixture */ public function execute() { + $configurablesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('configurable_products', 0); + if (!$configurablesCount) { + return; + } $this->application->resetObjectManager(); /* @var $model \Magento\Catalog\Model\Resource\Eav\Attribute */ diff --git a/dev/tools/performance-toolkit/fixtures/orders.php b/dev/tools/performance-toolkit/fixtures/orders.php new file mode 100644 index 0000000000000000000000000000000000000000..041fcea755125f106f7715913c5bfe13b1dff926 --- /dev/null +++ b/dev/tools/performance-toolkit/fixtures/orders.php @@ -0,0 +1,314 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +/** + * Class OrdersFixture + */ +class OrdersFixture extends \Magento\ToolkitFramework\Fixture +{ + /** + * @var int + */ + protected $priority = 135; + + /** + * {@inheritdoc} + */ + public function execute() + { + $ordersCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('orders', 0); + if ($ordersCount < 1) { + return; + } + $this->application->resetObjectManager(); + + $writeAdapter = $this->getConnection('write'); + + $quoteTableName = $this->getTableName( + 'quote', + 'Magento\Quote\Model\Resource\Quote' + ); + $quoteAddressTableName = $this->getTableName( + 'quote_address', + 'Magento\Quote\Model\Resource\Quote\Address' + ); + $quoteItemTableName = $this->getTableName( + 'quote_item', + 'Magento\Quote\Model\Resource\Quote\Item' + ); + $quoteItemOptionTableName = $this->getTableName( + 'quote_item_option', + 'Magento\Quote\Model\Resource\Quote\Item\Option' + ); + $quotePaymentTableName = $this->getTableName( + 'quote_payment', + 'Magento\Quote\Model\Resource\Quote\Payment' + ); + $quoteAddressRateTableName = $this->getTableName( + 'quote_shipping_rate', + 'Magento\Quote\Model\Resource\Quote\Address\Rate' + ); + $reportEventTableName = $this->getTableName( + 'report_event', + 'Magento\Reports\Model\Resource\Event' + ); + $salesOrderTableName = $this->getTableName( + 'sales_order', + 'Magento\Sales\Model\Resource\Order' + ); + $salesOrderAddressTableName = $this->getTableName( + 'sales_order_address', + 'Magento\Sales\Model\Resource\Order' + ); + $salesOrderGridTableName = $this->getTableName( + 'sales_order_grid', + 'Magento\Sales\Model\Resource\Order\Grid' + ); + $salesOrderItemTableName = $this->getTableName( + 'sales_order_item', + 'Magento\Sales\Model\Resource\Order\Item' + ); + $salesOrderPaymentTableName = $this->getTableName( + 'sales_order_payment', + 'Magento\Sales\Model\Resource\Order\Payment' + ); + $salesOrderStatusHistoryTableName = $this->getTableName( + 'sales_order_status_history', + 'Magento\Sales\Model\Resource\Order\Status\History' + ); + $eavEntityStoreTableName = $this->getTableName( + 'eav_entity_store', + '\Magento\Eav\Model\Resource\Entity\Store' + ); + /** @var \Magento\Store\Model\StoreManager $storeManager */ + $storeManager = $this->application->getObjectManager()->create('Magento\Store\Model\StoreManager'); + /** @var $category \Magento\Catalog\Model\Category */ + $category = $this->application->getObjectManager()->get('Magento\Catalog\Model\Category'); + /** @var $product \Magento\Catalog\Model\Product */ + $product = $this->application->getObjectManager()->get('Magento\Catalog\Model\Product'); + + $result = []; + $stores = $storeManager->getStores(); + foreach ($stores as $store) { + $storeId = $store->getStoreId(); + $websiteId = $store->getWebsite()->getId(); + $websiteName = $store->getWebsite()->getName(); + $groupName = $store->getGroup()->getName(); + $storeName = $store->getName(); + $storeRootCategory = $store->getRootCategoryId(); + $category->load($storeRootCategory); + $categoryResource = $category->getResource(); + //Get all categories + $resultsCategories = $categoryResource->getAllChildren($category); + foreach ($resultsCategories as $resultsCategory) { + $category->load($resultsCategory); + $structure = explode('/', $category->getPath()); + $pathSize = count($structure); + if ($pathSize > 1) { + $path = []; + for ($i = 1; $i < $pathSize; $i++) { + $path[] = $category->load($structure[$i])->getName(); + } + array_shift($path); + $resultsCategoryName = implode('/', $path); + } else { + $resultsCategoryName = $category->getName(); + } + //Not use root categories + if (trim($resultsCategoryName) != '') { + /** @var $productCategory \Magento\Catalog\Model\Category */ + $productCategory = $this->application->getObjectManager()->get('Magento\Catalog\Model\Category'); + + /** @var $simpleProductCollection \Magento\Catalog\Model\Resource\Product\Collection */ + $simpleProductCollection = $this->application->getObjectManager()->create( + 'Magento\Catalog\Model\Resource\Product\Collection' + ); + + $simpleProductCollection->addStoreFilter($storeId); + $simpleProductCollection->addWebsiteFilter($websiteId); + $simpleProductCollection->addCategoryFilter($productCategory->load($resultsCategory)); + $simpleProductCollection->getSelect()->where(" type_id = 'simple' "); + $simpleIds = $simpleProductCollection->getAllIds(2); + $simpleProductsResult = []; + foreach ($simpleIds as $key => $simpleId) { + $simpleProduct = $product->load($simpleId); + $simpleProductsResult[$key]['simpleProductId'] = $simpleId; + $simpleProductsResult[$key]['simpleProductSku'] = $simpleProduct->getSku(); + $simpleProductsResult[$key]['simpleProductName'] = $simpleProduct->getName(); + } + + $result[] = [ + $storeId, + $websiteName. '\n'. $groupName . '\n' . $storeName, + $simpleProductsResult + ]; + } + } + } + + $productStoreId = function ($index) use ($result) { + return $result[$index % count($result)][0]; + }; + $productStoreName = function ($index) use ($result) { + return $result[$index % count($result)][1]; + }; + + $simpleProductId[0] = function ($index) use ($result) { + return $result[$index % count($result)][2][0]['simpleProductId']; + }; + $simpleProductId[1] = function ($index) use ($result) { + return $result[$index % count($result)][2][1]['simpleProductId']; + }; + $simpleProductSku[0] = function ($index) use ($result) { + return $result[$index % count($result)][2][0]['simpleProductSku']; + }; + $simpleProductSku[1] = function ($index) use ($result) { + return $result[$index % count($result)][2][1]['simpleProductSku']; + }; + $simpleProductName[0] = function ($index) use ($result) { + return $result[$index % count($result)][2][0]['simpleProductName']; + }; + $simpleProductName[1] = function ($index) use ($result) { + return $result[$index % count($result)][2][1]['simpleProductName']; + }; + + $entityId = 1; + while ($entityId <= $ordersCount) { + $queries = ""; + + $orderNumber = 100000000 * $productStoreId($entityId) + $entityId; + $email = 'order_' . $entityId . '@example.com'; + $firstName = 'First Name'; + $lastName = 'Last Name'; + $company = 'Company'; + $address = 'Address'; + $city = 'City'; + $state = 'Alabama'; + $country = 'US'; + $zip = '11111'; + $phone = '911'; + $time = date("Y-m-d h:i:s"); + + $simpleProductIdLen[0] = strlen($simpleProductId[0]($entityId)); + $simpleProductIdLen[1] = strlen($simpleProductId[1]($entityId)); + + $queries .= "INSERT INTO `{$eavEntityStoreTableName}` (`entity_store_id`, `entity_type_id`, `store_id`, `increment_prefix`, `increment_last_id`) VALUES ({$productStoreId($entityId)}, 5, {$productStoreId($entityId)}, '{$productStoreId($entityId)}', '{$orderNumber}') ON DUPLICATE KEY UPDATE `increment_last_id`='{$orderNumber}';"; + + $quoteId = $entityId; + $queries .= "INSERT INTO `{$quoteTableName}` (`entity_id`, `store_id`, `created_at`, `updated_at`, `converted_at`, `is_active`, `is_virtual`, `is_multi_shipping`, `items_count`, `items_qty`, `orig_order_id`, `store_to_base_rate`, `store_to_quote_rate`, `base_currency_code`, `store_currency_code`, `quote_currency_code`, `grand_total`, `base_grand_total`, `checkout_method`, `customer_id`, `customer_tax_class_id`, `customer_group_id`, `customer_email`, `customer_prefix`, `customer_firstname`, `customer_middlename`, `customer_lastname`, `customer_suffix`, `customer_dob`, `customer_note`, `customer_note_notify`, `customer_is_guest`, `remote_ip`, `applied_rule_ids`, `reserved_order_id`, `password_hash`, `coupon_code`, `global_currency_code`, `base_to_global_rate`, `base_to_quote_rate`, `customer_taxvat`, `customer_gender`, `subtotal`, `base_subtotal`, `subtotal_with_discount`, `base_subtotal_with_discount`, `is_changed`, `trigger_recollect`, `ext_shipping_info`, `is_persistent`, `gift_message_id`) VALUES ({$quoteId}, {$productStoreId($entityId)}, '{$time}', '1970-01-01 03:00:00', NULL, 0, 0, 0, 2, 2.0000, 0, 0.0000, 0.0000, 'USD', 'USD', 'USD', 25.3000, 25.3000, 'guest', NULL, 3, 0, '{$email}', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, 1, '127.0.0.1', '1', NULL, NULL, NULL, 'USD', 1.0000, 1.0000, NULL, NULL, 17.0000, 17.0000, 15.3000, 15.3000, 1, 0, NULL, 0, NULL);"; + + $quoteAddressId[0] = $entityId * 2 - 1; + $quoteAddressId[1] = $entityId * 2; + $queries .= "INSERT INTO `{$quoteAddressTableName}` (`address_id`, `quote_id`, `created_at`, `updated_at`, `customer_id`, `save_in_address_book`, `customer_address_id`, `address_type`, `email`, `prefix`, `firstname`, `middlename`, `lastname`, `suffix`, `company`, `street`, `city`, `region`, `region_id`, `postcode`, `country_id`, `telephone`, `fax`, `same_as_billing`, `collect_shipping_rates`, `shipping_method`, `shipping_description`, `weight`, `subtotal`, `base_subtotal`, `subtotal_with_discount`, `base_subtotal_with_discount`, `tax_amount`, `base_tax_amount`, `shipping_amount`, `base_shipping_amount`, `shipping_tax_amount`, `base_shipping_tax_amount`, `discount_amount`, `base_discount_amount`, `grand_total`, `base_grand_total`, `customer_notes`, `applied_taxes`, `discount_description`, `shipping_discount_amount`, `base_shipping_discount_amount`, `subtotal_incl_tax`, `base_subtotal_total_incl_tax`, `hidden_tax_amount`, `base_hidden_tax_amount`, `shipping_hidden_tax_amount`, `base_shipping_hidden_tax_amnt`, `shipping_incl_tax`, `base_shipping_incl_tax`, `free_shipping`, `vat_id`, `vat_is_valid`, `vat_request_id`, `vat_request_date`, `vat_request_success`, `gift_message_id`) VALUES ({$quoteAddressId[0]}, {$quoteId}, '{$time}', '1970-01-01 03:00:00', NULL, 1, NULL, 'billing', '{$email}', NULL, '{$firstName}', NULL, '{$lastName}', NULL, '{$company}', '{$address}', '{$city}', '{$state}', 1, '{$zip}', '{$country}', '{$phone}', NULL, 0, 0, NULL, NULL, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, NULL, NULL, 0.0000, 0.0000, 0.0000, 0.0000, NULL, NULL, NULL, NULL, NULL, 0.0000, NULL, 0.0000, 0.0000, 0.0000, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);"; + $queries .= "INSERT INTO `{$quoteAddressTableName}` (`address_id`, `quote_id`, `created_at`, `updated_at`, `customer_id`, `save_in_address_book`, `customer_address_id`, `address_type`, `email`, `prefix`, `firstname`, `middlename`, `lastname`, `suffix`, `company`, `street`, `city`, `region`, `region_id`, `postcode`, `country_id`, `telephone`, `fax`, `same_as_billing`, `collect_shipping_rates`, `shipping_method`, `shipping_description`, `weight`, `subtotal`, `base_subtotal`, `subtotal_with_discount`, `base_subtotal_with_discount`, `tax_amount`, `base_tax_amount`, `shipping_amount`, `base_shipping_amount`, `shipping_tax_amount`, `base_shipping_tax_amount`, `discount_amount`, `base_discount_amount`, `grand_total`, `base_grand_total`, `customer_notes`, `applied_taxes`, `discount_description`, `shipping_discount_amount`, `base_shipping_discount_amount`, `subtotal_incl_tax`, `base_subtotal_total_incl_tax`, `hidden_tax_amount`, `base_hidden_tax_amount`, `shipping_hidden_tax_amount`, `base_shipping_hidden_tax_amnt`, `shipping_incl_tax`, `base_shipping_incl_tax`, `free_shipping`, `vat_id`, `vat_is_valid`, `vat_request_id`, `vat_request_date`, `vat_request_success`, `gift_message_id`) VALUES ({$quoteAddressId[1]}, {$quoteId}, '{$time}', '1970-01-01 03:00:00', NULL, 0, NULL, 'shipping', '{$email}', NULL, '{$firstName}', NULL, '{$lastName}', NULL, '{$company}', '{$address}', '{$city}', '{$state}', 1, '{$zip}', '{$country}', '{$phone}', NULL, 1, 0, 'flatrate_flatrate', 'Flat Rate - Fixed', 2.0000, 17.0000, 17.0000, 0.0000, 0.0000, 0.0000, 0.0000, 10.0000, 10.0000, 0.0000, 0.0000, -1.7000, -1.7000, 25.3000, 25.3000, NULL, 'a:0:{}', NULL, 0.0000, 0.0000, 17.0000, NULL, 0.0000, 0.0000, 0.0000, NULL, 10.0000, 10.0000, 0, NULL, NULL, NULL, NULL, NULL, NULL);"; + + $quoteItemId[0] = $entityId * 4 - 3; + $quoteItemId[1] = $entityId * 4 - 2; + $quoteItemId[2] = $entityId * 4 - 1; + $quoteItemId[3] = $entityId * 4; + $queries .= "INSERT INTO `{$quoteItemTableName}` (`item_id`, `quote_id`, `created_at`, `updated_at`, `product_id`, `store_id`, `parent_item_id`, `is_virtual`, `sku`, `name`, `description`, `applied_rule_ids`, `additional_data`, `is_qty_decimal`, `no_discount`, `weight`, `qty`, `price`, `base_price`, `custom_price`, `discount_percent`, `discount_amount`, `base_discount_amount`, `tax_percent`, `tax_amount`, `base_tax_amount`, `row_total`, `base_row_total`, `row_total_with_discount`, `row_weight`, `product_type`, `base_tax_before_discount`, `tax_before_discount`, `original_custom_price`, `redirect_url`, `base_cost`, `price_incl_tax`, `base_price_incl_tax`, `row_total_incl_tax`, `base_row_total_incl_tax`, `hidden_tax_amount`, `base_hidden_tax_amount`, `free_shipping`, `gift_message_id`, `weee_tax_applied`, `weee_tax_applied_amount`, `weee_tax_applied_row_amount`, `weee_tax_disposition`, `weee_tax_row_disposition`, `base_weee_tax_applied_amount`, `base_weee_tax_applied_row_amnt`, `base_weee_tax_disposition`, `base_weee_tax_row_disposition`) VALUES ({$quoteItemId[0]}, {$quoteId}, '1970-01-01 03:00:00', '1970-01-01 03:00:00', {$simpleProductId[0]($entityId)}, {$productStoreId($entityId)}, NULL, 0, '{$simpleProductSku[0]($entityId)}', '{$simpleProductName[0]($entityId)}', NULL, '1', NULL, 0, 0, 1.0000, 1.0000, 8.5000, 8.5000, NULL, 10.0000, 0.8500, 0.8500, 0.0000, 0.0000, 0.0000, 8.5000, 8.5000, 0.0000, 1.0000, 'simple', NULL, NULL, NULL, NULL, NULL, 8.5000, 8.5000, 8.5000, 8.5000, 0.0000, 0.0000, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);"; + $queries .= "INSERT INTO `{$quoteItemTableName}` (`item_id`, `quote_id`, `created_at`, `updated_at`, `product_id`, `store_id`, `parent_item_id`, `is_virtual`, `sku`, `name`, `description`, `applied_rule_ids`, `additional_data`, `is_qty_decimal`, `no_discount`, `weight`, `qty`, `price`, `base_price`, `custom_price`, `discount_percent`, `discount_amount`, `base_discount_amount`, `tax_percent`, `tax_amount`, `base_tax_amount`, `row_total`, `base_row_total`, `row_total_with_discount`, `row_weight`, `product_type`, `base_tax_before_discount`, `tax_before_discount`, `original_custom_price`, `redirect_url`, `base_cost`, `price_incl_tax`, `base_price_incl_tax`, `row_total_incl_tax`, `base_row_total_incl_tax`, `hidden_tax_amount`, `base_hidden_tax_amount`, `free_shipping`, `gift_message_id`, `weee_tax_applied`, `weee_tax_applied_amount`, `weee_tax_applied_row_amount`, `weee_tax_disposition`, `weee_tax_row_disposition`, `base_weee_tax_applied_amount`, `base_weee_tax_applied_row_amnt`, `base_weee_tax_disposition`, `base_weee_tax_row_disposition`) VALUES ({$quoteItemId[1]}, {$quoteId}, '1970-01-01 03:00:00', '1970-01-01 03:00:00', {$simpleProductId[1]($entityId)}, {$productStoreId($entityId)}, NULL, 0, '{$simpleProductSku[1]($entityId)}', '{$simpleProductName[1]($entityId)}', NULL, '1', NULL, 0, 0, 1.0000, 1.0000, 8.5000, 8.5000, NULL, 10.0000, 0.8500, 0.8500, 0.0000, 0.0000, 0.0000, 8.5000, 8.5000, 0.0000, 1.0000, 'simple', NULL, NULL, NULL, NULL, NULL, 8.5000, 8.5000, 8.5000, 8.5000, 0.0000, 0.0000, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);"; + + $quoteItemOptionId[0] = $entityId * 8 - 7; + $quoteItemOptionId[1] = $entityId * 8 - 6; + $quoteItemOptionId[2] = $entityId * 8 - 5; + $quoteItemOptionId[3] = $entityId * 8 - 4; + $quoteItemOptionId[4] = $entityId * 8 - 3; + $quoteItemOptionId[5] = $entityId * 8 - 2; + $quoteItemOptionId[6] = $entityId * 8 - 1; + $quoteItemOptionId[7] = $entityId * 8; + $queries .= "INSERT INTO `{$quoteItemOptionTableName}` (`option_id`, `item_id`, `product_id`, `code`, `value`) VALUES ({$quoteItemOptionId[0]}, {$quoteItemId[0]}, {$simpleProductId[0]($entityId)}, 'info_buyRequest', 'a:3:{s:4:\"uenc\";s:44:\"aHR0cDovL21hZ2UyLmNvbS9jYXRlZ29yeS0xLmh0bWw,\";s:7:\"product\";s:{$simpleProductIdLen[0]}:\"{$simpleProductId[0]($entityId)}\";s:3:\"qty\";i:1;}');"; + $queries .= "INSERT INTO `{$quoteItemOptionTableName}` (`option_id`, `item_id`, `product_id`, `code`, `value`) VALUES ({$quoteItemOptionId[1]}, {$quoteItemId[1]}, {$simpleProductId[1]($entityId)}, 'info_buyRequest', 'a:3:{s:4:\"uenc\";s:44:\"aHR0cDovL21hZ2UyLmNvbS9jYXRlZ29yeS0xLmh0bWw,\";s:7:\"product\";s:{$simpleProductIdLen[1]}:\"{$simpleProductId[1]($entityId)}\";s:3:\"qty\";i:1;}');"; + + $quotePaymentId = $quoteId; + $queries .= "INSERT INTO `{$quotePaymentTableName}` (`payment_id`, `quote_id`, `created_at`, `updated_at`, `method`, `cc_type`, `cc_number_enc`, `cc_last_4`, `cc_cid_enc`, `cc_owner`, `cc_exp_month`, `cc_exp_year`, `cc_ss_owner`, `cc_ss_start_month`, `cc_ss_start_year`, `po_number`, `additional_data`, `cc_ss_issue`, `additional_information`) VALUES ({$quotePaymentId}, {$quoteId}, '{$time}', '1970-01-01 03:00:00', 'checkmo', NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, NULL, NULL, NULL, NULL);"; + + $quoteShippingRateId = $quoteAddressId[1]; + $queries .= "INSERT INTO `{$quoteAddressRateTableName}` (`rate_id`, `address_id`, `created_at`, `updated_at`, `carrier`, `carrier_title`, `code`, `method`, `method_description`, `price`, `error_message`, `method_title`) VALUES ({$quoteShippingRateId}, {$quoteAddressId[1]}, '{$time}', '1970-01-01 03:00:00', 'flatrate', 'Flat Rate', 'flatrate_flatrate', 'flatrate', NULL, 10.0000, NULL, 'Fixed');"; + + $reportEventId[0] = $quoteItemId[0]; + $reportEventId[1] = $quoteItemId[1]; + $reportEventId[2] = $quoteItemId[2]; + $reportEventId[3] = $quoteItemId[3]; + $queries .= "INSERT INTO `{$reportEventTableName}` (`event_id`, `logged_at`, `event_type_id`, `object_id`, `subject_id`, `subtype`, `store_id`) VALUES ({$reportEventId[0]}, '{$time}', 4, {$simpleProductId[0]($entityId)}, 2, 1, {$productStoreId($entityId)});"; + $queries .= "INSERT INTO `{$reportEventTableName}` (`event_id`, `logged_at`, `event_type_id`, `object_id`, `subject_id`, `subtype`, `store_id`) VALUES ({$reportEventId[1]}, '{$time}', 4, {$simpleProductId[1]($entityId)}, 2, 1, {$productStoreId($entityId)});"; + + $salesOrderId = $quoteId; + $queries .= "INSERT INTO `{$salesOrderTableName}` (`entity_id`, `state`, `status`, `coupon_code`, `protect_code`, `shipping_description`, `is_virtual`, `store_id`, `customer_id`, `base_discount_amount`, `base_discount_canceled`, `base_discount_invoiced`, `base_discount_refunded`, `base_grand_total`, `base_shipping_amount`, `base_shipping_canceled`, `base_shipping_invoiced`, `base_shipping_refunded`, `base_shipping_tax_amount`, `base_shipping_tax_refunded`, `base_subtotal`, `base_subtotal_canceled`, `base_subtotal_invoiced`, `base_subtotal_refunded`, `base_tax_amount`, `base_tax_canceled`, `base_tax_invoiced`, `base_tax_refunded`, `base_to_global_rate`, `base_to_order_rate`, `base_total_canceled`, `base_total_invoiced`, `base_total_invoiced_cost`, `base_total_offline_refunded`, `base_total_online_refunded`, `base_total_paid`, `base_total_qty_ordered`, `base_total_refunded`, `discount_amount`, `discount_canceled`, `discount_invoiced`, `discount_refunded`, `grand_total`, `shipping_amount`, `shipping_canceled`, `shipping_invoiced`, `shipping_refunded`, `shipping_tax_amount`, `shipping_tax_refunded`, `store_to_base_rate`, `store_to_order_rate`, `subtotal`, `subtotal_canceled`, `subtotal_invoiced`, `subtotal_refunded`, `tax_amount`, `tax_canceled`, `tax_invoiced`, `tax_refunded`, `total_canceled`, `total_invoiced`, `total_offline_refunded`, `total_online_refunded`, `total_paid`, `total_qty_ordered`, `total_refunded`, `can_ship_partially`, `can_ship_partially_item`, `customer_is_guest`, `customer_note_notify`, `billing_address_id`, `customer_group_id`, `edit_increment`, `email_sent`, `send_email`, `forced_shipment_with_invoice`, `payment_auth_expiration`, `quote_address_id`, `quote_id`, `shipping_address_id`, `adjustment_negative`, `adjustment_positive`, `base_adjustment_negative`, `base_adjustment_positive`, `base_shipping_discount_amount`, `base_subtotal_incl_tax`, `base_total_due`, `payment_authorization_amount`, `shipping_discount_amount`, `subtotal_incl_tax`, `total_due`, `weight`, `customer_dob`, `increment_id`, `applied_rule_ids`, `base_currency_code`, `customer_email`, `customer_firstname`, `customer_lastname`, `customer_middlename`, `customer_prefix`, `customer_suffix`, `customer_taxvat`, `discount_description`, `ext_customer_id`, `ext_order_id`, `global_currency_code`, `hold_before_state`, `hold_before_status`, `order_currency_code`, `original_increment_id`, `relation_child_id`, `relation_child_real_id`, `relation_parent_id`, `relation_parent_real_id`, `remote_ip`, `shipping_method`, `store_currency_code`, `store_name`, `x_forwarded_for`, `customer_note`, `created_at`, `updated_at`, `total_item_count`, `customer_gender`, `hidden_tax_amount`, `base_hidden_tax_amount`, `shipping_hidden_tax_amount`, `base_shipping_hidden_tax_amnt`, `hidden_tax_invoiced`, `base_hidden_tax_invoiced`, `hidden_tax_refunded`, `base_hidden_tax_refunded`, `shipping_incl_tax`, `base_shipping_incl_tax`, `coupon_rule_name`, `gift_message_id`) VALUES ({$salesOrderId}, 'new', 'pending', NULL, '272ecb', 'Flat Rate - Fixed', 0, {$productStoreId($entityId)}, NULL, -1.7000, NULL, NULL, NULL, 25.3000, 10.0000, NULL, NULL, NULL, 0.0000, NULL, 17.0000, NULL, NULL, NULL, 0.0000, NULL, NULL, NULL, 1.0000, 1.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1.7000, NULL, NULL, NULL, 25.3000, 10.0000, NULL, NULL, NULL, 0.0000, NULL, 0.0000, 0.0000, 17.0000, NULL, NULL, NULL, 0.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2.0000, NULL, NULL, NULL, 1, 1, 2, 0, NULL, 1, 1, NULL, NULL, NULL, 1, 1, NULL, NULL, NULL, NULL, NULL, 17.0000, 25.3000, NULL, NULL, 17.0000, 25.3000, 2.0000, NULL, {$orderNumber}, '1', 'USD', '{$email}', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'USD', NULL, NULL, 'USD', NULL, NULL, NULL, NULL, NULL, '127.0.0.1', 'flatrate_flatrate', 'USD', '{$productStoreName($entityId)}', NULL, NULL, '{$time}', '{$time}', 2, NULL, 0.0000, 0.0000, 0.0000, NULL, NULL, NULL, NULL, NULL, 10.0000, 10.0000, NULL, NULL);"; + + $salesOrderAddressId[0] = $quoteAddressId[0]; + $salesOrderAddressId[1] = $quoteAddressId[1]; + $queries .= "INSERT INTO `{$salesOrderAddressTableName}` (`entity_id`, `parent_id`, `customer_address_id`, `quote_address_id`, `region_id`, `customer_id`, `fax`, `region`, `postcode`, `lastname`, `street`, `city`, `email`, `telephone`, `country_id`, `firstname`, `address_type`, `prefix`, `middlename`, `suffix`, `company`, `vat_id`, `vat_is_valid`, `vat_request_id`, `vat_request_date`, `vat_request_success`) VALUES ({$salesOrderAddressId[0]}, {$salesOrderId}, NULL, NULL, 1, NULL, NULL, '{$state}', '{$zip}', '{$lastName}', '{$address}', '{$city}', '{$email}', '{$phone}', '{$country}', '{$firstName}', 'shipping', NULL, NULL, NULL, '{$company}', NULL, NULL, NULL, NULL, NULL);"; + $queries .= "INSERT INTO `{$salesOrderAddressTableName}` (`entity_id`, `parent_id`, `customer_address_id`, `quote_address_id`, `region_id`, `customer_id`, `fax`, `region`, `postcode`, `lastname`, `street`, `city`, `email`, `telephone`, `country_id`, `firstname`, `address_type`, `prefix`, `middlename`, `suffix`, `company`, `vat_id`, `vat_is_valid`, `vat_request_id`, `vat_request_date`, `vat_request_success`) VALUES ({$salesOrderAddressId[1]}, {$salesOrderId}, NULL, NULL, 1, NULL, NULL, '{$state}', '{$zip}', '{$lastName}', '{$address}', '{$city}', '{$email}', '{$phone}', '{$country}', '{$firstName}', 'billing', NULL, NULL, NULL, '{$company}', NULL, NULL, NULL, NULL, NULL);"; + + $salesOrderGridId = $salesOrderId; + $queries .= "INSERT INTO `{$salesOrderGridTableName}` (`entity_id`, `status`, `store_id`, `store_name`, `customer_id`, `base_grand_total`, `base_total_paid`, `grand_total`, `total_paid`, `increment_id`, `base_currency_code`, `order_currency_code`, `shipping_name`, `billing_name`, `created_at`, `updated_at`) VALUES ({$salesOrderGridId}, 'pending', {$productStoreId($entityId)}, '{$productStoreName($entityId)}', NULL, 25.3000, NULL, 25.3000, NULL, {$orderNumber}, 'USD', 'USD', '', '', '{$time}', NULL);"; + + $salesOrderItemId[0] = $quoteItemId[0]; + $salesOrderItemId[1] = $quoteItemId[1]; + $salesOrderItemId[2] = $quoteItemId[2]; + $salesOrderItemId[3] = $quoteItemId[3]; + $queries .= "INSERT INTO `{$salesOrderItemTableName}` (`item_id`, `order_id`, `parent_item_id`, `quote_item_id`, `store_id`, `created_at`, `updated_at`, `product_id`, `product_type`, `product_options`, `weight`, `is_virtual`, `sku`, `name`, `description`, `applied_rule_ids`, `additional_data`, `is_qty_decimal`, `no_discount`, `qty_backordered`, `qty_canceled`, `qty_invoiced`, `qty_ordered`, `qty_refunded`, `qty_shipped`, `base_cost`, `price`, `base_price`, `original_price`, `base_original_price`, `tax_percent`, `tax_amount`, `base_tax_amount`, `tax_invoiced`, `base_tax_invoiced`, `discount_percent`, `discount_amount`, `base_discount_amount`, `discount_invoiced`, `base_discount_invoiced`, `amount_refunded`, `base_amount_refunded`, `row_total`, `base_row_total`, `row_invoiced`, `base_row_invoiced`, `row_weight`, `base_tax_before_discount`, `tax_before_discount`, `ext_order_item_id`, `locked_do_invoice`, `locked_do_ship`, `price_incl_tax`, `base_price_incl_tax`, `row_total_incl_tax`, `base_row_total_incl_tax`, `hidden_tax_amount`, `base_hidden_tax_amount`, `hidden_tax_invoiced`, `base_hidden_tax_invoiced`, `hidden_tax_refunded`, `base_hidden_tax_refunded`, `tax_canceled`, `hidden_tax_canceled`, `tax_refunded`, `base_tax_refunded`, `discount_refunded`, `base_discount_refunded`, `free_shipping`, `gift_message_id`, `gift_message_available`, `weee_tax_applied`, `weee_tax_applied_amount`, `weee_tax_applied_row_amount`, `weee_tax_disposition`, `weee_tax_row_disposition`, `base_weee_tax_applied_amount`, `base_weee_tax_applied_row_amnt`, `base_weee_tax_disposition`, `base_weee_tax_row_disposition`) VALUES ({$salesOrderItemId[0]}, {$salesOrderId}, NULL, {$quoteItemId[0]}, {$productStoreId($entityId)}, '{$time}', '0000-00-00 00:00:00', {$simpleProductId[0]($entityId)}, 'simple', 'a:1:{s:15:\"info_buyRequest\";a:3:{s:4:\"uenc\";s:44:\"aHR0cDovL21hZ2UyLmNvbS9jYXRlZ29yeS0xLmh0bWw,\";s:7:\"product\";s:{$simpleProductIdLen[0]}:\"{$simpleProductId[0]($entityId)}\";s:3:\"qty\";i:1;}}', 1.0000, 0, '{$simpleProductSku[0]($entityId)}', '{$simpleProductName[0]($entityId)}', NULL, '1', NULL, 0, 0, NULL, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, NULL, 8.5000, 8.5000, 10.0000, 10.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 10.0000, 0.8500, 0.8500, 0.0000, 0.0000, 0.0000, 0.0000, 8.5000, 8.5000, 0.0000, 0.0000, 1.0000, NULL, NULL, NULL, NULL, NULL, 8.5000, 8.5000, 8.5000, 8.5000, 0.0000, 0.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);"; + $queries .= "INSERT INTO `{$salesOrderItemTableName}` (`item_id`, `order_id`, `parent_item_id`, `quote_item_id`, `store_id`, `created_at`, `updated_at`, `product_id`, `product_type`, `product_options`, `weight`, `is_virtual`, `sku`, `name`, `description`, `applied_rule_ids`, `additional_data`, `is_qty_decimal`, `no_discount`, `qty_backordered`, `qty_canceled`, `qty_invoiced`, `qty_ordered`, `qty_refunded`, `qty_shipped`, `base_cost`, `price`, `base_price`, `original_price`, `base_original_price`, `tax_percent`, `tax_amount`, `base_tax_amount`, `tax_invoiced`, `base_tax_invoiced`, `discount_percent`, `discount_amount`, `base_discount_amount`, `discount_invoiced`, `base_discount_invoiced`, `amount_refunded`, `base_amount_refunded`, `row_total`, `base_row_total`, `row_invoiced`, `base_row_invoiced`, `row_weight`, `base_tax_before_discount`, `tax_before_discount`, `ext_order_item_id`, `locked_do_invoice`, `locked_do_ship`, `price_incl_tax`, `base_price_incl_tax`, `row_total_incl_tax`, `base_row_total_incl_tax`, `hidden_tax_amount`, `base_hidden_tax_amount`, `hidden_tax_invoiced`, `base_hidden_tax_invoiced`, `hidden_tax_refunded`, `base_hidden_tax_refunded`, `tax_canceled`, `hidden_tax_canceled`, `tax_refunded`, `base_tax_refunded`, `discount_refunded`, `base_discount_refunded`, `free_shipping`, `gift_message_id`, `gift_message_available`, `weee_tax_applied`, `weee_tax_applied_amount`, `weee_tax_applied_row_amount`, `weee_tax_disposition`, `weee_tax_row_disposition`, `base_weee_tax_applied_amount`, `base_weee_tax_applied_row_amnt`, `base_weee_tax_disposition`, `base_weee_tax_row_disposition`) VALUES ({$salesOrderItemId[1]}, {$salesOrderId}, NULL, {$quoteItemId[1]}, {$productStoreId($entityId)}, '{$time}', '0000-00-00 00:00:00', {$simpleProductId[1]($entityId)}, 'simple', 'a:1:{s:15:\"info_buyRequest\";a:3:{s:4:\"uenc\";s:44:\"aHR0cDovL21hZ2UyLmNvbS9jYXRlZ29yeS0xLmh0bWw,\";s:7:\"product\";s:{$simpleProductIdLen[1]}:\"{$simpleProductId[1]($entityId)}\";s:3:\"qty\";i:1;}}', 1.0000, 0, '{$simpleProductSku[1]($entityId)}', '{$simpleProductName[1]($entityId)}', NULL, '1', NULL, 0, 0, NULL, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, NULL, 8.5000, 8.5000, 10.0000, 10.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 10.0000, 0.8500, 0.8500, 0.0000, 0.0000, 0.0000, 0.0000, 8.5000, 8.5000, 0.0000, 0.0000, 1.0000, NULL, NULL, NULL, NULL, NULL, 8.5000, 8.5000, 8.5000, 8.5000, 0.0000, 0.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);"; + + $salesOrderPaymentId = $salesOrderId; + $queries .= "INSERT INTO `{$salesOrderPaymentTableName}` (`entity_id`, `parent_id`, `base_shipping_captured`, `shipping_captured`, `amount_refunded`, `base_amount_paid`, `amount_canceled`, `base_amount_authorized`, `base_amount_paid_online`, `base_amount_refunded_online`, `base_shipping_amount`, `shipping_amount`, `amount_paid`, `amount_authorized`, `base_amount_ordered`, `base_shipping_refunded`, `shipping_refunded`, `base_amount_refunded`, `amount_ordered`, `base_amount_canceled`, `quote_payment_id`, `additional_data`, `cc_exp_month`, `cc_ss_start_year`, `echeck_bank_name`, `method`, `cc_debug_request_body`, `cc_secure_verify`, `protection_eligibility`, `cc_approval`, `cc_last_4`, `cc_status_description`, `echeck_type`, `cc_debug_response_serialized`, `cc_ss_start_month`, `echeck_account_type`, `last_trans_id`, `cc_cid_status`, `cc_owner`, `cc_type`, `po_number`, `cc_exp_year`, `cc_status`, `echeck_routing_number`, `account_status`, `anet_trans_method`, `cc_debug_response_body`, `cc_ss_issue`, `echeck_account_name`, `cc_avs_status`, `cc_number_enc`, `cc_trans_id`, `address_status`, `additional_information`) VALUES ({$salesOrderPaymentId}, {$salesOrderId}, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 10.0000, 10.0000, NULL, NULL, 25.3000, NULL, NULL, NULL, 25.3000, NULL, NULL, NULL, NULL, '0', NULL, 'checkmo', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '0', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'a:1:{s:53:\"a:1:{s:12:\"method_title\";s:19:\"Check / Money order\";}\";N;}');"; + + $salesOrderStatusHistoryId = $salesOrderId; + $queries .= "INSERT INTO `{$salesOrderStatusHistoryTableName}` (`entity_id`, `parent_id`, `is_customer_notified`, `is_visible_on_front`, `comment`, `status`, `created_at`, `entity_name`) VALUES ({$salesOrderStatusHistoryId}, {$salesOrderId}, 1, 0, NULL, 'pending', '{$time}', 'order');"; + + $writeAdapter->multiQuery($queries); + + $entityId++; + } + } + + /** + * {@inheritdoc} + */ + public function getActionTitle() + { + return 'Generating orders'; + } + + /** + * {@inheritdoc} + */ + public function introduceParamLabels() + { + return [ + 'orders' => 'Orders' + ]; + } + + /** + * Get real table name for db table, validated by db adapter + * + * @param string $tableName + * @param string $resourceName + * @return string + */ + public function getTableName($tableName, $resourceName) + { + $resource = $this->application->getObjectManager()->get($resourceName); + return $this->getConnection('write')->getTableName($resource->getTable($tableName)); + } + + /** + * Retrieve connection to resource specified by $resourceName + * + * @param string $resourceName + * @return \Magento\Framework\DB\Adapter\AdapterInterface|false + */ + public function getConnection($resourceName) + { + return $this->application->getObjectManager()->get( + 'Magento\Framework\App\Resource' + )->getConnection($resourceName); + } +} + +return new OrdersFixture($this); diff --git a/dev/tools/performance-toolkit/fixtures/simple_products.php b/dev/tools/performance-toolkit/fixtures/simple_products.php index 26d676455aa1d4597f7cb5643e30d1c78c37033f..c38059cab07a16f604ddcabc3789647a19de3e96 100644 --- a/dev/tools/performance-toolkit/fixtures/simple_products.php +++ b/dev/tools/performance-toolkit/fixtures/simple_products.php @@ -19,7 +19,10 @@ class SimpleProductsFixture extends \Magento\ToolkitFramework\Fixture */ public function execute() { - $simpleProductsCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('simple_products', 180); + $simpleProductsCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('simple_products', 0); + if (!$simpleProductsCount) { + return; + } $this->application->resetObjectManager(); /** @var \Magento\Store\Model\StoreManager $storeManager */ diff --git a/dev/tools/performance-toolkit/fixtures/stores.php b/dev/tools/performance-toolkit/fixtures/stores.php index ac56367cc2701078828c3d74604042a32146d888..04978e151777b73289f1b7486bbae3187c79fe8d 100644 --- a/dev/tools/performance-toolkit/fixtures/stores.php +++ b/dev/tools/performance-toolkit/fixtures/stores.php @@ -19,9 +19,12 @@ class StoresFixture extends \Magento\ToolkitFramework\Fixture */ public function execute() { - $websitesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('websites', 2); - $storeGroupsCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('store_groups', 3); - $storesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('store_views', 5); + $websitesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('websites', 0); + $storeGroupsCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('store_groups', 0); + $storesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('store_views', 0); + if (!$websitesCount || !$storeGroupsCount || !$storesCount) { + return; + } $this->application->resetObjectManager(); /** @var \Magento\Store\Model\StoreManager $storeManager */ diff --git a/dev/tools/performance-toolkit/fixtures/tax_rates.php b/dev/tools/performance-toolkit/fixtures/tax_rates.php index d4a9cbbba16f6a4391fa82d630c6699a3db64a5b..22abecea441f460888d9fb3e7b867b4ec8cb0d5d 100644 --- a/dev/tools/performance-toolkit/fixtures/tax_rates.php +++ b/dev/tools/performance-toolkit/fixtures/tax_rates.php @@ -19,6 +19,10 @@ class TaxRatesFixture extends \Magento\ToolkitFramework\Fixture */ public function execute() { + $taxRatesFile = \Magento\ToolkitFramework\Config::getInstance()->getValue('tax_rates_file', null); + if (empty($taxRatesFile)) { + return; + } $this->application->resetObjectManager(); /** Clean predefined tax rates to maintain consistency */ /** @var $collection Magento\Tax\Model\Resource\Calculation\Rate\Collection */ @@ -36,7 +40,7 @@ class TaxRatesFixture extends \Magento\ToolkitFramework\Fixture /** * Import tax rates with import handler */ - $filename = realpath(__DIR__ . '/tax_rates.csv'); + $filename = realpath(__DIR__ . '/' . $taxRatesFile); $file = [ 'name' => $filename, 'type' => 'application/vnd.ms-excel', diff --git a/dev/tools/performance-toolkit/profiles/ce/extra_large.xml b/dev/tools/performance-toolkit/profiles/ce/extra_large.xml index 25575c3a77f66d0a75ec7ad2b4cb5d85938256b4..758fbef97f8730233c826ba009a5e24424b663fa 100644 --- a/dev/tools/performance-toolkit/profiles/ce/extra_large.xml +++ b/dev/tools/performance-toolkit/profiles/ce/extra_large.xml @@ -18,6 +18,8 @@ <cart_price_rules>100</cart_price_rules> <!-- Number of shopping cart price rules --> <cart_price_rules_floor>5</cart_price_rules_floor> <!-- The price rule condition: minimum products amount in shopping cart for price rule to be applied --> <customers>5000</customers> <!-- Number of customers to generate --> + <tax_rates_file>tax_rates.csv</tax_rates_file> <!-- Tax rates file in fixtures directory--> + <orders>80000</orders> <!-- Orders count --> <configs> <!-- Config variables and values for change --> <config> <path>admin/security/use_form_key</path> diff --git a/dev/tools/performance-toolkit/profiles/ce/large.xml b/dev/tools/performance-toolkit/profiles/ce/large.xml index 093f2868fe3a738ef7647958f2c4360620e11162..f89fa10faddc16f5e05f7be400b71f9ff94a8f1d 100644 --- a/dev/tools/performance-toolkit/profiles/ce/large.xml +++ b/dev/tools/performance-toolkit/profiles/ce/large.xml @@ -18,6 +18,8 @@ <cart_price_rules>50</cart_price_rules> <!-- Number of shopping cart price rules --> <cart_price_rules_floor>2</cart_price_rules_floor> <!-- The price rule condition: minimum products amount in shopping cart for price rule to be applied --> <customers>2000</customers> <!-- Number of customers to generate --> + <tax_rates_file>tax_rates.csv</tax_rates_file> <!-- Tax rates file in fixtures directory--> + <orders>40000</orders> <!-- Orders count --> <configs> <!-- Config variables and values for change --> <config> <path>admin/security/use_form_key</path> diff --git a/dev/tools/performance-toolkit/profiles/ce/medium.xml b/dev/tools/performance-toolkit/profiles/ce/medium.xml index edada57536f59043eb423dce5181a405676e49c4..fbcb4168bce8dbe2eb1b4f2bbe90a63c29bee4dd 100644 --- a/dev/tools/performance-toolkit/profiles/ce/medium.xml +++ b/dev/tools/performance-toolkit/profiles/ce/medium.xml @@ -18,6 +18,8 @@ <cart_price_rules>20</cart_price_rules> <!-- Number of shopping cart price rules --> <cart_price_rules_floor>2</cart_price_rules_floor> <!-- The price rule condition: minimum products amount in shopping cart for price rule to be applied --> <customers>200</customers> <!-- Number of customers to generate --> + <tax_rates_file>tax_rates.csv</tax_rates_file> <!-- Tax rates file in fixtures directory--> + <orders>1600</orders> <!-- Orders count --> <configs> <!-- Config variables and values for change --> <config> <path>admin/security/use_form_key</path> diff --git a/dev/tools/performance-toolkit/profiles/ce/small.xml b/dev/tools/performance-toolkit/profiles/ce/small.xml index 578d2feec9e43cf4337db2b6066e4e7a3d6cd66d..6507aa52f618843fac56a130461696f4342ac99f 100644 --- a/dev/tools/performance-toolkit/profiles/ce/small.xml +++ b/dev/tools/performance-toolkit/profiles/ce/small.xml @@ -18,6 +18,8 @@ <cart_price_rules>10</cart_price_rules> <!-- Number of shopping cart price rules --> <cart_price_rules_floor>2</cart_price_rules_floor> <!-- The price rule condition: minimum products amount in shopping cart for price rule to be applied --> <customers>20</customers> <!-- Number of customers to generate --> + <tax_rates_file>tax_rates.csv</tax_rates_file> <!-- Tax rates file in fixtures directory--> + <orders>80</orders> <!-- Orders count --> <configs> <!-- Config variables and values for change --> <config> <path>admin/security/use_form_key</path> diff --git a/lib/internal/Magento/Framework/App/Test/Unit/View/Deployment/VersionTest.php b/lib/internal/Magento/Framework/App/Test/Unit/View/Deployment/VersionTest.php old mode 100755 new mode 100644 index 65e059a58a3158ec6e5a627ad6ed85923a0317ac..092aeecbeff26912c6eec7d5070801c9f87312cb --- a/lib/internal/Magento/Framework/App/Test/Unit/View/Deployment/VersionTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/View/Deployment/VersionTest.php @@ -3,11 +3,13 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Framework\App\Test\Unit\View\Deployment; use \Magento\Framework\App\View\Deployment\Version; +/** + * Class VersionTest + */ class VersionTest extends \PHPUnit_Framework_TestCase { /** diff --git a/lib/internal/Magento/Framework/AppInterface.php b/lib/internal/Magento/Framework/AppInterface.php index 7bf9c70ada1b61682217450ee8aa846de7e01943..b363aff3a23479b3d3820e4055c2d4368450ffad 100644 --- a/lib/internal/Magento/Framework/AppInterface.php +++ b/lib/internal/Magento/Framework/AppInterface.php @@ -17,7 +17,7 @@ interface AppInterface /** * Magento version */ - const VERSION = '0.74.0-beta6'; + const VERSION = '0.74.0-beta7'; /** * Launch application diff --git a/lib/internal/Magento/Framework/Data/etc/argument/types.xsd b/lib/internal/Magento/Framework/Data/etc/argument/types.xsd index 5b6b6cedf73ce0d6d6d61ca840ba4ccd6018c115..065e8de3d18029677614bc5cc90855d53727c18e 100644 --- a/lib/internal/Magento/Framework/Data/etc/argument/types.xsd +++ b/lib/internal/Magento/Framework/Data/etc/argument/types.xsd @@ -46,6 +46,21 @@ </xs:complexContent> </xs:complexType> + <xs:complexType name="configurableObject" mixed="true"> + <xs:complexContent> + <xs:extension base="argumentType"> + <xs:sequence> + <xs:element name="argument" type="argumentType" minOccurs="1" maxOccurs="unbounded"> + <xs:key name="argumentConfigurableObjectName"> + <xs:selector xpath="argument"/> + <xs:field xpath="@name"/> + </xs:key> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="number"> <xs:complexContent> <xs:extension base="argumentType"/> diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php new file mode 100644 index 0000000000000000000000000000000000000000..f2d2779be11166b93310f688199c584c3b63c44f --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Argument\Interpreter; + +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Data\Argument\InterpreterInterface; + +/** + * Class ConfigurableObject + */ +class ConfigurableObject implements InterpreterInterface +{ + /** + * @var ObjectManagerInterface + */ + protected $objectManager; + + /** + * @var InterpreterInterface + */ + protected $argumentInterpreter; + + /** + * Constructor + * + * @param ObjectManagerInterface $objectManager + * @param InterpreterInterface $argumentInterpreter + */ + public function __construct(ObjectManagerInterface $objectManager, InterpreterInterface $argumentInterpreter) + { + $this->objectManager = $objectManager; + $this->argumentInterpreter = $argumentInterpreter; + } + + /** + * {@inheritdoc} + */ + public function evaluate(array $data) + { + if (!isset($data['argument'])) { + throw new \InvalidArgumentException('Node "argument" required for this type.'); + } + foreach ($data['argument'] as $name => $argument) { + $arguments[$name] = $this->argumentInterpreter->evaluate($argument); + } + if (!isset($arguments['class'])) { + throw new \InvalidArgumentException('Node "argument" with name "class" is required for this type.'); + } + $className = $arguments['class']; + unset($arguments['class']); + + return $this->objectManager->create($className, $arguments); + } +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ArrayObjectFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ArrayObjectFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..64c4cffc8cb596e60697e245c36ef9e526284f3f --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ArrayObjectFactory.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent; + +/** + * Class ArrayObjectFactory + */ +class ArrayObjectFactory +{ + /** + * Create class instance with specified parameters + * + * @param array $data + * @return \ArrayObject + */ + public function create(array $data = []) + { + return new \ArrayObject($data); + } +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Converter.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Converter.php new file mode 100644 index 0000000000000000000000000000000000000000..bf13c675696839882895b842a4e2b2252e64ff5f --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Converter.php @@ -0,0 +1,123 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Config; + +use Magento\Framework\Config\ConverterInterface; +use Magento\Framework\View\Layout\Argument\Parser; + +/** + * Class Converter + */ +class Converter implements ConverterInterface +{ + /** + * The key attributes of a node + */ + const DATA_ATTRIBUTES_KEY = '@attributes'; + + /** + * The key for the data arguments + */ + const DATA_ARGUMENTS_KEY = '@arguments'; + + /** + * The key of the argument node + */ + const ARGUMENT_KEY = 'argument'; + + /** + * Key name attribute value + */ + const NAME_ATTRIBUTE_KEY = 'name'; + + /** + * @var Parser + */ + protected $argumentParser; + + /** + * Constructor + * + * @param Parser $argumentParser + */ + public function __construct(Parser $argumentParser) + { + $this->argumentParser = $argumentParser; + } + + /** + * Transform Xml to array + * + * @param \DOMNode $node + * @return array|string + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + protected function toArray(\DOMNode $node) + { + $result = []; + $attributes = []; + // Collect data from attributes + if ($node->hasAttributes()) { + foreach ($node->attributes as $attribute) { + $attributes[$attribute->name] = $attribute->value; + } + } + switch ($node->nodeType) { + case XML_TEXT_NODE: + case XML_COMMENT_NODE: + case XML_CDATA_SECTION_NODE: + break; + default: + if ($node->localName === static::ARGUMENT_KEY) { + if (!isset($attributes[static::NAME_ATTRIBUTE_KEY])) { + throw new \InvalidArgumentException( + 'Attribute "' . static::NAME_ATTRIBUTE_KEY . '" is absent in the attributes node.' + ); + } + $result[ $attributes[static::NAME_ATTRIBUTE_KEY] ] = $this->argumentParser->parse($node); + } else { + $arguments = []; + for ($i = 0, $iLength = $node->childNodes->length; $i < $iLength; ++$i) { + $itemNode = $node->childNodes->item($i); + if (empty($itemNode->localName)) { + continue; + } + if ($itemNode->nodeName === static::ARGUMENT_KEY) { + $arguments += $this->toArray($itemNode); + } else { + $result[$itemNode->localName][] = $this->toArray($itemNode); + } + } + if (!empty($arguments)) { + $result[static::DATA_ARGUMENTS_KEY] = $arguments; + } + if (!empty($attributes)) { + $result[static::DATA_ATTRIBUTES_KEY] = $attributes; + } + } + break; + } + + return $result; + } + + /** + * Convert configuration + * + * @param \DOMDocument|null $source + * @return array + */ + public function convert($source) + { + if ($source === null) { + return []; + } + + return $this->toArray($source); + } +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMerger.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMerger.php new file mode 100644 index 0000000000000000000000000000000000000000..72b18bb610577f7218ef4615f0d7cde0cf3d421e --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMerger.php @@ -0,0 +1,455 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Config; + +use Magento\Framework\Config\Dom; +use Magento\Framework\Module\Dir\Reader as DirectoryReader; + +/** + * Class DomMerger + */ +class DomMerger implements DomMergerInterface +{ + /** + * Format of items in errors array to be used by default. Available placeholders - fields of \LibXMLError. + */ + const ERROR_FORMAT_DEFAULT = "Message: %message%\nLine: %line%\n"; + + /** + * Location schema file + * + * @var string + */ + protected $schemaFilePath; + + /** + * Result DOM document + * + * @var \DOMDocument + */ + protected $domDocument; + + /** + * Id attribute list + * + * @var array + */ + protected $idAttributes = []; + + /** + * Context XPath + * + * @var array + */ + protected $contextXPath = []; + + /** + * Is merge simple XML Element + * + * @var bool + */ + protected $isMergeSimpleXMLElement; + + /** + * Build DOM with initial XML contents and specifying identifier attributes for merging + * + * Format of $schemaFileType: array('etc', 'sql', 'data', 'i18n', 'view', 'Controller') + * Format of $schemaFileModule: 'Magento_XXXXX' + * Format of $schemaFileName: 'schema.xsd' + * Format of $idAttributes: array('name', 'id') + * Format of $contextXPath: array('/config/ui') + * The path to ID attribute name should not include any attribute notations or modifiers -- only node names + * + * @param string $schemaFileType + * @param string $schemaFileModule + * @param string $schemaFileName + * @param DirectoryReader $directoryReader + * @param bool $isMergeSimpleXMLElement + * @param array $contextXPath + * @param array $idAttributes + */ + public function __construct( + DirectoryReader $directoryReader, + $schemaFileType, + $schemaFileModule, + $schemaFileName, + $isMergeSimpleXMLElement = false, + array $contextXPath = [], + array $idAttributes = [] + ) { + $this->schemaFilePath = $directoryReader->getModuleDir($schemaFileType, $schemaFileModule) . '/' + . trim($schemaFileName, '/'); + $this->isMergeSimpleXMLElement = $isMergeSimpleXMLElement; + $this->contextXPath = $contextXPath; + $this->idAttributes = $idAttributes; + } + + /** + * Is id attribute + * + * @param string $attributeName + * @return bool + */ + protected function isIdAttribute($attributeName) + { + return in_array($attributeName, $this->idAttributes); + } + + /** + * Is merge context + * + * @param string $xPath + * @return bool + */ + protected function isMergeContext($xPath) + { + foreach ($this->contextXPath as $context) { + if (strpos($xPath, $context) === 0) { + return true; + } + } + return false; + } + + /** + * Is context XPath + * + * @param array $xPath + * @return bool + */ + protected function isContextXPath(array $xPath) + { + return count(array_intersect($xPath, $this->contextXPath)) === count($xPath); + } + + /** + * Merges attributes of the merge node to the base node + * + * @param \DOMElement $baseNode + * @param \DOMNode $mergeNode + * @return void + */ + protected function mergeAttributes(\DOMElement $baseNode, \DOMNode $mergeNode) + { + foreach ($mergeNode->attributes as $name => $attribute) { + $baseNode->setAttribute($name, $attribute->value); + } + } + + /** + * Create XPath + * + * @param \DOMNode $node + * @return string + */ + protected function createXPath(\DOMNode $node) + { + $parentXPath = ''; + $currentXPath = $node->getNodePath(); + if ($node->parentNode !== null && !$node->isSameNode($node->parentNode)) { + $parentXPath = $this->createXPath($node->parentNode); + $pathParts = explode('/', $currentXPath); + $currentXPath = '/' . end($pathParts); + } + $attributesXPath = ''; + if ($node->hasAttributes()) { + $attributes = []; + foreach ($node->attributes as $name => $attribute) { + if ($this->isIdAttribute($name)) { + $attributes[] = sprintf('@%s="%s"', $name, $attribute->value); + break; + } + } + if (!empty($attributes)) { + if (substr($currentXPath, -1) === ']') { + $currentXPath = substr($currentXPath, 0, strrpos($currentXPath, '[')); + } + $attributesXPath = '[' . implode(' and ', $attributes) . ']'; + } + } + return '/' . trim($parentXPath . $currentXPath . $attributesXPath, '/'); + } + + /** + * Merge nested xml nodes + * + * @param \DOMXPath $rootDomXPath + * @param \DOMNodeList $insertedNodes + * @param \DOMNode $contextNode + * @return void + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + protected function nestedMerge(\DOMXPath $rootDomXPath, \DOMNodeList $insertedNodes, \DOMNode $contextNode) + { + for ($i = 0, $iLength = $insertedNodes->length; $i < $iLength; ++$i) { + $insertedItem = $insertedNodes->item($i); + switch ($insertedItem->nodeType) { + case XML_TEXT_NODE: + case XML_COMMENT_NODE: + case XML_CDATA_SECTION_NODE: + if (trim($insertedItem->textContent) !== '') { + $this->insertBefore($contextNode, $insertedItem); + } + break; + default: + $insertedXPath = $this->createXPath($insertedItem); + $rootMatchList = $rootDomXPath->query($insertedXPath, $contextNode); + $jLength = $rootMatchList->length; + if ($jLength > 0) { + for ($j = 0; $j < $jLength; ++$j) { + $rootItem = $rootMatchList->item($j); + $rootItemXPath = $this->createXPath($rootItem); + if ($this->isMergeContext($insertedXPath)) { + if ($this->isTextNode($insertedItem) && $this->isTextNode($rootItem)) { + $rootItem->nodeValue = $insertedItem->nodeValue; + } else if (!$this->isContextXPath([$rootItemXPath, $insertedXPath]) + && !$this->hasIdAttribute($rootItem) + && !$this->hasIdAttribute($insertedItem) + ) { + if ($this->isMergeSimpleXMLElement) { + $this->nestedMerge($rootDomXPath, $insertedItem->childNodes, $rootItem); + $this->mergeAttributes($rootItem, $insertedItem); + } else { + $this->appendChild($contextNode, $insertedItem); + } + } else { + $this->nestedMerge($rootDomXPath, $insertedItem->childNodes, $rootItem); + $this->mergeAttributes($rootItem, $insertedItem); + } + } else { + $this->appendChild($contextNode, $insertedItem); + } + } + } else { + $this->appendChild($contextNode, $insertedItem); + } + break; + } + } + } + + /** + * Append child node + * + * @param \DOMNode $parentNode + * @param \DOMNode $childNode + * @return void + */ + protected function appendChild(\DOMNode $parentNode, \DOMNode $childNode) + { + $importNode = $this->getDom()->importNode($childNode, true); + $parentNode->appendChild($importNode); + } + + /** + * Insert before + * + * @param \DOMNode $parentNode + * @param \DOMNode $childNode + * @return void + */ + protected function insertBefore(\DOMNode $parentNode, \DOMNode $childNode) + { + $importNode = $this->getDom()->importNode($childNode, true); + $parentNode->insertBefore($importNode); + } + + /** + * Check if the node content is text + * + * @param \DOMNode $node + * @return bool + */ + protected function isTextNode(\DOMNode $node) + { + return $node->childNodes->length == 1 && $node->childNodes->item(0) instanceof \DOMText; + } + + /** + * Has ID attribute + * + * @param \DOMNode $node + * @return bool + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + protected function hasIdAttribute(\DOMNode $node) + { + if (!$node->hasAttributes()) { + return false; + } + + foreach ($node->attributes as $name => $attribute) { + if (in_array($name, $this->idAttributes)) { + return true; + } + } + + return false; + } + + /** + * Recursive merging of the \DOMElement into the original document + * + * Algorithm: + * 1. Find the same node in original document + * 2. Extend and override original document node attributes and scalar value if found + * 3. Append new node if original document doesn't have the same node + * + * @param \DOMElement $node + * @throws \Magento\Framework\Exception\LocalizedException + * @return void + */ + public function mergeNode(\DOMElement $node) + { + $parentDoom = $this->getDom(); + $this->nestedMerge(new \DOMXPath($parentDoom), $node->childNodes, $parentDoom->documentElement); + } + + /** + * Create DOM document based on $xml parameter + * + * @param string $xml + * @return \DOMDocument + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function createDomDocument($xml) + { + $domDocument = new \DOMDocument(); + $domDocument->loadXML($xml); + if ($this->schemaFilePath) { + $errors = $this->validateDomDocument($domDocument); + if (count($errors)) { + throw new \Magento\Framework\Exception\LocalizedException(implode("\n", $errors)); + } + } + + return $domDocument; + } + + /** + * Validate dom document + * + * @param \DOMDocument $domDocument + * @param string|null $schemaFilePath + * @return array of errors + * @throws \Exception + */ + protected function validateDomDocument(\DOMDocument $domDocument, $schemaFilePath = null) + { + $schemaFilePath = $schemaFilePath !== null ? $schemaFilePath : $this->schemaFilePath; + libxml_use_internal_errors(true); + try { + $result = $domDocument->schemaValidate($schemaFilePath); + $errors = []; + if (!$result) { + $validationErrors = libxml_get_errors(); + if (count($validationErrors)) { + foreach ($validationErrors as $error) { + $errors[] = $this->renderErrorMessage($error, static::ERROR_FORMAT_DEFAULT); + } + } else { + $errors[] = 'Unknown validation error'; + } + } + } catch (\Exception $exception) { + libxml_use_internal_errors(false); + throw $exception; + } + libxml_use_internal_errors(false); + + return $errors; + } + + /** + * Render error message string by replacing placeholders '%field%' with properties of \LibXMLError + * + * @param \LibXMLError $errorInfo + * @return string + * @throws \Magento\Framework\Exception\LocalizedException + */ + protected function renderErrorMessage(\LibXMLError $errorInfo) + { + $result = static::ERROR_FORMAT_DEFAULT; + foreach ($errorInfo as $field => $value) { + $result = str_replace('%' . $field . '%', trim((string)$value), $result); + } + if (strpos($result, '%') !== false) { + throw new \Magento\Framework\Exception\LocalizedException( + new \Magento\Framework\Phrase( + 'Error format "' . static::ERROR_FORMAT_DEFAULT . '" contains unsupported placeholders.' + ) + ); + } + + return $result; + } + + /** + * Merge string $xml into DOM document + * + * @param string $xml + * @return void + */ + public function merge($xml) + { + if (!isset($this->domDocument)) { + $this->domDocument = $this->createDomDocument($xml); + } else { + $this->mergeNode($this->createDomDocument($xml)->documentElement); + } + } + + /** + * Get DOM document + * + * @return \DOMDocument + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function getDom() + { + if (!isset($this->domDocument)) { + throw new \Magento\Framework\Exception\LocalizedException( + new \Magento\Framework\Phrase('Object DOMDocument should be created.') + ); + } + + return $this->domDocument; + } + + /** + * Set DOM document + * + * @param \DOMDocument $domDocument + * @return void + */ + public function setDom(\DOMDocument $domDocument) + { + $this->domDocument = $domDocument; + } + + /** + * Unset DOM document + * + * @return void + */ + public function unsetDom() + { + unset($this->domDocument); + } + + /** + * Validate self contents towards to specified schema + * + * @param string|null $schemaFilePath + * @return array + */ + public function validate($schemaFilePath = null) + { + return $this->validateDomDocument($this->getDom(), $schemaFilePath); + } +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMergerInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMergerInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..0fe94609ccebb4fc3c10b20e902d1e5ab49e494c --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMergerInterface.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Config; + +/** + * Interface DomMergerInterface + */ +interface DomMergerInterface +{ + /** + * Merge $xml into DOM document + * + * @param string $xml + * @return void + */ + public function merge($xml); + + /** + * Recursive merging of the \DOMElement into the original document + * + * Algorithm: + * 1. Find the same node in original document + * 2. Extend and override original document node attributes and scalar value if found + * 3. Append new node if original document doesn't have the same node + * + * @param \DOMElement $node + * @throws \Magento\Framework\Exception\LocalizedException + * @return void + */ + public function mergeNode(\DOMElement $node); + + /** + * Get DOM document + * + * @return \DOMDocument + */ + public function getDom(); + + /** + * Set DOM document + * + * @param \DOMDocument $domDocument + * @return void + */ + public function setDom(\DOMDocument $domDocument); + + /** + * Unset DOM document + * + * @return void + */ + public function unsetDom(); + + /** + * Validate self contents towards to specified schema + * + * @param string $schemaFileName + * @return array + */ + public function validate($schemaFileName); +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollector.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollector.php new file mode 100644 index 0000000000000000000000000000000000000000..880b6bc6e1ce75f83cc6dada5ba56a2cc9329a22 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollector.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Config\FileCollector; + +use Magento\Framework\Filesystem; +use Magento\Framework\View\DesignInterface; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\View\File\CollectorInterface; +use Magento\Framework\View\Element\UiComponent\Config\FileCollectorInterface; + +/** + * Class AggregatedFileCollector + */ +class AggregatedFileCollector implements FileCollectorInterface +{ + /** + * Search pattern + * + * @var string + */ + protected $searchPattern; + + /** + * @var CollectorInterface + */ + protected $collectorAggregated; + + /** + * @var DesignInterface + */ + protected $design; + + /** + * @var Filesystem + */ + protected $filesystem; + + /** + * Constructor + * + * @param CollectorInterface $collectorAggregated + * @param DesignInterface $design + * @param Filesystem $filesystem + * @param string $searchPattern + */ + public function __construct( + CollectorInterface $collectorAggregated, + DesignInterface $design, + Filesystem $filesystem, + $searchPattern = null + ) { + $this->searchPattern = $searchPattern; + $this->collectorAggregated = $collectorAggregated; + $this->design = $design; + $this->filesystem = $filesystem; + } + + /** + * Collect files + * + * @param string|null $searchPattern + * @return array + * @throws \Exception + */ + public function collectFiles($searchPattern = null) + { + $result = []; + if ($searchPattern === null) { + $searchPattern = $this->searchPattern; + } + if ($searchPattern === null) { + throw new \Exception('Search pattern cannot be empty.'); + } + $files = $this->collectorAggregated->getFiles($this->design->getDesignTheme(), $searchPattern); + $fileReader = $this->filesystem->getDirectoryRead(DirectoryList::ROOT); + foreach ($files as $file) { + $filePath = $fileReader->getRelativePath($file->getFilename()); + $result[sprintf('%x', crc32($filePath))] = $fileReader->readFile($filePath); + } + + return $result; + } +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollectorFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollectorFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..609156211828e0afc6e5f505211e2aea2ed1a766 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollectorFactory.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Config\FileCollector; + +use Magento\Framework\ObjectManagerInterface; + +/** + * Class AggregatedFileCollectorFactory + */ +class AggregatedFileCollectorFactory +{ + const INSTANCE_NAME = 'Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollector'; + + /** + * @var ObjectManagerInterface + */ + protected $objectManager; + + /** + * Constructor + * + * @param ObjectManagerInterface $objectManager + */ + public function __construct(ObjectManagerInterface $objectManager) + { + $this->objectManager = $objectManager; + } + + /** + * Create config reader + * + * @param array $arguments + * @return AggregatedFileCollector + */ + public function create(array $arguments = []) + { + return $this->objectManager->create(static::INSTANCE_NAME, $arguments); + } +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollectorInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollectorInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..c2f74254bed42237886c862978d5a7c889c190ba --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollectorInterface.php @@ -0,0 +1,20 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Config; + +/** + * Interface FileCollectorInterface + */ +interface FileCollectorInterface +{ + /** + * Collect files + * + * @param string|null $searchPattern + * @return array + */ + public function collectFiles($searchPattern = null); +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Manager.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Manager.php new file mode 100644 index 0000000000000000000000000000000000000000..a43e1aeacc804ecfc745b6223447538ab9355734 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Manager.php @@ -0,0 +1,331 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Config; + +use ArrayObject; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Config\CacheInterface; +use Magento\Framework\View\Element\UiComponent\ArrayObjectFactory; +use Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollectorFactory; +use Magento\Framework\View\Element\UiComponent\Config\Provider\Component\Definition as ComponentDefinition; + +/** + * Class Manager + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class Manager implements ManagerInterface +{ + /** + * ID in the storage cache + */ + const CACHE_ID = 'ui_component_configuration_data'; + + /** + * Configuration provider for UI component + * + * @var ComponentDefinition + */ + protected $componentConfigProvider; + + /** + * DOM document merger + * + * @var DomMergerInterface + */ + protected $domMerger; + + /** + * Factory for UI config reader + * + * @var ReaderFactory + */ + protected $readerFactory; + + /** + * Component data + * + * @var ArrayObject + */ + protected $componentsData; + + /** + * Components pool + * + * @var ArrayObject + */ + protected $componentsPool; + + /** + * Factory for ArrayObject + * + * @var ArrayObjectFactory + */ + protected $arrayObjectFactory; + + /** + * @var AggregatedFileCollectorFactory + */ + protected $aggregatedFileCollectorFactory; + + /** + * @var CacheInterface + */ + protected $cache; + + /** + * @var UiReaderInterface[] + */ + protected $uiReader; + + /** + * Constructor + * + * @param ComponentDefinition $componentConfigProvider + * @param DomMergerInterface $domMerger + * @param ReaderFactory $readerFactory + * @param ArrayObjectFactory $arrayObjectFactory + * @param AggregatedFileCollectorFactory $aggregatedFileCollectorFactory + * @param CacheInterface $cache + */ + public function __construct( + ComponentDefinition $componentConfigProvider, + DomMergerInterface $domMerger, + ReaderFactory $readerFactory, + ArrayObjectFactory $arrayObjectFactory, + AggregatedFileCollectorFactory $aggregatedFileCollectorFactory, + CacheInterface $cache + ) { + $this->componentConfigProvider = $componentConfigProvider; + $this->domMerger = $domMerger; + $this->readerFactory = $readerFactory; + $this->arrayObjectFactory = $arrayObjectFactory; + $this->componentsData = $this->arrayObjectFactory->create(); + $this->aggregatedFileCollectorFactory = $aggregatedFileCollectorFactory; + $this->cache = $cache; + } + + /** + * Get component data + * + * @param string $name + * @return array + */ + public function getData($name) + { + return (array) $this->componentsData->offsetGet($name); + } + + /** + * Has component data + * + * @param string $name + * @return bool + */ + protected function hasData($name) + { + return $this->componentsData->offsetExists($name); + } + + /** + * Prepare the initialization data of UI components + * + * @param string $name + * @return ManagerInterface + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function prepareData($name) + { + if ($name === null || $this->hasData($name)) { + throw new LocalizedException( + new \Magento\Framework\Phrase( + 'Initialization error component, check the ' + . 'spelling of the name or the correctness of the call.' + ) + ); + } + $this->componentsPool = $this->arrayObjectFactory->create(); + + $cacheID = static::CACHE_ID . '_' . $name; + $cachedPool = $this->cache->load($cacheID); + if ($cachedPool === false) { + $this->prepare($name); + $this->cache->save($this->componentsPool->serialize(), $cacheID); + } else { + $this->componentsPool->unserialize($cachedPool); + } + $this->componentsData->offsetSet($name, $this->componentsPool); + + return $this; + } + + /** + * To create the raw data components + * + * @param string $component + * @return array + */ + public function createRawComponentData($component) + { + $componentData = $this->componentConfigProvider->getComponentData($component); + $componentData[Converter::DATA_ATTRIBUTES_KEY] = isset($componentData[Converter::DATA_ATTRIBUTES_KEY]) + ? $componentData[Converter::DATA_ATTRIBUTES_KEY] + : []; + $componentData[Converter::DATA_ARGUMENTS_KEY] = isset($componentData[Converter::DATA_ARGUMENTS_KEY]) + ? $componentData[Converter::DATA_ARGUMENTS_KEY] + : []; + + return [ + ManagerInterface::COMPONENT_ATTRIBUTES_KEY => $componentData[Converter::DATA_ATTRIBUTES_KEY], + ManagerInterface::COMPONENT_ARGUMENTS_KEY => $componentData[Converter::DATA_ARGUMENTS_KEY], + ]; + } + + /** + * Get UIReader and collect base files configuration + * + * @param string $name + * @return UiReaderInterface + */ + public function getReader($name) + { + if (!isset($this->uiReader[$name])) { + $this->domMerger->unsetDom(); + $this->uiReader[$name] = $this->readerFactory->create( + [ + 'fileCollector' => $this->aggregatedFileCollectorFactory->create( + ['searchPattern' => sprintf(ManagerInterface::SEARCH_PATTERN, $name)] + ), + 'domMerger' => $this->domMerger + ] + ); + } + + return $this->uiReader[$name]; + } + + /** + * Initialize the new component data + * + * @param string $name + * @return void + */ + protected function prepare($name) + { + $componentData = $this->getReader($name)->read(); + $componentsPool = reset($componentData); + $componentsPool = reset($componentsPool); + $componentsPool[Converter::DATA_ATTRIBUTES_KEY] = array_merge( + ['name' => $name], + $componentsPool[Converter::DATA_ATTRIBUTES_KEY] + ); + $components = $this->createDataForComponent(key($componentData), [$componentsPool]); + $this->addComponentIntoPool($name, reset($components)); + } + + /** + * Create data for component instance + * + * @param string $name + * @param array $componentsPool + * @return array + */ + protected function createDataForComponent($name, array $componentsPool) + { + $createdComponents = []; + $rootComponent = $this->createRawComponentData($name); + foreach ($componentsPool as $key => $component) { + $resultConfiguration = [ManagerInterface::CHILDREN_KEY => []]; + $instanceName = $this->createName($component, $key, $name); + $resultConfiguration[ManagerInterface::COMPONENT_ARGUMENTS_KEY] = $this->mergeArguments( + $component, + $rootComponent + ); + unset($component[Converter::DATA_ARGUMENTS_KEY]); + $resultConfiguration[ManagerInterface::COMPONENT_ATTRIBUTES_KEY] = $this->mergeAttributes( + $component, + $rootComponent + ); + unset($component[Converter::DATA_ATTRIBUTES_KEY]); + // Create inner components + foreach ($component as $subComponentName => $subComponent) { + $resultConfiguration[ManagerInterface::CHILDREN_KEY] = array_merge( + $resultConfiguration[ManagerInterface::CHILDREN_KEY], + $this->createDataForComponent($subComponentName, $subComponent) + ); + } + $createdComponents[$instanceName] = $resultConfiguration; + } + + return $createdComponents; + } + + /** + * Add a component into pool + * + * @param string $instanceName + * @param array $configuration + * @return void + */ + protected function addComponentIntoPool($instanceName, array $configuration) + { + $this->componentsPool->offsetSet($instanceName, $configuration); + } + + /** + * Merge component arguments + * + * @param array $componentData + * @param array $rootComponentData + * @return array + */ + protected function mergeArguments(array $componentData, array $rootComponentData) + { + $baseArguments = isset($rootComponentData[ManagerInterface::COMPONENT_ARGUMENTS_KEY]) + ? $rootComponentData[ManagerInterface::COMPONENT_ARGUMENTS_KEY] + : []; + $componentArguments = isset($componentData[Converter::DATA_ARGUMENTS_KEY]) + ? $componentData[Converter::DATA_ARGUMENTS_KEY] + : []; + + return array_replace_recursive($baseArguments, $componentArguments); + } + + /** + * Merge component attributes + * + * @param array $componentData + * @param array $rootComponentData + * @return array + */ + protected function mergeAttributes(array $componentData, array $rootComponentData) + { + $baseAttributes = isset($rootComponentData[ManagerInterface::COMPONENT_ATTRIBUTES_KEY]) + ? $rootComponentData[ManagerInterface::COMPONENT_ATTRIBUTES_KEY] + : []; + $componentAttributes = isset($componentData[Converter::DATA_ATTRIBUTES_KEY]) + ? $componentData[Converter::DATA_ATTRIBUTES_KEY] + : []; + unset($componentAttributes['noNamespaceSchemaLocation']); + + return array_replace_recursive($baseAttributes, $componentAttributes); + } + + /** + * Create name component instance + * + * @param array $componentData + * @param string|int $key + * @param string $componentName + * @return string + */ + protected function createName(array $componentData, $key, $componentName) + { + return isset($componentData[Converter::DATA_ATTRIBUTES_KEY][Converter::NAME_ATTRIBUTE_KEY]) + ? $componentData[Converter::DATA_ATTRIBUTES_KEY][Converter::NAME_ATTRIBUTE_KEY] + : sprintf(ManagerInterface::ANONYMOUS_TEMPLATE, $componentName, $key); + } +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/ManagerInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/ManagerInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..29f26032ad8ffc7e5efafc5274718aaa49480a21 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/ManagerInterface.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Config; + +use Magento\Framework\Exception\LocalizedException; + +/** + * Interface ManagerInterface + */ +interface ManagerInterface +{ + /** + * Search pattern + */ + const SEARCH_PATTERN = '%s.xml'; + + /** + * The anonymous template name + */ + const ANONYMOUS_TEMPLATE = 'anonymous_%s_component_%d'; + + /** + * The key arguments in the data component + */ + const COMPONENT_ARGUMENTS_KEY = 'arguments'; + + /** + * The key attributes in the data component + */ + const COMPONENT_ATTRIBUTES_KEY = 'attributes'; + + /** + * The array key sub components + */ + const CHILDREN_KEY = 'children'; + + /** + * Prepare the initialization data of UI components + * + * @param string $name + * @return ManagerInterface + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function prepareData($name); + + /** + * Get component data + * + * @param string $name + * @return array + */ + public function getData($name); + + /** + * To create the raw data components + * + * @param string $component + * @return array + */ + public function createRawComponentData($component); + + /** + * Get UIReader and collect base files configuration + * + * @param string $name + * @return UiReaderInterface + */ + public function getReader($name); +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php new file mode 100644 index 0000000000000000000000000000000000000000..7e7e27bed013d0205c3f2f00c2112b9ba635b39e --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Config\Provider\Component; + +use Magento\Framework\Config\CacheInterface; +use Magento\Framework\View\Element\UiComponent\Config\Converter; +use Magento\Framework\View\Element\UiComponent\ArrayObjectFactory; +use Magento\Framework\View\Element\UiComponent\Config\UiReaderInterface; + +/** + * Class Definition + */ +class Definition +{ + /** + * ID in the storage cache + */ + const CACHE_ID = 'ui_component_definition_data'; + + /** + * Components node name in config + */ + const COMPONENTS_KEY = 'components'; + + /** + * @var CacheInterface + */ + protected $cache; + + /** + * UI component data + * + * @var \ArrayObject + */ + protected $componentData; + + /** + * Constructor + * + * @param UiReaderInterface $uiReader + * @param ArrayObjectFactory $arrayObjectFactory + * @param CacheInterface $cache + */ + public function __construct( + UiReaderInterface $uiReader, + ArrayObjectFactory $arrayObjectFactory, + CacheInterface $cache + ) { + $this->cache = $cache; + $this->componentData = $arrayObjectFactory->create(); + $cachedData = $this->cache->load(static::CACHE_ID); + if ($cachedData === false) { + $data = $uiReader->read(); + $this->cache->save(serialize($data), static::CACHE_ID); + } else { + $data = unserialize($cachedData); + } + $this->prepareComponentData($data); + } + + /** + * Get component data + * + * @param string $name + * @return array + */ + public function getComponentData($name) + { + return (array) $this->componentData->offsetGet($name); + } + + /** + * Set component data + * + * @param string $name + * @param array $data + * @return void + */ + public function setComponentData($name, array $data) + { + $this->componentData->offsetSet($name, $data); + } + + /** + * Prepare configuration data for the component + * + * @param array $componentsData + * @return void + */ + protected function prepareComponentData(array $componentsData) + { + $componentsData = reset($componentsData[static::COMPONENTS_KEY]); + unset($componentsData[Converter::DATA_ATTRIBUTES_KEY]); + foreach ($componentsData as $name => $data) { + $this->setComponentData($name, reset($data)); + } + } +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Template.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Template.php new file mode 100644 index 0000000000000000000000000000000000000000..1c47f39a1a993e2b80a9e4d0d67fe5e1858dfe6d --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Template.php @@ -0,0 +1,111 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Config\Provider; + +use Magento\Framework\Config\CacheInterface; +use Magento\Framework\View\Element\UiComponent\Config\ReaderFactory; +use Magento\Framework\View\Element\UiComponent\Config\DomMergerInterface; +use Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollector; +use Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollectorFactory; + +/** + * Class Template + */ +class Template +{ + /** + * Components node name in config + */ + const TEMPLATE_KEY = 'template'; + + /** + * ID in the storage cache + */ + const CACHE_ID = 'ui_component_templates'; + + /** + * @var AggregatedFileCollector + */ + protected $aggregatedFileCollector; + + /** + * @var DomMergerInterface + */ + protected $domMerger; + + /** + * @var CacheInterface + */ + protected $cache; + + /** + * Factory for UI config reader + * + * @var ReaderFactory + */ + protected $readerFactory; + + /** + * @var AggregatedFileCollectorFactory + */ + protected $aggregatedFileCollectorFactory; + + /** + * @var array + */ + protected $cachedTemplates = []; + + /** + * Constructor + * + * @param AggregatedFileCollector $aggregatedFileCollector + * @param DomMergerInterface $domMerger + * @param CacheInterface $cache + * @param ReaderFactory $readerFactory + * @param AggregatedFileCollectorFactory $aggregatedFileCollectorFactory + */ + public function __construct( + AggregatedFileCollector $aggregatedFileCollector, + DomMergerInterface $domMerger, + CacheInterface $cache, + ReaderFactory $readerFactory, + AggregatedFileCollectorFactory $aggregatedFileCollectorFactory + ) { + $this->aggregatedFileCollector = $aggregatedFileCollector; + $this->domMerger = $domMerger; + $this->cache = $cache; + $this->readerFactory = $readerFactory; + $this->aggregatedFileCollectorFactory = $aggregatedFileCollectorFactory; + + $cachedTemplates = $this->cache->load(static::CACHE_ID); + $this->cachedTemplates = $cachedTemplates === false ? [] : unserialize($cachedTemplates); + } + + /** + * Get template content + * + * @param string $template + * @return string + * @throws \Exception + */ + public function getTemplate($template) + { + $hash = sprintf('%x', crc32($template)); + if (isset($this->cachedTemplates[$hash])) { + return $this->cachedTemplates[$hash]; + } + + $this->cachedTemplates[$hash] = $this->readerFactory->create( + [ + 'fileCollector' => $this->aggregatedFileCollectorFactory->create(['searchPattern' => $template]), + 'domMerger' => $this->domMerger + ] + )->getContent(); + $this->cache->save(serialize($this->cachedTemplates), static::CACHE_ID); + + return $this->cachedTemplates[$hash]; + } +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Reader.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Reader.php new file mode 100644 index 0000000000000000000000000000000000000000..13ddec6465bf1995527ec36381856640f08531fd --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Reader.php @@ -0,0 +1,117 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Config; + +use Magento\Framework\Filesystem; +use Magento\Framework\Config\ConverterInterface; +use Magento\Framework\Config\FileIteratorFactory; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Filesystem\Directory\ReadInterface; + +/** + * Class Reader + */ +class Reader implements UiReaderInterface +{ + /** + * DOM document merger + * + * @var DomMergerInterface + */ + protected $domMerger; + + /** + * XML converter + * + * @var ConverterInterface + */ + protected $converter; + + /** + * Constructor + * + * @param FileCollectorInterface $fileCollector + * @param ConverterInterface $converter + * @param DomMergerInterface $domMerger + */ + public function __construct( + FileCollectorInterface $fileCollector, + ConverterInterface $converter, + DomMergerInterface $domMerger + ) { + $this->converter = $converter; + $this->domMerger = $domMerger; + $this->readFiles($fileCollector->collectFiles()); + } + + /** + * Read configuration files + * + * @param array $fileList + * @return array + * @throws \Magento\Framework\Exception\LocalizedException + */ + protected function readFiles(array $fileList) + { + foreach ($fileList as $fileContent) { + $this->domMerger->merge($fileContent); + } + } + + /** + * Add xml content in the merged file + * + * @param string $xmlContent + * @return void + */ + public function addXMLContent($xmlContent) + { + $this->domMerger->merge($xmlContent); + } + + /** + * Add DOM node into DOM document + * + * @param \DOMNode $node + * @return void + */ + public function addNode(\DOMNode $node) + { + $this->domMerger->mergeNode($node); + } + + /** + * Load configuration scope + * + * @param string|null $scope + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function read($scope = null) + { + return $this->converter->convert($this->domMerger->getDom()); + } + + /** + * Get content from the merged files + * + * @return string + */ + public function getContent() + { + return $this->domMerger->getDom()->saveXML(); + } + + /** + * Get DOM document + * + * @return \DOMDocument + */ + public function getDOMDocument() + { + return $this->domMerger->getDom(); + } +} diff --git a/app/code/Magento/Ui/DataProvider/Factory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/ReaderFactory.php similarity index 61% rename from app/code/Magento/Ui/DataProvider/Factory.php rename to lib/internal/Magento/Framework/View/Element/UiComponent/Config/ReaderFactory.php index c24c9d58bee80128958c3062dd41070624f131e9..3efb30cb1141dd4e0621fa1c614caf7665f79a51 100644 --- a/app/code/Magento/Ui/DataProvider/Factory.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/ReaderFactory.php @@ -3,15 +3,17 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Ui\DataProvider; +namespace Magento\Framework\View\Element\UiComponent\Config; use Magento\Framework\ObjectManagerInterface; /** - * Class Factory + * Class ReaderFactory */ -class Factory +class ReaderFactory { + const INSTANCE_NAME = 'Magento\Framework\View\Element\UiComponent\Config\Reader'; + /** * @var ObjectManagerInterface */ @@ -28,14 +30,13 @@ class Factory } /** - * Create data provider + * Create config reader * - * @param string $providerClass * @param array $arguments - * @return mixed + * @return UiReaderInterface */ - public function create($providerClass, array $arguments = []) + public function create(array $arguments = []) { - return $this->objectManager->create($providerClass, ['arguments' => $arguments]); + return $this->objectManager->create(static::INSTANCE_NAME, $arguments); } } diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/UiReaderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/UiReaderInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..a9c1915131fab999a939b2bf294eaa745926f15a --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/UiReaderInterface.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Config; + +use Magento\Framework\Config\ReaderInterface; + +/** + * Interface UiReaderInterface + */ +interface UiReaderInterface extends ReaderInterface +{ + /** + * Add xml content in the merged file + * + * @param string $xmlContent + * @return void + */ + public function addXMLContent($xmlContent); + + /** + * Get content from the merged files + * + * @return string + */ + public function getContent(); + + /** + * Get DOM document + * + * @return \DOMDocument + */ + public function getDOMDocument(); + + /** + * Add DOM node into DOM document + * + * @param \DOMNode $node + * @return void + */ + public function addNode(\DOMNode $node); +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigBuilderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigBuilderInterface.php deleted file mode 100644 index bba2e86556c49b6eb924e99c2a1e6bec70109dcf..0000000000000000000000000000000000000000 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigBuilderInterface.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\View\Element\UiComponent; - -/** - * Interface ConfigBuilderInterface - */ -interface ConfigBuilderInterface -{ - /** - * Config data to JSON by output - * - * @param ConfigInterface $configuration - * @return string - */ - public function toJson(ConfigInterface $configuration); -} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigFactory.php deleted file mode 100644 index 9470ec3119f2bba2b1956c0a82d32dbda6d443bb..0000000000000000000000000000000000000000 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigFactory.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\View\Element\UiComponent; - -use Magento\Framework\ObjectManagerInterface; - -/** - * Class ConfigFactory - */ -class ConfigFactory -{ - /** - * Object Manager instance - * - * @var ObjectManagerInterface - */ - protected $objectManager = null; - - /** - * Instance name to create - * - * @var string - */ - protected $instanceName = null; - - /** - * Factory constructor - * - * @param ObjectManagerInterface $objectManager - * @param string $instanceName - */ - public function __construct( - ObjectManagerInterface $objectManager, - $instanceName = 'Magento\Framework\View\Element\UiComponent\ConfigInterface' - ) { - $this->objectManager = $objectManager; - $this->instanceName = $instanceName; - } - - /** - * Create class instance with specified parameters - * - * @param array $data - * @return \Magento\Framework\View\Element\UiComponent\ConfigInterface - */ - public function create(array $data = []) - { - return $this->objectManager->create($this->instanceName, $data); - } -} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigInterface.php deleted file mode 100644 index ad665bc3de14e7b1d5470a65f13f498b07b93c83..0000000000000000000000000000000000000000 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigInterface.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\View\Element\UiComponent; - -/** - * Class ConfigInterface - */ -interface ConfigInterface -{ - /** - * Get configuration data - * - * @param string|null $key - * @return mixed - */ - public function getData($key = null); - - /** - * Add configuration data - * - * @param string $key - * @param mixed $data - * @return mixed - */ - public function addData($key, $data); - - /** - * Update configuration data - * - * @param string $key - * @param mixed $data - * @return mixed - */ - public function updateData($key, $data); - - /** - * Get owner name - * - * @return string - */ - public function getName(); - - /** - * Get owner parent name - * - * @return string - */ - public function getParentName(); -} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageBuilderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageBuilderInterface.php deleted file mode 100644 index ef081fd327d6f7a2a82f2f520cf6996e615426fe..0000000000000000000000000000000000000000 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageBuilderInterface.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\View\Element\UiComponent; - -/** - * Interface ConfigStorageBuilderInterface - */ -interface ConfigStorageBuilderInterface -{ - /** - * Config storage data to JSON by output - * - * @param ConfigStorageInterface $storage - * @param string $parentName - * @return string - */ - public function toJson(ConfigStorageInterface $storage, $parentName = null); -} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageInterface.php deleted file mode 100644 index 3b31ff3e7de77de41d104050c5b929dbc818669e..0000000000000000000000000000000000000000 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageInterface.php +++ /dev/null @@ -1,222 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\View\Element\UiComponent; - -use Magento\Framework\Api\CriteriaInterface; -use Magento\Framework\Data\CollectionDataSourceInterface; - -/** - * Class ConfigurationStorageInterface - */ -interface ConfigStorageInterface -{ - /** - * Register component - * - * @param string $name - * @param array $data - * @return mixed - */ - public function addComponent($name, $data); - - /** - * Add components configuration - * - * @param ConfigInterface $config - * @return void - */ - public function addComponentsData(ConfigInterface $config); - - /** - * Remove components configuration - * - * @param ConfigInterface $configuration - * @return void - */ - public function removeComponentsData(ConfigInterface $configuration); - - /** - * Get components configuration - * - * @param string|null $name - * @return ConfigInterface|null|array - */ - public function getComponentsData($name = null); - - /** - * @return array - */ - public function getComponents(); - - /** - * Add data in storage - * - * @param string $name - * @param array $dataSource - * @return void - */ - public function addDataSource($name, array $dataSource); - - /** - * Remove data in storage - * - * @param string $name - * @return void - */ - public function removeDataSource($name); - - /** - * Get data from storage - * - * @param string|null $name - * @return array|null - */ - public function getDataSource($name = null); - - /** - * Update data in storage - * - * @param string $name - * @param array $dataSource - * @return void - */ - public function updateDataSource($name, array $dataSource); - - /** - * Add meta data - * - * @param string $key - * @param array $data - * @return mixed - */ - public function addMeta($key, array $data); - - /** - * Remove meta data - * - * @param string $key - * @return array - */ - public function removeMeta($key); - - /** - * Get meta data - * - * @param string|null $key - * @return array|null - */ - public function getMeta($key = null); - - /** - * Update meta data in storage - * - * @param string $key - * @param array $data - * @return void - */ - public function updateMeta($key, array $data); - - /** - * @return array - */ - public function getMetaKeys(); - - /** - * Set data collection - * - * @param string $key - * @param CollectionDataSourceInterface|CriteriaInterface $dataCollection - * @return void - */ - public function addDataCollection($key, CollectionDataSourceInterface $dataCollection); - - /** - * Get data collection - * - * @param string|null $key - * @return CollectionDataSourceInterface|CriteriaInterface - */ - public function getDataCollection($key = null); - - /** - * Update data collection in storage - * - * @param string $key - * @param CollectionDataSourceInterface|CriteriaInterface $dataCollection - * @return mixed - */ - public function updateDataCollection($key, CollectionDataSourceInterface $dataCollection); - - /** - * Add cloud data in storage - * - * @param string $key - * @param array $data - * @return void - */ - public function addGlobalData($key, array $data); - - /** - * Remove cloud data in storage - * - * @param string $key - * @return void - */ - public function removeGlobalData($key); - - /** - * Get cloud data from storage - * - * @param string|null $key - * @return array|null - */ - public function getGlobalData($key = null); - - /** - * @param string $key - * @param DataProviderInterface $dataProvider - * @return void - */ - public function addDataProvider($key, DataProviderInterface $dataProvider); - - /** - * @param string $key - * @return void - */ - public function removeDataProvider($key); - - /** - * @param null|string $key - * @return DataProviderInterface[]|DataProviderInterface|null - */ - public function getDataProvider($key = null); - - /** - * @param string $key - * @param DataProviderInterface $dataProvider - * @return void - */ - public function updateDataProvider($key, DataProviderInterface $dataProvider); - - /** - * @param string $dataScope - * @param array $structure - * @return void - */ - public function addLayoutStructure($dataScope, array $structure); - - /** - * @return array - */ - public function getLayoutStructure(); - - /** - * @param string $name - * @param mixed $default - * @return array - */ - public function getLayoutNode($name, $default = null); -} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContainerInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContainerInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..4966134eaf77811bc53bf5d1cd6bb5cafdba74a7 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContainerInterface.php @@ -0,0 +1,16 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent; + +use Magento\Framework\View\Element\BlockInterface; + +/** + * Interface ContainerInterface + */ +interface ContainerInterface extends BlockInterface +{ + // +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/AbstractContentType.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/AbstractContentType.php new file mode 100644 index 0000000000000000000000000000000000000000..72c021138f7892e7ae8e24d71f00ac7252fe3a14 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/AbstractContentType.php @@ -0,0 +1,39 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\ContentType; + +use Magento\Framework\View\FileSystem; +use Magento\Framework\View\TemplateEnginePool; + +/** + * Class AbstractContentType + */ +abstract class AbstractContentType implements ContentTypeInterface +{ + /** + * @var FileSystem + */ + protected $filesystem; + + /** + * @var TemplateEnginePool + */ + protected $templateEnginePool; + + /** + * Constructor + * + * @param FileSystem $filesystem + * @param TemplateEnginePool $templateEnginePool + */ + public function __construct( + FileSystem $filesystem, + TemplateEnginePool $templateEnginePool + ) { + $this->filesystem = $filesystem; + $this->templateEnginePool = $templateEnginePool; + } +} diff --git a/app/code/Magento/Ui/ContentType/ContentTypeFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/ContentTypeFactory.php similarity index 72% rename from app/code/Magento/Ui/ContentType/ContentTypeFactory.php rename to lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/ContentTypeFactory.php index 5bdda92584f66a60744b4e22b654b89110086a0d..886331cf65935b7662688e42fcf22c5c009cf162 100644 --- a/app/code/Magento/Ui/ContentType/ContentTypeFactory.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/ContentTypeFactory.php @@ -3,7 +3,7 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Ui\ContentType; +namespace Magento\Framework\View\Element\UiComponent\ContentType; use Magento\Framework\ObjectManagerInterface; @@ -12,26 +12,17 @@ use Magento\Framework\ObjectManagerInterface; */ class ContentTypeFactory { - /** - * Default content type - */ - const DEFAULT_TYPE = 'html'; - /** * Content types * * @var array */ - protected $types = [ - 'html' => 'Magento\Ui\ContentType\Html', - 'json' => 'Magento\Ui\ContentType\Json', - 'xml' => 'Magento\Ui\ContentType\Xml', - ]; + protected $types; /** * Object manager * - * @var \Magento\Framework\ObjectManagerInterface + * @var ObjectManagerInterface */ protected $objectManager; @@ -41,9 +32,9 @@ class ContentTypeFactory * @param ObjectManagerInterface $objectManager * @param array $types */ - public function __construct(ObjectManagerInterface $objectManager, array $types = []) + public function __construct(ObjectManagerInterface $objectManager, array $types) { - $this->types = array_merge($this->types, $types); + $this->types = $types; $this->objectManager = $objectManager; } @@ -54,7 +45,7 @@ class ContentTypeFactory * @return ContentTypeInterface * @throws \InvalidArgumentException */ - public function get($type = ContentTypeFactory::DEFAULT_TYPE) + public function get($type) { if (!isset($this->types[$type])) { throw new \InvalidArgumentException(sprintf("Wrong content type '%s', renderer not exists.", $type)); diff --git a/app/code/Magento/Ui/ContentType/ContentTypeInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/ContentTypeInterface.php similarity index 55% rename from app/code/Magento/Ui/ContentType/ContentTypeInterface.php rename to lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/ContentTypeInterface.php index 575c42e77d1dd9f0b6108be376c61654e9ce6656..cbefd547d9caae922abf02085c51feeb603d29f8 100644 --- a/app/code/Magento/Ui/ContentType/ContentTypeInterface.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/ContentTypeInterface.php @@ -3,7 +3,7 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Ui\ContentType; +namespace Magento\Framework\View\Element\UiComponent\ContentType; use Magento\Framework\View\Element\UiComponentInterface; @@ -13,11 +13,11 @@ use Magento\Framework\View\Element\UiComponentInterface; interface ContentTypeInterface { /** - * Render data + * Render component * - * @param UiComponentInterface $view + * @param UiComponentInterface $component * @param string $template - * @return mixed + * @return string */ - public function render(UiComponentInterface $view, $template = ''); + public function render(UiComponentInterface $component, $template = ''); } diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Html.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Html.php new file mode 100644 index 0000000000000000000000000000000000000000..4283327e3e86bd5ecd8eb6486d66a8c2489da20c --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Html.php @@ -0,0 +1,49 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\ContentType; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Class Html + */ +class Html extends AbstractContentType +{ + /** + * Render data + * + * @param UiComponentInterface $component + * @param string $template + * @return string + */ + public function render(UiComponentInterface $component, $template = '') + { + $result = ''; + if ($template) { + $extension = pathinfo($template, PATHINFO_EXTENSION); + $templateEngine = $this->templateEnginePool->get($extension); + $result = $templateEngine->render($component, $this->getTemplate($extension, $template)); + } + return $result; + } + + /** + * Get template path + * + * @param string $extension + * @param string $template + * @return string + */ + protected function getTemplate($extension, $template) + { + switch ($extension) { + case 'xhtml': + return $template; + default: + return $this->filesystem->getTemplateFileName($template); + } + } +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Json.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Json.php new file mode 100644 index 0000000000000000000000000000000000000000..3185bc6cb2ac0b83581502f57e48607b624257ab --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Json.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\ContentType; + +use Magento\Framework\View\FileSystem; +use Magento\Framework\View\TemplateEnginePool; +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Class Json + */ +class Json extends AbstractContentType +{ + /** + * Constructor + * + * @param FileSystem $filesystem + * @param TemplateEnginePool $templateEnginePool + */ + public function __construct( + FileSystem $filesystem, + TemplateEnginePool $templateEnginePool + ) { + parent::__construct($filesystem, $templateEnginePool); + } + + /** + * Render data + * + * @param UiComponentInterface $component + * @param string $template + * @return string + * @throws \Exception + */ + public function render(UiComponentInterface $component, $template = '') + { + $data = $component->getDataSourceData(); + $data = reset($data); + + return json_encode($data['config']['data']); + } +} diff --git a/app/code/Magento/Ui/ContentType/Xml.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Xml.php similarity index 82% rename from app/code/Magento/Ui/ContentType/Xml.php rename to lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Xml.php index 065a34d73a17f71633cc5ee3ea702bd1e4d77915..9715e8d6ea510e4861d6e5cc3ed4535baa303e9e 100644 --- a/app/code/Magento/Ui/ContentType/Xml.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Xml.php @@ -3,43 +3,47 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Ui\ContentType; +namespace Magento\Framework\View\Element\UiComponent\ContentType; -use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\Xml\Generator; use Magento\Framework\View\FileSystem; use Magento\Framework\View\TemplateEnginePool; -use Magento\Framework\Xml\Generator; +use Magento\Framework\View\Element\UiComponentInterface; /** * Class Xml */ -class Xml implements ContentTypeInterface +class Xml extends AbstractContentType { /** - * @var \Magento\Framework\View\FileSystem + * @var FileSystem */ protected $filesystem; /** - * @var \Magento\Framework\View\TemplateEnginePool + * @var TemplateEnginePool */ protected $templateEnginePool; /** - * @var \Magento\Framework\Xml\Generator + * @var Generator */ protected $generator; /** + * Constructor + * * @param FileSystem $filesystem * @param TemplateEnginePool $templateEnginePool * @param Generator $generator */ - public function __construct(FileSystem $filesystem, TemplateEnginePool $templateEnginePool, Generator $generator) - { - $this->filesystem = $filesystem; - $this->templateEnginePool = $templateEnginePool; + public function __construct( + FileSystem $filesystem, + TemplateEnginePool $templateEnginePool, + Generator $generator + ) { $this->generator = $generator; + parent::__construct($filesystem, $templateEnginePool); } /** @@ -48,6 +52,7 @@ class Xml implements ContentTypeInterface * @param UiComponentInterface $view * @param string $template * @return string + * @throws \Exception */ public function render(UiComponentInterface $view, $template = '') { @@ -62,7 +67,8 @@ class Xml implements ContentTypeInterface } else { $result = $this->getDataXml($view); } - return $result; + + throw new \Exception('Please implement XML renderer'); } /** diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php index 582fad08370f42cba9aac5880f3fd353e8adfc78..2e9e35bce7ef1db4cc563e3d15d3ffed00f6f85e 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php @@ -5,29 +5,32 @@ */ namespace Magento\Framework\View\Element\UiComponent; +use Magento\Framework\UrlInterface; use Magento\Framework\App\RequestInterface; -use Magento\Framework\Registry; -use Magento\Framework\View\Element\UiComponentFactory; -use Magento\Framework\View\LayoutInterface; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\Control\ActionPoolFactory; +use Magento\Framework\View\Element\UiComponent\Control\ActionPoolInterface; +use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderFactory; +use Magento\Framework\View\Element\UiComponent\ContentType\ContentTypeFactory; +use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; +use Magento\Framework\View\Element\UiComponent\ContentType\ContentTypeInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; +use Magento\Framework\View\LayoutInterface as PageLayoutInterface; /** * Class Context */ -class Context extends Registry +class Context implements ContextInterface { /** - * Configuration storage builder - * - * @var ConfigStorageBuilderInterface + * @var string */ - protected $configStorageBuilder; + protected $namespace; /** - * Configuration storage - * - * @var ConfigStorageInterface + * @var DataProviderInterface */ - protected $configStorage; + protected $dataProvider; /** * Application request @@ -36,6 +39,13 @@ class Context extends Registry */ protected $request; + /** + * Factory renderer for a content type + * + * @var ContentTypeFactory + */ + protected $contentTypeFactory; + /** * Accept type * @@ -44,191 +54,249 @@ class Context extends Registry protected $acceptType; /** - * @var LayoutInterface + * @var PageLayoutInterface */ protected $pageLayout; /** - * @var LayoutInterface + * @var ButtonProviderFactory */ - protected $layout; + protected $buttonProviderFactory; /** - * @var UiComponentFactory + * @var ActionPoolInterface */ - protected $factory; + protected $actionPool; /** - * Data Namespace + * Registry components * - * @var string + * @var array */ - protected $namespace; + protected $componentsDefinitions = []; /** - * Constructor + * Url Builder * - * @param ConfigStorageInterface $configStorage - * @param ConfigStorageBuilderInterface $configStorageBuilder + * @var UrlInterface + */ + protected $urlBuilder; + + /** + * @param PageLayoutInterface $pageLayout * @param RequestInterface $request + * @param ButtonProviderFactory $buttonProviderFactory + * @param ActionPoolFactory $actionPoolFactory + * @param ContentTypeFactory $contentTypeFactory + * @param UrlInterface $urlBuilder + * @param DataProviderInterface|null $dataProvider + * @param string $namespace */ public function __construct( - ConfigStorageInterface $configStorage, - ConfigStorageBuilderInterface $configStorageBuilder, - RequestInterface $request + PageLayoutInterface $pageLayout, + RequestInterface $request, + ButtonProviderFactory $buttonProviderFactory, + ActionPoolFactory $actionPoolFactory, + ContentTypeFactory $contentTypeFactory, + UrlInterface $urlBuilder, + DataProviderInterface $dataProvider = null, + $namespace = null ) { - $this->configStorage = $configStorage; - $this->configStorageBuilder = $configStorageBuilder; + $this->namespace = $namespace; $this->request = $request; + $this->buttonProviderFactory = $buttonProviderFactory; + $this->dataProvider = $dataProvider; + $this->pageLayout = $pageLayout; + $this->actionPool = $actionPoolFactory->create(['context' => $this]); + $this->contentTypeFactory = $contentTypeFactory; + $this->urlBuilder = $urlBuilder; + $this->setAcceptType(); } /** - * Getting requested accept type + * Add component into registry * + * @param string $name + * @param array $config * @return void */ - protected function setAcceptType() + public function addComponentDefinition($name, array $config) { - $this->acceptType = 'xml'; - - $rawAcceptType = $this->request->getHeader('Accept'); - if (strpos($rawAcceptType, 'json') !== false) { - $this->acceptType = 'json'; - } elseif (strpos($rawAcceptType, 'html') !== false) { - $this->acceptType = 'html'; + if (!isset($this->componentsDefinitions[$name])) { + $this->componentsDefinitions[$name] = $config; } } /** - * Getting accept type + * To get the registry components * - * @return string + * @return array */ - public function getAcceptType() + public function getComponentsDefinitions() { - return $this->acceptType; + return $this->componentsDefinitions; } /** - * Set Ui Components Factory + * Get render engine * - * @param UiComponentFactory $render - * @return void + * @return ContentTypeInterface */ - public function setRender(UiComponentFactory $render) + public function getRenderEngine() { - $this->factory = $render; + return $this->contentTypeFactory->get($this->getAcceptType()); } /** - * Get Ui Components Factory - * - * @return UiComponentFactory + * @return string */ - public function getRender() + public function getNamespace() { - return $this->factory; + return $this->namespace; } /** - * Set root layout + * Getting accept type * - * @param LayoutInterface $layout - * @return void + * @return string */ - public function setPageLayout(LayoutInterface $layout) + public function getAcceptType() { - $this->pageLayout = $layout; + return $this->acceptType; } /** - * Get root layout + * Getting all request data * - * @return LayoutInterface + * @return mixed */ - public function getPageLayout() + public function getRequestParams() { - return $this->pageLayout; + return $this->request->getParams(); } /** - * Set root view + * Getting data according to the key * - * @param string $namespace - * @return void + * @param string $key + * @param mixed|null $defaultValue + * @return mixed */ - public function setNamespace($namespace) + public function getRequestParam($key, $defaultValue = null) { - $this->namespace = $namespace; + return $this->request->getParam($key, $defaultValue); } /** - * Get root view + * Get data provider * - * @return string + * @return DataProviderInterface */ - public function getNamespace() + public function getDataProvider() { - return $this->namespace; + return $this->dataProvider; } /** - * Getting all request data + * Get page layout * - * @return mixed + * @return PageLayoutInterface */ - public function getRequestParams() + public function getPageLayout() { - return $this->request->getParams(); + return $this->pageLayout; } /** - * Getting data according to the key + * Add button in the actions toolbar * - * @param string $key - * @param mixed|null $defaultValue - * @return mixed + * @param array $buttons + * @param UiComponentInterface $component + * @return void */ - public function getRequestParam($key, $defaultValue = null) + public function addButtons(array $buttons, UiComponentInterface $component) { - return $this->request->getParam($key, $defaultValue); + if (!empty($buttons)) { + foreach ($buttons as $buttonId => $buttonData) { + if (is_array($buttonData)) { + $buttons[$buttonId] = $buttonData; + continue; + } + /** @var ButtonProviderInterface $button */ + $button = $this->buttonProviderFactory->create($buttonData); + $buttonData = $button->getButtonData(); + if (!$buttonData) { + unset($buttons[$buttonId]); + continue; + } + $buttons[$buttonId] = $buttonData; + } + uasort($buttons, [$this, 'sortButtons']); + + foreach ($buttons as $buttonId => $buttonData) { + if (isset($buttonData['url'])) { + $buttonData['url'] = $this->getUrl($buttonData['url']); + } + $this->actionPool->add($buttonId, $buttonData, $component); + } + } } /** - * Get storage configuration + * Sort buttons by sort order * - * @return ConfigStorageInterface + * @param array $itemA + * @param array $itemB + * @return int */ - public function getStorage() + public function sortButtons(array $itemA, array $itemB) { - return $this->configStorage; + $sortOrderA = isset($itemA['sort_order']) ? intval($itemA['sort_order']) : 0; + $sortOrderB = isset($itemB['sort_order']) ? intval($itemB['sort_order']) : 0; + + return $sortOrderA - $sortOrderB; } /** - * Get configuration builder + * Getting requested accept type * - * @return ConfigStorageBuilderInterface + * @return void */ - public function getConfigBuilder() + protected function setAcceptType() { - return $this->configStorageBuilder; + $this->acceptType = 'html'; + + $rawAcceptType = $this->request->getHeader('Accept'); + if ($this->request->getParam('isAjax') === 'true' || strpos($rawAcceptType, 'json') !== false) { + $this->acceptType = 'json'; + } else if (strpos($rawAcceptType, 'html') !== false) { + $this->acceptType = 'html'; + } else if (strpos($rawAcceptType, 'xml') !== false) { + $this->acceptType = 'xml'; + } } /** - * @param LayoutInterface $layout + * Set data provider + * + * @param DataProviderInterface $dataProvider * @return void */ - public function setLayout(LayoutInterface $layout) + public function setDataProvider(DataProviderInterface $dataProvider) { - $this->layout = $layout; + $this->dataProvider = $dataProvider; } /** - * @return LayoutInterface + * Generate url by route and parameters + * + * @param string $route + * @param array $params + * @return string */ - public function getLayout() + public function getUrl($route = '', $params = []) { - return $this->layout; + return $this->urlBuilder->getUrl($route, $params); } } diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContextFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContextFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..5708da5d21278eb8342e92c4cd753e81e3158d40 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContextFactory.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent; + +use Magento\Framework\ObjectManagerInterface; + +/** + * Class ContextFactory + */ +class ContextFactory +{ + const INSTANCE_NAME = 'Magento\Framework\View\Element\UiComponent\ContextInterface'; + + /** + * @var ObjectManagerInterface + */ + protected $objectManager; + + /** + * Constructor + * + * @param ObjectManagerInterface $objectManager + */ + public function __construct(ObjectManagerInterface $objectManager) + { + $this->objectManager = $objectManager; + } + + /** + * Create context + * + * @param array $arguments + * @return ContextInterface + */ + public function create(array $arguments = []) + { + return $this->objectManager->create(static::INSTANCE_NAME, $arguments); + } +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContextInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContextInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..321f2cc5b2e066774a462c6a424edc4f43694384 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContextInterface.php @@ -0,0 +1,110 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent; + +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\ContentType\ContentTypeInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; +use Magento\Framework\View\LayoutInterface as PageLayoutInterface; + +/** + * Interface ContextInterface + */ +interface ContextInterface +{ + /** + * Add components definition + * + * @param string $name + * @param array $config + * @return void + */ + public function addComponentDefinition($name, array $config); + + /** + * Get components definitions + * + * @return array + */ + public function getComponentsDefinitions(); + + /** + * Getting root component name + * + * @return string + */ + public function getNamespace(); + + /** + * Getting accept type + * + * @return string + */ + public function getAcceptType(); + + /** + * Set data provider + * + * @param DataProviderInterface $dataProvider + * @return void + */ + public function setDataProvider(DataProviderInterface $dataProvider); + + /** + * Get data provider + * + * @return DataProviderInterface + */ + public function getDataProvider(); + + /** + * Getting all request data + * + * @return mixed + */ + public function getRequestParams(); + + /** + * Getting data according to the key + * + * @param string $key + * @param mixed|null $defaultValue + * @return mixed + */ + public function getRequestParam($key, $defaultValue = null); + + /** + * Get root layout + * + * @return PageLayoutInterface + */ + public function getPageLayout(); + + /** + * Add button in the actions toolbar + * + * @param array $buttons + * @param UiComponentInterface $component + * @return void + */ + public function addButtons(array $buttons, UiComponentInterface $component); + + /** + * Get render engine + * + * @return ContentTypeInterface + */ + public function getRenderEngine(); + + /** + * Generate url by route and parameters + * + * @param string $route + * @param array $params + * @return string + */ + public function getUrl($route = '', $params = []); +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ActionPoolFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ActionPoolFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..477ff99cebcb3ce5a129184330c43f4e47b4abc1 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ActionPoolFactory.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Control; + +use Magento\Framework\ObjectManagerInterface; + +/** + * Class ActionPoolFactory + */ +class ActionPoolFactory +{ + const INSTANCE = 'Magento\Framework\View\Element\UiComponent\Control\ActionPoolInterface'; + + /** + * @var ObjectManagerInterface + */ + protected $objectManager; + + /** + * Constructor + * + * @param ObjectManagerInterface $objectManager + */ + public function __construct(ObjectManagerInterface $objectManager) + { + $this->objectManager = $objectManager; + } + + /** + * Create Action Pool + * + * @param array $arguments + * @return ActionPoolInterface + */ + public function create(array $arguments = []) + { + return $this->objectManager->create(static::INSTANCE, $arguments); + } +} diff --git a/app/code/Magento/Ui/Component/Control/ActionPoolInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ActionPoolInterface.php similarity index 76% rename from app/code/Magento/Ui/Component/Control/ActionPoolInterface.php rename to lib/internal/Magento/Framework/View/Element/UiComponent/Control/ActionPoolInterface.php index 2a9d361a58f59c1c0ce9e7364eef0110c7e1a8b6..225bfe0dcf81b7faef0e797b4629bc7c0ec7a32e 100644 --- a/app/code/Magento/Ui/Component/Control/ActionPoolInterface.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ActionPoolInterface.php @@ -3,8 +3,9 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Ui\Component\Control; +namespace Magento\Framework\View\Element\UiComponent\Control; +use Magento\Framework\View\Element\BlockInterface; use Magento\Framework\View\Element\UiComponentInterface; /** @@ -38,4 +39,11 @@ interface ActionPoolInterface * @return void */ public function update($key, array $data); + + /** + * Get toolbar block + * + * @return bool|BlockInterface + */ + public function getToolbar(); } diff --git a/app/code/Magento/Ui/Component/Control/ButtonProviderFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ButtonProviderFactory.php similarity index 93% rename from app/code/Magento/Ui/Component/Control/ButtonProviderFactory.php rename to lib/internal/Magento/Framework/View/Element/UiComponent/Control/ButtonProviderFactory.php index c30c7a0f9ced52d49d42778a52063f4f27abca66..b4fe0c6561ebe8d033d2b58776b93819c4683e6f 100644 --- a/app/code/Magento/Ui/Component/Control/ButtonProviderFactory.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ButtonProviderFactory.php @@ -3,13 +3,12 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Ui\Component\Control; +namespace Magento\Framework\View\Element\UiComponent\Control; use Magento\Framework\ObjectManagerInterface; /** * Class ButtonProviderFactory - * @package Magento\Ui\DataProvider */ class ButtonProviderFactory { @@ -43,6 +42,7 @@ class ButtonProviderFactory sprintf('"%s" must implement the interface ButtonProviderInterface.', $providerClass) ); } + return $object; } } diff --git a/app/code/Magento/Ui/Component/Control/ButtonProviderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ButtonProviderInterface.php similarity index 76% rename from app/code/Magento/Ui/Component/Control/ButtonProviderInterface.php rename to lib/internal/Magento/Framework/View/Element/UiComponent/Control/ButtonProviderInterface.php index 508ae595faac9f4b5929e04a5d6edbe16952e8bb..160968779bd5384033f1e617b3506ec99f1a5e09 100644 --- a/app/code/Magento/Ui/Component/Control/ButtonProviderInterface.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ButtonProviderInterface.php @@ -3,11 +3,10 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Ui\Component\Control; +namespace Magento\Framework\View\Element\UiComponent\Control; /** * Interface ButtonProviderInterface - * @package Magento\Ui\Component\Control */ interface ButtonProviderInterface { diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ControlInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ControlInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..2b5870a14a36e50048338dcac6dac21973c1c263 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Control/ControlInterface.php @@ -0,0 +1,16 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\Control; + +use Magento\Framework\View\Element\BlockInterface; + +/** + * Interface ControlInterface + */ +interface ControlInterface extends BlockInterface +{ + // +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/DataProviderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/DataProviderInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..034e0fa56c6c448229160f3272384652ce70a158 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/DataProviderInterface.php @@ -0,0 +1,125 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent\DataProvider; + +/** + * Interface DataProviderInterface + */ +interface DataProviderInterface +{ + /** + * Get config data + * + * @return mixed + */ + public function getConfigData(); + + /** + * Set config data + * + * @param mixed $config + * @return void + */ + public function setConfigData($config); + + /** + * @return array + */ + public function getMeta(); + + /** + * @param string $fieldSetName + * @param string $fieldName + * @return array + */ + public function getFieldMetaInfo($fieldSetName, $fieldName); + + /** + * @param string $fieldSetName + * @return array + */ + public function getFieldsMetaInfo($fieldSetName); + + /** + * Get primary field name + * + * @return string + */ + public function getPrimaryFieldName(); + + /** + * Get field name in request + * + * @return string + */ + public function getRequestFieldName(); + + /** + * Get data + * + * @return mixed + */ + public function getData(); + + /** + * Add field to select + * + * @param string|array $field + * @param string|null $alias + * @return void + */ + public function addField($field, $alias = null); + + /** + * Add field filter to collection + * + * @param string|array $field + * @param string|int|array|null $condition + * @return void + */ + public function addFilter($field, $condition = null); + + /** + * Add ORDER BY to the end or to the beginning + * + * @param string $field + * @param string $direction + * @return void + */ + public function addOrder($field, $direction); + + /** + * Set Query limit + * + * @param int $offset + * @param int $size + * @return void + */ + public function setLimit($offset, $size); + + /** + * Removes field from select + * + * @param string|null $field + * @param bool $isAlias Alias identifier + * @return void + */ + public function removeField($field, $isAlias = false); + + /** + * Removes all fields from select + * + * @return void + */ + public function removeAllFields(); + + /** + * Retrieve count of loaded items + * + * @return int + */ + public function count(); +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/DataProviderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/DataProviderInterface.php deleted file mode 100644 index 2ba4ce76daf8ea7d97421c6266b2b5bf6cd6cef2..0000000000000000000000000000000000000000 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/DataProviderInterface.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\View\Element\UiComponent; - -/** - * Interface DataProviderInterface - * @package Magento\Framework\View\Element\UiComponent - */ -interface DataProviderInterface -{ - /** - * Get meta data - * - * @return array - */ - public function getMeta(); - - /** - * Get data - * - * @return array - */ - public function getData(); -} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/DataSourceInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/DataSourceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..d2d8f67167ab159d90b297f56935461f32481031 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/DataSourceInterface.php @@ -0,0 +1,20 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent; + +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Interface DataSourceInterface + */ +interface DataSourceInterface extends UiComponentInterface +{ + /** + * @return DataProviderInterface + */ + public function getDataProvider(); +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/JsConfigInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/JsConfigInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..0826398d684042927ad8675b0cc6ae75cf68c7e2 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/JsConfigInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Interface JsConfigInterface + */ +interface JsConfigInterface extends UiComponentInterface +{ + /** + * Get JS config + * + * @return array|string + */ + public function getJsConfig(); +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/LayoutInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/LayoutInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..d5d98ecace047ea3ac1587a5f45ceca14fd1992d --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/LayoutInterface.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\View\Element\UiComponent; + +use Magento\Framework\View\Element\UiComponentInterface; + +/** + * Interface LayoutInterface + */ +interface LayoutInterface +{ + const SECTIONS_KEY = 'sections'; + + const AREAS_KEY = 'areas'; + + const GROUPS_KEY = 'groups'; + + const ELEMENTS_KEY = 'elements'; + + const DATA_SOURCE_KEY = 'data_source'; + + /** + * @param UiComponentInterface $component + * @return array + */ + public function build(UiComponentInterface $component); +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php index 48239e9c92261b3b62ae5e0e19b942f2ff21fd72..a1b37315a3a1c632053ea0f39b5766151ac61796 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php @@ -6,9 +6,11 @@ namespace Magento\Framework\View\Element; use Magento\Framework\Object; -use Magento\Framework\View\Element\UiComponent\Context as RenderContext; -use Magento\Framework\View\LayoutFactory; -use Magento\Framework\View\LayoutInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Data\Argument\InterpreterInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponent\Config\ManagerInterface; /** * Class UiComponentFactory @@ -16,172 +18,154 @@ use Magento\Framework\View\LayoutInterface; class UiComponentFactory extends Object { /** - * Ui element view + * Object manager * - * @var UiComponentInterface + * @var ObjectManagerInterface */ - protected $view; + protected $objectManager; /** - * Render context + * UI component manager * - * @var RenderContext + * @var ManagerInterface */ - protected $renderContext; + protected $componentManager; /** - * Layout Interface + * Argument interpreter * - * @var \Magento\Framework\View\LayoutFactory + * @var InterpreterInterface */ - protected $layoutFactory; - - /** - * @var LayoutInterface - */ - protected $layout; - - /** - * @var bool - */ - protected $layoutLoaded = false; + protected $argumentInterpreter; /** * Constructor * - * @param RenderContext $renderContext - * @param LayoutFactory $layoutFactory + * @param ObjectManagerInterface $objectManager + * @param ManagerInterface $componentManager + * @param InterpreterInterface $argumentInterpreter * @param array $data */ public function __construct( - RenderContext $renderContext, - LayoutFactory $layoutFactory, + ObjectManagerInterface $objectManager, + ManagerInterface $componentManager, + InterpreterInterface $argumentInterpreter, array $data = [] ) { - $this->renderContext = $renderContext; - $this->renderContext->setRender($this); - $this->layoutFactory = $layoutFactory; + $this->objectManager = $objectManager; + $this->componentManager = $componentManager; + $this->argumentInterpreter = $argumentInterpreter; parent::__construct($data); } /** - * Get component name - * - * @return string - */ - public function getComponent() - { - return $this->getData('configuration/component'); - } - - /** - * Get layout handle - * - * @return string - */ - public function getLayoutHandle() - { - return $this->getData('configuration/name'); - } - - /** - * @param LayoutInterface $layout - * @return void - */ - public function setLayout(LayoutInterface $layout) - { - if (!$this->renderContext->getPageLayout()) { - $this->renderContext->setPageLayout($layout); - } - } - - /** - * Create Ui Component instance + * Create child components * - * @param string $componentName - * @param string $handleName - * @param array $arguments + * @param array $bundleComponents + * @param ContextInterface $renderContext + * @param string $identifier * @return UiComponentInterface */ - public function createUiComponent($componentName, $handleName, array $arguments = []) - { - if (!$this->layout) { - $this->renderContext->setNamespace($handleName); - $this->layout = $this->layoutFactory->create(); - $this->renderContext->setLayout($this->layout); - $this->layout->getUpdate()->addHandle('ui_components'); - $this->layout->getUpdate()->addHandle($handleName); - $this->loadLayout(); - $this->layoutLoaded = true; + protected function createChildComponent( + array $bundleComponents, + ContextInterface $renderContext, + $identifier + ) { + list($className, $arguments) = $this->argumentsResolver($identifier, $bundleComponents); + if (isset($arguments['data']['disabled']) && $arguments['data']['disabled'] === 'true') { + return null; } - - $view = $this->getUiElementView($componentName); - $view->update($arguments); - if ($this->layoutLoaded) { - $this->prepare($view); + $components = []; + foreach ($bundleComponents['children'] as $childrenIdentifier => $childrenData) { + $children = $this->createChildComponent( + $childrenData, + $renderContext, + $childrenIdentifier + ); + $components[$childrenIdentifier] = $children; + } + $components = array_filter($components); + $arguments['components'] = $components; + if (!isset($arguments['context'])) { + $arguments['context'] = $renderContext; } - return $view; + return $this->objectManager->create($className, $arguments); } /** - * Prepare UI Component data + * Resolve arguments * - * @param object $view - * @return void + * @param string $identifier + * @param array $componentData + * @return array */ - protected function prepare($view) + protected function argumentsResolver($identifier, array $componentData) { - if ($view instanceof UiComponentInterface) { - $view->prepare(); + $attributes = $componentData[ManagerInterface::COMPONENT_ATTRIBUTES_KEY]; + $className = $attributes['class']; + unset($attributes['class']); + $arguments = []; + foreach ($componentData[ManagerInterface::COMPONENT_ARGUMENTS_KEY] as $name => $argument) { + $arguments[$name] = $this->argumentInterpreter->evaluate($argument); } - foreach ($view->getLayout()->getChildNames($view->getNameInLayout()) as $childAlias) { - $name = $view->getLayout()->getChildName($view->getNameInLayout(), $childAlias); - if ($view->getLayout()->isContainer($name)) { - foreach ($view->getLayout()->getChildNames($name) as $childName) { - $child = $view->getLayout()->getBlock($childName); - $this->prepare($child); - } - } else { - $child = $view->getChildBlock($childAlias); - if ($child) { - $this->prepare($child); - } - } + + if (!isset($arguments['data'])) { + $arguments['data'] = []; } + + $arguments['data'] = array_merge($arguments['data'], ['name' => $identifier], $attributes); + return [$className, $arguments]; } /** - * Get UI Element View + * Create component object * - * @param string $uiElementName + * @param string $identifier + * @param string $name + * @param array $arguments * @return UiComponentInterface - * @throws \InvalidArgumentException + * @throws \Magento\Framework\Exception\LocalizedException */ - public function getUiElementView($uiElementName) + public function create($identifier, $name = null, array $arguments = []) { - /** @var UiComponentInterface $view */ - $view = $this->layout->getBlock($uiElementName); - if (!$view instanceof UiComponentInterface) { - throw new \InvalidArgumentException( - sprintf( - 'UI Element "%s" must implement \Magento\Framework\View\Element\UiComponentInterface', - $uiElementName - ) + if ($name === null) { + $bundleComponents = $this->componentManager->prepareData($identifier)->getData($identifier); + if (empty($bundleComponents)) { + throw new LocalizedException(new \Magento\Framework\Phrase('You use an empty set.')); + } + list($className, $componentArguments) = $this->argumentsResolver( + $identifier, + $bundleComponents[$identifier] ); - } - return $view; - } + $componentArguments = array_merge($componentArguments, $arguments); + if (!isset($componentArguments['context'])) { + throw new LocalizedException(new \Magento\Framework\Phrase('Context, is required argument.')); + } + $componentContext = $componentArguments['context']; + $components = []; + foreach ($bundleComponents[$identifier]['children'] as $childrenIdentifier => $childrenData) { + $children = $this->createChildComponent( + $childrenData, + $componentContext, + $childrenIdentifier + ); + $components[$childrenIdentifier] = $children; + } + $components = array_filter($components); + $componentArguments['components'] = $components; - /** - * Load layout - * - * @return void - */ - protected function loadLayout() - { - $this->layout->getUpdate()->load(); - $this->layout->generateXml(); - $this->layout->generateElements(); + /** @var \Magento\Framework\View\Element\UiComponentInterface $component */ + $component = $this->objectManager->create($className, array_merge($componentArguments, $arguments)); + + return $component; + } else { + $defaultData = $this->componentManager->createRawComponentData($name); + list($className, $componentArguments) = $this->argumentsResolver($identifier, $defaultData); + /** @var \Magento\Framework\View\Element\UiComponentInterface $component */ + $component = $this->objectManager->create($className, array_merge($componentArguments, $arguments)); + + return $component; + } } } diff --git a/lib/internal/Magento/Framework/View/Element/UiComponentInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponentInterface.php index 343f82b40d49eda567334bda03af72991cfe1ef6..a38823e7f0b14933a9fad1a2eaece9386d79f818 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponentInterface.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponentInterface.php @@ -5,98 +5,105 @@ */ namespace Magento\Framework\View\Element; -use Magento\Framework\View\Element\UiComponent\Context as RenderContext; -use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; /** - * Class UiComponentInterface + * Interface UiComponentInterface */ interface UiComponentInterface extends BlockInterface { /** - * Update component data + * Get component instance name * - * @param array $arguments * @return string */ - public function update(array $arguments = []); + public function getName(); /** - * Prepare component data + * Get component name * - * @return void + * @return string */ - public function prepare(); + public function getComponentName(); /** * Render component * - * @param array $data * @return string */ - public function render(array $data = []); + public function render(); /** - * Render label + * Add component * - * @return mixed|string + * @param string $name + * @param UiComponentInterface $component + * @return void */ - public function renderLabel(); + public function addComponent($name, UiComponentInterface $component); /** - * Getting template for rendering content - * - * @return string|false + * @param string $name + * @return UiComponentInterface */ - public function getContentTemplate(); + public function getComponent($name); /** - * Getting template for rendering label + * Get child components * - * @return string|false + * @return UiComponentInterface[] */ - public function getLabelTemplate(); + public function getChildComponents(); /** - * Getting instance name + * Get template * * @return string */ - public function getName(); + public function getTemplate(); /** - * Getting parent name component instance + * Get component context * - * @return string + * @return ContextInterface */ - public function getParentName(); + public function getContext(); /** - * Get render context + * Render child component * - * @return RenderContext + * @param string $name + * @return string */ - public function getRenderContext(); + public function renderChildComponent($name); /** - * Get elements + * Component data setter * - * @return UiComponentInterface[] + * @param string|array $key + * @param mixed $value + * @return void */ - public function getElements(); + public function setData($key, $value = null); /** - * Set elements + * Component data getter * - * @param array $elements + * @param string $key + * @param string|int $index * @return mixed */ - public function setElements(array $elements); + public function getData($key = '', $index = null); + + /** + * @return array + */ + public function getDataSourceData(); /** - * Get configuration builder + * Prepare component configuration * - * @return ConfigBuilderInterface + * @return void */ - public function getConfigBuilder(); + public function prepare(); } diff --git a/lib/internal/Magento/Framework/View/Element/UiElementFactory.php b/lib/internal/Magento/Framework/View/Element/UiElementFactory.php deleted file mode 100644 index e6ae25787d59439286227694e66b78bab2ee4ad9..0000000000000000000000000000000000000000 --- a/lib/internal/Magento/Framework/View/Element/UiElementFactory.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\View\Element; - -use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\View\Element\UiComponent\Context as UiContext; - -/** - * Class UiElementFactory - */ -class UiElementFactory -{ - /** - * @var ObjectManagerInterface - */ - protected $objectManager; - - /** - * @var UiContext - */ - protected $context; - - /** - * Constructor - * - * @param ObjectManagerInterface $objectManager - * @param UiContext $context - */ - public function __construct(ObjectManagerInterface $objectManager, UiContext $context) - { - $this->objectManager = $objectManager; - $this->context = $context; - } - - /** - * Create data provider - * - * @param string $elementName - * @param array $data - * @return bool|BlockInterface - * @throws \Exception - */ - public function create($elementName, array $data = []) - { - if ('text' == $elementName) { - $elementName = 'input'; - } - $block = $this->context->getLayout()->getBlock($elementName); - if (!$block) { - throw new \Exception('Can not find block of element ' . $elementName); - } - $newBlock = clone $block; - $newBlock->addData($data); - return $newBlock; - } -} diff --git a/lib/internal/Magento/Framework/View/Layout/Argument/Parser.php b/lib/internal/Magento/Framework/View/Layout/Argument/Parser.php index 7697660afc02f2bd378e632c53d2fc4701976dc0..fd4bca2122cda5a66b55053ec86018c8495cea12 100644 --- a/lib/internal/Magento/Framework/View/Layout/Argument/Parser.php +++ b/lib/internal/Magento/Framework/View/Layout/Argument/Parser.php @@ -41,7 +41,13 @@ class Parser if (!$this->converter) { $arrayNodeConfig = new ArrayNodeConfig( new NodePathMatcher(), - ['argument/param' => 'name', 'argument(/item)+' => 'name', 'argument(/item)+/param' => 'name'], + [ + 'argument/param' => 'name', + 'argument(/item)+' => 'name', + 'argument(/item)+/param' => 'name', + 'argument(/argument)+' => 'name', + 'argument((/argument)+(/item)+)+' => 'name', + ], ['argument/updater'] ); $this->converter = new FlatConverter($arrayNodeConfig); diff --git a/lib/internal/Magento/Framework/View/Layout/Element.php b/lib/internal/Magento/Framework/View/Layout/Element.php index 01e58372cec32bb6781a007019b9c6f37710c336..3ea80ec098168716b3d5ec83c2273f3db890b07a 100644 --- a/lib/internal/Magento/Framework/View/Layout/Element.php +++ b/lib/internal/Magento/Framework/View/Layout/Element.php @@ -37,7 +37,7 @@ class Element extends \Magento\Framework\Simplexml\Element const TYPE_MOVE = 'move'; - const TYPE_UI_COMPONENT = 'ui_component'; + const TYPE_UI_COMPONENT = 'uiComponent'; const TYPE_HEAD = 'head'; diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/UiComponent.php b/lib/internal/Magento/Framework/View/Layout/Generator/UiComponent.php index 0356d93d04c868518ad389136162898e15a3201e..d5a8fcda61c2a164f1da15f4f9f3482112d18fe1 100644 --- a/lib/internal/Magento/Framework/View/Layout/Generator/UiComponent.php +++ b/lib/internal/Magento/Framework/View/Layout/Generator/UiComponent.php @@ -5,45 +5,63 @@ */ namespace Magento\Framework\View\Layout\Generator; -use Magento\Framework\Data\Argument\InterpreterInterface; -use Magento\Framework\View\Element\UiComponentFactory; use Magento\Framework\View\Layout; +use Magento\Framework\View\Element\BlockFactory; +use Magento\Framework\View\Layout\Data\Structure; +use Magento\Framework\View\Layout\GeneratorInterface; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\Data\Argument\InterpreterInterface; +use Magento\Framework\View\Element\UiComponent\ContainerInterface; +use Magento\Framework\View\Layout\Reader\Context as ReaderContext; +use Magento\Framework\View\Layout\Generator\Context as GeneratorContext; +use Magento\Framework\View\Element\UiComponent\ContextFactory as UiComponentContextFactory; +use Magento\Framework\View\LayoutInterface; -class UiComponent implements Layout\GeneratorInterface +/** + * Class UiComponent + */ +class UiComponent implements GeneratorInterface { /** * Generator type */ - const TYPE = 'ui_component'; + const TYPE = 'uiComponent'; /** - * @var \Magento\Framework\View\Element\UiComponentFactory + * Block container for components + */ + const CONTAINER = 'Magento\Framework\View\Element\UiComponent\ContainerInterface'; + + /** + * @var UiComponentFactory */ protected $uiComponentFactory; /** - * @var \Magento\Framework\Data\Argument\InterpreterInterface + * @var UiComponentContextFactory */ - protected $argumentInterpreter; + protected $contextFactory; /** * Constructor * * @param UiComponentFactory $uiComponentFactory - * @param \Magento\Framework\Data\Argument\InterpreterInterface $argumentInterpreter + * @param BlockFactory $blockFactory + * @param UiComponentContextFactory $contextFactory */ public function __construct( UiComponentFactory $uiComponentFactory, - InterpreterInterface $argumentInterpreter + BlockFactory $blockFactory, + UiComponentContextFactory $contextFactory ) { $this->uiComponentFactory = $uiComponentFactory; - $this->argumentInterpreter = $argumentInterpreter; + $this->blockFactory = $blockFactory; + $this->contextFactory = $contextFactory; } /** * {@inheritdoc} - * - * @return string */ public function getType() { @@ -53,11 +71,11 @@ class UiComponent implements Layout\GeneratorInterface /** * Creates UI Component object based on scheduled data and add it to the layout * - * @param Layout\Reader\Context $readerContext - * @param Context $generatorContext + * @param ReaderContext $readerContext + * @param GeneratorContext $generatorContext * @return $this */ - public function process(Layout\Reader\Context $readerContext, Layout\Generator\Context $generatorContext) + public function process(ReaderContext $readerContext, GeneratorContext $generatorContext) { $scheduledStructure = $readerContext->getScheduledStructure(); $scheduledElements = $scheduledStructure->getElements(); @@ -66,18 +84,16 @@ class UiComponent implements Layout\GeneratorInterface } $structure = $generatorContext->getStructure(); $layout = $generatorContext->getLayout(); - $this->uiComponentFactory->setLayout($layout); + + // Instantiate blocks and collect all actions data /** @var $blocks \Magento\Framework\View\Element\AbstractBlock[] */ $blocks = []; - // Instantiate blocks and collect all actions data foreach ($scheduledElements as $elementName => $element) { - list($type, $data) = $element; - if ($type === self::TYPE) { - $block = $this->generateComponent($structure, $elementName, $data); - $blocks[$elementName] = $block; - $layout->setBlock($elementName, $block); - $scheduledStructure->unsetElement($elementName); - } + list(, $data) = $element; + $block = $this->generateComponent($structure, $elementName, $data, $layout); + $blocks[$elementName] = $block; + $layout->setBlock($elementName, $block); + $scheduledStructure->unsetElement($elementName); } return $this; @@ -86,35 +102,49 @@ class UiComponent implements Layout\GeneratorInterface /** * Create component object * - * @param \Magento\Framework\View\Layout\Data\Structure $structure + * @param Structure $structure * @param string $elementName * @param string $data - * @return \Magento\Framework\View\Element\UiComponentInterface + * @param LayoutInterface $layout + * @return ContainerInterface */ - protected function generateComponent(Layout\Data\Structure $structure, $elementName, $data) + protected function generateComponent(Structure $structure, $elementName, $data, LayoutInterface $layout) { $attributes = $data['attributes']; if (!empty($attributes['group'])) { $structure->addToParentGroup($elementName, $attributes['group']); } - $arguments = empty($data['arguments']) ? [] : $this->evaluateArguments($data['arguments']); - $componentName = isset($attributes['component']) ? $attributes['component'] : ''; - $uiComponent = $this->uiComponentFactory->createUiComponent($componentName, $elementName, $arguments); - return $uiComponent; + + $context = $this->contextFactory->create([ + 'namespace' => $elementName, + 'pageLayout' => $layout + ]); + + $component = $this->uiComponentFactory->create($elementName, null, [ + 'context' => $context + ]); + $this->prepareComponent($component); + + /** @var ContainerInterface $blockContainer */ + $blockContainer = $this->blockFactory->createBlock(static::CONTAINER, ['component' => $component]); + + return $blockContainer; } /** - * Compute and return argument values + * Call prepare method in the component UI * - * @param array $arguments - * @return array + * @param UiComponentInterface $component + * @return void */ - protected function evaluateArguments(array $arguments) + protected function prepareComponent(UiComponentInterface $component) { - $result = []; - foreach ($arguments as $argumentName => $argumentData) { - $result[$argumentName] = $this->argumentInterpreter->evaluate($argumentData); + $childComponents = $component->getChildComponents(); + if (!empty($childComponents)) { + foreach ($childComponents as $child) { + $this->prepareComponent($child); + } } - return $result; + $component->prepare(); } } diff --git a/lib/internal/Magento/Framework/View/Layout/Reader/UiComponent.php b/lib/internal/Magento/Framework/View/Layout/Reader/UiComponent.php index ae986912df95d2d2a2a928056141f5b1f3b40a48..ad363e5286cba67f5b781e77d6aecf62a28f316c 100644 --- a/lib/internal/Magento/Framework/View/Layout/Reader/UiComponent.php +++ b/lib/internal/Magento/Framework/View/Layout/Reader/UiComponent.php @@ -8,12 +8,15 @@ namespace Magento\Framework\View\Layout\Reader; use Magento\Framework\App; use Magento\Framework\View\Layout; +/** + * Class UiComponent + */ class UiComponent implements Layout\ReaderInterface { /**#@+ * Supported types */ - const TYPE_UI_COMPONENT = 'ui_component'; + const TYPE_UI_COMPONENT = 'uiComponent'; /**#@-*/ /** @@ -39,18 +42,14 @@ class UiComponent implements Layout\ReaderInterface * @param Layout\ScheduledStructure\Helper $helper * @param string|null $scopeType */ - public function __construct( - Layout\ScheduledStructure\Helper $helper, - $scopeType = null - ) { + public function __construct(Layout\ScheduledStructure\Helper $helper, $scopeType = null) + { $this->layoutHelper = $helper; $this->scopeType = $scopeType; } /** * {@inheritdoc} - * - * @return string[] */ public function getSupportedNodes() { @@ -59,27 +58,24 @@ class UiComponent implements Layout\ReaderInterface /** * {@inheritdoc} - * - * @param Context $readerContext - * @param Layout\Element $currentElement - * @return $this */ public function interpret(Context $readerContext, Layout\Element $currentElement) { + $attributes = $this->getAttributes($currentElement); $scheduledStructure = $readerContext->getScheduledStructure(); $referenceName = $this->layoutHelper->scheduleStructure( - $readerContext->getScheduledStructure(), + $scheduledStructure, $currentElement, $currentElement->getParent(), - ['attributes' => $this->getAttributes($currentElement)] + ['attributes' => $attributes] ); - $scheduledStructure->setStructureElementData($referenceName, [ - 'attributes' => $this->getAttributes($currentElement) - ]); + + $scheduledStructure->setStructureElementData($referenceName, ['attributes' => $attributes]); $configPath = (string)$currentElement->getAttribute('ifconfig'); if (!empty($configPath)) { $scheduledStructure->setElementToIfconfigList($referenceName, $configPath, $this->scopeType); } + return $this; } @@ -95,6 +91,7 @@ class UiComponent implements Layout\ReaderInterface foreach ($this->attributes as $attributeName) { $attributes[$attributeName] = (string)$element->getAttribute($attributeName); } + return $attributes; } } diff --git a/lib/internal/Magento/Framework/View/Layout/etc/body.xsd b/lib/internal/Magento/Framework/View/Layout/etc/body.xsd index a8d5a75f795b074e2c90def67696e5a4784829b2..3b187137d61fcfbe88750b48835e516edf736d9e 100644 --- a/lib/internal/Magento/Framework/View/Layout/etc/body.xsd +++ b/lib/internal/Magento/Framework/View/Layout/etc/body.xsd @@ -17,7 +17,7 @@ <xs:element ref="container" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="remove" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="move" minOccurs="0" maxOccurs="unbounded"/> - <xs:element ref="ui_component" minOccurs="0" maxOccurs="unbounded"/> + <xs:element ref="uiComponent" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> diff --git a/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd b/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd index 02fe8da728aa2233fea3c1c6adbea31708de5bc2..fc44f93df682b41c5ea8182aa2d9202b8239e2df 100644 --- a/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd +++ b/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd @@ -108,15 +108,15 @@ <xs:element type="containerReferenceType" name="referenceContainer"/> - <xs:element type="uiComponentType" name="ui_component"> + <xs:element type="uiComponentType" name="uiComponent"> <xs:annotation> <xs:documentation> Argument name must be unique in scope of all Blocks, Containers and other UI Components. </xs:documentation> </xs:annotation> <xs:key name="uiElementArgumentName"> - <xs:selector xpath="./arguments/argument"></xs:selector> - <xs:field xpath="@name"></xs:field> + <xs:selector xpath="./argument"/> + <xs:field xpath="@name"/> </xs:key> </xs:element> @@ -185,7 +185,7 @@ <xs:element ref="container" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="referenceBlock" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="referenceContainer" minOccurs="0" maxOccurs="unbounded"/> - <xs:element ref="ui_component" minOccurs="0" maxOccurs="unbounded"/> + <xs:element ref="uiComponent" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute type="elementNameType" name="name"/> <xs:attribute type="xs:string" name="label"/> @@ -216,7 +216,7 @@ <xs:element ref="block" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="container" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="referenceBlock" minOccurs="0" maxOccurs="unbounded"/> - <xs:element ref="ui_component" minOccurs="0" /> + <xs:element ref="uiComponent" minOccurs="0" /> </xs:sequence> <xs:attribute type="elementNameType" name="name" use="optional"/> <xs:attribute type="blockClassType" name="class" use="optional"/> @@ -238,8 +238,8 @@ Part of view that can generate appropriate content. </xs:documentation> </xs:annotation> - <xs:sequence minOccurs="0" maxOccurs="unbounded"> - <xs:element ref="arguments" minOccurs="0" maxOccurs="1"/> + <xs:sequence> + <xs:element name="argument" type="argumentType" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute type="componentNameType" name="component" use="optional"/> <xs:attribute type="elementNameType" name="name" use="optional"/> @@ -311,7 +311,7 @@ <xs:element ref="container" minOccurs="0"/> <xs:element ref="referenceBlock" minOccurs="0" /> <xs:element ref="referenceContainer" minOccurs="0"/> - <xs:element ref="ui_component" minOccurs="0" /> + <xs:element ref="uiComponent" minOccurs="0" /> </xs:choice> <xs:attribute type="elementNameType" name="name" use="required"/> </xs:complexType> @@ -322,7 +322,7 @@ <xs:element ref="block" minOccurs="0" /> <xs:element ref="container" minOccurs="0" /> <xs:element ref="referenceBlock" minOccurs="0" /> - <xs:element ref="ui_component" minOccurs="0" /> + <xs:element ref="uiComponent" minOccurs="0" /> </xs:choice> <xs:attribute type="elementNameType" name="name" use="required"/> <xs:attribute type="htmlTagType" name="htmlTag"/> diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Generator/UiComponentTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Generator/UiComponentTest.php index a15a926d50882d4c4fe81d5810789070a8a655cb..754a00210c34605eae25089667c656621b08d801 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Generator/UiComponentTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Generator/UiComponentTest.php @@ -39,6 +39,16 @@ class UiComponentTest extends \PHPUnit_Framework_TestCase */ protected $argumentInterpreterMock; + /** + * @var \Magento\Framework\View\Element\UiComponent\ContextFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $contextFactoryMock; + + /** + * @var \Magento\Framework\View\Element\BlockFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $blockFactoryMock; + /** * @var \Magento\Framework\View\Layout\Generator\UiComponent */ @@ -49,17 +59,31 @@ class UiComponentTest extends \PHPUnit_Framework_TestCase $this->objectManagerHelper = new ObjectManagerHelper($this); $this->argumentInterpreterMock = $this->getMockBuilder('Magento\Framework\Data\Argument\InterpreterInterface') ->disableOriginalConstructor()->getMockForAbstractClass(); - $this->uiComponentFactoryMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponentFactory') ->disableOriginalConstructor()->getMock(); $this->scheduledStructureMock = $this->getMockBuilder('Magento\Framework\View\Layout\ScheduledStructure') ->disableOriginalConstructor()->getMock(); + $this->contextFactoryMock = $this->getMock( + 'Magento\Framework\View\Element\UiComponent\ContextFactory', + [], + [], + '', + false + ); + $this->blockFactoryMock = $this->getMock( + 'Magento\Framework\View\Element\BlockFactory', + [], + [], + '', + false + ); $this->uiComponent = $this->objectManagerHelper->getObject( 'Magento\Framework\View\Layout\Generator\UiComponent', [ 'uiComponentFactory' => $this->uiComponentFactoryMock, - 'argumentInterpreter' => $this->argumentInterpreterMock + 'blockFactory' => $this->blockFactoryMock, + 'contextFactory' => $this->contextFactoryMock ] ); } @@ -100,16 +124,50 @@ class UiComponentTest extends \PHPUnit_Framework_TestCase ->with($layoutMock) ->willReturnSelf(); - $blockMock = $this->getMockBuilder('Magento\Framework\View\Element\AbstractBlock') - ->disableOriginalConstructor()->getMock(); + $componentMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponentInterface', + [], + '', + false, + true, + true, + [] + ); + + $contextMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\UiComponent\ContextInterface', + [], + '', + false + ); + $blockMock = $this->getMockForAbstractClass( + 'Magento\Framework\View\Element\BlockInterface', + [], + '', + false + ); + + $this->contextFactoryMock->expects($this->once()) + ->method('create') + ->with( + [ + 'namespace' => 'uiComponent', + 'pageLayout' => $layoutMock + ] + )->willReturn($contextMock); $this->uiComponentFactoryMock->expects($this->any()) - ->method('createUiComponent') + ->method('create') ->with( - 'component_name', - UiComponent::TYPE, - ['attribute_1' => 'value_1', 'attribute_2' => 'value_2'] - )->willReturn($blockMock); + 'uiComponent', + null, + ['context' => $contextMock] + )->willReturn($componentMock); + + $this->blockFactoryMock->expects($this->once()) + ->method('createBlock') + ->with(UiComponent::CONTAINER, ['component' => $componentMock]) + ->willReturn($blockMock); $this->argumentInterpreterMock->expects($this->any()) ->method('evaluate') diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/UiComponentTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/UiComponentTest.php index 145c8f6992e9167ec631c92fdb132f38386afac4..1c573b9a2a8915ae92c27111caaa86c10ded1f8c 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/UiComponentTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/UiComponentTest.php @@ -82,8 +82,8 @@ class UiComponentTest extends \PHPUnit_Framework_TestCase return [ [ $this->getElement( - '<ui_component name="cms_block_listing" component="listing" ifconfig="config_path"/>', - 'ui_component' + '<uiComponent name="cms_block_listing" component="listing" ifconfig="config_path"/>', + 'uiComponent' ), ] ]; diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index 769a3a5d91d3f53dba9d6c08ee4fb4a25dbe4732..c2cf9161040653d1d6a8628baaee2e045fb075b3 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -2,7 +2,7 @@ "name": "magento/framework", "description": "N/A", "type": "magento2-library", - "version": "0.74.0-beta6", + "version": "0.74.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/lib/web/css/source/lib/_utilities.less b/lib/web/css/source/lib/_utilities.less index fe49f1b1cbaf9eb97148dd655ce000b4ce7ecccd..0b31aaa2f1132525036f04c4e9907ad4ca018927 100644 --- a/lib/web/css/source/lib/_utilities.less +++ b/lib/web/css/source/lib/_utilities.less @@ -467,9 +467,18 @@ appearance: @value; } +.vendor-prefix-column-count ( + @_value +) { + -webkit-column-count: @_value; + -moz-column-count: @_value; + column-count: @_value; +} + // // Pointer for popups or dropdowns // --------------------------------------------- + .pointer( @_size: 6px, @_background-color: @color-white, diff --git a/lib/web/date-format-normalizer.js b/lib/web/date-format-normalizer.js deleted file mode 100644 index f7a50afc01a7243a05da62324ecb40325e45a9d7..0000000000000000000000000000000000000000 --- a/lib/web/date-format-normalizer.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([],function(){ - 'use strict'; - - var formatCache = {}; - - function Formatter() { - - /** - * Convert from string-Magento-date-format - * to string-moment-js-date-format. Result - * stored in internal cache. - * @param {String} zendFormat - * @return {String} - */ - return function(zendFormat) { - var momentFormat = ''; - - if(formatCache[zendFormat]) { - momentFormat = formatCache[zendFormat]; - } else { - // List of differences. Got from 'MMM d, y h:mm:ss a' -> "MMM D, YYYY h:mm:ss A" - momentFormat = String(zendFormat). - replace('D','DDD'). - replace('dd','DD'). - replace('d','D'). - replace('EEEE','dddd'). - replace('EEE','ddd'). - replace('e','d'). - replace('y','YYYY'). - replace('a','A'). - toString(); - formatCache[zendFormat] = momentFormat; - } - - return momentFormat; - } - } - - return new Formatter; -}); \ No newline at end of file diff --git a/lib/web/mage/adminhtml/globals.js b/lib/web/mage/adminhtml/globals.js new file mode 100644 index 0000000000000000000000000000000000000000..c9f708bd6846e7f4366f43232148d1bccba6e5d3 --- /dev/null +++ b/lib/web/mage/adminhtml/globals.js @@ -0,0 +1,16 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ +], function () { + 'use strict'; + + /** + * Set of a temporary methods used to provide + * backward compatability with a legacy code. + */ + window.setLocation = function (url) { + window.location.href = url; + }; +}); diff --git a/lib/web/mage/utils.js b/lib/web/mage/utils.js deleted file mode 100644 index 239fca6d918ea5e78c51249e147f1a1be49e0c23..0000000000000000000000000000000000000000 --- a/lib/web/mage/utils.js +++ /dev/null @@ -1,451 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -//TODO: assemble all util methods in this module -define([ - 'underscore' -], function (_) { - 'use strict'; - - var tplRegxp = /\{(\w*)\}/g; - - /** @namespace */ - var utils = {}; - - /** - * Replaces matches of '{*}' pattern with a matched property in 'data' object. - * @private - * - * @param {String} tpl - String to process. - * @param {Object} data - Data to match with pattern. - * @returns {String} Modified string. - * - * @example - * template('Hello {one}!', {one: 'World'}); - * => 'Hello World!'; - */ - function template(tpl, data){ - return tpl.replace(tplRegxp, function(match, key){ - return data.hasOwnProperty(key) ? data[key] : ''; - }); - } - - /** - * Sets nested property of a specified object. - * @private - * - * @param {Object} parent - Object to look inside for the properties. - * @param {Array} path - Splitted path the property. - * @param {*} value - Value of the last property in 'path' array. - * returns {*} New value for the property. - */ - function setNested(parent, path, value){ - var last = path.pop(); - - path.forEach(function(part) { - if (_.isUndefined(parent[part])) { - parent[part] = {}; - } - - parent = parent[part]; - }); - - return (parent[last] = value); - } - - /** - * Retrieves value of a nested property. - * @private - * - * @param {Object} parent - Object to look inside for the properties. - * @param {Array} path - Splitted path the property. - * @returns {*} Value of the property. - */ - function getNested(parent, path){ - var exists; - - exists = path.every(function(part) { - parent = parent[part]; - - return !_.isUndefined(parent); - }); - - if(exists){ - return parent; - } - } - - /** - * Removes property from a specified object. - * @private - * - * @param {Object} parent - Object from which to remove property. - * @param {Array} path - Splitted path to the propery. - */ - function removeNested(parent, path) { - var field = path.pop(); - - parent = getNested(parent, path); - - if (_.isObject(parent)) { - delete parent[field]; - } - } - - /** - * Object manipulation methods. - */ - _.extend(utils, { - /** - * Retrieves or defines objects' property by a composite path. - * - * @param {Object} data - Container for the properties specified in path. - * @param {String} path - Objects' properties divided by dots. - * @param {*} [value] - New value for the last property. - * @returns {*} Returns value of the last property in chain. - * - * @example - * utils.nested({}, 'one.two', 3); - * => { one: {two: 3} } - */ - nested: function(data, path, value){ - var action = arguments.length > 2 ? setNested : getNested; - - path = path ? path.split('.') : []; - - return action(data, path, value); - }, - - /** - * Removes nested property from an object. - * - * @param {Object} data - Data source. - * @param {String} path - Path to the property e.g. 'one.two.three' - */ - nestedRemove: function(data, path) { - path = path.split('.'); - - removeNested(data, path); - }, - - /** - * Flattens objects' nested properties. - * - * @param {Object} data - Object to flatten. - * @param {String} [separator='.'] - Objects' keys separator. - * @returns {Object} Flattened object. - * - * @example Example with a default separator. - * utils.flatten({one: { two: { three: 'value'} }}); - * => { 'one.two.three': 'value' }; - * - * @example Example with a custom separator. - * utils.flatten({one: { two: { three: 'value'} }}, '=>'); - * => {'one=>two=>three': 'value'}; - */ - flatten: function(data, separator, parent, result){ - separator = separator || '.'; - result = result || {}; - - _.each(data, function(node, name){ - if(parent){ - name = parent + separator + name; - } - - typeof node === 'object' ? - this.flatten(node, separator, name, result) : - (result[name] = node); - - }, this); - - return result; - }, - - /** - * Opposite operation of the 'flatten' method. - * - * @param {Object} data - Previously flattened object. - * @param {String} [separator='.'] - Keys separator. - * @returns {Object} Object with nested properties. - * - * @example Example using custom separator. - * utils.unflatten({'one=>two': 'value'}, '=>'); - * => { - * one: { two: 'value' } - * }; - */ - unflatten: function(data, separator){ - var result = {}; - - separator = separator || '.'; - - _.each(data, function(value, nodes){ - nodes = nodes.split(separator); - - setNested(result, nodes, value); - }); - - return result; - }, - - /** - * Same operation as 'flatten' method, - * but returns objects' keys wrapped in '[]'. - * - * @param {Object} data - Object that should be serialized. - * @returns {Object} Serialized data. - * - * @example - * utils.serialize({one: { two: { three: 'value'} }}); - * => { 'one[two][three]': 'value' } - */ - serialize: function(data){ - var result = {}; - - data = this.flatten(data); - - _.each(data, function(value, keys){ - keys = this.serializeName(keys); - value = _.isUndefined(value) ? '' : value; - - result[keys] = value; - }, this); - - return result; - }, - - /** - * Applies provided data to the template. - * - * @param {(String|Object)} template - * @param {Object} source - Data object to match with template. - * @returns {String|Object} - * - * @example Template defined as a string. - * var source = { foo: 'Random Stuff', bar: 'Some' }; - * - * utils.template('{bar} {foo}', source); - * => 'Some Random Stuff'; - * - * @example Example of template defined as object. - * var tpl = { key: { '{bar}_Baz': '{foo}' } }; - * - * utils.template(tpl, source); - * => { key: { 'Some_Baz': 'Random Stuff' } }; - */ - template: function(templ, source){ - var result, - parse; - - if(_.isObject(templ)){ - templ = JSON.stringify(templ); - parse = true; - } - - result = template(templ, source); - - return parse ? JSON.parse(result) : result; - } - }); - - /** - * Helpers for working with strings. - */ - _.extend(utils, { - /** - * Splits string by separator if it's possible, - * otherwise returns the incoming value. - * - * @param {(String|Array|*)} str - String to split. - * @param {String} [separator=' '] - Seperator based on which to split the string. - * @returns {Array|*} Splitted string or the incoming value. - */ - stringToArray: function(str, separator){ - separator = separator || ' '; - - return typeof str === 'string' ? - str.split(separator) : - str; - }, - - /** - * Converts the incoming string which consists - * of a specified delimiters into a format commonly used in form elements. - * - * @param {String} name - The incoming string. - * @param {String} [separator='.'] - * @returns {String} Serialized string. - * - * @example - * utils.serializeName('one.two.three'); - * => 'one[two][three]'; - */ - serializeName: function(name, separator){ - var result; - - separator = separator || '.'; - name = name.split(separator); - - result = name.shift(); - - name.forEach(function(part){ - result += '[' + part + ']'; - }); - - return result; - } - }); - - /** - * Array manipulation methods. - */ - _.extend(utils, { - /** - * Facade method to remove/add value from/to array - * without creating a new instance. - * - * @param {Array} arr - Array to be modified. - * @param {*} value - Value to add/remove. - * @param {Boolean} add - Flag that specfies operation. - * @returns {Utils} Chainable. - */ - toggle: function(arr, value, add){ - return add ? - this.add(arr, value) : - this.remove(arr, value); - }, - - /** - * Removes the incoming value from array in case - * without creating a new instance of it. - * - * @param {Array} arr - Array to be modified. - * @param {*} value - Value to be removed. - * @returns {Utils} Chainable. - */ - remove: function(arr, value){ - var index = arr.indexOf(value); - - if(~index){ - arr.splice(index, 1); - } - - return this; - }, - - /** - * Adds the incoming value to array if - * it's not alredy present in there. - * - * @param {Array} arr - Array to be modifed. - * @param {...*} Values to be added. - * @returns {Utils} Chainable. - */ - add: function(arr){ - var values = _.toArray(arguments).slice(1); - - values.forEach(function(value){ - if(!~arr.indexOf(value)){ - arr.push(value); - } - }); - - return this; - }, - - /** - * Extends an incoming array with a specified ammount of undefined values - * starting from a specified position. - * - * @param {Array} container - Array to be extended. - * @param {Number} size - Ammount of values to be added. - * @param {Number} [offset=0] - Position at which to start inserting values. - * @returns {Array} Modified array. - */ - reserve: function(container, size, offset){ - container.splice(offset || 0, 0, new Array(size)); - - return _.flatten(container); - }, - - /** - * Compares multiple arrays without tracking order of their elements. - * - * @param {...Array} Multiple arrays to compare. - * @returns {Bollean} True if arrays are identical to each other. - */ - identical: function(){ - var arrays = _.toArray(arguments), - first = arrays.shift(); - - return arrays.every(function(arr) { - return ( - arr.length === first.length && - !_.difference(arr, first).length - ); - }); - } - }); - - /** - * Miscellaneous. - */ - _.extend(utils, { - /** - * Generates a unique identifier. - * - * @param {Number} [size=7] - Length of a resulting identifier. - * @returns {String} - */ - uniqueid: function (size) { - var code = (Math.random() * 25 + 65) | 0, - idstr = String.fromCharCode(code); - - size = size || 7; - - while (idstr.length < size) { - code = Math.floor((Math.random() * 42) + 48); - - if (code < 58 || code > 64) { - idstr += String.fromCharCode(code); - } - } - - return idstr; - }, - - /** - * Serializes and sends data via POST request. - * - * @param {Object} options - - * Options object that consists of - * a 'url' and 'data' properties. - */ - submit: function(options){ - var form = document.createElement('form'), - data = this.serialize(options.data), - field; - - form.setAttribute('action', options.url); - form.setAttribute('method', 'post'); - - _.each(data, function(value, name){ - field = document.createElement('input'); - - field.setAttribute('name', name); - field.setAttribute('type', 'hidden'); - - field.value = value; - - form.appendChild(field); - }); - - document.body.appendChild(form); - - form.submit(); - } - }); - - return utils; -}); \ No newline at end of file diff --git a/lib/web/mage/utils/arrays.js b/lib/web/mage/utils/arrays.js new file mode 100644 index 0000000000000000000000000000000000000000..54fb9a6189a8df0335808a989c5be5b859643ed8 --- /dev/null +++ b/lib/web/mage/utils/arrays.js @@ -0,0 +1,110 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + './strings' +], function (_, utils) { + 'use strict'; + + return { + /** + * Facade method to remove/add value from/to array + * without creating a new instance. + * + * @param {Array} arr - Array to be modified. + * @param {*} value - Value to add/remove. + * @param {Boolean} add - Flag that specfies operation. + * @returns {Utils} Chainable. + */ + toggle: function (arr, value, add) { + return add ? + this.add(arr, value) : + this.remove(arr, value); + }, + + /** + * Removes the incoming value from array in case + * without creating a new instance of it. + * + * @param {Array} arr - Array to be modified. + * @param {*} value - Value to be removed. + * @returns {Utils} Chainable. + */ + remove: function (arr, value) { + var index = arr.indexOf(value); + + if (~index) { + arr.splice(index, 1); + } + + return this; + }, + + /** + * Adds the incoming value to array if + * it's not alredy present in there. + * + * @param {Array} arr - Array to be modifed. + * @param {...*} Values to be added. + * @returns {Utils} Chainable. + */ + add: function (arr) { + var values = _.toArray(arguments).slice(1); + + values.forEach(function (value) { + if (!~arr.indexOf(value)) { + arr.push(value); + } + }); + + return this; + }, + + /** + * Extends an incoming array with a specified ammount of undefined values + * starting from a specified position. + * + * @param {Array} container - Array to be extended. + * @param {Number} size - Ammount of values to be added. + * @param {Number} [offset=0] - Position at which to start inserting values. + * @returns {Array} Modified array. + */ + reserve: function (container, size, offset) { + container.splice(offset || 0, 0, new Array(size)); + + return _.flatten(container); + }, + + /** + * Compares multiple arrays without tracking order of their elements. + * + * @param {...Array} Multiple arrays to compare. + * @returns {Bollean} True if arrays are identical to each other. + */ + identical: function () { + var arrays = _.toArray(arguments), + first = arrays.shift(); + + return arrays.every(function (arr) { + return arr.length === first.length && + !_.difference(arr, first).length; + }); + }, + + formatOffset: function(elems, offset) { + if (utils.isEmpty(offset)) { + offset = -1; + } + + offset = +offset; + + if (offset < 0) { + offset += elems.length + 1; + } + + return offset; + } + }; +}); diff --git a/lib/web/mage/utils/compare.js b/lib/web/mage/utils/compare.js new file mode 100644 index 0000000000000000000000000000000000000000..f71e1bf8922273a2d40817151ffa00599f070c7e --- /dev/null +++ b/lib/web/mage/utils/compare.js @@ -0,0 +1,133 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + 'mage/utils/objects' +], function (_, utils) { + 'use strict'; + + var primitives = [ + 'undefined', + 'boolean', + 'number', + 'string' + ]; + + function isDifferent(a, b) { + var oldIsPrimitive = a === null || ~primitives.indexOf(typeof a); + + return oldIsPrimitive ? a !== b : true; + } + + function fullPath(prefix, part) { + return prefix ? prefix + '.' + part : part; + } + + function format(name, newValue, oldValue, type) { + return { + name: name, + type: type, + value: newValue, + oldValue: oldValue + }; + } + + function flatten(obj, ns, result) { + result = result || {}; + ns = ns || ''; + + if (!utils.isObject(obj)) { + obj = {}; + } + + _.each(obj, function (value, key) { + key = fullPath(ns, key); + + if (utils.isObject(value)) { + flatten(value, key, result); + } + + result[key] = value; + }); + + return result; + } + + function getConatiners(changes) { + var indexed, + result = {}; + + indexed = _.indexBy(changes, 'name'); + + _.each(indexed, function (change, name) { + var path; + + name = name.split('.'); + + name.forEach(function (part) { + path = fullPath(path, part); + + if (!_.has(indexed, path)) { + result[path] = result[path] || []; + result[path].push(change); + } + }); + }); + + return result; + } + + function getModified(oldValues, current, key) { + var previous, + someIsObject; + + if (_.has(oldValues, key)) { + previous = oldValues[key]; + someIsObject = !utils.isObject(previous) || !utils.isObject(current); + + if (someIsObject && isDifferent(previous, current)) { + return format(key, current, previous, 'update'); + } + } else { + return format(key, current, undefined, 'add'); + } + } + + function getRemoved(newValues, previous, key) { + if (!_.has(newValues, key)) { + return format(key, undefined, previous, 'remove'); + } + } + + function compare(oldObj, newObj, ns) { + var removed, + modfied; + + oldObj = flatten(oldObj, ns); + newObj = flatten(newObj, ns); + + removed = _.map(oldObj, getRemoved.bind(null, newObj)), + modfied = _.map(newObj, getModified.bind(null, oldObj)); + + return _.compact(Array.prototype.concat(removed, modfied)); + } + + return { + compare: function (oldValue, newValue, ns) { + var changes = []; + + if (utils.isObject(oldValue) || utils.isObject(newValue)) { + changes = compare.apply(null, arguments); + } else if (isDifferent(oldValue, newValue)) { + changes.push(format(ns, newValue, oldValue, 'update')); + } + + return { + containers: getConatiners(changes), + changes: changes + }; + } + }; +}); diff --git a/lib/web/mage/utils/main.js b/lib/web/mage/utils/main.js new file mode 100644 index 0000000000000000000000000000000000000000..82b56e713e8c063b1f4d4920ae3d9a58bbf18478 --- /dev/null +++ b/lib/web/mage/utils/main.js @@ -0,0 +1,20 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define(function (require) { + 'use strict'; + + var utils = {}, + _ = require('underscore'); + + return _.extend( + utils, + require('./arrays'), + require('./compare'), + require('./misc'), + require('./objects'), + require('./strings'), + require('./template') + ); +}); diff --git a/lib/web/mage/utils/misc.js b/lib/web/mage/utils/misc.js new file mode 100644 index 0000000000000000000000000000000000000000..5b24831adaf97483335f910fe97e5b026d58d796 --- /dev/null +++ b/lib/web/mage/utils/misc.js @@ -0,0 +1,117 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore' +], function (_) { + 'use strict'; + + var map = { + 'D': 'DDD', + 'dd': 'DD', + 'd': 'D', + 'EEEE': 'dddd', + 'EEE': 'ddd', + 'e': 'd', + 'y': 'YYYY', + 'a': 'A' + }; + + function limitWrapper(data) { + var args = _.toArray(arguments).splice(1); + + if (data.id) { + window.clearTimeout(data.id); + } + + data.id = window.setTimeout(function () { + delete data.id; + + data.fn.apply(data.owner, args); + }, data.limit); + } + + return { + /** + * Generates a unique identifier. + * + * @param {Number} [size=7] - Length of a resulting identifier. + * @returns {String} + */ + uniqueid: function (size) { + var code = Math.random() * 25 + 65 | 0, + idstr = String.fromCharCode(code); + + size = size || 7; + + while (idstr.length < size) { + code = Math.floor(Math.random() * 42 + 48); + + if (code < 58 || code > 64) { + idstr += String.fromCharCode(code); + } + } + + return idstr; + }, + + limit: function (owner, target, limit) { + var data = { + owner: owner, + limit: limit, + fn: owner[target] + }; + + owner[target] = limitWrapper.bind(null, data); + }, + + /** + * Converts mage date format to a moment.js format. + * + * @param {String} mageFormat + * @returns {String} + */ + normalizeDate: function (mageFormat) { + var result = mageFormat; + + _.each(map, function (moment, mage) { + result = result.replace(mage, moment); + }); + + return result; + }, + + /** + * Serializes and sends data via POST request. + * + * @param {Object} options - Options object that consists of + * a 'url' and 'data' properties. + */ + submit: function (options) { + var form = document.createElement('form'), + data = this.serialize(options.data), + field; + + data.form_key = FORM_KEY; + + form.setAttribute('action', options.url); + form.setAttribute('method', 'post'); + + _.each(data, function (value, name) { + field = document.createElement('input'); + + field.setAttribute('name', name); + field.setAttribute('type', 'hidden'); + + field.value = value; + + form.appendChild(field); + }); + + document.body.appendChild(form); + + form.submit(); + } + }; +}); diff --git a/lib/web/mage/utils/objects.js b/lib/web/mage/utils/objects.js new file mode 100644 index 0000000000000000000000000000000000000000..c2d88f8386227a7779c310ff9890a11142c3c5d7 --- /dev/null +++ b/lib/web/mage/utils/objects.js @@ -0,0 +1,228 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'jquery', + 'underscore' +], function ($, _) { + 'use strict'; + + /** + * Sets nested property of a specified object. + * @private + * + * @param {Object} parent - Object to look inside for the properties. + * @param {Array} path - Splitted path the property. + * @param {*} value - Value of the last property in 'path' array. + * returns {*} New value for the property. + */ + function setNested(parent, path, value) { + var last = path.pop(); + + path.forEach(function (part) { + if (_.isUndefined(parent[part])) { + parent[part] = {}; + } + + parent = parent[part]; + }); + + parent[last] = value; + + return value; + } + + /** + * Retrieves value of a nested property. + * @private + * + * @param {Object} parent - Object to look inside for the properties. + * @param {Array} path - Splitted path the property. + * @returns {*} Value of the property. + */ + function getNested(parent, path) { + var exists; + + exists = path.every(function (part) { + parent = parent[part]; + + return !_.isUndefined(parent); + }); + + if (exists) { + return parent; + } + } + + /** + * Removes property from a specified object. + * @private + * + * @param {Object} parent - Object from which to remove property. + * @param {Array} path - Splitted path to the propery. + */ + function removeNested(parent, path) { + var field = path.pop(); + + parent = getNested(parent, path); + + if (_.isObject(parent)) { + delete parent[field]; + } + } + + return { + /** + * Retrieves or defines objects' property by a composite path. + * + * @param {Object} data - Container for the properties specified in path. + * @param {String} path - Objects' properties divided by dots. + * @param {*} [value] - New value for the last property. + * @returns {*} Returns value of the last property in chain. + * + * @example + * utils.nested({}, 'one.two', 3); + * => { one: {two: 3} } + */ + nested: function (data, path, value) { + var action = arguments.length > 2 ? setNested : getNested; + + path = path ? path.split('.') : []; + + return action(data, path, value); + }, + + /** + * Removes nested property from an object. + * + * @param {Object} data - Data source. + * @param {String} path - Path to the property e.g. 'one.two.three' + */ + nestedRemove: function (data, path) { + path = path.split('.'); + + removeNested(data, path); + }, + + /** + * Flattens objects' nested properties. + * + * @param {Object} data - Object to flatten. + * @param {String} [separator='.'] - Objects' keys separator. + * @returns {Object} Flattened object. + * + * @example Example with a default separator. + * utils.flatten({one: { two: { three: 'value'} }}); + * => { 'one.two.three': 'value' }; + * + * @example Example with a custom separator. + * utils.flatten({one: { two: { three: 'value'} }}, '=>'); + * => {'one=>two=>three': 'value'}; + */ + flatten: function (data, separator, parent, result) { + separator = separator || '.'; + result = result || {}; + + _.each(data, function (node, name) { + if (parent) { + name = parent + separator + name; + } + + typeof node === 'object' ? + this.flatten(node, separator, name, result) : + result[name] = node; + + }, this); + + return result; + }, + + /** + * Opposite operation of the 'flatten' method. + * + * @param {Object} data - Previously flattened object. + * @param {String} [separator='.'] - Keys separator. + * @returns {Object} Object with nested properties. + * + * @example Example using custom separator. + * utils.unflatten({'one=>two': 'value'}, '=>'); + * => { + * one: { two: 'value' } + * }; + */ + unflatten: function (data, separator) { + var result = {}; + + separator = separator || '.'; + + _.each(data, function (value, nodes) { + nodes = nodes.split(separator); + + setNested(result, nodes, value); + }); + + return result; + }, + + /** + * Same operation as 'flatten' method, + * but returns objects' keys wrapped in '[]'. + * + * @param {Object} data - Object that should be serialized. + * @returns {Object} Serialized data. + * + * @example + * utils.serialize({one: { two: { three: 'value'} }}); + * => { 'one[two][three]': 'value' } + */ + serialize: function (data) { + var result = {}; + + data = this.flatten(data); + + _.each(data, function (value, keys) { + keys = this.serializeName(keys); + value = _.isUndefined(value) ? '' : value; + + result[keys] = value; + }, this); + + return result; + }, + + extend: function (target) { + var extenders = _.toArray(arguments).splice(1), + clone, + src; + + extenders.forEach(function (node) { + _.each(node, function (value, key) { + src = target[key]; + + if (this.isObject(value) || Array.isArray(value)) { + if (Array.isArray(value)) { + clone = src && Array.isArray(src) ? src : []; + } else { + clone = src && this.isObject(src) ? src : {}; + } + + target[key] = this.extend(clone, value); + } else if (!_.isUndefined(value)) { + target[key] = value; + } + }, this); + }, this); + + return target; + }, + + isObject: function (data) { + var objProto = Object.prototype; + + return typeof data == 'object' ? + objProto.toString.call(data) === '[object Object]' : + false; + } + }; +}); diff --git a/lib/web/mage/utils/strings.js b/lib/web/mage/utils/strings.js new file mode 100644 index 0000000000000000000000000000000000000000..185951886aaf3271e84cfc4d79d16016aec1d5ef --- /dev/null +++ b/lib/web/mage/utils/strings.js @@ -0,0 +1,69 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore' +], function (_) { + 'use strict'; + + return { + /** + * Splits string by separator if it's possible, + * otherwise returns the incoming value. + * + * @param {(String|Array|*)} str - String to split. + * @param {String} [separator=' '] - Seperator based on which to split the string. + * @returns {Array|*} Splitted string or the incoming value. + */ + stringToArray: function (str, separator) { + separator = separator || ' '; + + return typeof str === 'string' ? + str.split(separator) : + str; + }, + + /** + * Converts the incoming string which consists + * of a specified delimiters into a format commonly used in form elements. + * + * @param {String} name - The incoming string. + * @param {String} [separator='.'] + * @returns {String} Serialized string. + * + * @example + * utils.serializeName('one.two.three'); + * => 'one[two][three]'; + */ + serializeName: function (name, separator) { + var result; + + separator = separator || '.'; + name = name.split(separator); + + result = name.shift(); + + name.forEach(function (part) { + result += '[' + part + ']'; + }); + + return result; + }, + + /** + * Checks wether the incoming value is not empty, + * e.g. not 'null' or 'undefined' + * + * @param {*} value - Value to check. + * @returns {Boolean} + */ + isEmpty: function (value) { + return value === '' || _.isUndefined(value) || _.isNull(value); + }, + + fullPath: function (prefix, part) { + return prefix ? prefix + '.' + part : part; + } + }; +}); diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js new file mode 100644 index 0000000000000000000000000000000000000000..86c53247dcf9776400136e09e5e56f434c50481e --- /dev/null +++ b/lib/web/mage/utils/template.js @@ -0,0 +1,84 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + 'mage/utils/objects' +], function (_, utils) { + 'use strict'; + + var opener = '<%'; + + function isTemplate(value) { + return _.isString(value) && ~value.indexOf(opener); + } + + function render(tmpl, data) { + var last = tmpl; + + data = Object.create(data); + + while (~tmpl.indexOf(opener)) { + tmpl = _.template(tmpl)(data); + + if (tmpl === last) { + break; + } + + last = tmpl; + } + + return tmpl; + } + + return { + /** + * Applies provided data to the template. + * + * @param {Object} tmpl + * @param {Object} [$data] - Data object to match with template. + * @returns {Object} + * + * @example Template defined as a string. + * var source = { foo: 'Random Stuff', bar: 'Some' }; + * + * utils.template('{bar} {foo}', source); + * => 'Some Random Stuff'; + * + * @example Example of template defined as object. + * var tpl = { key: { '{bar}_Baz': '{foo}' } }; + * + * utils.template(tpl, source); + * => { key: { 'Some_Baz': 'Random Stuff' } }; + */ + template: function (tmpl, $data) { + tmpl = utils.extend({}, tmpl); + + tmpl.$data = $data || {}; + + _.each(tmpl, function iterate(value, key, list) { + if (key === '$data') { + return; + } + + if (isTemplate(key)) { + delete list[key]; + + key = render(key, tmpl); + list[key] = value; + } + + if (isTemplate(value)) { + list[key] = render(value, tmpl); + } else if (_.isObject(value)) { + _.each(value, iterate); + } + }); + + delete tmpl.$data; + + return tmpl; + } + }; +}); diff --git a/lib/web/underscore.js b/lib/web/underscore.js index d5b3375f28d445b12ae8bdc7bbcebb8031ed48a2..e272fca43f7b6c59357fcf20d791e2295e44921f 100644 --- a/lib/web/underscore.js +++ b/lib/web/underscore.js @@ -1,6 +1,6 @@ -// Underscore.js 1.7.0 +// Underscore.js 1.8.2 // http://underscorejs.org -// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // Underscore may be freely distributed under the MIT license. (function() { @@ -21,7 +21,6 @@ var push = ArrayProto.push, slice = ArrayProto.slice, - concat = ArrayProto.concat, toString = ObjProto.toString, hasOwnProperty = ObjProto.hasOwnProperty; @@ -30,7 +29,11 @@ var nativeIsArray = Array.isArray, nativeKeys = Object.keys, - nativeBind = FuncProto.bind; + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; // Create a safe reference to the Underscore object for use below. var _ = function(obj) { @@ -52,12 +55,12 @@ } // Current version. - _.VERSION = '1.7.0'; + _.VERSION = '1.8.2'; // Internal function that returns an efficient (for current engines) version // of the passed-in callback, to be repeatedly applied in other Underscore // functions. - var createCallback = function(func, context, argCount) { + var optimizeCb = function(func, context, argCount) { if (context === void 0) return func; switch (argCount == null ? 3 : argCount) { case 1: return function(value) { @@ -81,12 +84,52 @@ // A mostly-internal function to generate callbacks that can be applied // to each element in a collection, returning the desired result — either // identity, an arbitrary callback, a property matcher, or a property accessor. - _.iteratee = function(value, context, argCount) { + var cb = function(value, context, argCount) { if (value == null) return _.identity; - if (_.isFunction(value)) return createCallback(value, context, argCount); - if (_.isObject(value)) return _.matches(value); + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); return _.property(value); }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var isArrayLike = function(collection) { + var length = collection && collection.length; + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; // Collection Functions // -------------------- @@ -95,11 +138,10 @@ // Handles raw objects in addition to array-likes. Treats all // sparse array-likes as if they were dense. _.each = _.forEach = function(obj, iteratee, context) { - if (obj == null) return obj; - iteratee = createCallback(iteratee, context); - var i, length = obj.length; - if (length === +length) { - for (i = 0; i < length; i++) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { iteratee(obj[i], i, obj); } } else { @@ -113,77 +155,66 @@ // Return the results of applying the iteratee to each element. _.map = _.collect = function(obj, iteratee, context) { - if (obj == null) return []; - iteratee = _.iteratee(iteratee, context); - var keys = obj.length !== +obj.length && _.keys(obj), + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), length = (keys || obj).length, - results = Array(length), - currentKey; + results = Array(length); for (var index = 0; index < length; index++) { - currentKey = keys ? keys[index] : index; + var currentKey = keys ? keys[index] : index; results[index] = iteratee(obj[currentKey], currentKey, obj); } return results; }; - var reduceError = 'Reduce of empty array with no initial value'; + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } // **Reduce** builds up a single result from a list of values, aka `inject`, // or `foldl`. - _.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) { - if (obj == null) obj = []; - iteratee = createCallback(iteratee, context, 4); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - index = 0, currentKey; - if (arguments.length < 3) { - if (!length) throw new TypeError(reduceError); - memo = obj[keys ? keys[index++] : index++]; - } - for (; index < length; index++) { - currentKey = keys ? keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; + _.reduce = _.foldl = _.inject = createReduce(1); // The right-associative version of reduce, also known as `foldr`. - _.reduceRight = _.foldr = function(obj, iteratee, memo, context) { - if (obj == null) obj = []; - iteratee = createCallback(iteratee, context, 4); - var keys = obj.length !== + obj.length && _.keys(obj), - index = (keys || obj).length, - currentKey; - if (arguments.length < 3) { - if (!index) throw new TypeError(reduceError); - memo = obj[keys ? keys[--index] : --index]; - } - while (index--) { - currentKey = keys ? keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; + _.reduceRight = _.foldr = createReduce(-1); // Return the first value which passes a truth test. Aliased as `detect`. _.find = _.detect = function(obj, predicate, context) { - var result; - predicate = _.iteratee(predicate, context); - _.some(obj, function(value, index, list) { - if (predicate(value, index, list)) { - result = value; - return true; - } - }); - return result; + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; }; // Return all the elements that pass a truth test. // Aliased as `select`. _.filter = _.select = function(obj, predicate, context) { var results = []; - if (obj == null) return results; - predicate = _.iteratee(predicate, context); + predicate = cb(predicate, context); _.each(obj, function(value, index, list) { if (predicate(value, index, list)) results.push(value); }); @@ -192,19 +223,17 @@ // Return all the elements for which a truth test fails. _.reject = function(obj, predicate, context) { - return _.filter(obj, _.negate(_.iteratee(predicate)), context); + return _.filter(obj, _.negate(cb(predicate)), context); }; // Determine whether all of the elements match a truth test. // Aliased as `all`. _.every = _.all = function(obj, predicate, context) { - if (obj == null) return true; - predicate = _.iteratee(predicate, context); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - index, currentKey; - for (index = 0; index < length; index++) { - currentKey = keys ? keys[index] : index; + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; if (!predicate(obj[currentKey], currentKey, obj)) return false; } return true; @@ -213,24 +242,21 @@ // Determine if at least one element in the object matches a truth test. // Aliased as `any`. _.some = _.any = function(obj, predicate, context) { - if (obj == null) return false; - predicate = _.iteratee(predicate, context); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - index, currentKey; - for (index = 0; index < length; index++) { - currentKey = keys ? keys[index] : index; + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; if (predicate(obj[currentKey], currentKey, obj)) return true; } return false; }; // Determine if the array or object contains a given value (using `===`). - // Aliased as `include`. - _.contains = _.include = function(obj, target) { - if (obj == null) return false; - if (obj.length !== +obj.length) obj = _.values(obj); - return _.indexOf(obj, target) >= 0; + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, target, fromIndex) { + if (!isArrayLike(obj)) obj = _.values(obj); + return _.indexOf(obj, target, typeof fromIndex == 'number' && fromIndex) >= 0; }; // Invoke a method (with arguments) on every item in a collection. @@ -238,7 +264,8 @@ var args = slice.call(arguments, 2); var isFunc = _.isFunction(method); return _.map(obj, function(value) { - return (isFunc ? method : value[method]).apply(value, args); + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); }); }; @@ -250,13 +277,13 @@ // Convenience version of a common use case of `filter`: selecting only objects // containing specific `key:value` pairs. _.where = function(obj, attrs) { - return _.filter(obj, _.matches(attrs)); + return _.filter(obj, _.matcher(attrs)); }; // Convenience version of a common use case of `find`: getting the first object // containing specific `key:value` pairs. _.findWhere = function(obj, attrs) { - return _.find(obj, _.matches(attrs)); + return _.find(obj, _.matcher(attrs)); }; // Return the maximum element (or element-based computation). @@ -264,7 +291,7 @@ var result = -Infinity, lastComputed = -Infinity, value, computed; if (iteratee == null && obj != null) { - obj = obj.length === +obj.length ? obj : _.values(obj); + obj = isArrayLike(obj) ? obj : _.values(obj); for (var i = 0, length = obj.length; i < length; i++) { value = obj[i]; if (value > result) { @@ -272,7 +299,7 @@ } } } else { - iteratee = _.iteratee(iteratee, context); + iteratee = cb(iteratee, context); _.each(obj, function(value, index, list) { computed = iteratee(value, index, list); if (computed > lastComputed || computed === -Infinity && result === -Infinity) { @@ -289,7 +316,7 @@ var result = Infinity, lastComputed = Infinity, value, computed; if (iteratee == null && obj != null) { - obj = obj.length === +obj.length ? obj : _.values(obj); + obj = isArrayLike(obj) ? obj : _.values(obj); for (var i = 0, length = obj.length; i < length; i++) { value = obj[i]; if (value < result) { @@ -297,7 +324,7 @@ } } } else { - iteratee = _.iteratee(iteratee, context); + iteratee = cb(iteratee, context); _.each(obj, function(value, index, list) { computed = iteratee(value, index, list); if (computed < lastComputed || computed === Infinity && result === Infinity) { @@ -312,7 +339,7 @@ // Shuffle a collection, using the modern version of the // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). _.shuffle = function(obj) { - var set = obj && obj.length === +obj.length ? obj : _.values(obj); + var set = isArrayLike(obj) ? obj : _.values(obj); var length = set.length; var shuffled = Array(length); for (var index = 0, rand; index < length; index++) { @@ -328,7 +355,7 @@ // The internal `guard` argument allows it to work with `map`. _.sample = function(obj, n, guard) { if (n == null || guard) { - if (obj.length !== +obj.length) obj = _.values(obj); + if (!isArrayLike(obj)) obj = _.values(obj); return obj[_.random(obj.length - 1)]; } return _.shuffle(obj).slice(0, Math.max(0, n)); @@ -336,7 +363,7 @@ // Sort the object's values by a criterion produced by an iteratee. _.sortBy = function(obj, iteratee, context) { - iteratee = _.iteratee(iteratee, context); + iteratee = cb(iteratee, context); return _.pluck(_.map(obj, function(value, index, list) { return { value: value, @@ -358,7 +385,7 @@ var group = function(behavior) { return function(obj, iteratee, context) { var result = {}; - iteratee = _.iteratee(iteratee, context); + iteratee = cb(iteratee, context); _.each(obj, function(value, index) { var key = iteratee(value, index, obj); behavior(result, value, key); @@ -386,37 +413,24 @@ if (_.has(result, key)) result[key]++; else result[key] = 1; }); - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iteratee, context) { - iteratee = _.iteratee(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = array.length; - while (low < high) { - var mid = low + high >>> 1; - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; - }; - // Safely create a real, live array from anything iterable. _.toArray = function(obj) { if (!obj) return []; if (_.isArray(obj)) return slice.call(obj); - if (obj.length === +obj.length) return _.map(obj, _.identity); + if (isArrayLike(obj)) return _.map(obj, _.identity); return _.values(obj); }; // Return the number of elements in an object. _.size = function(obj) { if (obj == null) return 0; - return obj.length === +obj.length ? obj.length : _.keys(obj).length; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; }; // Split a collection into two arrays: one whose elements all satisfy the given // predicate, and one whose elements all do not satisfy the predicate. _.partition = function(obj, predicate, context) { - predicate = _.iteratee(predicate, context); + predicate = cb(predicate, context); var pass = [], fail = []; _.each(obj, function(value, key, obj) { (predicate(value, key, obj) ? pass : fail).push(value); @@ -433,30 +447,27 @@ _.first = _.head = _.take = function(array, n, guard) { if (array == null) return void 0; if (n == null || guard) return array[0]; - if (n < 0) return []; - return slice.call(array, 0, n); + return _.initial(array, array.length - n); }; // Returns everything but the last entry of the array. Especially useful on // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. The **guard** check allows it to work with - // `_.map`. + // the array, excluding the last N. _.initial = function(array, n, guard) { return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); }; // Get the last element of an array. Passing **n** will return the last N - // values in the array. The **guard** check allows it to work with `_.map`. + // values in the array. _.last = function(array, n, guard) { if (array == null) return void 0; if (n == null || guard) return array[array.length - 1]; - return slice.call(array, Math.max(array.length - n, 0)); + return _.rest(array, Math.max(0, array.length - n)); }; // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. The **guard** - // check allows it to work with `_.map`. + // the rest N values in the array. _.rest = _.tail = _.drop = function(array, n, guard) { return slice.call(array, n == null || guard ? 1 : n); }; @@ -467,18 +478,20 @@ }; // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, strict, output) { - if (shallow && _.every(input, _.isArray)) { - return concat.apply(output, input); - } - for (var i = 0, length = input.length; i < length; i++) { + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = input && input.length; i < length; i++) { var value = input[i]; - if (!_.isArray(value) && !_.isArguments(value)) { - if (!strict) output.push(value); - } else if (shallow) { - push.apply(output, value); - } else { - flatten(value, shallow, strict, output); + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; } } return output; @@ -486,7 +499,7 @@ // Flatten out an array, either recursively (by default), or just one level. _.flatten = function(array, shallow) { - return flatten(array, shallow, false, []); + return flatten(array, shallow, false); }; // Return a version of the array that does not contain the specified value(s). @@ -504,21 +517,21 @@ iteratee = isSorted; isSorted = false; } - if (iteratee != null) iteratee = _.iteratee(iteratee, context); + if (iteratee != null) iteratee = cb(iteratee, context); var result = []; var seen = []; for (var i = 0, length = array.length; i < length; i++) { - var value = array[i]; + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; if (isSorted) { - if (!i || seen !== value) result.push(value); - seen = value; + if (!i || seen !== computed) result.push(value); + seen = computed; } else if (iteratee) { - var computed = iteratee(value, i, array); - if (_.indexOf(seen, computed) < 0) { + if (!_.contains(seen, computed)) { seen.push(computed); result.push(value); } - } else if (_.indexOf(result, value) < 0) { + } else if (!_.contains(result, value)) { result.push(value); } } @@ -528,7 +541,7 @@ // Produce an array that contains the union: each distinct element from all of // the passed-in arrays. _.union = function() { - return _.uniq(flatten(arguments, true, true, [])); + return _.uniq(flatten(arguments, true, true)); }; // Produce an array that contains every item shared between all the @@ -551,7 +564,7 @@ // Take the difference between one array and a number of other arrays. // Only the elements present in just the first array will remain. _.difference = function(array) { - var rest = flatten(slice.call(arguments, 1), true, true, []); + var rest = flatten(arguments, true, true, 1); return _.filter(array, function(value){ return !_.contains(rest, value); }); @@ -559,23 +572,28 @@ // Zip together multiple lists into a single array -- elements that share // an index go together. - _.zip = function(array) { - if (array == null) return []; - var length = _.max(arguments, 'length').length; - var results = Array(length); - for (var i = 0; i < length; i++) { - results[i] = _.pluck(arguments, i); + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, 'length').length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); } - return results; + return result; }; // Converts lists into objects. Pass either a single array of `[key, value]` // pairs, or two parallel arrays of the same length -- one of keys, and one of // the corresponding values. _.object = function(list, values) { - if (list == null) return {}; var result = {}; - for (var i = 0, length = list.length; i < length; i++) { + for (var i = 0, length = list && list.length; i < length; i++) { if (values) { result[list[i]] = values[i]; } else { @@ -590,30 +608,63 @@ // If the array is large and already in sort order, pass `true` // for **isSorted** to use binary search. _.indexOf = function(array, item, isSorted) { - if (array == null) return -1; - var i = 0, length = array.length; - if (isSorted) { - if (typeof isSorted == 'number') { - i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted; - } else { - i = _.sortedIndex(array, item); - return array[i] === item ? i : -1; - } + var i = 0, length = array && array.length; + if (typeof isSorted == 'number') { + i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted; + } else if (isSorted && length) { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + if (item !== item) { + return _.findIndex(slice.call(array, i), _.isNaN); } for (; i < length; i++) if (array[i] === item) return i; return -1; }; _.lastIndexOf = function(array, item, from) { - if (array == null) return -1; - var idx = array.length; + var idx = array ? array.length : 0; if (typeof from == 'number') { idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1); } + if (item !== item) { + return _.findLastIndex(slice.call(array, 0, idx), _.isNaN); + } while (--idx >= 0) if (array[idx] === item) return idx; return -1; }; + // Generator function to create the findIndex and findLastIndex functions + function createIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = array != null && array.length; + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createIndexFinder(1); + + _.findLastIndex = createIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = array.length; + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + // Generate an integer Array containing an arithmetic progression. A port of // the native Python `range()` function. See // [the Python documentation](http://docs.python.org/library/functions.html#range). @@ -637,25 +688,25 @@ // Function (ahem) Functions // ------------------ - // Reusable constructor function for prototype setting. - var Ctor = function(){}; + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; // Create a function bound to a given object (assigning `this`, and arguments, // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if // available. _.bind = function(func, context) { - var args, bound; if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); - args = slice.call(arguments, 2); - bound = function() { - if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); - Ctor.prototype = func.prototype; - var self = new Ctor; - Ctor.prototype = null; - var result = func.apply(self, args.concat(slice.call(arguments))); - if (_.isObject(result)) return result; - return self; + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); }; return bound; }; @@ -665,15 +716,16 @@ // as a placeholder, allowing any combination of arguments to be pre-filled. _.partial = function(func) { var boundArgs = slice.call(arguments, 1); - return function() { - var position = 0; - var args = boundArgs.slice(); - for (var i = 0, length = args.length; i < length; i++) { - if (args[i] === _) args[i] = arguments[position++]; + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; } while (position < arguments.length) args.push(arguments[position++]); - return func.apply(this, args); + return executeBound(func, bound, this, this, args); }; + return bound; }; // Bind a number of an object's methods to that object. Remaining arguments @@ -693,7 +745,7 @@ _.memoize = function(func, hasher) { var memoize = function(key) { var cache = memoize.cache; - var address = hasher ? hasher.apply(this, arguments) : key; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); return cache[address]; }; @@ -712,9 +764,7 @@ // Defers a function, scheduling it to run after the current call stack has // cleared. - _.defer = function(func) { - return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); - }; + _.defer = _.partial(_.delay, _, 1); // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. Normally, the throttled function will run @@ -739,8 +789,10 @@ context = this; args = arguments; if (remaining <= 0 || remaining > wait) { - clearTimeout(timeout); - timeout = null; + if (timeout) { + clearTimeout(timeout); + timeout = null; + } previous = now; result = func.apply(context, args); if (!timeout) context = args = null; @@ -761,7 +813,7 @@ var later = function() { var last = _.now() - timestamp; - if (last < wait && last > 0) { + if (last < wait && last >= 0) { timeout = setTimeout(later, wait - last); } else { timeout = null; @@ -814,7 +866,7 @@ }; }; - // Returns a function that will only be executed after being called N times. + // Returns a function that will only be executed on and after the Nth call. _.after = function(times, func) { return function() { if (--times < 1) { @@ -823,15 +875,14 @@ }; }; - // Returns a function that will only be executed before being called N times. + // Returns a function that will only be executed up to (but not including) the Nth call. _.before = function(times, func) { var memo; return function() { if (--times > 0) { memo = func.apply(this, arguments); - } else { - func = null; } + if (times <= 1) func = null; return memo; }; }; @@ -843,13 +894,47 @@ // Object Functions // ---------------- - // Retrieve the names of an object's properties. + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. // Delegates to **ECMAScript 5**'s native `Object.keys` _.keys = function(obj) { if (!_.isObject(obj)) return []; if (nativeKeys) return nativeKeys(obj); var keys = []; for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); return keys; }; @@ -864,6 +949,21 @@ return values; }; + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + // Convert an object into a list of `[key, value]` pairs. _.pairs = function(obj) { var keys = _.keys(obj); @@ -896,37 +996,38 @@ }; // Extend a given object with all the properties in passed-in object(s). - _.extend = function(obj) { - if (!_.isObject(obj)) return obj; - var source, prop; - for (var i = 1, length = arguments.length; i < length; i++) { - source = arguments[i]; - for (prop in source) { - if (hasOwnProperty.call(source, prop)) { - obj[prop] = source[prop]; - } - } + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; } - return obj; }; // Return a copy of the object only containing the whitelisted properties. - _.pick = function(obj, iteratee, context) { - var result = {}, key; + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; if (obj == null) return result; - if (_.isFunction(iteratee)) { - iteratee = createCallback(iteratee, context); - for (key in obj) { - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); } else { - var keys = concat.apply([], slice.call(arguments, 1)); - obj = new Object(obj); - for (var i = 0, length = keys.length; i < length; i++) { - key = keys[i]; - if (key in obj) result[key] = obj[key]; - } + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; } return result; }; @@ -936,7 +1037,7 @@ if (_.isFunction(iteratee)) { iteratee = _.negate(iteratee); } else { - var keys = _.map(concat.apply([], slice.call(arguments, 1)), String); + var keys = _.map(flatten(arguments, false, false, 1), String); iteratee = function(value, key) { return !_.contains(keys, key); }; @@ -945,16 +1046,7 @@ }; // Fill in a given object with default properties. - _.defaults = function(obj) { - if (!_.isObject(obj)) return obj; - for (var i = 1, length = arguments.length; i < length; i++) { - var source = arguments[i]; - for (var prop in source) { - if (obj[prop] === void 0) obj[prop] = source[prop]; - } - } - return obj; - }; + _.defaults = createAssigner(_.allKeys, true); // Create a (shallow-cloned) duplicate of an object. _.clone = function(obj) { @@ -970,6 +1062,19 @@ return obj; }; + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + // Internal recursive comparison function for `isEqual`. var eq = function(a, b, aStack, bStack) { // Identical objects are equal. `0 === -0`, but they aren't identical. @@ -1004,74 +1109,76 @@ // of `NaN` are not equivalent. return +a === +b; } - if (typeof a != 'object' || typeof b != 'object') return false; + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } // Assume equality for cyclic structures. The algorithm for detecting cyclic // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; var length = aStack.length; while (length--) { // Linear search. Performance is inversely proportional to the number of // unique nested structures. if (aStack[length] === a) return bStack[length] === b; } - // Objects with different constructors are not equivalent, but `Object`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if ( - aCtor !== bCtor && - // Handle Object.create(x) cases - 'constructor' in a && 'constructor' in b && - !(_.isFunction(aCtor) && aCtor instanceof aCtor && - _.isFunction(bCtor) && bCtor instanceof bCtor) - ) { - return false; - } + // Add the first object to the stack of traversed objects. aStack.push(a); bStack.push(b); - var size, result; + // Recursively compare objects and arrays. - if (className === '[object Array]') { + if (areArrays) { // Compare array lengths to determine if a deep comparison is necessary. - size = a.length; - result = size === b.length; - if (result) { - // Deep compare the contents, ignoring non-numeric properties. - while (size--) { - if (!(result = eq(a[size], b[size], aStack, bStack))) break; - } + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; } } else { // Deep compare objects. var keys = _.keys(a), key; - size = keys.length; + length = keys.length; // Ensure that both objects contain the same number of properties before comparing deep equality. - result = _.keys(b).length === size; - if (result) { - while (size--) { - // Deep compare each member - key = keys[size]; - if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; - } + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; } } // Remove the first object from the stack of traversed objects. aStack.pop(); bStack.pop(); - return result; + return true; }; // Perform a deep comparison to check if two objects are equal. _.isEqual = function(a, b) { - return eq(a, b, [], []); + return eq(a, b); }; // Is a given array, string, or object empty? // An "empty" object has no enumerable own-properties. _.isEmpty = function(obj) { if (obj == null) return true; - if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0; - for (var key in obj) if (_.has(obj, key)) return false; - return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; }; // Is a given value a DOM element? @@ -1091,14 +1198,14 @@ return type === 'function' || type === 'object' && !!obj; }; - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. - _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { _['is' + name] = function(obj) { return toString.call(obj) === '[object ' + name + ']'; }; }); - // Define a fallback version of the method in browsers (ahem, IE), where + // Define a fallback version of the method in browsers (ahem, IE < 9), where // there isn't any inspectable "Arguments" type. if (!_.isArguments(arguments)) { _.isArguments = function(obj) { @@ -1106,8 +1213,9 @@ }; } - // Optimize `isFunction` if appropriate. Work around an IE 11 bug. - if (typeof /./ !== 'function') { + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { _.isFunction = function(obj) { return typeof obj == 'function' || false; }; @@ -1170,28 +1278,30 @@ _.property = function(key) { return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { return obj[key]; }; }; - // Returns a predicate for checking whether an object has a given set of `key:value` pairs. - _.matches = function(attrs) { - var pairs = _.pairs(attrs), length = pairs.length; + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); return function(obj) { - if (obj == null) return !length; - obj = new Object(obj); - for (var i = 0; i < length; i++) { - var pair = pairs[i], key = pair[0]; - if (pair[1] !== obj[key] || !(key in obj)) return false; - } - return true; + return _.isMatch(obj, attrs); }; }; // Run a function **n** times. _.times = function(n, iteratee, context) { var accum = Array(Math.max(0, n)); - iteratee = createCallback(iteratee, context, 1); + iteratee = optimizeCb(iteratee, context, 1); for (var i = 0; i < n; i++) accum[i] = iteratee(i); return accum; }; @@ -1240,10 +1350,12 @@ // If the value of the named `property` is a function then invoke it with the // `object` as context; otherwise, return it. - _.result = function(object, property) { - if (object == null) return void 0; - var value = object[property]; - return _.isFunction(value) ? object[property]() : value; + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; }; // Generate a unique integer id (unique within the entire client session). @@ -1358,8 +1470,8 @@ // underscore functions. Wrapped objects may be chained. // Helper function to continue chaining intermediate results. - var result = function(obj) { - return this._chain ? _(obj).chain() : obj; + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; }; // Add your own custom functions to the Underscore object. @@ -1369,7 +1481,7 @@ _.prototype[name] = function() { var args = [this._wrapped]; push.apply(args, arguments); - return result.call(this, func.apply(_, args)); + return result(this, func.apply(_, args)); }; }); }; @@ -1384,7 +1496,7 @@ var obj = this._wrapped; method.apply(obj, arguments); if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; - return result.call(this, obj); + return result(this, obj); }; }); @@ -1392,7 +1504,7 @@ _.each(['concat', 'join', 'slice'], function(name) { var method = ArrayProto[name]; _.prototype[name] = function() { - return result.call(this, method.apply(this._wrapped, arguments)); + return result(this, method.apply(this._wrapped, arguments)); }; }); @@ -1401,6 +1513,14 @@ return this._wrapped; }; + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + // AMD registration happens at the end for compatibility with AMD loaders // that may not enforce next-turn semantics on modules. Even though general // practice for AMD registration is to be anonymous, underscore registers diff --git a/setup/pub/styles/setup.css b/setup/pub/styles/setup.css index ebe7d360aa51a5727093b1b86326a529a7fc3c07..d667b416c7a211c9990db9a8b32bf896fdadc6a6 100644 --- a/setup/pub/styles/setup.css +++ b/setup/pub/styles/setup.css @@ -3,4 +3,4 @@ * See COPYING.txt for license details. */ -html{box-sizing:border-box;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}:after,:before{box-sizing:content-box}.abs-clearer:after,.form-row:after,.header:after,.nav:after,.row:after{content:"";display:table;clear:both}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/light/opensans-300.eot);src:url(../../pub/fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../../pub/fonts/opensans/light/opensans-300.woff) format('woff'),url(../../pub/fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../../pub/fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/regular/opensans-400.eot);src:url(../../pub/fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../../pub/fonts/opensans/regular/opensans-400.woff) format('woff'),url(../../pub/fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../../pub/fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/semibold/opensans-600.eot);src:url(../../pub/fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../../pub/fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../../pub/fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../../pub/fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/bold/opensans-700.eot);src:url(../../pub/fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../../pub/fonts/opensans/bold/opensans-700.woff) format('woff'),url(../../pub/fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../../pub/fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:400;line-height:1.4}h1,h2,h3,h4,h5,h6{font-weight:400;margin-top:0}p{margin:0 0 1em}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}@font-face{font-family:Icons;src:url(../../pub/fonts/icons/icons.eot);src:url(../../pub/fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/icons/icons.woff2) format('woff2'),url(../../pub/fonts/icons/icons.woff) format('woff'),url(../../pub/fonts/icons/icons.ttf) format('truetype'),url(../../pub/fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}[class*=icon-]:after{font-family:Icons}.icon-success-thick:after{content:'\e600'}.icon-success:after{content:'\e601'}.icon-collapse:after{content:'\e602'}.icon-failed-thick:after{content:'\e603'}.icon-failed:after{content:'\e604'}.icon-expand:after{content:'\e605'}.icon-warning:after{content:'\e606'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.8em;left:0;position:absolute;right:0;top:.15em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e600'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e603'}dl,ol,ul{margin-top:0}.list{margin-bottom:1em;padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before{font-family:Icons;font-size:1.6em;left:-.1em;position:absolute;top:-.2em}.list-item-success:before{color:#79a22e;content:'\e601'}.list-item-failed:before{color:#e22626;content:'\e604'}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .5em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1)}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active{background-color:#574e48}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary.disabled:hover,.ie9 .btn-secondary[disabled]:active,.ie9 .btn-secondary[disabled]:hover{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;border-radius:2px;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;vertical-align:top;padding:.43em .55em .5em 0}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{margin-bottom:2.5em;padding-top:1.5em;font-weight:600;font-size:1.25em}.form-legend{width:100%;border-top:1px solid #ccc}.form-legend-light{margin-bottom:1.5em;font-size:1em}.form-legend-expand{transition:opacity .2s linear;cursor:pointer}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e602'}.form-legend-expand:after{margin-left:.5em;font-weight:400;font-size:1.15em;font-family:Icons;content:'\e605';vertical-align:sub}.form-el-checkbox,.form-el-radio{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{border-color:#adadad;border-radius:2px;height:1.4rem;line-height:1;width:1.4rem}.form-el-checkbox:checked+.form-label::before{content:'\e600';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.6rem;width:1.6rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;border-radius:2px;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{position:relative;height:45.2rem;border:1px solid #adadad;overflow:auto;margin:0 0 1.5rem}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;border-radius:2px;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.4235em .6655em .605em}.check-result-message{margin-left:.5em;min-height:3.68rem;-webkit-align-items:center;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-webkit-flex;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}.pseudo-table{display:table}.pseudo-td{display:table-cell}.messages{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:14px;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.message{margin-bottom:3rem}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0 2rem}.row{margin-left:0;margin-right:0}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:.8rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after{display:none}.nav-bar>li.active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a{color:#000}.nav-bar>li.active a:hover{cursor:default}.nav-bar>li.active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:.7rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:.7rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.1rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.1rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:20rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@-webkit-keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}@-webkit-keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}@-ms-keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span:nth-child(1){-webkit-animation-delay:.27s;-ms-animation-delay:.27s;animation-delay:.27s;-webkit-transform:rotate(-315deg);-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){-webkit-animation-delay:.36s;-ms-animation-delay:.36s;animation-delay:.36s;-webkit-transform:rotate(-270deg);-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){-webkit-animation-delay:.45s;-ms-animation-delay:.45s;animation-delay:.45s;-webkit-transform:rotate(-225deg);-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){-webkit-animation-delay:.54s;-ms-animation-delay:.54s;animation-delay:.54s;-webkit-transform:rotate(-180deg);-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){-webkit-animation-delay:.63s;-ms-animation-delay:.63s;animation-delay:.63s;-webkit-transform:rotate(-135deg);-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){-webkit-animation-delay:.72s;-ms-animation-delay:.72s;animation-delay:.72s;-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){-webkit-animation-delay:.81s;-ms-animation-delay:.81s;animation-delay:.81s;-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){-webkit-animation-delay:.9;-ms-animation-delay:.9;animation-delay:.9;-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}.spinner>span{-webkit-animation-direction:linear;-ms-animation-direction:linear;animation-direction:linear;-webkit-animation-duration:.72s;-ms-animation-duration:.72s;animation-duration:.72s;-webkit-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:fade;-ms-animation-name:fade;animation-name:fade;-webkit-transform:scale(0.4);-ms-transform:scale(0.4);transform:scale(0.4);background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../../pub/images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.main{padding-bottom:2rem;padding-top:3rem}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;margin:2.5rem 0 3.5rem 5rem}.page-title{font-size:2rem;margin-bottom:1.3em}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit{margin-bottom:20px}.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.rediness-check-item{margin-bottom:4rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:7.5rem}.readiness-check-content{margin-left:7.5rem;margin-right:22rem}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.rediness-check-side{float:right;padding-left:2.4rem;width:22rem}.rediness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:2rem;margin-top:.7rem}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .customize-your-store-default .legend{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;margin:1rem 0 2rem;max-height:20rem;overflow-y:auto;padding:1.5rem 2rem 2rem}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}@media all and (max-width:1047px){.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}}@media all and (min-width:768px){.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}} \ No newline at end of file +html{box-sizing:border-box;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}:after,:before{box-sizing:content-box}.abs-clearer:after,.form-row:after,.header:after,.nav:after,.row:after{content:"";display:table;clear:both}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/light/opensans-300.eot);src:url(../../pub/fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../../pub/fonts/opensans/light/opensans-300.woff) format('woff'),url(../../pub/fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../../pub/fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/regular/opensans-400.eot);src:url(../../pub/fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../../pub/fonts/opensans/regular/opensans-400.woff) format('woff'),url(../../pub/fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../../pub/fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/semibold/opensans-600.eot);src:url(../../pub/fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../../pub/fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../../pub/fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../../pub/fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../../pub/fonts/opensans/bold/opensans-700.eot);src:url(../../pub/fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../../pub/fonts/opensans/bold/opensans-700.woff) format('woff'),url(../../pub/fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../../pub/fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:400;line-height:1.4}h1,h2,h3,h4,h5,h6{font-weight:400;margin-top:0}p{margin:0 0 1em}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}@font-face{font-family:Icons;src:url(../../pub/fonts/icons/icons.eot);src:url(../../pub/fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../../pub/fonts/icons/icons.woff2) format('woff2'),url(../../pub/fonts/icons/icons.woff) format('woff'),url(../../pub/fonts/icons/icons.ttf) format('truetype'),url(../../pub/fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}[class*=icon-]:after{font-family:Icons}.icon-success-thick:after{content:'\e600'}.icon-success:after{content:'\e601'}.icon-collapse:after{content:'\e602'}.icon-failed-thick:after{content:'\e603'}.icon-failed:after{content:'\e604'}.icon-expand:after{content:'\e605'}.icon-warning:after{content:'\e606'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.8em;left:0;position:absolute;right:0;top:.15em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e600'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e603'}dl,ol,ul{margin-top:0}.list{margin-bottom:1em;padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before{font-family:Icons;font-size:1.6em;left:-.1em;position:absolute;top:-.2em}.list-item-success:before{color:#79a22e;content:'\e601'}.list-item-failed:before{color:#e22626;content:'\e604'}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .5em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1)}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active{background-color:#574e48}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary.disabled:hover,.ie9 .btn-secondary[disabled]:active,.ie9 .btn-secondary[disabled]:hover{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;border-radius:2px;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;vertical-align:top;padding:.43em .55em .5em 0}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{margin-bottom:2.5em;padding-top:1.5em;font-weight:600;font-size:1.25em}.form-legend{width:100%;border-top:1px solid #ccc}.form-legend-light{margin-bottom:1.5em;font-size:1em}.form-legend-expand{transition:opacity .2s linear;cursor:pointer}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e602'}.form-legend-expand:after{margin-left:.5em;font-weight:400;font-size:1.15em;font-family:Icons;content:'\e605';vertical-align:sub}.form-el-checkbox,.form-el-radio{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{border-color:#adadad;border-radius:2px;height:1.4rem;line-height:1;width:1.4rem}.form-el-checkbox:checked+.form-label::before{content:'\e600';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.6rem;width:1.6rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;border-radius:2px;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{position:relative;height:45.2rem;border:1px solid #adadad;overflow:auto;margin:0 0 1.5rem}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;border-radius:2px;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.4235em .6655em .605em}.check-result-message{margin-left:.5em;min-height:3.68rem;-webkit-align-items:center;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-webkit-flex;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}.pseudo-table{display:table}.pseudo-td{display:table-cell}.messages{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:14px;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.message{margin-bottom:3rem}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0 2rem}.row{margin-left:0;margin-right:0}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:.8rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after{display:none}.nav-bar>li.active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a{color:#000}.nav-bar>li.active a:hover{cursor:default}.nav-bar>li.active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:.7rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:.7rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.1rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.1rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:20rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@-webkit-keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}@-webkit-keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span:nth-child(1){-webkit-animation-delay:.27s;animation-delay:.27s;-webkit-transform:rotate(-315deg);-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){-webkit-animation-delay:.36s;animation-delay:.36s;-webkit-transform:rotate(-270deg);-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){-webkit-animation-delay:.45s;animation-delay:.45s;-webkit-transform:rotate(-225deg);-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){-webkit-animation-delay:.54s;animation-delay:.54s;-webkit-transform:rotate(-180deg);-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){-webkit-animation-delay:.63s;animation-delay:.63s;-webkit-transform:rotate(-135deg);-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){-webkit-animation-delay:.72s;animation-delay:.72s;-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){-webkit-animation-delay:.81s;animation-delay:.81s;-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){-webkit-animation-delay:.9;animation-delay:.9;-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}.spinner>span{-webkit-animation-direction:linear;animation-direction:linear;-webkit-animation-duration:.72s;animation-duration:.72s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:fade;animation-name:fade;-webkit-transform:scale(0.4);-ms-transform:scale(0.4);transform:scale(0.4);background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../../pub/images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.main{padding-bottom:2rem;padding-top:3rem}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;margin:2.5rem 0 3.5rem 5rem}.page-title{font-size:2rem;margin-bottom:1.3em}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit{margin-bottom:20px}.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.rediness-check-item{margin-bottom:4rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:7.5rem}.readiness-check-content{margin-left:7.5rem;margin-right:22rem}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.rediness-check-side{float:right;padding-left:2.4rem;width:22rem}.rediness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:2rem;margin-top:.7rem}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .customize-your-store-default .legend{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;margin:1rem 0 2rem;max-height:20rem;overflow-y:auto;padding:1.5rem 2rem 2rem}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}@media all and (max-width:1047px){.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}}@media all and (min-width:768px){.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}} \ No newline at end of file diff --git a/setup/view/styles/lib/forms/_checkbox-radio.less b/setup/view/styles/lib/forms/_checkbox-radio.less index 6155541bde86c9f9c1a7111eb63b1bc7d638b4c0..a0510ad6a7c66349c140eefe1745c4e64fcbe3de 100644 --- a/setup/view/styles/lib/forms/_checkbox-radio.less +++ b/setup/view/styles/lib/forms/_checkbox-radio.less @@ -9,7 +9,6 @@ @checkbox__border-color: @color-gray68; @radio-bullet__color: @color-brownie; -@color-required: @color-prime; // // Common @@ -23,7 +22,8 @@ &[disabled], &.disabled { - + .form-label, + .form-label:before { + + .form-label, + + .form-label:before { cursor: default; opacity: @disabled__opacity; pointer-events: none; @@ -31,7 +31,6 @@ } // Hover state - &:not([disabled]), &:not(.disabled) { + .form-label { diff --git a/setup/view/styles/lib/forms/_forms.less b/setup/view/styles/lib/forms/_forms.less index a0e79796f56bbe243d677517531e7222caf0c7be..e0468c4a39b6c5f71bdf67988813b268bb5d1eea 100644 --- a/setup/view/styles/lib/forms/_forms.less +++ b/setup/view/styles/lib/forms/_forms.less @@ -12,6 +12,8 @@ @form-el__focus__border-color: @focus__color; @form-el__hover__border-color: darken(@form-el__border-color, 10%); +@color-required: @color-prime; + // // Structure // _____________________________________________