Skip to content

Commit

Permalink
Merge pull request #5097 from magento-tsg-csl3/2.4-develop-pr1
Browse files Browse the repository at this point in the history
[TSG-CSL3] For 2.4 (pr1)
  • Loading branch information
zakdma authored Dec 12, 2019
2 parents 27a3905 + 0bf0c9f commit f540160
Show file tree
Hide file tree
Showing 43 changed files with 1,416 additions and 280 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@
namespace Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab;

use Magento\Backend\Block\Widget\Form\Generic;
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
use Magento\Config\Model\Config\Source\Yesno;
use Magento\Eav\Block\Adminhtml\Attribute\PropertyLocker;
use Magento\Eav\Helper\Data;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Stdlib\DateTime;

/**
* Product attribute add/edit form main tab
* Product attribute add/edit advanced form tab
*
* @api
* @since 100.0.2
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Advanced extends Generic
{
Expand Down Expand Up @@ -70,7 +74,7 @@ public function __construct(
* Adding product form elements for editing attribute
*
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
* @throws LocalizedException
* @SuppressWarnings(PHPMD)
*/
protected function _prepareForm()
Expand Down Expand Up @@ -139,7 +143,21 @@ protected function _prepareForm()
'label' => __('Default Value'),
'title' => __('Default Value'),
'value' => $attributeObject->getDefaultValue(),
'date_format' => $dateFormat
'date_format' => $dateFormat,
]
);

$timeFormat = $this->_localeDate->getTimeFormat(\IntlDateFormatter::SHORT);
$fieldset->addField(
'default_value_datetime',
'date',
[
'name' => 'default_value_datetime',
'label' => __('Default Value'),
'title' => __('Default Value'),
'value' => $this->getLocalizedDateDefaultValue(),
'date_format' => $dateFormat,
'time_format' => $timeFormat,
]
);

Expand Down Expand Up @@ -266,7 +284,7 @@ protected function _initFormValues()
/**
* Retrieve attribute object from registry
*
* @return mixed
* @return Attribute
*/
private function getAttributeObject()
{
Expand All @@ -285,4 +303,28 @@ private function getPropertyLocker()
}
return $this->propertyLocker;
}

