Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#7698 - modularize admin global search #9192

Closed
wants to merge 15 commits into from
Closed

#7698 - modularize admin global search #9192

wants to merge 15 commits into from

Conversation

tzyganu
Copy link
Contributor

@tzyganu tzyganu commented Apr 10, 2017

This PR solves the issue #7698.
It modularizes the admin global search and translates the preview links "keyword in Pages"...

Description

The PR makes the admin global search modularized. The composition of the search was moved to the proper module. (sales search in Sales module di.xml. Also for customer and cms pages).
I removed the preview link 'keywords in Products' because the products admin grid does not have a full text search, so clicking on that link does not give out the expected result.
In the search.phtml the text for previews ('keyword' in customers) was not translatable. Not it should be.
The list of previews was not extensible. It was hardcoded in the search.phtml template.
I added one more class member of the Magento\Backend\Controller\Adminhtml\Index\GlobalSearch that holds an array of elements that can be displayed as preview for different modules.

What I didn't do, is to increment the module version in module.xml and composer.json. I will need some guidance on that.

Fixed Issues (if relevant)

  1. Admin Global Search was build in a hurry #7698: Admin Global Search was build in a hurry

Manual testing scenarios

Steps to reproduce are listed in the issue

Contribution checklist

  • Pull request has a meaningful description of its purpose
  • All commits are accompanied by meaningful commit messages
  • All new or changed code is covered with unit/integration tests (if applicable)
  • All automated tests passed successfully (all builds on Travis CI are green)

@tzyganu
Copy link
Contributor Author

tzyganu commented Apr 10, 2017

I know, I know. I have some tests to fix.

</item>
</argument>
<argument name="searchModules" xsi:type="array" />
<argument name="prevideModules" xsi:type="array" />

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo for previewModules?

@southerncomputer
Copy link
Contributor

Need to hook this up to elasticsearch so it really can be a global search!

@maghamed maghamed self-requested a review April 21, 2017 12:19
@maghamed maghamed self-assigned this Apr 21, 2017
Copy link
Contributor

@maghamed maghamed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the preview link 'keywords in Products' because the products admin grid does not have a full text search, so clicking on that link does not give out the expected result.

Currently it's a bug, that Product Grid doesn't provide Search functionality. And that would be fixed soon in the scope of #10089
which is awaiting to be processed.
So, no need to remove 'keywords in Products' drop-down item

/**
* @return array
*/
protected function getPreviewItems()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's give just "private" visibility for all the new functions

}
$result[] = [
'url' => $this->getUrl($previewConfig['url']).'?search='.$query,
'name' => __($previewConfig['text'], $query)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't have translate="true" attribute in DI.xml , as we have for UI components configuration, thus translation would not work correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maghamed Any pointers on how to handle this so the translation will work and still be able to keep the texts in DI? O maybe move them somewhere else?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tzyganu I found a possibility to specify "string" type to be translatable in DI.xml
using the "translate" attribute
Here is the definition of this attribute for any xsi:type="string" attribute type in types.XSD schema which is used by ObjectManager

<xs:extension base="argumentType">
<xs:attribute name="translate" use="optional" type="xs:boolean"/>
</xs:extension>

Here is how this attribute interpreted

$needTranslation = isset($data['translate']) ? $this->booleanUtils->toBoolean($data['translate']) : false;
if ($needTranslation) {
$result = (string)new \Magento\Framework\Phrase($result);
}

But there is no any usage of this attribute in Magento.
And looks like all the tries to pass strings using DI.xml just don't translate at all

Like this one:

    <type name="Magento\Catalog\Model\Entity\Product\Attribute\Design\Options\Container">
        <arguments>
            <argument name="options" xsi:type="array">
                <item name="option1" xsi:type="array">
                    <item name="value" xsi:type="string">container1</item>
                    <item name="label" xsi:type="string">Product Info Column</item>
                </item>
                <item name="option2" xsi:type="array">
                    <item name="value" xsi:type="string">container2</item>
                    <item name="label" xsi:type="string">Block after Info Column</item>
                </item>
            </argument>
        </arguments>
    </type>

or this one:

    <type name="Magento\Customer\Ui\Component\MassAction\Group\Options">
        <arguments>
            <argument name="data" xsi:type="array">
                <item name="urlPath" xsi:type="string">customer/index/massAssignGroup</item>
                <item name="paramName" xsi:type="string">group</item>
                <item name="confirm" xsi:type="array">
                    <item name="title" xsi:type="string">Assign a Customer Group</item>
                    <item name="message" xsi:type="string">Are you sure to assign selected customers to new group?</item>
                </item>
            </argument>
        </arguments>
    </type>

}
}

