Temat: deleteThreaded

Szukalem jakiegos zgrabnego rozwiazania (byc moze nie dokladnie i wynalazlem kolo poraz drugi)  na usuwanie rekordow z drzewka opartego tylko o parent_id... (bez wag left i right) i splodzilem takich kilka metod modelu :

        /**
         * Deletes tree element with all of his descendants.
         * @return boolean
         * @param array $records Results of find("threaded") query.
         * @param array $recordToDelete id of record to be deleted.
         * @param mixed $model Instance of model or null. When null this object will be used.
         */
        public function deleteAllThreaded($records,$recordToDelete,$model =null)
        {
            $flatArray = array(); 
            if(is_null($model))
            {
                $model = $this;
            }
            $this->toSingleDimmension($flatArray, $records,$model->name);
            $toDelete[] = $recordToDelete;
            $this->findChildren($toDelete,$flatArray,$recordToDelete);
            $model->deleteAll(array("id" => $toDelete));
            
            return true;
        }
        
        /**
         * Makes multidimensional array falt. 
         * Recurrent helper method.
         * @param array $flatArray Destination array.
         * @param array $data Multidimensional array.
         * @param string $model Model name.
         */
        private function toSingleDimmension(&$flatArray, $data, $modelName)
        {    
            foreach($data as $record)
            {                        
                $flatArray[] = $record[$modelName];
                if(!empty($record["children"]))
                {            
                    $this->toSingleDimmension($flatArray, $record["children"],$modelName);
                }
            }
        }
        
    /**
     * Searches all given records to the bottom, for children with given $parentId
     * Recurrent helper method.
     * @param array $toDelete stack for ids of record to be deleted.
     * @param array $records falt array which contains flat array created from results of find("threaded").
     * @param integer $parentId id of parent to search for.
     */
    private function findChildren(&$toDelete,$records,$parentId)
    {
        foreach($records as $record)
        {
            if($record["parent_id"] == $parentId)
            {
                $toDelete[] = $record["id"];
                $this->findChildren($toDelete,$records,$record["id"]);                
            }
        }
    }

Wsie metody powinny sie znadywac w modelu lub w app model.

pryklad uzycia ....

        public function deleteTreeElement($data)
        {
            $TemplateMenuItem = $this->getModelObject("TemplateMenuItem");
            $records = $TemplateMenuItem->find("threaded");
            
            $this->deleteAllThreaded($records,$data["elementId"], $TemplateMenuItem);
                       ....
                 }

Ostatnio edytowany przez robal77 (2009-08-05 12:54:03)

2

Odp: deleteThreaded

Hmm, a próbowałeś zrobić to przy pomocy relacji?

Definiujesz w modelu Node:

$hasMany = array('NodeChild' => array('className'=> 'Node', 'foreign_key'=>'parent_id', 'dependent' => 'true');

W takim wypadku utworzysz relację o nazwie NodeChild, do modelu Node (tego samego), kluczem obcym jest parent_id. Klucz dependent ustawiony na true oznacza, że przy usuwaniu danego elementu Node zostaną usunięte jego dzieci.

To jest tylko koncepcja, bo nigdy nie próbowałem czegoś takiego zrobić. Może się okazać, że zostaną usunięte tylko "dzieci", a już nie "wnuki" i tak dalej- to musiałbyć sam sprawdzić.

3

Odp: deleteThreaded

Metoda z relecja powinna dzialac - jesli jest cos co mozna zrobic bardziej cakeowo to lepiej to stosowac:)

4

Odp: deleteThreaded

Nie, nie bedzie dzialac.  Dziala ale nie tak jak powinna tzn w drzewie


---root
       |----level 1
               |------- level 1- 1
               |             |-------- level  1 - 1 -1
               |
               |------- level 1 - 2

Usuwajac galaz level 1, zostana usiniete galezie 1 - 1, i 1 - 2 - lisc 1 - 1 - 1 zostanie "osierocony" tak jak pisal id02009  ;-)

Kłejkowo nie zawsze znaczy dobrze, albo tak dobrze jakbysmy chcieli ( mozesz np chciec sprawdzic jakies warunki zanim usuniesz dany element drzewa, nawet gdyby dobindowanie modeule zdalo egzamin, to napierw wywliasz ile tam elementow zanim zorientujesz sie ze dla kolejnego elementu dany warunek nie jest spelniony, wiec np cala struktura ktora probowales usunac powinna zostac nietknieta).

Pozatym metody  toSingleDimmension, i findChildren mozna wykozystac jako metody pomocnicze np kolenej metody ktora wyegenruje liste warosci dropdowna poukladanych w ten posob :

level 1
      level 1 - 1
           level 1 - 1 - 1
      level 1 - 2

Ostatnio edytowany przez robal77 (2009-08-05 18:09:50)