* @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) */ namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; use Exception; use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\DuplicateWebserviceKeyException; use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\WebserviceConstraintException; use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\Key; use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; use PrestaShop\PrestaShop\Core\Search\Filters\WebserviceKeyFilters; use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; use PrestaShopBundle\Security\Annotation\AdminSecurity; use PrestaShopBundle\Security\Annotation\DemoRestricted; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * Responsible of "Configure > Advanced Parameters > Webservice" page. * * @todo: add unit tests */ class WebserviceController extends FrameworkBundleAdminController { private const WEBSERVICE_ENTRY_ENDPOINT = '/api'; /** * Displays the Webservice main page. * * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") * * @param WebserviceKeyFilters $filters - filters for webservice list * @param Request $request * * @return Response */ public function indexAction(WebserviceKeyFilters $filters, Request $request) { return $this->renderPage($request, $filters, $this->getFormHandler()->getForm()); } /** * Shows Webservice Key form and handles its submit * * @AdminSecurity("is_granted('create', request.get('_legacy_controller'))") * * @param Request $request * * @return Response */ public function createAction(Request $request) { $formHandler = $this->get('prestashop.core.form.identifiable_object.handler.webservice_key_form_handler'); $formBuilder = $this->get('prestashop.core.form.identifiable_object.builder.webservice_key_form_builder'); $form = $formBuilder->getForm(); $form->handleRequest($request); try { $result = $formHandler->handle($form); if (null !== $result->getIdentifiableObjectId()) { $this->addFlash('success', $this->trans('Successful creation', 'Admin.Notifications.Success')); return $this->redirectToRoute('admin_webservice_keys_index'); } } catch (Exception $e) { $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); } return $this->render( '@PrestaShop/Admin/Configure/AdvancedParameters/Webservice/create.html.twig', [ 'webserviceKeyForm' => $form->createView(), ] ); } /** * Redirects to webservice account form where existing webservice account record can be edited. * * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))") * * @param int $webserviceKeyId * @param Request $request * * @return Response */ public function editAction($webserviceKeyId, Request $request) { $formHandler = $this->get('prestashop.core.form.identifiable_object.handler.webservice_key_form_handler'); $formBuilder = $this->get('prestashop.core.form.identifiable_object.builder.webservice_key_form_builder'); $form = $formBuilder->getFormFor((int) $webserviceKeyId); $form->handleRequest($request); try { $result = $formHandler->handleFor((int) $webserviceKeyId, $form); if ($result->isSubmitted() && $result->isValid()) { $this->addFlash('success', $this->trans('Successful update', 'Admin.Notifications.Success')); return $this->redirectToRoute('admin_webservice_keys_index'); } } catch (Exception $e) { $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); } return $this->render( '@PrestaShop/Admin/Configure/AdvancedParameters/Webservice/edit.html.twig', [ 'webserviceKeyForm' => $form->createView(), ] ); } /** * @deprecated since 1.7.8 and will be removed in next major. Use CommonController:searchGridAction instead * * Searches for specific records. * * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") * * @param Request $request * * @return RedirectResponse */ public function searchAction(Request $request) { $definitionFactory = $this->get('prestashop.core.grid.definition.factory.webservice_key'); $webserviceDefinition = $definitionFactory->getDefinition(); $gridFilterFormFactory = $this->get('prestashop.core.grid.filter.form_factory'); $searchParametersForm = $gridFilterFormFactory->create($webserviceDefinition); $searchParametersForm->handleRequest($request); $filters = []; if ($searchParametersForm->isSubmitted()) { $filters = $searchParametersForm->getData(); } return $this->redirectToRoute('admin_webservice_keys_index', ['filters' => $filters]); } /** * Deletes single record. * * @DemoRestricted(redirectRoute="admin_webservice_keys_index") * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", message="You do not have permission to delete this.") * * @param int $webserviceKeyId * * @return RedirectResponse */ public function deleteAction($webserviceKeyId) { $webserviceEraser = $this->get('prestashop.adapter.webservice.webservice_key_eraser'); $errors = $webserviceEraser->erase([$webserviceKeyId]); if (!empty($errors)) { $this->flashErrors($errors); } else { $this->addFlash( 'success', $this->trans('Successful deletion', 'Admin.Notifications.Success') ); } return $this->redirectToRoute('admin_webservice_keys_index'); } /** * Deletes selected records. * * @DemoRestricted(redirectRoute="admin_webservice_keys_index") * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", message="You do not have permission to delete this.") * * @param Request $request * * @return RedirectResponse */ public function bulkDeleteAction(Request $request) { $webserviceToDelete = $request->request->get('webservice_key_bulk_action'); $webserviceEraser = $this->get('prestashop.adapter.webservice.webservice_key_eraser'); $errors = $webserviceEraser->erase($webserviceToDelete); if (!empty($errors)) { $this->flashErrors($errors); } else { $this->addFlash( 'success', $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') ); } return $this->redirectToRoute('admin_webservice_keys_index'); } /** * Enables status for selected rows. * * @DemoRestricted(redirectRoute="admin_webservice_keys_index") * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to edit this.") * * @param Request $request * * @return RedirectResponse */ public function bulkEnableAction(Request $request) { $webserviceToEnable = $request->request->get('webservice_key_bulk_action'); $statusModifier = $this->get('prestashop.adapter.webservice.webservice_key_status_modifier'); if ($statusModifier->setStatus($webserviceToEnable, true)) { $this->addFlash( 'success', $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') ); } return $this->redirectToRoute('admin_webservice_keys_index'); } /** * Disables status for selected rows. * * @DemoRestricted(redirectRoute="admin_webservice_keys_index") * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to edit this.") * * @param Request $request * * @return RedirectResponse */ public function bulkDisableAction(Request $request) { $webserviceToDisable = $request->request->get('webservice_key_bulk_action'); $statusModifier = $this->get('prestashop.adapter.webservice.webservice_key_status_modifier'); if ($statusModifier->setStatus($webserviceToDisable, false)) { $this->addFlash( 'success', $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') ); } return $this->redirectToRoute('admin_webservice_keys_index'); } /** * Toggles webservice account status. * * @DemoRestricted(redirectRoute="admin_webservice_keys_index") * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to edit this.") * * @param int $webserviceKeyId * * @return RedirectResponse */ public function toggleStatusAction($webserviceKeyId) { $statusModifier = $this->get('prestashop.adapter.webservice.webservice_key_status_modifier'); $errors = $statusModifier->toggleStatus($webserviceKeyId); if (!empty($errors)) { $this->flashErrors($errors); } else { $this->addFlash( 'success', $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') ); } return $this->redirectToRoute('admin_webservice_keys_index'); } /** * Process the Webservice configuration form. * * @DemoRestricted(redirectRoute="admin_webservice_keys_index") * @AdminSecurity( * "is_granted('create', request.get('_legacy_controller')) && is_granted('update', request.get('_legacy_controller')) && is_granted('delete', request.get('_legacy_controller'))", * message="You do not have permission to edit this." * ) * * @param Request $request * @param WebserviceKeyFilters $filters * * @return Response|RedirectResponse */ public function saveSettingsAction(Request $request, WebserviceKeyFilters $filters) { $this->dispatchHook('actionAdminAdminWebserviceControllerPostProcessBefore', ['controller' => $this]); $form = $this->getFormHandler()->getForm(); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $saveErrors = $this->getFormHandler()->save($form->getData()); if (0 === count($saveErrors)) { $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); return $this->redirectToRoute('admin_webservice_keys_index'); } else { $this->flashErrors($saveErrors); } } return $this->renderPage($request, $filters, $form); } /** * @param Request $request * @param WebserviceKeyFilters $filters * @param FormInterface $form * * @return Response */ protected function renderPage(Request $request, WebserviceKeyFilters $filters, FormInterface $form): Response { $grid = $this->get('prestashop.core.grid.factory.webservice_key')->getGrid($filters); return $this->render( '@PrestaShop/Admin/Configure/AdvancedParameters/Webservice/index.html.twig', [ 'help_link' => $this->generateSidebarLink($request->get('_legacy_controller')), 'webserviceConfigurationForm' => $form->createView(), 'grid' => $this->presentGrid($grid), 'configurationWarnings' => $this->lookForWarnings(), 'webserviceStatus' => $this->getWebServiceStatus($request), ] ); } /** * @return FormHandlerInterface */ private function getFormHandler(): FormHandlerInterface { return $this->get('prestashop.adapter.webservice.form_handler'); } /** * @return string[] */ private function lookForWarnings() { $configurationChecker = $this->get('prestashop.core.webservice.server_requirements_checker'); return $configurationChecker->checkForErrors(); } /** * @return array */ private function getErrorMessages() { return [ WebserviceConstraintException::class => [ WebserviceConstraintException::INVALID_KEY => $this->trans( 'Key length must be %length% characters long.', 'Admin.Advparameters.Notification', [ '%length%' => Key::LENGTH, ] ), ], DuplicateWebserviceKeyException::class => $this->trans('This key already exists.', 'Admin.Advparameters.Notification'), ]; } /** * @param Request $request * * @return array */ private function getWebServiceStatus(Request $request): array { $webserviceConfiguration = $this->get('prestashop.admin.webservice.form_data_provider')->getData(); $webserviceStatus = [ 'isEnabled' => (bool) $webserviceConfiguration['enable_webservice'], 'isFunctional' => false, 'endpoint' => null, ]; if ($webserviceStatus['isEnabled']) { $webserviceStatus['endpoint'] = rtrim($request->getSchemeAndHttpHost(), '/'); $webserviceStatus['endpoint'] .= rtrim($this->getContext()->shop->getBaseURI(), '/'); $webserviceStatus['endpoint'] .= self::WEBSERVICE_ENTRY_ENDPOINT; $webserviceStatus['isFunctional'] = $this->checkWebserviceEndpoint($webserviceStatus['endpoint']); } return $webserviceStatus; } /** * @param string $url * * @return bool */ private function checkWebserviceEndpoint(string $url): bool { $client = HttpClient::create(); $statusCode = null; try { $response = $client->request('GET', $url, [ 'max_redirects' => 5, ]); $statusCode = $response->getStatusCode(); } catch (Exception $e) { $this->addFlash('error', $e->getMessage()); return false; } if ($statusCode >= Response::HTTP_OK && $statusCode < Response::HTTP_MULTIPLE_CHOICES) { return true; } elseif ($statusCode == Response::HTTP_UNAUTHORIZED) { return true; } return false; } }