vendor/pimcore/advanced-object-search/src/Controller/AdminController.php line 557

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace AdvancedObjectSearchBundle\Controller;
  15. use AdvancedObjectSearchBundle\Event\AdvancedObjectSearchEvents;
  16. use AdvancedObjectSearchBundle\Event\FilterListingEvent;
  17. use AdvancedObjectSearchBundle\Model\SavedSearch;
  18. use AdvancedObjectSearchBundle\Service;
  19. use Pimcore\Bundle\AdminBundle\Helper\QueryParams;
  20. use Pimcore\Db;
  21. use Pimcore\Model\DataObject;
  22. use Pimcore\Tool;
  23. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  24. use Symfony\Component\HttpFoundation\Request;
  25. use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
  26. use Symfony\Component\Routing\Annotation\Route;
  27. /**
  28.  * Class AdminController
  29.  *
  30.  * @Route("/admin")
  31.  */
  32. class AdminController extends \Pimcore\Bundle\AdminBundle\Controller\AdminController
  33. {
  34.     /**
  35.      * @param Request $request
  36.      * @Route("/get-fields")
  37.      */
  38.     public function getFieldsAction(Request $requestService $service)
  39.     {
  40.         $type strip_tags($request->get('type'));
  41.         $allowInheritance false;
  42.         switch ($type) {
  43.             case 'class':
  44.                 $classId strip_tags($request->get('class_id'));
  45.                 $definition DataObject\ClassDefinition::getById($classId);
  46.                 $allowInheritance $definition->getAllowInherit();
  47.                 break;
  48.             case 'fieldcollection':
  49.                 $key strip_tags($request->get('key'));
  50.                 $definition DataObject\Fieldcollection\Definition::getByKey($key);
  51.                 $allowInheritance false;
  52.                 break;
  53.             case 'objectbrick':
  54.                 $key strip_tags($request->get('key'));
  55.                 $definition DataObject\Objectbrick\Definition::getByKey($key);
  56.                 $classId strip_tags($request->get('class_id'));
  57.                 $classDefinition DataObject\ClassDefinition::getById($classId);
  58.                 $allowInheritance $classDefinition->getAllowInherit();
  59.                 break;
  60.             default:
  61.                 throw new \Exception("Invalid type '$type''");
  62.         }
  63.         $fieldSelectionInformationEntries $service->getFieldSelectionInformationForClassDefinition($definition$allowInheritance);
  64.         $fields = [];
  65.         foreach ($fieldSelectionInformationEntries as $entry) {
  66.             $fields[] = $entry->toArray();
  67.         }
  68.         return $this->adminJson(['data' => $fields]);
  69.     }
  70.     /**
  71.      * @param Request $request
  72.      * @Route("/grid-proxy")
  73.      */
  74.     public function gridProxyAction(Request $requestService $serviceEventDispatcherInterface $eventDispatcher)
  75.     {
  76.         $requestedLanguage $request->get('language');
  77.         if ($requestedLanguage) {
  78.             if ($requestedLanguage != 'default') {
  79.                 $request->setLocale($requestedLanguage);
  80.             }
  81.         } else {
  82.             $requestedLanguage $request->getLocale();
  83.         }
  84.         if ($request->get('data')) {
  85.             return $this->forward('Pimcore\Bundle\AdminBundle\Controller\Admin\DataObject\DataObjectController:gridProxyAction', [], $request->query->all());
  86.         } else {
  87.             // get list of objects
  88.             $class DataObject\ClassDefinition::getById($request->get('classId'));
  89.             $className $class->getName();
  90.             $fields = [];
  91.             if ($request->get('fields')) {
  92.                 $fields $request->get('fields');
  93.             }
  94.             $start 0;
  95.             $limit 20;
  96.             if ($request->get('limit')) {
  97.                 $limit $request->get('limit');
  98.             }
  99.             if ($request->get('start')) {
  100.                 $start $request->get('start');
  101.             }
  102.             $listClass '\\Pimcore\\Model\\DataObject\\' ucfirst($className) . '\\Listing';
  103.             //get ID list from ES Service
  104.             $data json_decode($request->get('filter'), true);
  105.             $results $service->doFilter($data['classId'], $data['conditions']['filters'], $data['conditions']['fulltextSearchTerm'], $start$limit);
  106.             $total $service->extractTotalCountFromResult($results);
  107.             $ids $service->extractIdsFromResult($results);
  108.             /**
  109.              * @var \Pimcore\Model\DataObject\Listing $list
  110.              */
  111.             $list = new $listClass();
  112.             $list->setObjectTypes(['object''folder''variant']);
  113.             $conditionFilters = [];
  114.             if (!$this->getAdminUser()->isAdmin()) {
  115.                 $userIds $this->getAdminUser()->getRoles();
  116.                 $userIds[] = $this->getAdminUser()->getId();
  117.                 $conditionFilters[] = ' (
  118.                                                     (select list from users_workspaces_object where userId in (' implode(','$userIds) . ') and LOCATE(CONCAT(o_path,o_key),cpath)=1  ORDER BY LENGTH(cpath) DESC LIMIT 1)=1
  119.                                                     OR
  120.                                                     (select list from users_workspaces_object where userId in (' implode(','$userIds) . ') and LOCATE(cpath,CONCAT(o_path,o_key))=1  ORDER BY LENGTH(cpath) DESC LIMIT 1)=1
  121.                                                  )';
  122.             }
  123.             if (!empty($ids)) {
  124.                 $conditionFilters[] = 'o_id IN (' implode(','$ids) . ')';
  125.                 //$list->setCondition("o_id IN (" . implode(",", $ids) . ")");
  126.                 $list->setOrderKey(' FIELD(o_id, ' implode(','$ids) . ')'false);
  127.             } else {
  128.                 $conditionFilters[] = '1=2';
  129.                 //$list->setCondition("1=2");
  130.             }
  131.             $list->setCondition(implode(' AND '$conditionFilters));
  132.             /* @phpstan-ignore-next-line */
  133.             $eventDispatcher->dispatch(new FilterListingEvent($list), AdvancedObjectSearchEvents::LISTING_FILER);
  134.             $list->load();
  135.             $objects = [];
  136.             foreach ($list->getObjects() as $object) {
  137.                 $o DataObject\Service::gridObjectData($object$fields$requestedLanguage);
  138.                 $objects[] = $o;
  139.             }
  140.             return $this->adminJson(['data' => $objects'success' => true'total' => $total]);
  141.         }
  142.     }
  143.     /**
  144.      * @param Request $request
  145.      * @Route("/get-batch-jobs")
  146.      */
  147.     public function getBatchJobsAction(Request $requestService $service)
  148.     {
  149.         if ($request->get('language')) {
  150.             $request->setLocale($request->get('language'));
  151.         }
  152.         $class DataObject\ClassDefinition::getById($request->get('classId'));
  153.         //get ID list from ES Service
  154.         $data json_decode($request->get('filter'), true);
  155.         $results $service->doFilter($data['classId'], $data['conditions']['filters'] ?? [], $data['conditions']['fulltextSearchTerm'] ?? [], null9999);
  156.         $ids $service->extractIdsFromResult($results);
  157.         $className $class->getName();
  158.         $listClass '\\Pimcore\\Model\\DataObject\\' ucfirst($className) . '\\Listing';
  159.         $list = new $listClass();
  160.         $list->setObjectTypes(['object''folder''variant']);
  161.         $list->setCondition('o_id IN (' implode(','$ids) . ')');
  162.         $list->setOrderKey(' FIELD(o_id, ' implode(','$ids) . ')'false);
  163.         if ($request->get('objecttype')) {
  164.             $list->setObjectTypes([$request->get('objecttype')]);
  165.         }
  166.         $jobs $list->loadIdList();
  167.         return $this->adminJson(['success' => true'jobs' => $jobs]);
  168.     }
  169.     protected function getCsvFile($fileHandle)
  170.     {
  171.         return PIMCORE_SYSTEM_TEMP_DIRECTORY '/' $fileHandle '.csv';
  172.     }
  173.     /**
  174.      * @param Request $request
  175.      * @Route("/get-export-jobs")
  176.      */
  177.     public function getExportJobsAction(Request $requestService $service)
  178.     {
  179.         if ($request->get('language')) {
  180.             $request->setLocale($request->get('language'));
  181.         }
  182.         $data json_decode($request->get('filter'), true);
  183.         if (empty($ids $request->get('ids'false))) {
  184.             $results $service->doFilter(
  185.                 $data['classId'],
  186.                 $data['conditions']['filters'],
  187.                 $data['conditions']['fulltextSearchTerm'],
  188.                 0,
  189.                 9999 // elastic search cannot export more results than 9999 in one request
  190.             );
  191.             //get ID list from ES Service
  192.             $ids $service->extractIdsFromResult($results);
  193.         }
  194.         $jobs array_chunk($ids20);
  195.         $fileHandle uniqid('export-');
  196.         file_put_contents($this->getCsvFile($fileHandle), '');
  197.         return $this->adminJson(['success' => true'jobs' => $jobs'fileHandle' => $fileHandle]);
  198.     }
  199.     /**
  200.      * @param Request $request
  201.      * @Route("/save")
  202.      */
  203.     public function saveAction(Request $request)
  204.     {
  205.         $data $request->get('data');
  206.         $data json_decode($data);
  207.         $id = (intval($request->get('id')));
  208.         if ($id) {
  209.             $savedSearch SavedSearch::getById($id);
  210.         } else {
  211.             $savedSearch = new SavedSearch();
  212.             $savedSearch->setOwner($this->getAdminUser());
  213.         }
  214.         $savedSearch->setName($data->settings->name);
  215.         $savedSearch->setDescription($data->settings->description);
  216.         $savedSearch->setCategory($data->settings->category);
  217.         $savedSearch->setSharedUserIds(array_merge($data->settings->shared_users$data->settings->shared_roles));
  218.         $savedSearch->setShareGlobally($this->getAdminUser()->isAdmin() && $data->settings->share_globally);
  219.         $config = ['classId' => $data->classId'gridConfig' => $data->gridConfig'conditions' => $data->conditions];
  220.         $savedSearch->setConfig(json_encode($config));
  221.         $savedSearch->save();
  222.         return $this->adminJson(['success' => true'id' => $savedSearch->getId()]);
  223.     }
  224.     /**
  225.      * @param Request $request
  226.      * @Route("/delete")
  227.      */
  228.     public function deleteAction(Request $request)
  229.     {
  230.         $id intval($request->get('id'));
  231.         $savedSearch SavedSearch::getById($id);
  232.         if ($savedSearch) {
  233.             $savedSearch->delete();
  234.             return $this->adminJson(['success' => true'id' => $savedSearch->getId()]);
  235.         } else {
  236.             return $this->adminJson(['success' => false'message' => "Saved Search with $id not found."]);
  237.         }
  238.     }
  239.     /**
  240.      * @param Request $request
  241.      * @Route("/find")
  242.      */
  243.     public function findAction(Request $request)
  244.     {
  245.         $user $this->getAdminUser();
  246.         $query $request->get('query');
  247.         if ($query == '*') {
  248.             $query '';
  249.         }
  250.         $query str_replace('%''*'$query);
  251.         $offset intval($request->get('start'));
  252.         $limit intval($request->get('limit'));
  253.         $offset $offset $offset 0;
  254.         $limit $limit $limit 50;
  255.         $db Db::get();
  256.         $searcherList = new SavedSearch\Listing();
  257.         $conditionParts = [];
  258.         $conditionParams = [];
  259.         //filter for current user
  260.         $userIds = [$user->getId()];
  261.         $userIds array_merge($userIds$user->getRoles());
  262.         $userIds implode('|'$userIds);
  263.         $conditionParts[] = '(shareGlobally = 1 OR ownerId = ? OR sharedUserIds REGEXP ?)';
  264.         $conditionParams[] = $user->getId();
  265.         $conditionParams[] = ',(' $userIds '),';
  266.         //filter for query
  267.         if (!empty($query)) {
  268.             $conditionParts[] = sprintf('(%s LIKE ? OR %s LIKE ? OR %s LIKE ?)',
  269.                 $db->quoteIdentifier('name'),
  270.                 $db->quoteIdentifier('description'),
  271.                 $db->quoteIdentifier('category')
  272.             );
  273.             $conditionParams[] = '%' $query '%';
  274.             $conditionParams[] = '%' $query '%';
  275.             $conditionParams[] = '%' $query '%';
  276.         }
  277.         $condition implode(' AND '$conditionParts);
  278.         $searcherList->setCondition($condition$conditionParams);
  279.         $searcherList->setOffset($offset);
  280.         $searcherList->setLimit($limit);
  281.         $sortingSettings QueryParams::extractSortingSettings(array_merge($request->request->all(), $request->query->all()));
  282.         if ($sortingSettings['orderKey']) {
  283.             $searcherList->setOrderKey($sortingSettings['orderKey']);
  284.         }
  285.         if ($sortingSettings['order']) {
  286.             $searcherList->setOrder($sortingSettings['order']);
  287.         }
  288.         $results = []; //$searcherList->load();
  289.         foreach ($searcherList->load() as $result) {
  290.             $results[] = [
  291.                 'id' => $result->getId(),
  292.                 'name' => $result->getName(),
  293.                 'description' => $result->getDescription(),
  294.                 'category' => $result->getCategory(),
  295.                 'owner' => $result->getOwner() ? $result->getOwner()->getUsername() . ' (' $result->getOwner()->getFirstname() . ' ' $result->getOwner()->getLastName() . ')' '',
  296.                 'ownerId' => $result->getOwnerId()
  297.             ];
  298.         }
  299.         // only get the real total-count when the limit parameter is given otherwise use the default limit
  300.         if ($request->get('limit')) {
  301.             $totalMatches $searcherList->getTotalCount();
  302.         } else {
  303.             $totalMatches count($results);
  304.         }
  305.         return $this->adminJson(['data' => $results'success' => true'total' => $totalMatches]);
  306.     }
  307.     /**
  308.      * @param Request $request
  309.      * @Route("/load-search")
  310.      */
  311.     public function loadSearchAction(Request $request)
  312.     {
  313.         $id intval($request->get('id'));
  314.         $savedSearch SavedSearch::getById($id);
  315.         if ($savedSearch) {
  316.             $config json_decode($savedSearch->getConfig(), true);
  317.             $classDefinition DataObject\ClassDefinition::getById($config['classId']);
  318.             if (!empty($config['gridConfig']['columns'])) {
  319.                 $helperColumns = [];
  320.                 foreach ($config['gridConfig']['columns'] as &$column) {
  321.                     if (!($column['isOperator'] ?? false)) {
  322.                         $fieldDefinition $classDefinition->getFieldDefinition($column['key']);
  323.                         if ($fieldDefinition) {
  324.                             $width = isset($column['layout']['width']) ? $column['layout']['width'] : null;
  325.                             $column['layout'] = json_decode(json_encode($fieldDefinition), true);
  326.                             if ($width) {
  327.                                 $column['layout']['width'] = $width;
  328.                             }
  329.                         }
  330.                     }
  331.                     if (!DataObject\Service::isHelperGridColumnConfig($column['key'])) {
  332.                         continue;
  333.                     }
  334.                     // columnconfig has to be a stdclass
  335.                     $helperColumns[$column['key']] = json_decode(json_encode($column));
  336.                 }
  337.                 // store the saved search columns in the session, otherwise they won't work
  338.                 Tool\Session::useSession(function (AttributeBagInterface $session) use ($helperColumns) {
  339.                     $existingColumns $session->get('helpercolumns', []);
  340.                     $helperColumns array_merge($existingColumns$helperColumns);
  341.                     $session->set('helpercolumns'$helperColumns);
  342.                 }, 'pimcore_gridconfig');
  343.             }
  344.             return $this->adminJson([
  345.                 'id' => $savedSearch->getId(),
  346.                 'classId' => $config['classId'],
  347.                 'settings' => [
  348.                     'name' => $savedSearch->getName(),
  349.                     'description' => $savedSearch->getDescription(),
  350.                     'category' => $savedSearch->getCategory(),
  351.                     'sharedUserIds' => $savedSearch->getSharedUserIds(),
  352.                     'shareGlobally' => $savedSearch->getShareGlobally(),
  353.                     'isOwner' => $savedSearch->getOwnerId() == $this->getAdminUser()->getId(),
  354.                     'hasShortCut' => $savedSearch->isInShortCutsForUser($this->getAdminUser())
  355.                 ],
  356.                 'conditions' => $config['conditions'],
  357.                 'gridConfig' => $config['gridConfig']
  358.             ]);
  359.         } else {
  360.             return $this->adminJson(['success' => false'message' => "Saved Search with $id not found."]);
  361.         }
  362.     }
  363.     /**
  364.      * @param Request $request
  365.      * @Route("/load-short-cuts")
  366.      */
  367.     public function loadShortCutsAction(Request $request)
  368.     {
  369.         $list = new SavedSearch\Listing();
  370.         $list->setCondition(
  371.             '(shareGlobally = ? OR ownerId = ? OR sharedUserIds LIKE ?) AND shortCutUserIds LIKE ?',
  372.             [
  373.                 true,
  374.                 $this->getAdminUser()->getId(),
  375.                 '%,' $this->getAdminUser()->getId() . ',%',
  376.                 '%,' $this->getAdminUser()->getId() . ',%'
  377.             ]
  378.         );
  379.         $list->load();
  380.         $entries = [];
  381.         foreach ($list->getSavedSearches() as $entry) {
  382.             $entries[] = [
  383.                 'id' => $entry->getId(),
  384.                 'name' => $entry->getName()
  385.             ];
  386.         }
  387.         return $this->adminJson(['entries' => $entries]);
  388.     }
  389.     /**
  390.      * @param Request $request
  391.      * @Route("/toggle-short-cut")
  392.      */
  393.     public function toggleShortCutAction(Request $request)
  394.     {
  395.         $id intval($request->get('id'));
  396.         $savedSearch SavedSearch::getById($id);
  397.         if ($savedSearch) {
  398.             $user $this->getAdminUser();
  399.             if ($savedSearch->isInShortCutsForUser($user)) {
  400.                 $savedSearch->removeShortCutForUser($user);
  401.             } else {
  402.                 $savedSearch->addShortCutForUser($user);
  403.             }
  404.             $savedSearch->save();
  405.             return $this->adminJson(['success' => 'true''hasShortCut' => $savedSearch->isInShortCutsForUser($user)]);
  406.         } else {
  407.             return $this->adminJson(['success' => 'false']);
  408.         }
  409.     }
  410.     /**
  411.      * @param Request $request
  412.      * @Route("/get-users")
  413.      */
  414.     public function getUsersAction(Request $request)
  415.     {
  416.         $users = [];
  417.         // condition for users with groups having DAM permission
  418.         $condition = [];
  419.         $rolesList = new \Pimcore\Model\User\Role\Listing();
  420.         $rolesList->addConditionParam("CONCAT(',', permissions, ',') LIKE ?"'%,bundle_advancedsearch_search,%');
  421.         $rolesList->load();
  422.         $roles $rolesList->getRoles();
  423.         foreach ($roles as $role) {
  424.             $condition[] = "CONCAT(',', roles, ',') LIKE '%," $role->getId() . ",%'";
  425.         }
  426.         // get available user
  427.         $list = new \Pimcore\Model\User\Listing();
  428.         $condition[] = 'admin = 1';
  429.         $list->addConditionParam("((CONCAT(',', permissions, ',') LIKE ? ) OR " implode(' OR '$condition) . ')''%,bundle_advancedsearch_search,%');
  430.         $list->addConditionParam('id != ?'$this->getAdminUser()->getId());
  431.         $list->load();
  432.         $userList $list->getUsers();
  433.         foreach ($userList as $user) {
  434.             $users[] = [
  435.                 'id' => $user->getId(),
  436.                 'label' => $user->getName()
  437.             ];
  438.         }
  439.         return $this->adminJson(['success' => true'total' => count($users), 'data' => $users]);
  440.     }
  441.     /**
  442.      * @Route("/get-roles")
  443.      */
  444.     public function getRolesAction()
  445.     {
  446.         $roles = [];
  447.         $rolesList = new \Pimcore\Model\User\Role\Listing();
  448.         $rolesList->setCondition('type = "role"');
  449.         $rolesList->addConditionParam("CONCAT(',', permissions, ',') LIKE ?"'%,bundle_advancedsearch_search,%');
  450.         $rolesList->load();
  451.         foreach ($rolesList->getRoles() as $role) {
  452.             $roles[] = [
  453.                 'id' => $role->getId(),
  454.                 'label' => $role->getName()
  455.             ];
  456.         }
  457.         return $this->adminJson(['success' => true'total' => count($roles), 'data' => $roles]);
  458.     }
  459.     /**
  460.      * @param Request $request
  461.      * @Route("/check-index-status")
  462.      */
  463.     public function checkIndexStatusAction(Request $requestService $service)
  464.     {
  465.         return $this->adminJson(['indexUptodate' => $service->updateQueueEmpty()]);
  466.     }
  467. }