Skip to content

Commit d82edbc

Browse files
committed
MAGETWO-71048: WIP: Admin Config Search #10335
- Merge Pull Request #10335 from liip-forks/magento2:develop - Merged commits: 1. 30c1c5d 2. 94b423b 3. e2e2048 4. b9398af 5. f5dd204 6. a1d0f2d 7. 05de33c 8. 3f84bd1 9. 42baff6 10. c366ac4 11. 74a3b06 12. a468317 13. 10cbd63 14. 95503dd 15. aff2aa5 16. 93f4245 17. 27dfdff 18. 76b11c8 19. 951f41e 20. fab44c3
2 parents ecefd85 + fab44c3 commit d82edbc

File tree

24 files changed

+933
-5
lines changed

24 files changed

+933
-5
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Backend\Model\Search;
7+
8+
use Magento\Backend\Model\Search\Config\Result\Builder;
9+
use Magento\Config\Model\Config\Structure;
10+
use Magento\Config\Model\Config\Structure\Element\AbstractComposite;
11+
use Magento\Config\Model\Config\Structure\Element\Iterator as ElementIterator;
12+
13+
/**
14+
* Search Config Model
15+
*/
16+
class Config extends \Magento\Framework\DataObject
17+
{
18+
/**
19+
* @var \Magento\Framework\App\Config\ConfigTypeInterface
20+
*/
21+
private $configStructure;
22+
23+
/**
24+
* @var Builder
25+
*/
26+
private $resultBuilder;
27+
28+
/**
29+
* @param Structure $configStructure
30+
* @param Builder $resultBuilder
31+
*/
32+
public function __construct(Structure $configStructure, Builder $resultBuilder)
33+
{
34+
$this->configStructure = $configStructure;
35+
$this->resultBuilder = $resultBuilder;
36+
}
37+
38+
/**
39+
* @param string $query
40+
* @return $this
41+
*/
42+
public function setQuery($query)
43+
{
44+
$this->setData('query', $query);
45+
return $this;
46+
}
47+
48+
/**
49+
* @return string|null
50+
*/
51+
public function getQuery()
52+
{
53+
return $this->getData('query');
54+
}
55+
56+
/**
57+
* @return bool
58+
*/
59+
public function hasQuery()
60+
{
61+
return $this->hasData('query');
62+
}
63+
64+
/**
65+
* @param array $results
66+
* @return $this
67+
*/
68+
public function setResults(array $results)
69+
{
70+
$this->setData('results', $results);
71+
return $this;
72+
}
73+
74+
/**
75+
* @return array|null
76+
*/
77+
public function getResults()
78+
{
79+
return $this->getData('results');
80+
}
81+
82+
/**
83+
* Load search results
84+
*
85+
* @return $this
86+
*/
87+
public function load()
88+
{
89+
$this->findInStructure($this->configStructure->getTabs(), $this->getQuery());
90+
$this->setResults($this->resultBuilder->getAll());
91+
return $this;
92+
}
93+
94+
/**
95+
* @param ElementIterator $structureElementIterator
96+
* @param string $searchTerm
97+
* @param string $pathLabel
98+
* @return void
99+
* @SuppressWarnings(PHPMD.LongVariable)
100+
*/
101+
private function findInStructure(ElementIterator $structureElementIterator, $searchTerm, $pathLabel = '')
102+
{
103+
if (empty($searchTerm)) {
104+
return;
105+
}
106+
foreach ($structureElementIterator as $structureElement) {
107+
if (mb_stripos((string)$structureElement->getLabel(), $searchTerm) !== false) {
108+
$this->resultBuilder->add($structureElement, $pathLabel);
109+
}
110+
$elementPathLabel = $pathLabel . ' / ' . $structureElement->getLabel();
111+
if ($structureElement instanceof AbstractComposite && $structureElement->hasChildren()) {
112+
$this->findInStructure($structureElement->getChildren(), $searchTerm, $elementPathLabel);
113+
}
114+
}
115+
}
116+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Backend\Model\Search\Config\Result;
7+
8+
use Magento\Backend\Model\Search\Config\Structure\ElementBuilderInterface;
9+
use Magento\Backend\Model\UrlInterface;
10+
use Magento\Config\Model\Config\StructureElementInterface;
11+
12+
/**
13+
* Config SearchResult Builder
14+
* @SuppressWarnings(PHPMD.LongVariable)
15+
*/
16+
class Builder
17+
{
18+
/**
19+
* @var array
20+
*/
21+
private $results = [];
22+
23+
/**
24+
* @var UrlInterface
25+
*/
26+
private $urlBuilder;
27+
28+
/**
29+
* @var ElementBuilderInterface[]
30+
*/
31+
private $structureElementTypes;
32+
33+
/**
34+
* @param UrlInterface $urlBuilder
35+
* @param array $structureElementTypes
36+
*/
37+
public function __construct(UrlInterface $urlBuilder, array $structureElementTypes)
38+
{
39+
$this->urlBuilder = $urlBuilder;
40+
$this->structureElementTypes = $structureElementTypes;
41+
}
42+
43+
/**
44+
* @return array
45+
*/
46+
public function getAll()
47+
{
48+
return $this->results;
49+
}
50+
51+
/**
52+
* @param StructureElementInterface $structureElement
53+
* @param string $elementPathLabel
54+
* @return void
55+
*/
56+
public function add(StructureElementInterface $structureElement, $elementPathLabel)
57+
{
58+
$urlParams = [];
59+
$elementData = $structureElement->getData();
60+
61+
if (!in_array($elementData['_elementType'], array_keys($this->structureElementTypes))) {
62+
return;
63+
}
64+
65+
if (isset($this->structureElementTypes[$elementData['_elementType']])) {
66+
$urlParamsBuilder = $this->structureElementTypes[$elementData['_elementType']];
67+
$urlParams = $urlParamsBuilder->build($structureElement);
68+
}
69+
70+
$this->results[] = [
71+
'id' => $structureElement->getPath(),
72+
'type' => null,
73+
'name' => (string)$structureElement->getLabel(),
74+
'description' => $elementPathLabel,
75+
'url' => $this->urlBuilder->getUrl('*/system_config/edit', $urlParams),
76+
];
77+
}
78+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Backend\Model\Search\Config\Structure\Element\Builder;
7+
8+
use Magento\Backend\Model\Search\Config\Structure\ElementBuilderInterface;
9+
use Magento\Config\Model\Config\StructureElementInterface;
10+
11+
class Field implements ElementBuilderInterface
12+
{
13+
/**
14+
* @inheritdoc
15+
*/
16+
public function build(StructureElementInterface $structureElement)
17+
{
18+
$elementPathParts = explode('/', $structureElement->getPath());
19+
return [
20+
'section' => $elementPathParts[0],
21+
'group' => $elementPathParts[1],
22+
'field' => $structureElement->getId(),
23+
];
24+
}
25+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Backend\Model\Search\Config\Structure\Element\Builder;
7+
8+
use Magento\Backend\Model\Search\Config\Structure\ElementBuilderInterface;
9+
use Magento\Config\Model\Config\StructureElementInterface;
10+
11+
class Group implements ElementBuilderInterface
12+
{
13+
/**
14+
* @inheritdoc
15+
*/
16+
public function build(StructureElementInterface $structureElement)
17+
{
18+
$elementPathParts = explode('/', $structureElement->getPath());
19+
return [
20+
'section' => $elementPathParts[0],
21+
'group' => $elementPathParts[1],
22+
];
23+
}
24+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Backend\Model\Search\Config\Structure\Element\Builder;
7+
8+
use Magento\Backend\Model\Search\Config\Structure\ElementBuilderInterface;
9+
use Magento\Config\Model\Config\StructureElementInterface;
10+
11+
class Section implements ElementBuilderInterface
12+
{
13+
/**
14+
* @inheritdoc
15+
*/
16+
public function build(StructureElementInterface $structureElement)
17+
{
18+
$elementPathParts = explode('/', $structureElement->getPath());
19+
return ['section' => $elementPathParts[1]];
20+
}
21+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Backend\Model\Search\Config\Structure;
7+
8+
use Magento\Config\Model\Config\StructureElementInterface;
9+
10+
interface ElementBuilderInterface
11+
{
12+
/**
13+
* @param StructureElementInterface $structureElement
14+
* @return array
15+
*/
16+
public function build(StructureElementInterface $structureElement);
17+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Backend\Test\Unit\Model\Search\Config\Result;
7+
8+
use Magento\Backend\Model\Search\Config\Structure\ElementBuilderInterface;
9+
use Magento\Backend\Model\UrlInterface;
10+
use Magento\Backend\Model\Search\Config\Result\Builder;
11+
use Magento\Config\Model\Config\StructureElementInterface;
12+
use PHPUnit\Framework\TestCase;
13+
14+
/**
15+
* @SuppressWarnings(PHPMD.LongVariable)
16+
*/
17+
class BuilderTest extends TestCase
18+
{
19+
/**
20+
* @var Builder
21+
*/
22+
protected $model;
23+
24+
/**
25+
* @var StructureElementInterface|\PHPUnit_Framework_MockObject_MockObject
26+
*/
27+
protected $structureElementMock;
28+
29+
/**
30+
* @var UrlInterface|\PHPUnit_Framework_MockObject_MockObject
31+
*/
32+
protected $urlBuilderMock;
33+
34+
/**
35+
* @var ElementBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
36+
*/
37+
protected $structureElementUrlParamsBuilderMock;
38+
39+
protected function setUp()
40+
{
41+
$this->urlBuilderMock = $this->getMockForAbstractClass(UrlInterface::class);
42+
$this->structureElementMock = $this->getMockForAbstractClass(StructureElementInterface::class);
43+
$this->structureElementUrlParamsBuilderMock = $this->getMockForAbstractClass(ElementBuilderInterface::class);
44+
$this->model = new Builder($this->urlBuilderMock, ['section' => $this->structureElementUrlParamsBuilderMock]);
45+
}
46+
47+
public function testAddWithNotSupportedStructureElementReturnsNothing()
48+
{
49+
$this->structureElementMock
50+
->expects($this->once())
51+
->method('getData')
52+
->will($this->returnValue(['_elementType' => 'not_declared_structure_element_type']));
53+
$this->model->add($this->structureElementMock, '');
54+
$this->assertEquals([], $this->model->getAll());
55+
}
56+
57+
public function testAddWithSupportedStructureElements()
58+
{
59+
$structureElementPath = '/section_code';
60+
$structureElementLabel = 'Section Label';
61+
$buildUrlParams = ['param_key' => 'param_value'];
62+
$generatedUrl = 'http://example.com';
63+
64+
$expectedSearchResult = [
65+
[
66+
'id' => $structureElementPath,
67+
'type' => null,
68+
'name' => 'Section Label',
69+
'description' => 'Section Label',
70+
'url' => 'http://example.com',
71+
],
72+
];
73+
74+
$this->structureElementMock
75+
->expects($this->once())
76+
->method('getData')
77+
->willReturn(['_elementType' => 'section']);
78+
$this->structureElementMock
79+
->expects($this->once())
80+
->method('getPath')
81+
->willReturn($structureElementPath);
82+
$this->structureElementMock
83+
->expects($this->once())
84+
->method('getLabel')
85+
->willReturn($structureElementLabel);
86+
87+
$this->structureElementUrlParamsBuilderMock->expects($this->once())
88+
->method('build')
89+
->willReturn($buildUrlParams);
90+
91+
$this->urlBuilderMock
92+
->expects($this->once())
93+
->method('getUrl')
94+
->with('*/system_config/edit', $buildUrlParams)
95+
->will($this->returnValue($generatedUrl));
96+
97+
$this->model->add($this->structureElementMock, $structureElementLabel);
98+
$this->assertEquals($expectedSearchResult, $this->model->getAll());
99+
}
100+
}

0 commit comments

Comments
 (0)