projectRepository = $projectRepository; $this->exportRepository = $exportRepository; $this->elementTypeCollect = $elementTypeCollect; $this->groupCollect = $groupCollect; $this->requestStack = $requestStack; $this->profileQuery = $profileQuery; $this->elementTypeRepository = $elementTypeRepository; $this->elementTypeTemplateRepository = $elementTypeTemplateRepository; $this->tagCollect = $tagCollect; } private function getIdUserByRequestStack() { $token = $this->requestStack->getCurrentRequest()->headers->get('x-auth-token'); $idUser = $this->profileQuery->getUserIdFromToken($token); return $idUser; } /** * {@inheritDoc} */ public function list(array $groupIds, bool $globalList = true, bool $getArchivedProjects = false, bool $useUserId = true): array { $idUser = $this->getIdUserByRequestStack(); $projects = $this->projectRepository->list($groupIds, $idUser, $globalList, $getArchivedProjects, $useUserId); $view = []; $elementTypes = $this->getElementTypes(); if (!empty($projects)) { $elementTypeNoPIM = []; $groups = $this->getGroups($projects); foreach ($projects as $project) { $exportTypesArray = $this->getExportTypes($project); $exportTypes = implode(', ', $exportTypesArray); $elementTypeNoPIM = $this->checkElementTypeNoPIM($project); if (!empty($elementTypes)) { $elementTypesProjectArray = $this->getElementTypesProject($project, $elementTypes); $elementTypesProject = implode(', ', $elementTypesProjectArray); } else { $elementTypesProject = ''; } if (empty($groups)) { $arrayGroup = []; } else { $arrayGroup = $this->getProjectGroups($project, $groups); } $view[] = new ProjectView( $project->getId(), $project->getName(), $project->getDraft(), $exportTypes, $elementTypesProject, // array_values(array_unique($auths)), // Keep this part until we'll be sure to unuse $arrayGroup, $project->getIdUser(), $project->getIdOwnergroup(), $project->getArchiving() ); } if (!empty($elementTypeNoPIM)) { $this->elementTypeTemplateRepository->saveMultiple($elementTypeNoPIM); } } return $view; } /** * {@inheritDoc} */ public function listIdByWorkflowId(int $workflowId): array { $projects = $this->projectRepository->listIdByWorkflowId($workflowId); $view = []; foreach ($projects as $project) { $view[] = new ProjectIdView( $project['id'] ); } return $view; } public function getExportTypesArray(int $projectId) { $project = $this->projectRepository->findById($projectId); $exportTypes = []; if (!empty($project) && !empty($project->getExports())) { foreach ($project->getExports() as $export) { if ($export->getExportType() && isset($this->exportRepository::EXPORT_TYPE[$export->getExportType()])) { $exportTypes[] = $this->exportRepository::EXPORT_TYPE[$export->getExportType()]; } } } return $exportTypes; } private function getExportTypes(Project $project): array { $exportTypes = []; if (!empty($project->getExports())) { foreach ($project->getExports() as $export) { if ($export->getExportType() && isset($this->exportRepository::EXPORT_TYPE[$export->getExportType()])) { $exportTypes[] = $this->exportRepository::EXPORT_TYPE[$export->getExportType()]; } } } $exportTypesCount = array_count_values($exportTypes); $exportTypesWithCount = array_map(function ($key, $value) { return $key . ' (' . $value . ')'; }, array_keys($exportTypesCount), array_values($exportTypesCount)); return $exportTypesWithCount; } private function getElementTypesProject(Project $project, array $elementTypes): array { $elementTypesProject = []; if (!empty($project->getElementTypes())) { foreach ($project->getElementTypes() as $elemType) { $types = array_values(array_filter($elementTypes, function ($type) use ($elemType) { return $elemType->getElementTypePIM() === $type['id']; })); if (!empty($types)) { $elementTypesProject[] = reset($types)['name'] . ' (' . count($elemType->getElementsPIM()) . ')'; } } } return $elementTypesProject; } /** * @param Project $project * @param array $tags * * @return array */ private function getTagsProject(Project $project, array $tags): array { $flattenTags = $this->getFlattenTags($tags); $tagsProject = []; foreach ($project->getElementTypes() as $elemType) { if ($elemType->getTagsPIM()) { $tags = json_decode($elemType->getTagsPIM()); foreach ($tags as $tag) { $arr = array_values(array_filter($flattenTags, function ($t) use ($tag) { return $tag === $t['id']; })); if (!empty($arr) && !in_array(reset($arr)['name'], $tagsProject)) { $tagsProject[] = reset($arr)['name'] /*. ' (' . count($elemType->getElementsPIM()) . ')'*/; } } } } return $tagsProject; } /** * @param array $tags * * @return array */ private function getFlattenTags(array $tags): array { $arr = []; foreach ($tags as $sub) { foreach ($sub as $key => $value) { if ($key === "children" && is_array($value)) { $arr = array_merge($arr, $this->getFlattenTags($value)); } } $arr[] = $sub; } return $arr; } private function getElementTypes(): array { $result = $this->elementTypeCollect->list(); return is_array($result) ? $result : []; } private function checkElementTypeNoPIM(Project $project) { $elementType = $this->elementTypeRepository->findNoElementTypeByIdProject($project->getId()); $exportTemplateNoPIMs = []; if (empty($elementType)) { $elementType = new ElementType(); $elementType->setProject($project); $elementType = $this->elementTypeRepository->save($elementType); if (!empty($elementType) && !$project->getExports()->isEmpty()) { foreach ($project->getExports() as $export) { $exportTemplate = $export->getTemplates()->first(); $exportTemplateNoPIM = new ElementTypesTemplates(); $exportTemplateNoPIM->setTemplates($exportTemplate->getTemplates()); $exportTemplateNoPIM->setElementType($elementType); $exportTemplateNoPIM->setExport($export); $exportTemplateNoPIMs[] = $exportTemplateNoPIM; } } } return $exportTemplateNoPIMs; } /** * Get group's data from admin by project group's id * * @param array $projects * @param array $userGroupIds * * @return array */ private function getGroups(array $projects, array $userGroupIds = []): array { $data = []; $groupIds = []; foreach ($projects as $project) { $projectGroupIds = $project->getGroupProject()->map(function ($groupProject) { return $groupProject->getGroup(); }); $groupIds = array_merge($groupIds, $projectGroupIds->getValues()); } $groupIds = array_merge($groupIds, $userGroupIds); if (!empty($groupIds)) { $data = $this->groupCollect->getByIds($groupIds)["data"]; } return $data; } /** * Get project's group's name * * @param Project $project * @param array $groups * * @return array */ private function getProjectGroups(Project $project, array $groups): array { // $auths = []; $projectGroups = []; foreach ($project->getGroupProject() as $groupProject) { // Keep this part until we'll be sure to unuse /* if($groupProject->getAuths() !== "null" && $groupProject->getAuths() !== null && in_array($groupProject->getGroup(), $groupIds)){ $auths = array_merge($auths, json_decode($groupProject->getAuths(), true)); }*/ $filtered = array_filter($groups, function ($group) use ($groupProject) { return $groupProject->getGroup() === $group['id']; }); if (!empty($filtered)) { $projectGroups[] = reset($filtered)['name']; } } return $projectGroups; } /** * {@inheritDoc} */ public function dataTableList(array $groupIds, DatatableRequestView $view, array $customFilters): DatatableResponseView { $idUser = $this->getIdUserByRequestStack(); $sortField = $this->controlSortField($view->sortField); $tableData = $this->projectRepository->listByDataTableFilters($groupIds, $idUser, $view->sortOrder, $sortField, $view->first, $view->rows, $view->globalFilter, $customFilters, $view->strictMode, $view->searchOnFieldValue, $view->searchOnArchived); if (isset($tableData['data'])) { $projectsData = $tableData['data']; $projectsDataArray = []; $projectsElementTypes = $this->getElementTypes(); // All element types from pim $projectsTags = $this->tagCollect->list(); // All tags from pim $projectsGroups = $this->getGroups($projectsData, $groupIds); // All groups from all filtered projects AND user if (!empty($projectsData)) { foreach ($projectsData as $project) { $projectExportTypes = $this->getExportTypes($project); $projectElementTypes = $this->getElementTypesProject($project, $projectsElementTypes); $projectTags = $this->getTagsProject($project, $projectsTags); $projectGroups = $this->getProjectGroups($project, $projectsGroups); $projectsDataArray[] = [ 'name' => $project->getName(), 'exportTypes' => $projectExportTypes, 'elementTypes' => $projectElementTypes, 'tags' => $projectTags, 'groups' => $projectGroups, 'dateCreate' => $project->getCreatedAt() ? $project->getCreatedAt()->format('Y-m-d') : null, 'dateUpdate' => $project->getUpdatedAt() ? $project->getUpdatedAt()->format('Y-m-d') : null, 'id' => $project->getId(), 'draft' => $project->getDraft(), 'archived' => $project->getArchiving(), 'idUser' => $project->getIdUser(), 'idOwnerGroup' => $project->getIdOwnergroup() ]; } $recordsTotal = null; if (isset($tableData["recordsFiltered"])) { $recordsFiltered = $tableData["recordsFiltered"]; } else { throw new \Exception("No recordsFiltered key provided !"); } $rows = array_values($projectsDataArray); } else { $recordsTotal = 0; $recordsFiltered = 0; $rows = []; } $hiddenColumns = ['id', 'draft', 'archived', 'idUser', 'idOwnerGroup']; $columns = $this->getDataTableColumns($projectsDataArray, $hiddenColumns); $repositoryExportTypes = $this->exportRepository->listExportType(); $projectsExportTypesIdsAndNames = array_map(function ($key, $val) { return ['id' => $key, 'name' => $val]; }, array_keys($repositoryExportTypes), array_values($repositoryExportTypes)); $dataTableData = new DatatableResponseView( $rows, $columns, $recordsTotal, $recordsFiltered, $view, // Return received filters to let reload data with same filters $projectsExportTypesIdsAndNames, // Contains all export types $projectsElementTypes, // Contains all element types from pim $projectsTags, // Contains all tags from pim $projectsGroups // Contains all groups used in projects that match filters AND user groups ); return $dataTableData; } else { throw new \Exception("No data key provided !"); } } /** * Since repository method returns object, there is no mapping like in PIM, so we need to convert names to entity attributes * * @param string $field * * @return string */ private function controlSortField(string $field): string { $fragment = 'p.'; if ('dateCreate' === $field) { $attribute = 'createdAt'; $sortField = $fragment . $attribute; } else if ('dateUpdate' === $field) { $attribute = 'updatedAt'; $sortField = $fragment . $attribute; } else { $attribute = str_replace('p.', '', $field); $sortField = $field; } if (!property_exists(Project::class, $attribute)) { throw new \Exception("Property '$attribute' used by query builder doesn't exist in Project class ! "); } return $sortField; } /** * @param array $projectsData * @param array $hiddenColumns * * @return array */ private function getDataTableColumns(array $projectsData, array $hiddenColumns): array { $columns = [ // Map repository columns with datatable columns (field & sortField can be different) 'name' => new DatatableColumnView('', 'p.name', true, true, null, null), 'exportTypes' => new DatatableColumnView('', null, false, true, 'filterExportTypes', 'ex.exportType'), // Does not make sense to sortable & filter on it since data are added after repository response 'elementTypes' => new DatatableColumnView('', null, false, true, 'filterElementTypes', 'et.elementTypePIM'), // Does not make sense to sortable & filter on it since data are added after repository response 'tags' => new DatatableColumnView("", null, false, true, "filterTags", "et.tagsPIM"), // Does not make sense to sortable & filter on it since data are added after repository response 'groups' => new DatatableColumnView('', null, false, true, 'filterGroups', 'gp.group'), // Does not make sense to sortable & filter on it since data are added after repository response 'dateCreate' => new DatatableColumnView('', 'dateCreate', false, true, null, null), 'dateUpdate' => new DatatableColumnView('', 'dateUpdate', false, true, null, null), 'actions' => new DatatableColumnView('actions', null, false, false, null, null) ]; if (!empty($projectsData)) { $columnsHeaders = array_keys(reset($projectsData)); foreach ($columnsHeaders as $col) { if (!in_array($col, $hiddenColumns)) { $columns[$col]->field = $col; } } } else { foreach ($columns as $key => $col) { $columns[$key]->field = $key; } } return $columns; } }