Rekurzivní funkce opačné vypsání

FoUkR
Člen | 2
+
0
-

Zdravím všechny karanténní duše dneška! :). Předem mi odpuste místy nesprávnou formulaci jsem nováček a tudíž mi některé logické vazby chybí

Mám nedomyšlenou rekurzivní funkci která mi hledá všechny rodiče daného záznamu. Problém je v tom, že chci dostat opačný výsledek. A nevím jak postup obrátit.

Nyní se mi menu uloží do promene navigation ve fuknci prepareDefaultData ta si pak zavola rekurzivni funkci checkAllParents

Jak utvorim strukturu abych dostal opacny vysledek?

Do prepareDefaultData pritece aktualni parentID processu ktery ma vypsat sve podprocesy nebo null v tom priprade je parentId = 1

4.3.1.1 Kategorie ve ktere se nachazim
	 4.3.1 nadrazena
		4.3 nadrazena
			4 nadrazena
				0 Nejvyšší rodič

Potřebuji aby struktura byla uložena opačně. tedy

0 Nejvyšší rodič
	4 subcategory
		4.3 sub-sub category
			4.3.1 sub-sub category
				4.3.1.1 Kategorie ve ktere se nachazim

o pripravu zakladnich dat do presenteru z fasady se mi stara funkce prepareDefaultData ktera pripravy data pro presenter.
V teto fukci se snazim do promene navigation dostat spravne serazene menu.

protected function checkAllParents(?int $processParentId): ?array
 {
   $result = [];

   $parents = new ProcessFiltration();
   $parents->filterByProcessId($processParentId);

   $list = $this->processList;
   $dataResult = $list->getList($parents, null, null);
   foreach ($dataResult as $row) {
     try {
       $temp = new Process($this->database, $row);

       $parentsResult = new ProcessTreeDefaultData();
       $parentsResult->name = $temp->getName();
       $parentsResult->code = $temp->getCode();
       $parentsResult->processParentId = $temp->getProcessParentId();

       $parentsResult->showChildTreeData = new LinkData();
       $parentsResult->showChildTreeData->action = ProcessTreePresenter::ACTION_DEFAULT_NAME;
       $parentsResult->showChildTreeData->module = "";
       $parentsResult->showChildTreeData->presenter = "ProcessTree";
       $parentsResult->showChildTreeData->params = ['processParentId' => $temp->getId()];

       if (!empty($temp->getProcessParentId())) {
         $parentsResult->child = $this->checkAllParents($temp->getProcessParentId()); // zbytecna promena child ? zjistit lepsi al
       }
       $result[] = $parentsResult; // aktualni procesy se zadanym processParentId
     } catch (NoResultException $e) {
       // TODO: dodelat vyjimku pokud je prazdny vysledek
     }
   }
   return array_reverse($result);
 }

 /**
  * Funkce pro pripravu dat vychozi akce
  * @param int|null $processParentId
  * @return ProcessData
  * @throws DatabaseException
  * @throws InvalidArgumentException
  * @throws LogicException
  * @throws NotImplementedExceptionAlias
  */
 public function prepareDefaultData(?int $processParentId): ProcessData
 {
   $data = new ProcessData();

   $data->applicationName = 'NES';

   $data->navigation = $this->checkAllParents($processParentId);

   $dataFilter = new ProcessFiltration();
   $dataFilter->filterByParentProcessId($processParentId);

   $dataSortation = new ProcessSortation();
   $dataSortation->sortBySortOrder();

   $dataList = $this->processList;

   $dataListResult = $dataList->getList($dataFilter, null, $dataSortation);

   foreach ($dataListResult as $rowId) {
     try {
       $tmp = new Process($this->database, $rowId);

       $processTreeDefaultData = new ProcessTreeDefaultData();
       $processTreeDefaultData->name = $tmp->getName();
       $processTreeDefaultData->code = $tmp->getCode();
       $processTreeDefaultData->processParentId = $tmp->getProcessParentId();

       $processTreeDefaultData->showDetailLinkData = new LinkData();
       $processTreeDefaultData->showDetailLinkData->action = ProcessDetailPresenter::ACTION_DEFAULT_NAME;
       $processTreeDefaultData->showDetailLinkData->module = "";
       $processTreeDefaultData->showDetailLinkData->presenter = "ProcessDetail";
       $processTreeDefaultData->showDetailLinkData->params = ['id' => $tmp->getId()];

       $processTreeDefaultData->showChildTreeData = new LinkData();
       $processTreeDefaultData->showChildTreeData->action = ProcessTreePresenter::ACTION_DEFAULT_NAME;
       $processTreeDefaultData->showChildTreeData->module = "";
       $processTreeDefaultData->showChildTreeData->presenter = "ProcessTree";
       $processTreeDefaultData->showChildTreeData->params = ['processParentId' => $tmp->getId()];

       // zde si chci zjistit zda proces ma podprocesy (urcite by to slo efektivneji -> zjistit jak)
       $checkChildNumberFiltration = new ProcessFiltration(); // vytvoreni nove instance filtracni tridy
       $checkChildNumberFiltration->filterByParentProcessId($tmp->getId()); // misto id rodice dam aktualni id jelikoz chci zjistit childy aktualniho id

       $processTreeDefaultData->processChild = $dataList->getList($checkChildNumberFiltration, null, $dataSortation);
       if(!empty($processTreeDefaultData->processChild)){ // true = ma potomky, false = nema potomky
         $processTreeDefaultData->processChild = true;
       }else{
         $processTreeDefaultData->processChild = false;
       }

       $data->processes[] = $processTreeDefaultData; // aktualni procesy se zadanym processParentId

     } catch (NoResultException $e) {
       // TODO: dodelat vyjimku pokud je prazdny vysledek
     }
   }
   return $data;
 } // prepareDefaultData()
Kamil Valenta
Člen | 758
+
0
-

Kód jsem nijak nestudoval, ale pokud máš rekurzivní funkci, která vrací třeba pole:

['4.3.1.1', '4.3.1', '4.3', '4', '0']

můžeš potom jen udělat reverse toho pole.

Ages
Člen | 128
+
+2
-

Za předpokladu že máš menu v DB by se data dala předpřipravit s využitím CTE.
Inspirace: https://www.akki.io/…a-using-cte/