Skip to content

Commit 32c1845

Browse files
authored
MAGETWO-71048: WIP: Admin Config Search #10335
2 parents e3b3ea4 + be8ecdb commit 32c1845

File tree

24 files changed

+929
-5
lines changed

24 files changed

+929
-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)