/**
* Get localized date default value
*
* @return string
* @throws LocalizedException
*/
private function getLocalizedDateDefaultValue(): string
{
$attributeObject = $this->getAttributeObject();
if (empty($attributeObject->getDefaultValue()) || $attributeObject->getFrontendInput() !== 'datetime') {
return (string)$attributeObject->getDefaultValue();
}

try {
$localizedDate = $this->_localeDate->date($attributeObject->getDefaultValue(), null, false);
$localizedDate->setTimezone(new \DateTimeZone($this->_localeDate->getConfigTimezone()));
$localizedDate = $localizedDate->format(DateTime::DATETIME_PHP_FORMAT);
} catch (\Exception $e) {
throw new LocalizedException(__('The default date is invalid.'));
}

return $localizedDate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,60 @@
/**
* Product attribute add/edit form main tab
*
* @author Magento Core Team <core@magentocommerce.com>
* @author Magento Core Team <core@magentocommerce.com>
*/
namespace Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab;

use Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Apply as HelperApply;
use Magento\Eav\Block\Adminhtml\Attribute\Edit\Main\AbstractMain;
use Magento\Framework\Data\Form\Element\AbstractElement;
use Magento\Framework\Data\Form\Element\Fieldset;
use Magento\Framework\DataObject;

/**
* Product attribute add/edit form main tab
*
* @api
* @SuppressWarnings(PHPMD.DepthOfInheritance)
* @since 100.0.2
*/
class Main extends AbstractMain
{
/**
* Adding product form elements for editing attribute
*
* @return $this
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
* @inheritdoc
*/
protected function _prepareForm()
{
parent::_prepareForm();
/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attributeObject */
$attributeObject = $this->getAttributeObject();
/* @var $form \Magento\Framework\Data\Form */
$form = $this->getForm();
/* @var $fieldset \Magento\Framework\Data\Form\Element\Fieldset */
$fieldset = $form->getElement('base_fieldset');
$fieldsToRemove = ['attribute_code', 'is_unique', 'frontend_class'];

foreach ($fieldset->getElements() as $element) {
/** @var \Magento\Framework\Data\Form\AbstractForm $element */
if (substr($element->getId(), 0, strlen('default_value')) == 'default_value') {
$fieldsToRemove[] = $element->getId();
}
}
foreach ($fieldsToRemove as $id) {
$fieldset->removeField($id);
}
$this->removeUnusedFields();
$this->processFrontendInputTypes();

$this->_eventManager->dispatch('product_attribute_form_build_main_tab', ['form' => $this->getForm()]);

return $this;
}

/**
* @inheritdoc
*/
protected function _getAdditionalElementTypes()
{
return ['apply' => HelperApply::class];
}

/**
* Process frontend input types for product attributes
*
* @return void
*/
private function processFrontendInputTypes(): void
{
$form = $this->getForm();
/** @var AbstractElement $frontendInputElm */
$frontendInputElm = $form->getElement('frontend_input');
$additionalTypes = [
['value' => 'price', 'label' => __('Price')],
['value' => 'media_image', 'label' => __('Media Image')],
];
$additionalReadOnlyTypes = ['gallery' => __('Gallery')];
if (isset($additionalReadOnlyTypes[$attributeObject->getFrontendInput()])) {
$additionalTypes[] = [
'value' => $attributeObject->getFrontendInput(),
'label' => $additionalReadOnlyTypes[$attributeObject->getFrontendInput()],
];
}
$additionalTypes = $this->getAdditionalFrontendInputTypes();

$response = new \Magento\Framework\DataObject();
$response = new DataObject();
$response->setTypes([]);
$this->_eventManager->dispatch('adminhtml_product_attribute_types', ['response' => $response]);
$_hiddenFields = [];
Expand All @@ -74,19 +74,51 @@ protected function _prepareForm()

$frontendInputValues = array_merge($frontendInputElm->getValues(), $additionalTypes);
$frontendInputElm->setValues($frontendInputValues);
}

$this->_eventManager->dispatch('product_attribute_form_build_main_tab', ['form' => $form]);
/**
* Get additional Frontend Input Types for product attributes
*
* @return array
*/
private function getAdditionalFrontendInputTypes(): array
{
$additionalTypes = [
['value' => 'price', 'label' => __('Price')],
['value' => 'media_image', 'label' => __('Media Image')],
];

return $this;
$additionalReadOnlyTypes = ['gallery' => __('Gallery')];
$attributeObject = $this->getAttributeObject();
if (isset($additionalReadOnlyTypes[$attributeObject->getFrontendInput()])) {
$additionalTypes[] = [
'value' => $attributeObject->getFrontendInput(),
'label' => $additionalReadOnlyTypes[$attributeObject->getFrontendInput()],
];
}

return $additionalTypes;
}

/**
* Retrieve additional element types for product attributes
* Remove unused form fields
*
* @return array
* @return void
*/
protected function _getAdditionalElementTypes()
private function removeUnusedFields(): void
{
return ['apply' => \Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Apply::class];
$form = $this->getForm();
/* @var $fieldset Fieldset */
$fieldset = $form->getElement('base_fieldset');
$fieldsToRemove = ['attribute_code', 'is_unique', 'frontend_class'];
foreach ($fieldset->getElements() as $element) {
/** @var AbstractElement $element */
if (substr($element->getId(), 0, strlen('default_value')) === 'default_value') {
$fieldsToRemove[] = $element->getId();
}
}
foreach ($fieldsToRemove as $id) {
$fieldset->removeField($id);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
</arguments>

<amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid"/>
<conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFilters"/>
<fillField selector="{{AdminProductAttributeGridSection.FilterByAttributeCode}}" userInput="{{ProductAttribute.attribute_code}}" stepKey="setAttributeCode"/>
<click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="searchForAttributeFromTheGrid"/>
<click selector="{{AdminProductAttributeGridSection.FirstRow}}" stepKey="clickOnAttributeRow"/>
Expand Down Expand Up @@ -351,6 +352,23 @@
<fillField stepKey="fillDefaultValue" selector="{{AdvancedAttributePropertiesSection.DefaultValueDate}}" userInput="{{date}}"/>
</actionGroup>

<!-- Inputs datetime default value and attribute code-->
<actionGroup name="CreateProductAttributeWithDatetimeField" extends="createProductAttribute" insertAfter="checkRequired">
<annotations>
<description>EXTENDS: createProductAttribute. Fills in the Attribute Code and Default Value (Attribute Type: Date and Time Field).</description>
</annotations>
<arguments>
<argument name="date" type="string"/>
</arguments>

<scrollTo selector="{{AdvancedAttributePropertiesSection.AdvancedAttributePropertiesSectionToggle}}" stepKey="scrollToAdvancedSection"/>
<conditionalClick selector="{{AdvancedAttributePropertiesSection.AdvancedAttributePropertiesSectionToggle}}" dependentSelector="{{AdvancedAttributePropertiesSection.AttributeCode}}" visible="false" stepKey="openAdvancedSection"/>
<waitForElementVisible selector="{{AdvancedAttributePropertiesSection.AttributeCode}}" stepKey="waitForSlideOutAdvancedSection"/>
<fillField selector="{{AdvancedAttributePropertiesSection.AttributeCode}}" userInput="{{attribute.attribute_code}}" stepKey="fillCode"/>
<scrollTo selector="{{AdvancedAttributePropertiesSection.defaultValueDatetime}}" stepKey="scrollToDefaultField"/>
<fillField selector="{{AdvancedAttributePropertiesSection.defaultValueDatetime}}" userInput="{{date}}" stepKey="fillDefaultValue"/>
</actionGroup>

<!-- Creates dropdown option at row without saving-->
<actionGroup name="createAttributeDropdownNthOption">
<annotations>
Expand All @@ -376,4 +394,15 @@

<checkOption selector="{{AttributePropertiesSection.dropdownNthOptionIsDefault(row)}}" stepKey="setAsDefault" after="fillStoreView"/>
</actionGroup>

<!-- Go to advanced attribute properties -->
<actionGroup name="AdminNavigateToProductAttributeAdvancedSection">
<annotations>
<description>Navigate and open Advanced Attribute Properties section on product attribute page</description>
</annotations>

<scrollTo selector="{{AdvancedAttributePropertiesSection.AdvancedAttributePropertiesSectionToggle}}" stepKey="scrollToSection"/>
<conditionalClick selector="{{AdvancedAttributePropertiesSection.AdvancedAttributePropertiesSectionToggle}}" dependentSelector="{{AdvancedAttributePropertiesSection.AttributeCode}}" visible="false" stepKey="openSection"/>
<waitForElementVisible selector="{{AdvancedAttributePropertiesSection.AttributeCode}}" stepKey="waitForSlideOutSection"/>
</actionGroup>
</actionGroups>
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,10 @@
<data key="frontend_input">date</data>
<data key="is_required_admin">No</data>
</entity>
<entity name="DatetimeProductAttribute" extends="productAttributeWysiwyg" type="ProductAttribute">
<data key="frontend_input">datetime</data>
<data key="is_required_admin">No</data>
</entity>
<entity name="priceProductAttribute" extends="productAttributeWysiwyg" type="ProductAttribute">
<data key="frontend_input">date</data>
<data key="is_required_admin">No</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
<element name="DefaultValueText" type="textarea" selector="#default_value_text"/>
<element name="DefaultValueTextArea" type="textarea" selector="#default_value_textarea"/>
<element name="DefaultValueDate" type="textarea" selector="#default_value_date"/>
<element name="defaultValueDatetime" type="date" selector="#default_value_datetime"/>
<element name="DefaultValueYesNo" type="textarea" selector="#default_value_yesno"/>
<element name="Scope" type="select" selector="#is_global"/>
<element name="UniqueValue" type="select" selector="#is_unique"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,7 @@
<element name="productCount" type="text" selector="#catalog_category_products-total-count"/>
<element name="productPerPage" type="select" selector="#catalog_category_products_page-limit"/>
<element name="storeViewDropdown" type="text" selector="//select[@name='store_id']/option[contains(.,'{{storeView}}')]" parameterized="true"/>
<element name="inputByCodeRangeFrom" type="input" selector="input.admin__control-text[name='{{code}}[from]']" parameterized="true"/>
<element name="inputByCodeRangeTo" type="input" selector="input.admin__control-text[name='{{code}}[to]']" parameterized="true"/>
</section>
</sections>
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
<test name="AdminCreateDatetimeProductAttributeTest">
<annotations>
<features value="Catalog"/>
<stories value="Datetime product attributes support"/>
<title value="Datetime product attribute type is supported"/>
<description value="Admin should be able to create datetime product attribute"/>
<severity value="CRITICAL"/>
<testCaseId value="MC-21451"/>
<group value="catalog"/>
</annotations>
<before>
<actionGroup ref="LoginAsAdmin" stepKey="login"/>
</before>
<after>
<actionGroup ref="deleteProductAttribute" stepKey="deleteAttribute">
<argument name="ProductAttribute" value="DatetimeProductAttribute"/>
</actionGroup>
<actionGroup ref="AdminGridFilterResetActionGroup" stepKey="resetGridFilter"/>
<actionGroup ref="logout" stepKey="logout"/>
</after>
<!-- Generate the datetime default value -->
<generateDate date="now" format="m/j/y g:i A" stepKey="generateDefaultValue"/>
<!-- Create new datetime product attribute -->
<amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="goToProductAttributes"/>
<waitForPageLoad stepKey="waitForPageLoadAttributes"/>
<actionGroup ref="CreateProductAttributeWithDatetimeField" stepKey="createAttribute">
<argument name="attribute" value="DatetimeProductAttribute"/>
<argument name="date" value="{$generateDefaultValue}"/>
</actionGroup>
<!-- Navigate to created product attribute -->
<actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute">
<argument name="ProductAttribute" value="DatetimeProductAttribute"/>
</actionGroup>
<!-- Check the saved datetime default value -->
<actionGroup ref="AdminNavigateToProductAttributeAdvancedSection" stepKey="goToAdvancedSection"/>
<scrollTo selector="{{AdvancedAttributePropertiesSection.defaultValueDatetime}}" stepKey="scrollToDefaultValue"/>
<seeInField userInput="{$generateDefaultValue}"
selector="{{AdvancedAttributePropertiesSection.defaultValueDatetime}}"
stepKey="checkDefaultValue"/>
</test>
</tests>
Loading

0 comments on commit f540160

Please sign in to comment.