/** @var \Magento\Framework\Controller\Result\Json $resultJson */
$resultJson = $this->resultJsonFactory->create();
return $resultJson->setData($items);
}

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please provide a clear description for this function

*
* @var array
*/
protected $previewModules;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't use protected for newly created properties

@@ -21,16 +21,26 @@ class GlobalSearch extends \Magento\Backend\Controller\Adminhtml\Index
protected $_searchModules;

/**
* modules that support preview
Copy link
Contributor

@maghamed maghamed Jul 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw this controller should be marked with PHP DocBlock as @ api
because now it represents extension point for other search modules.

Btw it makes sense to use another extension point for these purposes

if (empty($className)) {
continue;
}
$searchInstance = $this->_objectManager->create($className);
Copy link
Contributor

@maghamed maghamed Jul 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we use ObjectManager here?
the dedicated factory should be used instead. Btw, this factory should check the type of needed object . All the search classes should implement common interface/provide the same contract
Because for now there is no any guarantee that created class supports contract by which you work with it below

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maghamed I didn't add this by myself. The code was there I just moved it around. But I will try to find a way around it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marius, you right this looks like legacy code, even taking into account that it was written quite recently.

What we usually do for such cases is to introduce new Interface with the common contract, and Factory which is responsible for producing an instance of this interface and making sure that object which would be created is an instance of the interface mentioned above.
Factory also could serve as an extension point and other developers could introduce own instance of the contract and register it using DI configuration in this factory (constructor argument).

Doing so we get:

  • well defined interface for some piece of functionality
  • well defined Factory which creates some particular implementation of this interface
  • extension point which helps 3rd party developers to extend basic implementations with custom one

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maghamed already on it.

</item>
</argument>
<argument name="searchModules" xsi:type="array" />
<argument name="previewModules" xsi:type="array" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not mandatory to provide these configurations

@tzyganu
Copy link
Contributor Author

tzyganu commented Jul 11, 2017

@maghamed Thanks for pointing me in the right direction. I will try to fix the requested changes and come back with a better code.

*/
public function __construct(
\Magento\Backend\App\Action\Context $context,
ItemsFactory $itemsFactory,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New argument to constructor may only be added as the last on the list to preserve backwards compatibility.
Please refer to Backwards Compatible Development guide for more information

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By last, you mean last one that does not have a default value, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, @ishakhsuvarov means last in a list of all existing arguments (after all existing arguments).
And each new argument added should be optional (nullable)

use Magento\Backend\Api\Search\ItemsInterface;
use Magento\Framework\ObjectManagerInterface;

class ItemsFactory
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consider using ItemFactory name for this class to be consistent with other Factories.

@ishakhsuvarov ishakhsuvarov self-assigned this Jul 11, 2017
Copy link
Contributor

@maghamed maghamed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marius, please pay attention on my comments.

Also, could you please add 'keywords in Products' , because we already have this functionality worked in another PR

namespace Magento\Backend\Api\Search;

/**
* @api
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please provide description for this interface.
All interfaces marked as @ api should be accompanied with clear and precise description

$items = array_merge_recursive($items, $results);

} catch (\LogicException $exception) {
continue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exception swallowing is a bad practice.
at least we need to log critical message here.
But in general, LogicalException should not be just swallowed and silently continue script execution

if you don't know in this specific case how to handle Exception, maybe make sense not to catch it at all

}

/**
* retrieve all entity items that should appear in global search
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please, start the sentences with the capital letter

use Magento\Backend\Model\Search\ItemsFactory;

/**
* @api
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

everything marked as @ api should be accompanied with description

* set offset
*
* @param int $start
* @return ItemsInterface
Copy link
Contributor

@maghamed maghamed Jul 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't recommend to use "fluent interfaces" and "method chaining", we support CQS where the command should return void instead of $this.
Returning $this from the setter method is allowed just for Builder implementation
(I see that we have this chaining in code before your changes, just think that if we started to improve the code quality, let's fix this out)
or let's use Builder pattern here

Thus, there are two options @tzyganu :

  1. Build/Fill kind of SearchCriterial and introduce an independent interface for processing this SearchCriteria - in this case, we will segregate responsibilities.
  2. Or use Builder pattern - all setters change the state, getResults() - build objects and reset the state

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maghamed I was trying the SearchCriteria approach, but hit a wall.
I was doing it like this.
have an ItemInterface with a single method getResults(\Magento\Framework\Api\SearchCriteria $searchCriteria) but I cannot add the filter in the search criteria for the query because the query filtering is dependent on the entity I'm filtering. So maybe I can do it via an additional parameter?. Have getResults look like this getResults($searchCriteria, $query) and the classes that implement this interface are responsible for handling the query.
I could also avoid changing the $searchCriteria parameter by using an additional searchCriteriaBuilder inside the implementations of getResults. (this is already like that for the customer search)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tzyganu I think the existing SearchCriteria we have in Framework \Magento\Framework\Api\SearchCriteria would not fit your needs. It's too heavyweight for your specific case.
When I said "SearchCriteria" I meant similar approach we use with SearchCriteria:

  1. To have a dedicated interface to describe your request (aka SearchCriteria). In your case that would be something like:
namespace Your\Custom\Api;

class SearchCriteria
{
      public function setStart($start);
      public function setQuery($query);
      public function setLimit($limit);
      public function getStart();
      public function getQuery();
      public function getLimit();
}
  1. To have Search interfaces which will process a search query based on the SearchCriteria given as Input parameter. Something like:
namespace Your\Custom\Api;

class QueryProcessor
{
      public function getResults(SearchCriteria $searchCriteria);  // or maybe Search(SearchCriteria $searchCriteria)
}

Doing so we make a responsibility segregation and don't have problems with managing and keeping the state in entity responsible for search request execution because all the parameters come as input from the outside each time.

*
* @return array
*/
public function getResults();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This interface is pretty bad one because it has a temporal coupling
on the level of contract. Because contract implies an order in which these methods would be called.
Firstly initialize all setters, and then call getResuls()

BTW This interface looks like a good application of Builder pattern for me.
So, if we would rename it to SearchResultBuilder that will make more sense.

use Magento\Backend\Api\Search\ItemsInterface;
use Magento\Framework\DataObject;

abstract class ItemsAbstract extends DataObject implements ItemsInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

introducing of abstract classes is a bad practice. In M2 we are trying to avoid using Inheritance Based API.

use composition instead, if your main reason for Inheritance usage to get rid of Copy-Paste

public function create($instanceName, array $data = [])
{
$object = $this->objectManager->create($instanceName, $data);
if ($object instanceof ItemsInterface) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's better to make a type check before the object instantiation.
Use string which represents class name and check whether it's an implementation of needed class

*/
public function create($instanceName, array $data = [])
{
$object = $this->objectManager->create($instanceName, $data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like it's better to use 'get' instead of 'create' as this should be stateless object

return $object;
}
throw new \LogicException(
"The class '{$instanceName}' does not implement ".ItemsInterface::class
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use spaces between concatenation
"" . ItemsInterface::class

use Magento\Backend\Model\Search\ItemsFactory;

/**
* @api
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current Controller became big enough and now contains Business logic inside.
It's better to introduce dedicated handler/model for this.

In M2 we are trying to make Controllers as light/ thin as possible

This Handler would be marked as @ api intead of current controller

if ($previewConfig['acl'] && !$this->_authorization->isAllowed($previewConfig['acl'])) {
continue;
}
if (!$previewConfig['url'] || !$previewConfig['text']) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not correct comparison
!$previewConfig['url'] || !$previewConfig['text']

use isset instead

@tzyganu
Copy link
Contributor Author

tzyganu commented Jul 12, 2017

@maghamed Ok. Let's recap. It would be easier for me to follow your instructions since I'm not that familiarized with all your code quality standards.

  • No abstract classes just to avoid copy-paste
  • to temporal coupling interfaces. Use a builder instead (I have to check how other builders work. An example I can follow would be nice)
  • check class type before instantiating object
  • use objects that return the results as singletons (get instead of create)
  • Don't mark the full global search controller as api. Just one action?
  • Don't hide the LogicException.
  • put back the product search
  • merge to latest develop and fix conflicts.
  • small coding standards fixes (like spaces, capitalization of comments, ...)

For the string translation in di.xml files, I propose to add the translate attribute on the item tags and when the translation if fixed to be picked up this will work (maybe I can even take a swing in a different PR at fixing this)

Let me know if I missed something.

One more question. Should I close this PR and open a new cleaner one following your guidelines? Or should I continue on this as it is easier to follow?

tzyganu and others added 2 commits July 12, 2017 10:40
@maghamed
Copy link
Contributor

Hey @tzyganu

No abstract classes just to avoid copy-paste

We are against the usage of any abstract class in newly created code. And all the existing abstract classes is the point of refactoring now or in future. For example, we would like to eliminate all the "Layer Super Types" like AbstractBlock, AbstractModel, AbstractConstructor.
We prefer to use composition instead.

to temporal coupling interfaces.

Correct. You should not design interface in a way to have an implicit relationship between two, or more, methods of a class requiring clients to invoke one method before the other.
Builder would not help you to get rid of temporal coupling, you should re-design your interface to segregate responsibilities

check class type before instantiating object

It's not a general rule. just to be more secure, because in your specific case factory accepts class to instantiate as external argument.

Don't mark the full global search controller as api. Just one action?

We are not fans of having business logic in the controllers. In your case Controller became an extension point, and anybody who wants to extend/customize search. Or add new module for search should add additional parameter for this controller. But our Controllers are responsible just for specific entry point. For example, for Mobile application we could have another Controller.
Thus, we need to copy-paste this business logic to support all the entry points.
The best rule is to keep controllers as thin as possible.

Based on the above this logic should belong to some model, not to Controller.

Don't hide the LogicException.

That's true for all the exception types

put back the product search

correct

small coding standards fixes (like spaces, capitalization of comments, ...)

would be nice

For the string translation in di.xml files, I propose to add the translate attribute on the item

yes, let's do this

Or should I continue on this as it is easier to follow?

I think we can continue in the scope of this PR

BTW , that would be helpful for you to get aware with main Magento principles and guidelines :

  1. Technical Guidelines
  2. Versioning
  3. Backward Compatibility Developers Guide

@tzyganu
Copy link
Contributor Author

tzyganu commented Jul 13, 2017

@maghamed I'm done. I hope. Just codacy is complaining a bit. I did the last changes I can think of. Please have another look.

ItemFactory $itemFactory,
SearchCriteriaFactory $criteriaFactory,
array $searchModules = [],
array $previewModules = []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Such changes to the class constructor violate backwards compatibility policy:

  • New dependencies must not be added to the middle, only as a last parameter.
  • All newly added arguments must be nullable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like

array $searchModules = [],
ItemFactory $itemFactory = null,
SearchCriteriaFactory $criteriaFactory = null,
array $previewModules = []

And then loading the optional constructor if null via $newDependency ?: \Magento\Framework\App\ObjectManager::getInstance()->get(\New\Dependency\Interface::class) would work well here I think.

/**
* @api
*/
interface ItemsInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest renaming this interface, as Items is too broad definition.
Also getResults method in ItemsInterface creates confusion, since there may not be results of items.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ishakhsuvarov do you have a suggestion for @tzyganu in this case? I could think that ResultsInterface and getResults would work well.

) {
$this->itemFactory = $itemFactory;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please refer to the Adding a constructor parameter section of Backwards Compatible Development Guide for a definition and code example for adding constructor parameters.

$this->_searchModules = $searchModules;
$this->previewModules = $previewModules;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consider extracting this logic to a dedicated model, since It does not look like it is in controllers responsibility.
Magento 2 is aiming to implement controllers as lightweight as possible, moving all possible parts outside.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ishakhsuvarov I agree whit this, but I don't see a solution to move the search logic to a separate class and keep backwards compatibility (as suggested in other comments) at the same time. Maybe I can move this to a separate class, and you release it when you break BC for something else anyway.

*
* @param string $instanceName
* @param array $data
* @return ItemsInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@throws annotation may be added here as well

use Magento\Backend\Api\Search\ItemsInterface;
use Magento\Framework\ObjectManagerInterface;

class ItemFactory
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brief description for this class may be added here

* @param \Magento\Framework\Stdlib\StringUtils $string
* @param QueryFactory $queryFactory
*/
public function __construct(
\Magento\Backend\Helper\Data $adminhtmlData,
\Magento\Backend\Helper\Data $adminHtmlData,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is considered to be backwards incompatible, please revert to maximize backwards compatibility

*/
public function load()
public function getResults(SearchCriteria $searchCriteria)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change effectively removes method load, this violates backwards compatibility for the third-party code which may rely on it.
You may add a new method and proxy calls from the old one, given that result will be compatible

* @param \Magento\Framework\Api\FilterBuilder $filterBuilder
* @param \Magento\Customer\Helper\View $customerViewHelper
*/
public function __construct(
\Magento\Backend\Helper\Data $adminhtmlData,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

@@ -3,32 +3,19 @@
* Copyright © Magento, Inc. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately a class can not be moved, since already existing 3rd-party code may already rely on it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ishakhsuvarov How about if I deprecate the class, leave it empty and make it extend my new class (the one in the right module)? Would that solve the issue for 3rd party code that may use plugins on it?

*/
public function load()
public function getResults(SearchCriteria $searchCriteria)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

@ishakhsuvarov
Copy link
Contributor

Hi @tzyganu
Do you have any questions regarding the code reviews? Please let us know if you would like any help with coding also.
Thanks!

@tzyganu
Copy link
Contributor Author

tzyganu commented Jul 18, 2017

@ishakhsuvarov Thanks for the tips. I'm on vacation for the next 2 weeks and I don't want to see any code in this period. 😄 If you're in a hurry, you can pic it up from where I left off. If not I will give it an other shot it august.

@okorshenko okorshenko added this to the July 2017 milestone Jul 20, 2017
@ishakhsuvarov
Copy link
Contributor

@tzyganu We are not in a hurry for sure. Take your time. Just let us know if you are going to need any assistance.

@okorshenko okorshenko modified the milestones: July 2017, August 2017 Aug 1, 2017
@dmanners
Copy link
Contributor

I love the fact you have moved the classes into the "right" modules. I think this a great improvement, though I cannot think 100% how to stop the BC breaks between the new and old classes other than leaving them as they are and just deprecating them. Maybe @ishakhsuvarov or @maghamed have a great example some place of this sort of change.

@ishakhsuvarov
Copy link
Contributor

@dmanners For now we may not remove the old implementations, only mark those with @deprecated annotations and possibly proxying the calls to the new ones to maximize compatibility.
When it is applicable those annotations will be scanned and "old" classes removed, if possible.

@ishakhsuvarov
Copy link
Contributor

@tzyganu I am closing this PR for now due to inactivity. Please reopen and fix merge conflicts when you would like to continue.
Thank you for collaboration.

@tzyganu
Copy link
Contributor Author

tzyganu commented Aug 21, 2017

@ishakhsuvarov I don't think I will pick this up again. At least until you make up your mind.
I got mixed comments about this PR. You (as in core team) want me to move the logic to a separate class (which sounds reasonable) and at the same time keep the backwards compatibility. I don't have a (clean) solution on how to do both. Just let me know when you are willing to break BC on this one and maybe I will pick it up again.

@orlangur
Copy link
Contributor

@tzyganu,

willing to break BC on this one

I don't think it will ever happen. The one always should deprecate some unneeded classes/methods and only in some next release they will be removed.

If you feel some implementation approach with respect to http://devdocs.magento.com/guides/v2.1/ext-best-practices/extension-coding/backwards-compatible-development/index.html does not seem to be clean, let's discuss it first and try to figure out the cleanest possible BC-compliant approch (maybe, we will determine that it's still too dirty to be embodied into life, who knows...).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants