Skip to content

Commit 333a3d3

Browse files
committed
Merge remote-tracking branch 'origin/MC-19282-web-setup' into MC-33394-pr-delivery
2 parents c0539e9 + 33987b4 commit 333a3d3

File tree

13 files changed

+827
-8
lines changed

13 files changed

+827
-8
lines changed

setup/config/states.install.config.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* See COPYING.txt for license details.
55
*/
66

7+
//phpcs:ignore
78
$base = basename($_SERVER['SCRIPT_FILENAME']);
89

910
return [
@@ -93,27 +94,39 @@
9394
'order' => 5,
9495
'type' => 'install'
9596
],
97+
[
98+
'id' => 'root.configure-catalog-search',
99+
'url' => 'configure-catalog-search',
100+
'templateUrl' => "{$base}/configure-catalog-search",
101+
'title' => "Configure \n Search",
102+
'header' => 'Step 5: Configure Catalog Search',
103+
'controller' => 'configureCatalogSearchController',
104+
'nav' => true,
105+
'validate' => true,
106+
'order' => 6,
107+
'type' => 'install'
108+
],
96109
[
97110
'id' => 'root.create-admin-account',
98111
'url' => 'create-admin-account',
99112
'templateUrl' => "{$base}/create-admin-account",
100113
'title' => "Create \n Admin Account",
101-
'header' => 'Step 5: Create Admin Account',
114+
'header' => 'Step 6: Create Admin Account',
102115
'controller' => 'createAdminAccountController',
103116
'nav' => true,
104117
'validate' => true,
105-
'order' => 6,
118+
'order' => 7,
106119
'type' => 'install'
107120
],
108121
[
109122
'id' => 'root.install',
110123
'url' => 'install',
111124
'templateUrl' => "{$base}/install",
112125
'title' => 'Install',
113-
'header' => 'Step 6: Install',
126+
'header' => 'Step 7: Install',
114127
'controller' => 'installController',
115128
'nav' => true,
116-
'order' => 7,
129+
'order' => 8,
117130
'type' => 'install'
118131
],
119132
[
@@ -123,7 +136,7 @@
123136
'title' => 'Success',
124137
'controller' => 'successController',
125138
'main' => true,
126-
'order' => 8,
139+
'order' => 9,
127140
'type' => 'install'
128141
],
129142
],

setup/pub/magento/setup/app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ var app = angular.module(
1515
'add-database',
1616
'web-configuration',
1717
'customize-your-store',
18+
'configure-catalog-search',
1819
'create-admin-account',
1920
'install',
2021
'success',
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
'use strict';
7+
angular.module('configure-catalog-search', ['ngStorage', 'ngSanitize'])
8+
.controller('configureCatalogSearchController', ['$scope', '$localStorage' , '$state', '$http', function ($scope, $localStorage, $state, $http) {
9+
$scope.search = {
10+
config: {
11+
engine: null,
12+
elasticsearch: {},
13+
},
14+
testConnection: {
15+
result: {}
16+
},
17+
};
18+
19+
if ($localStorage.search) {
20+
$scope.search.config = $localStorage.search;
21+
}
22+
23+
$scope.$on('nextState', function () {
24+
$localStorage.search = $scope.search.config;
25+
});
26+
27+
// Listens on form validate event, dispatched by parent controller
28+
$scope.$on('validate-' + $state.current.id, function() {
29+
$scope.validate();
30+
});
31+
32+
// Dispatch 'validation-response' event to parent controller
33+
$scope.validate = function() {
34+
if ($scope.searchConfig.$valid) {
35+
$scope.$emit('validation-response', true);
36+
} else {
37+
$scope.$emit('validation-response', false);
38+
$scope.searchConfig.submitted = true;
39+
}
40+
};
41+
42+
// Update 'submitted' flag
43+
$scope.$watch(function() { return $scope.searchConfig.$valid }, function(valid) {
44+
if (valid) {
45+
$scope.searchConfig.submitted = false;
46+
}
47+
});
48+
49+
if (!$scope.search.config.engine) {
50+
$http.get('index.php/configure-catalog-search/default-parameters',{'responseType' : 'json'})
51+
.then(function successCallback(resp) {
52+
$scope.search.config = resp.data;
53+
});
54+
}
55+
56+
$scope.testConnection = function(goNext) {
57+
$scope.checking = true;
58+
$scope.search.testConnection.result = {};
59+
$http.post('index.php/search-engine-check', $scope.search.config)
60+
.then(function successCallback(resp) {
61+
if (resp.data.success) {
62+
$scope.search.testConnection.result.success = true;
63+
if (goNext) {
64+
$scope.nextState();
65+
} else {
66+
$scope.search.testConnection.result.message = 'Test connection successful.';
67+
}
68+
} else {
69+
$scope.search.testConnection.result.success = false;
70+
$scope.search.testConnection.result.message = resp.data.error;
71+
}
72+
$scope.checking = false;
73+
}, function errorCallback() {
74+
$scope.search.testConnection.result.success = false;
75+
$scope.search.testConnection.result.message =
76+
'An unknown error occurred. Please check configuration and try again.';
77+
$scope.checking = false;
78+
});
79+
};
80+
}]);

setup/pub/magento/setup/install.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ angular.module('install', ['ngStorage'])
7070
'db': $localStorage.db,
7171
'admin': $localStorage.admin,
7272
'store': $localStorage.store,
73-
'config': $localStorage.config
73+
'config': $localStorage.config,
74+
'search': $localStorage.search
7475
};
7576
$scope.isStarted = true;
7677
$scope.isInProgress = true;

setup/pub/styles/setup.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Setup\Controller;
9+
10+
use Laminas\Mvc\Controller\AbstractActionController;
11+
use Laminas\View\Model\JsonModel;
12+
use Laminas\View\Model\ViewModel;
13+
use Magento\Setup\Model\SearchConfigOptionsList;
14+
15+
/**
16+
* ConfigureCatalogSearch controller
17+
*/
18+
class ConfigureCatalogSearch extends AbstractActionController
19+
{
20+
/**
21+
* @var SearchConfigOptionsList
22+
*/
23+
private $searchConfigOptionsList;
24+
25+
/**
26+
* @param SearchConfigOptionsList $searchConfigOptionsList
27+
*/
28+
public function __construct(SearchConfigOptionsList $searchConfigOptionsList)
29+
{
30+
$this->searchConfigOptionsList = $searchConfigOptionsList;
31+
}
32+
33+
/**
34+
* Index action
35+
*
36+
* @return ViewModel
37+
*/
38+
public function indexAction(): ViewModel
39+
{
40+
$view = new ViewModel([
41+
'availableSearchEngines' => $this->searchConfigOptionsList->getAvailableSearchEngineList(),
42+
]);
43+
$view->setTerminal(true);
44+
return $view;
45+
}
46+
47+
/**
48+
* Fetch default configuration parameters
49+
*
50+
* @return JsonModel
51+
*/
52+
public function defaultParametersAction(): JsonModel
53+
{
54+
$defaults = [
55+
'engine' => SearchConfigOptionsList::DEFAULT_SEARCH_ENGINE,
56+
'elasticsearch' => [
57+
'hostname' => SearchConfigOptionsList::DEFAULT_ELASTICSEARCH_HOST,
58+
'port' => SearchConfigOptionsList::DEFAULT_ELASTICSEARCH_PORT,
59+
'timeout' => SearchConfigOptionsList::DEFAULT_ELASTICSEARCH_TIMEOUT,
60+
'indexPrefix' => SearchConfigOptionsList::DEFAULT_ELASTICSEARCH_INDEX_PREFIX,
61+
'enableAuth' => false
62+
]
63+
];
64+
65+
return new JsonModel($defaults);
66+
}
67+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Setup\Controller;
9+
10+
use Laminas\Json\Json;
11+
use Laminas\Mvc\Controller\AbstractActionController;
12+
use Laminas\View\Model\JsonModel;
13+
use Magento\Framework\Exception\InputException;
14+
use Magento\Setup\Model\SearchConfigOptionsList;
15+
use Magento\Setup\Validator\ElasticsearchConnectionValidator;
16+
17+
/**
18+
* SearchEngineCheck controller
19+
*/
20+
class SearchEngineCheck extends AbstractActionController
21+
{
22+
/**
23+
* @var ElasticsearchConnectionValidator
24+
*/
25+
private $connectionValidator;
26+
27+
/**
28+
* @var SearchConfigOptionsList
29+
*/
30+
private $searchConfigOptionsList;
31+
32+
/**
33+
* @param ElasticsearchConnectionValidator $connectionValidator
34+
* @param SearchConfigOptionsList $searchConfigOptionsList
35+
*/
36+
public function __construct(
37+
ElasticsearchConnectionValidator $connectionValidator,
38+
SearchConfigOptionsList $searchConfigOptionsList
39+
) {
40+
$this->connectionValidator = $connectionValidator;
41+
$this->searchConfigOptionsList = $searchConfigOptionsList;
42+
}
43+
44+
/**
45+
* Result of checking Elasticsearch connection
46+
*
47+
* @return JsonModel
48+
*/
49+
public function indexAction(): JsonModel
50+
{
51+
try {
52+
$params = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY);
53+
$this->isValidSearchEngine($params);
54+
$isValid = $this->connectionValidator->isValidConnection(
55+
[
56+
'hostname' => $params['elasticsearch']['hostname'] ?? null,
57+
'port' => $params['elasticsearch']['port'] ?? null,
58+
'enableAuth' => $params['elasticsearch']['enableAuth'] ?? false,
59+
'username' => $params['elasticsearch']['username'] ?? null,
60+
'password' => $params['elasticsearch']['password'] ?? null,
61+
'indexPrefix' => $params['elasticsearch']['indexPrefix'] ?? ''
62+
]
63+
);
64+
return new JsonModel(['success' => $isValid]);
65+
} catch (\Exception $e) {
66+
return new JsonModel(['success' => false, 'error' => $e->getMessage()]);
67+
}
68+
}
69+
70+
/**
71+
* Check search engine parameter is valid
72+
*
73+
* @param $requestParams
74+
* @return bool
75+
* @throws InputException
76+
*/
77+
private function isValidSearchEngine($requestParams): bool
78+
{
79+
$selectedEngine = $requestParams['engine'] ?? null;
80+
$availableSearchEngines = $this->searchConfigOptionsList->getAvailableSearchEngineList();
81+
if (empty($selectedEngine) || !isset($availableSearchEngines[$selectedEngine])) {
82+
throw new InputException(__('Please select a valid search engine.'));
83+
}
84+
85+
return true;
86+
}
87+
}

