1<?php 2/** 3 * Copyright since 2007 PrestaShop SA and Contributors 4 * PrestaShop is an International Registered Trademark & Property of PrestaShop SA 5 * 6 * NOTICE OF LICENSE 7 * 8 * This source file is subject to the Open Software License (OSL 3.0) 9 * that is bundled with this package in the file LICENSE.md. 10 * It is also available through the world-wide-web at this URL: 11 * https://opensource.org/licenses/OSL-3.0 12 * If you did not receive a copy of the license and are unable to 13 * obtain it through the world-wide-web, please send an email 14 * to license@prestashop.com so we can send you a copy immediately. 15 * 16 * DISCLAIMER 17 * 18 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer 19 * versions in the future. If you wish to customize PrestaShop for your 20 * needs please refer to https://devdocs.prestashop.com/ for more information. 21 * 22 * @author PrestaShop SA and Contributors <contact@prestashop.com> 23 * @copyright Since 2007 PrestaShop SA and Contributors 24 * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) 25 */ 26 27namespace PrestaShopBundle\Controller\Admin\Improve; 28 29use DateTime; 30use Exception; 31use Module; 32use PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider; 33use PrestaShop\PrestaShop\Adapter\Module\Module as ModuleAdapter; 34use PrestaShop\PrestaShop\Core\Addon\AddonListFilter; 35use PrestaShop\PrestaShop\Core\Addon\AddonListFilterStatus; 36use PrestaShop\PrestaShop\Core\Addon\AddonListFilterType; 37use PrestaShop\PrestaShop\Core\Addon\AddonsCollection; 38use PrestaShop\PrestaShop\Core\Addon\Module\Exception\UnconfirmedModuleActionException; 39use PrestaShop\PrestaShop\Core\Addon\Module\ModuleRepository; 40use PrestaShopBundle\Controller\Admin\Improve\Modules\ModuleAbstractController; 41use PrestaShopBundle\Entity\ModuleHistory; 42use PrestaShopBundle\Security\Annotation\AdminSecurity; 43use PrestaShopBundle\Security\Voter\PageVoter; 44use PrestaShopBundle\Service\DataProvider\Admin\CategoriesProvider; 45use Profile; 46use Symfony\Component\Form\Util\ServerParams; 47use Symfony\Component\HttpFoundation\JsonResponse; 48use Symfony\Component\HttpFoundation\Request; 49use Symfony\Component\HttpFoundation\Response; 50use Symfony\Component\Routing\Generator\UrlGeneratorInterface; 51use Symfony\Component\Validator\Constraints as Assert; 52 53/** 54 * Responsible of "Improve > Modules > Modules & Services > Catalog / Manage" page display. 55 */ 56class ModuleController extends ModuleAbstractController 57{ 58 public const CONTROLLER_NAME = 'ADMINMODULESSF'; 59 60 public const MAX_MODULES_DISPLAYED = 6; 61 62 /** 63 * @AdminSecurity("is_granted(['read'], 'ADMINMODULESSF_')") 64 * 65 * @return Response 66 */ 67 public function catalogAction() 68 { 69 return $this->render( 70 '@PrestaShop/Admin/Module/catalog.html.twig', 71 [ 72 'layoutHeaderToolbarBtn' => $this->getToolbarButtons(), 73 'layoutTitle' => $this->trans('Modules catalog', 'Admin.Navigation.Menu'), 74 'requireAddonsSearch' => true, 75 'requireBulkActions' => false, 76 'showContentHeader' => true, 77 'enableSidebar' => true, 78 'help_link' => $this->generateSidebarLink('AdminModules'), 79 'requireFilterStatus' => false, 80 'level' => $this->authorizationLevel(self::CONTROLLER_NAME), 81 'errorMessage' => $this->trans( 82 'You do not have permission to add this.', 83 'Admin.Notifications.Error' 84 ), 85 ] 86 ); 87 } 88 89 /** 90 * Controller responsible for displaying "Catalog Module Grid" section of Module management pages with ajax. 91 * 92 * @AdminSecurity("is_granted(['read'], 'ADMINMODULESSF_')") 93 * 94 * @return Response 95 */ 96 public function manageAction() 97 { 98 $modulesProvider = $this->get('prestashop.core.admin.data_provider.module_interface'); 99 $shopService = $this->get('prestashop.adapter.shop.context'); 100 $moduleRepository = $this->get('prestashop.core.admin.module.repository'); 101 $themeRepository = $this->get('prestashop.core.addon.theme.repository'); 102 103 // Retrieve current shop 104 $shopId = $shopService->getContextShopId(); 105 $shops = $shopService->getShops(); 106 $modulesTheme = []; 107 if (isset($shops[$shopId]) && is_array($shops[$shopId])) { 108 $shop = $shops[$shopId]; 109 $currentTheme = $themeRepository->getInstanceByName($shop['theme_name']); 110 $modulesTheme = $currentTheme->getModulesToEnable(); 111 } 112 113 $filters = new AddonListFilter(); 114 $filters->setType(AddonListFilterType::MODULE | AddonListFilterType::SERVICE) 115 ->removeStatus(AddonListFilterStatus::UNINSTALLED); 116 $installedProducts = $moduleRepository->getFilteredList($filters); 117 118 $categories = $this->getCategories($modulesProvider, $installedProducts); 119 $bulkActions = [ 120 'bulk-uninstall' => $this->trans('Uninstall', 'Admin.Actions'), 121 'bulk-disable' => $this->trans('Disable', 'Admin.Actions'), 122 'bulk-enable' => $this->trans('Enable', 'Admin.Actions'), 123 'bulk-reset' => $this->trans('Reset', 'Admin.Actions'), 124 'bulk-enable-mobile' => $this->trans('Enable Mobile', 'Admin.Modules.Feature'), 125 'bulk-disable-mobile' => $this->trans('Disable Mobile', 'Admin.Modules.Feature'), 126 ]; 127 128 return $this->render( 129 '@PrestaShop/Admin/Module/manage.html.twig', 130 [ 131 'maxModulesDisplayed' => self::MAX_MODULES_DISPLAYED, 132 'bulkActions' => $bulkActions, 133 'layoutHeaderToolbarBtn' => $this->getToolbarButtons(), 134 'layoutTitle' => $this->trans('Module manager', 'Admin.Modules.Feature'), 135 'categories' => $categories['categories'], 136 'topMenuData' => $this->getTopMenuData($categories), 137 'requireAddonsSearch' => false, 138 'requireBulkActions' => true, 139 'enableSidebar' => true, 140 'help_link' => $this->generateSidebarLink('AdminModules'), 141 'requireFilterStatus' => true, 142 'level' => $this->authorizationLevel(self::CONTROLLER_NAME), 143 'errorMessage' => $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'), 144 ] 145 ); 146 } 147 148 /** 149 * @AdminSecurity("is_granted(['read'], 'ADMINMODULESSF_')") 150 * 151 * @param Request $request 152 * 153 * @return Response 154 */ 155 public function getPreferredModulesAction(Request $request) 156 { 157 $tabModulesList = $request->get('tab_modules_list'); 158 159 if ($tabModulesList) { 160 $tabModulesList = explode(',', $tabModulesList); 161 } 162 $modulesListUnsorted = $this->getModulesByInstallation( 163 $tabModulesList 164 ); 165 166 $installed = $uninstalled = []; 167 168 if (!empty($tabModulesList)) { 169 foreach ($tabModulesList as $key => $value) { 170 foreach ($modulesListUnsorted['installed'] as $moduleInstalled) { 171 if ($moduleInstalled['attributes']['name'] == $value) { 172 $installed[] = $moduleInstalled; 173 174 continue 2; 175 } 176 } 177 178 foreach ($modulesListUnsorted['not_installed'] as $moduleNotInstalled) { 179 if ($moduleNotInstalled['attributes']['name'] == $value) { 180 $uninstalled[] = $moduleNotInstalled; 181 182 continue 2; 183 } 184 } 185 } 186 } 187 188 $moduleListSorted = [ 189 'installed' => $installed, 190 'notInstalled' => $uninstalled, 191 ]; 192 193 $twigParams = [ 194 'currentIndex' => '', 195 'modulesList' => $moduleListSorted, 196 'level' => $this->authorizationLevel(self::CONTROLLER_NAME), 197 ]; 198 199 if ($request->request->has('admin_list_from_source')) { 200 $twigParams['adminListFromSource'] = $request->request->get('admin_list_from_source'); 201 } 202 203 return $this->render( 204 '@PrestaShop/Admin/Module/tab-modules-list.html.twig', 205 $twigParams 206 ); 207 } 208 209 /** 210 * @AdminSecurity("is_granted(['read', 'create', 'update', 'delete'], 'ADMINMODULESSF_')") 211 * 212 * @param Request $module_name 213 * 214 * @return Response 215 */ 216 public function configureModuleAction($module_name) 217 { 218 /** @var UrlGeneratorInterface $legacyUrlGenerator */ 219 $legacyUrlGenerator = $this->get('prestashop.core.admin.url_generator_legacy'); 220 $legacyContextProvider = $this->get('prestashop.adapter.legacy.context'); 221 $legacyContext = $legacyContextProvider->getContext(); 222 $moduleRepository = $this->get('prestashop.core.admin.module.repository'); 223 // Get accessed module object 224 $moduleAccessed = $moduleRepository->getModule($module_name); 225 226 // Get current employee Id 227 $currentEmployeeId = $legacyContext->employee->id; 228 // Get accessed module DB Id 229 $moduleAccessedId = (int) $moduleAccessed->database->get('id'); 230 231 // Save history for this module 232 $moduleHistory = $this->getDoctrine() 233 ->getRepository('PrestaShopBundle:ModuleHistory') 234 ->findOneBy( 235 [ 236 'idEmployee' => $currentEmployeeId, 237 'idModule' => $moduleAccessedId, 238 ] 239 ); 240 241 if (null === $moduleHistory) { 242 $moduleHistory = new ModuleHistory(); 243 } 244 245 $moduleHistory->setIdEmployee($currentEmployeeId); 246 $moduleHistory->setIdModule($moduleAccessedId); 247 $moduleHistory->setDateUpd(new DateTime()); 248 249 $em = $this->getDoctrine()->getManager(); 250 $em->persist($moduleHistory); 251 $em->flush(); 252 253 return $this->redirect( 254 $legacyUrlGenerator->generate( 255 'admin_module_configure_action', 256 [ 257 // do not transmit limit & offset: go to the first page when redirecting 258 'configure' => $module_name, 259 ] 260 ) 261 ); 262 } 263 264 /** 265 * @AdminSecurity("is_granted(['read'], 'ADMINMODULESSF_')") 266 * 267 * @param int $moduleId 268 * 269 * @return Response 270 */ 271 public function getModuleCartAction($moduleId) 272 { 273 $moduleRepository = $this->get('prestashop.core.admin.module.repository'); 274 $module = $moduleRepository->getModuleById($moduleId); 275 276 $addOnsAdminDataProvider = $this->get('prestashop.core.admin.data_provider.module_interface'); 277 $addOnsAdminDataProvider->generateAddonsUrls( 278 AddonsCollection::createFrom([$module]) 279 ); 280 281 $modulePresenter = $this->get('prestashop.adapter.presenter.module'); 282 $moduleToPresent = $modulePresenter->present($module); 283 284 return $this->render( 285 '@PrestaShop/Admin/Module/Includes/modal_read_more_content.html.twig', 286 [ 287 'module' => $moduleToPresent, 288 'level' => $this->authorizationLevel(self::CONTROLLER_NAME), 289 ] 290 ); 291 } 292 293 /** 294 * Controller responsible for displaying "Catalog Module Grid" section of Module management pages with ajax. 295 * 296 * @param Request $request 297 * 298 * @return JsonResponse 299 */ 300 public function refreshCatalogAction(Request $request) 301 { 302 $deniedAccess = $this->checkPermissions( 303 [ 304 PageVoter::LEVEL_READ, 305 PageVoter::LEVEL_CREATE, 306 PageVoter::LEVEL_DELETE, 307 PageVoter::LEVEL_UPDATE, 308 ] 309 ); 310 if (null !== $deniedAccess) { 311 return $deniedAccess; 312 } 313 314 $modulesProvider = $this->get('prestashop.core.admin.data_provider.module_interface'); 315 $moduleRepository = $this->get('prestashop.core.admin.module.repository'); 316 $responseArray = []; 317 318 $filters = new AddonListFilter(); 319 $filters->setType(AddonListFilterType::MODULE | AddonListFilterType::SERVICE) 320 ->setStatus(~AddonListFilterStatus::INSTALLED); 321 322 try { 323 $modulesFromRepository = AddonsCollection::createFrom($moduleRepository->getFilteredList($filters)); 324 $modulesProvider->generateAddonsUrls($modulesFromRepository); 325 326 $modules = $modulesFromRepository->toArray(); 327 shuffle($modules); 328 $categories = $this->getCategories($modulesProvider, $modules); 329 330 $responseArray['domElements'][] = $this->constructJsonCatalogCategoriesMenuResponse($categories); 331 $responseArray['domElements'][] = $this->constructJsonCatalogBodyResponse( 332 $categories, 333 $modules 334 ); 335 $responseArray['status'] = true; 336 } catch (Exception $e) { 337 $responseArray['msg'] = $this->trans( 338 'Cannot get catalog data, please try again later. Reason: %error_details%', 339 'Admin.Modules.Notification', 340 ['%error_details%' => print_r($e->getMessage(), true)] 341 ); 342 $responseArray['status'] = false; 343 } 344 345 return new JsonResponse($responseArray); 346 } 347 348 /** 349 * @param Request $request 350 * 351 * @return JsonResponse 352 */ 353 public function moduleAction(Request $request) 354 { 355 $action = $request->get('action'); 356 357 switch ($action) { 358 case ModuleAdapter::ACTION_UPGRADE: 359 case ModuleAdapter::ACTION_RESET: 360 case ModuleAdapter::ACTION_ENABLE: 361 case ModuleAdapter::ACTION_DISABLE: 362 case ModuleAdapter::ACTION_ENABLE_MOBILE: 363 case ModuleAdapter::ACTION_DISABLE_MOBILE: 364 $deniedAccess = $this->checkPermission(PageVoter::UPDATE); 365 break; 366 case ModuleAdapter::ACTION_INSTALL: 367 $deniedAccess = $this->checkPermission(PageVoter::CREATE); 368 break; 369 case ModuleAdapter::ACTION_UNINSTALL: 370 $deniedAccess = $this->checkPermission(PageVoter::DELETE); 371 break; 372 373 default: 374 $deniedAccess = null; 375 } 376 377 if (null !== $deniedAccess) { 378 return $deniedAccess; 379 } 380 381 if ($this->isDemoModeEnabled()) { 382 return $this->getDisabledFunctionalityResponse($request); 383 } 384 385 $module = $request->get('module_name'); 386 $moduleManager = $this->container->get('prestashop.module.manager'); 387 $moduleManager->setActionParams($request->request->get('actionParams', [])); 388 $moduleRepository = $this->container->get('prestashop.core.admin.module.repository'); 389 $modulesProvider = $this->container->get('prestashop.core.admin.data_provider.module_interface'); 390 $response = [$module => []]; 391 392 if (!method_exists($moduleManager, $action)) { 393 $response[$module]['status'] = false; 394 $response[$module]['msg'] = $this->trans('Invalid action', 'Admin.Notifications.Error'); 395 396 return new JsonResponse($response); 397 } 398 399 $actionTitle = str_replace('_', ' ', $action); 400 401 try { 402 $response[$module]['status'] = $moduleManager->{$action}($module); 403 404 if ($response[$module]['status'] === true) { 405 $response[$module]['msg'] = $this->trans( 406 '%action% action on module %module% succeeded.', 407 'Admin.Modules.Notification', 408 [ 409 '%action%' => ucfirst($actionTitle), 410 '%module%' => $module, 411 ] 412 ); 413 414 if ($action !== 'uninstall') { 415 $response[$module]['module_name'] = $module; 416 $response[$module]['is_configurable'] = (bool) $this 417 ->get('prestashop.core.admin.module.repository') 418 ->getModule($module) 419 ->attributes 420 ->get('is_configurable'); 421 } 422 } elseif ($response[$module]['status'] === false) { 423 $error = $moduleManager->getError($module); 424 $response[$module]['msg'] = $this->trans( 425 'Cannot %action% module %module%. %error_details%', 426 'Admin.Modules.Notification', 427 [ 428 '%action%' => $actionTitle, 429 '%module%' => $module, 430 '%error_details%' => $error, 431 ] 432 ); 433 } else { 434 $response[$module]['status'] = false; 435 $response[$module]['msg'] = $this->trans( 436 '%module% did not return a valid response on %action% action.', 437 'Admin.Modules.Notification', 438 [ 439 '%module%' => $module, 440 '%action%' => $actionTitle, 441 ] 442 ); 443 } 444 } catch (UnconfirmedModuleActionException $e) { 445 $collection = AddonsCollection::createFrom([$e->getModule()]); 446 $modules = $modulesProvider->generateAddonsUrls($collection); 447 $response[$module] = array_replace( 448 $response[$module], 449 [ 450 'status' => false, 451 'confirmation_subject' => $e->getSubject(), 452 'module' => $this 453 ->container 454 ->get('prestashop.adapter.presenter.module') 455 ->presentCollection($modules)[0], 456 'msg' => $this->trans( 457 'Confirmation needed by module %module% on %action% (%subject%).', 458 'Admin.Modules.Notification', 459 [ 460 '%subject%' => $e->getSubject(), 461 '%action%' => $e->getAction(), 462 '%module%' => $module, 463 ] 464 ), 465 ] 466 ); 467 } catch (Exception $e) { 468 $response[$module]['status'] = false; 469 $response[$module]['msg'] = $this->trans( 470 'Exception thrown by module %module% on %action%. %error_details%', 471 'Admin.Modules.Notification', 472 [ 473 '%action%' => $actionTitle, 474 '%module%' => $module, 475 '%error_details%' => $e->getMessage(), 476 ] 477 ); 478 479 // Get accessed module object 480 $moduleAccessed = $moduleRepository->getModule($module); 481 // Get accessed module DB Id 482 $moduleAccessedId = (int) $moduleAccessed->database->get('id'); 483 $logger = $this->container->get('logger'); 484 $logger->error($response[$module]['msg'], ['object_type' => 'Module', 'object_id' => $moduleAccessedId]); 485 } 486 487 if ($response[$module]['status'] === true && $action != 'uninstall') { 488 $moduleInstance = $moduleRepository->getModule($module); 489 $collection = AddonsCollection::createFrom([$moduleInstance]); 490 $response[$module]['action_menu_html'] = $this->container->get('templating')->render( 491 '@PrestaShop/Admin/Module/Includes/action_menu.html.twig', 492 [ 493 'module' => $this->container->get('prestashop.adapter.presenter.module') 494 ->presentCollection($modulesProvider->generateAddonsUrls($collection))[0], 495 'level' => $this->authorizationLevel(self::CONTROLLER_NAME), 496 ] 497 ); 498 } 499 500 return new JsonResponse($response); 501 } 502 503 /** 504 * Controller responsible for importing new module from DropFile zone in BO. 505 * 506 * @param Request $request 507 * 508 * @return JsonResponse 509 */ 510 public function importModuleAction(Request $request) 511 { 512 if ($this->isDemoModeEnabled()) { 513 return new JsonResponse( 514 [ 515 'status' => false, 516 'msg' => $this->getDemoModeErrorMessage(), 517 ] 518 ); 519 } 520 521 $deniedAccess = $this->checkPermissions( 522 [ 523 PageVoter::LEVEL_CREATE, 524 PageVoter::LEVEL_DELETE, 525 ] 526 ); 527 if (null !== $deniedAccess) { 528 return $deniedAccess; 529 } 530 531 $moduleManager = $this->get('prestashop.module.manager'); 532 $moduleZipManager = $this->get('prestashop.module.zip.manager'); 533 $serverParams = new ServerParams(); 534 $moduleName = ''; 535 536 try { 537 if ($serverParams->hasPostMaxSizeBeenExceeded()) { 538 throw new Exception($this->trans( 539 'The uploaded file exceeds the post_max_size directive in php.ini', 540 'Admin.Notifications.Error' 541 )); 542 } 543 544 $fileUploaded = $request->files->get('file_uploaded'); 545 $constraints = [ 546 new Assert\NotNull( 547 [ 548 'message' => $this->trans( 549 'The file is missing.', 550 'Admin.Notifications.Error' 551 ), 552 ] 553 ), 554 new Assert\File( 555 [ 556 'maxSize' => ini_get('upload_max_filesize'), 557 'mimeTypes' => [ 558 'application/zip', 559 'application/x-gzip', 560 'application/gzip', 561 'application/x-gtar', 562 'application/x-tgz', 563 ], 564 ] 565 ), 566 ]; 567 568 $violations = $this->get('validator')->validate($fileUploaded, $constraints); 569 if (0 !== count($violations)) { 570 $violationsMessages = []; 571 foreach ($violations as $violation) { 572 $violationsMessages[] = $violation->getMessage(); 573 } 574 575 throw new Exception(implode(PHP_EOL, $violationsMessages)); 576 } 577 578 $moduleName = $moduleZipManager->getName($fileUploaded->getPathname()); 579 580 // Install the module 581 $installationResponse = [ 582 'status' => $moduleManager->install($fileUploaded->getPathname()), 583 'msg' => '', 584 'module_name' => $moduleName, 585 ]; 586 587 if ($installationResponse['status'] === null) { 588 $installationResponse['status'] = false; 589 $installationResponse['msg'] = $this->trans( 590 '%module% did not return a valid response on installation.', 591 'Admin.Modules.Notification', 592 ['%module%' => $moduleName] 593 ); 594 } elseif ($installationResponse['status'] === true) { 595 $installationResponse['msg'] = $this->trans( 596 'Installation of module %module% was successful.', 597 'Admin.Modules.Notification', 598 ['%module%' => $moduleName] 599 ); 600 $installationResponse['is_configurable'] = (bool) $this->get('prestashop.core.admin.module.repository') 601 ->getModule($moduleName) 602 ->attributes 603 ->get('is_configurable'); 604 } else { 605 $error = $moduleManager->getError($moduleName); 606 $installationResponse['msg'] = $this->trans( 607 'Installation of module %module% failed. %error%', 608 'Admin.Modules.Notification', 609 [ 610 '%module%' => $moduleName, 611 '%error%' => $error, 612 ] 613 ); 614 } 615 } catch (UnconfirmedModuleActionException $e) { 616 $collection = AddonsCollection::createFrom([$e->getModule()]); 617 $modules = $this->get('prestashop.core.admin.data_provider.module_interface') 618 ->generateAddonsUrls($collection); 619 $installationResponse = [ 620 'status' => false, 621 'confirmation_subject' => $e->getSubject(), 622 'module' => $this->get('prestashop.adapter.presenter.module')->presentCollection($modules)[0], 623 'msg' => $this->trans( 624 'Confirmation needed by module %module% on %action% (%subject%).', 625 'Admin.Modules.Notification', 626 [ 627 '%subject%' => $e->getSubject(), 628 '%action%' => $e->getAction(), 629 '%module%' => $moduleName, 630 ] 631 ), 632 ]; 633 } catch (Exception $e) { 634 try { 635 if (isset($moduleName)) { 636 $moduleManager->disable($moduleName); 637 } 638 } catch (Exception $subE) { 639 } 640 641 throw $e; 642 } 643 644 return new JsonResponse($installationResponse); 645 } 646 647 private function getModulesByInstallation($modulesSelectList = null) 648 { 649 $addonsProvider = $this->get('prestashop.core.admin.data_provider.module_interface'); 650 $moduleRepository = $this->get('prestashop.core.admin.module.repository'); 651 $modulePresenter = $this->get('prestashop.adapter.presenter.module'); 652 $tabRepository = $this->get('prestashop.core.admin.tab.repository'); 653 654 $modulesOnDisk = AddonsCollection::createFrom($moduleRepository->getList()); 655 656 $modulesList = [ 657 'installed' => [], 658 'not_installed' => [], 659 ]; 660 661 $modulesOnDisk = $addonsProvider->generateAddonsUrls($modulesOnDisk); 662 foreach ($modulesOnDisk as $module) { 663 if (!isset($modulesSelectList) || in_array($module->get('name'), $modulesSelectList)) { 664 $perm = true; 665 if ($module->get('id')) { 666 $perm &= Module::getPermissionStatic( 667 $module->get('id'), 668 'configure', 669 $this->getContext()->employee 670 ); 671 } else { 672 $id_admin_module = $tabRepository->findOneIdByClassName('AdminModules'); 673 $access = Profile::getProfileAccess( 674 $this->getContext()->employee->id_profile, 675 $id_admin_module 676 ); 677 678 $perm &= !$access['edit']; 679 } 680 681 if ($module->get('author') === ModuleRepository::PARTNER_AUTHOR) { 682 $module->set('type', 'addonsPartner'); 683 } 684 685 if ($perm) { 686 $module->fillLogo(); 687 if ($module->database->get('installed') == 1) { 688 $modulesList['installed'][] = $modulePresenter->present($module); 689 } else { 690 $modulesList['not_installed'][] = $modulePresenter->present($module); 691 } 692 } 693 } 694 } 695 696 return $modulesList; 697 } 698 699 private function getTopMenuData(array $topMenuData, $activeMenu = null) 700 { 701 if (isset($activeMenu)) { 702 if (!isset($topMenuData[$activeMenu])) { 703 throw new Exception(sprintf('Menu \'%s\' not found in Top Menu data', $activeMenu), 1); 704 } 705 706 $topMenuData[$activeMenu]->class = 'active'; 707 } 708 709 return $topMenuData; 710 } 711 712 /** 713 * @param Request $request 714 * 715 * @return JsonResponse 716 */ 717 private function getDisabledFunctionalityResponse(Request $request) 718 { 719 $content = [ 720 $request->get('module_name') => [ 721 'status' => false, 722 'msg' => $this->getDemoModeErrorMessage(), 723 ], 724 ]; 725 726 return new JsonResponse($content); 727 } 728 729 /** 730 * Construct Json struct for catalog body response. 731 * 732 * @param array $categories 733 * @param array $modules 734 * 735 * @return array 736 */ 737 private function constructJsonCatalogBodyResponse( 738 array $categories, 739 array $modules 740 ) { 741 $formattedContent = []; 742 $formattedContent['selector'] = '.module-catalog-page'; 743 $formattedContent['content'] = $this->render( 744 '@PrestaShop/Admin/Module/Includes/sorting.html.twig', 745 [ 746 'totalModules' => count($modules), 747 ] 748 )->getContent(); 749 750 $errorMessage = $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'); 751 752 $formattedContent['content'] .= $this->render( 753 '@PrestaShop/Admin/Module/catalog-refresh.html.twig', 754 [ 755 'categories' => $categories['categories'], 756 'requireAddonsSearch' => true, 757 'level' => $this->authorizationLevel(self::CONTROLLER_NAME), 758 'errorMessage' => $errorMessage, 759 ] 760 )->getContent(); 761 762 return $formattedContent; 763 } 764 765 /** 766 * Construct json struct from top menu. 767 * 768 * @param array $categories 769 * 770 * @return array 771 */ 772 private function constructJsonCatalogCategoriesMenuResponse(array $categories) 773 { 774 $formattedContent = []; 775 $formattedContent['selector'] = '.module-menu-item'; 776 $formattedContent['content'] = $this->render( 777 '@PrestaShop/Admin/Module/Includes/dropdown_categories_catalog.html.twig', 778 [ 779 'topMenuData' => $this->getTopMenuData($categories), 780 ] 781 )->getContent(); 782 783 return $formattedContent; 784 } 785 786 /** 787 * Check user permission. 788 * 789 * @param array $pageVoter 790 * 791 * @return JsonResponse|null 792 */ 793 private function checkPermissions(array $pageVoter) 794 { 795 if (!in_array( 796 $this->authorizationLevel(self::CONTROLLER_NAME), 797 $pageVoter 798 ) 799 ) { 800 return new JsonResponse( 801 [ 802 'status' => false, 803 'msg' => $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'), 804 ] 805 ); 806 } 807 808 return null; 809 } 810 811 /** 812 * @param string $pageVoter 813 * 814 * @return JsonResponse|null 815 */ 816 private function checkPermission($pageVoter) 817 { 818 if (!$this->isGranted($pageVoter, self::CONTROLLER_NAME)) { 819 return new JsonResponse( 820 [ 821 'status' => false, 822 'msg' => $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'), 823 ] 824 ); 825 } 826 827 return null; 828 } 829 830 /** 831 * Get categories and its modules. 832 * 833 * @param array $modules List of installed modules 834 * 835 * @return array 836 */ 837 private function getCategories(AdminModuleDataProvider $modulesProvider, array $modules) 838 { 839 /** @var CategoriesProvider $categoriesProvider */ 840 $categoriesProvider = $this->get('prestashop.categories_provider'); 841 $categories = $categoriesProvider->getCategoriesMenu($modules); 842 843 foreach ($categories['categories']->subMenu as $category) { 844 $collection = AddonsCollection::createFrom($category->modules); 845 $modulesProvider->generateAddonsUrls($collection); 846 $category->modules = $this->get('prestashop.adapter.presenter.module') 847 ->presentCollection($category->modules); 848 } 849 850 return $categories; 851 } 852} 853