setup/src/Magento/Setup/Model/RequestDataConverter.php

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ public function convert(array $source)
2626
$result = array_merge(
2727
$this->convertDeploymentConfigForm($source),
2828
$this->convertUserConfigForm($source),
29-
$this->convertAdminUserForm($source)
29+
$this->convertAdminUserForm($source),
30+
$this->convertSearchConfigForm($source)
3031
);
3132
return $result;
3233
}
@@ -122,4 +123,56 @@ private function convertAdminUserForm(array $source)
122123
$result[AdminAccount::KEY_LAST_NAME] = $result[AdminAccount::KEY_USER];
123124
return $result;
124125
}
126+
127+
/**
128+
* Convert data from request to format of search config model
129+
*
130+
* @param array $source
131+
* @return array
132+
*/
133+
private function convertSearchConfigForm(array $source): array
134+
{
135+
$result = [];
136+
if (!isset($source['search'])) {
137+
return $result;
138+
}
139+
$result[SearchConfigOptionsList::INPUT_KEY_SEARCH_ENGINE] =
140+
$this->getValueFromArray($source['search'], 'engine', '');
141+
142+
$esConfig = $source['search']['elasticsearch'];
143+
$result[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_HOST] =
144+
$this->getValueFromArray($esConfig, 'hostname', '');
145+
$result[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_PORT] =
146+
$this->getValueFromArray($esConfig, 'port', '');
147+
$result[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_INDEX_PREFIX] =
148+
$this->getValueFromArray($esConfig, 'indexPrefix', '');
149+
$result[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_TIMEOUT] =
150+
$this->getValueFromArray($esConfig, 'timeout', '');
151+
152+
if (isset($esConfig['enableAuth']) && true === $esConfig['enableAuth']) {
153+
$result[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_ENABLE_AUTH] = $esConfig['enableAuth'];
154+
$result[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_USERNAME] =
155+
$this->getValueFromArray($esConfig, 'username', '');
156+
$result[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_PASSWORD] =
157+
$this->getValueFromArray($esConfig, 'password', '');
158+
} else {
159+
$result[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_ENABLE_AUTH] =
160+
$this->getValueFromArray($esConfig, 'enableAuth', false);
161+
}
162+
163+
return $result;
164+
}
165+
166+
/**
167+
* Get value from array by key, or return default
168+
*
169+
* @param array $array
170+
* @param string $key
171+
* @param mixed $defaultValue
172+
* @return mixed
173+
*/
174+
private function getValueFromArray(array $array, string $key, $defaultValue = null)
175+
{
176+
return isset($array[$key]) ? $array[$key] : $defaultValue;
177+
}
125178
}

0 commit comments

Comments
 (0)