0

I want to get a tree of Categories to show it like this:

cat1
    subcat1
    subcat2
    subcat3
        subsubcat1
cat2
    subcat1
...

I have this table:

CREATE TABLE IF NOT EXISTS `kategorie` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(256) collate utf8_polish_ci NOT NULL,
  `father` int(11) NOT NULL default '-7',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `name` (`name`)
)

So each record contains only self and parent id (I cannot add left and right ids).

For now I made this model:

class Category extends AppModel 
    {
        public $name = 'Category';
        public $useDbConfig = 'external';
        public $useTable = 'kategorie';

        var $belongsTo = array(  
            'ParentCategory' => array(  
                'className' => 'Category',  
                'foreignKey' => 'father'  
        ));  

        var $hasMany = array(  
            'ChildCategory' => array(  
                'className' => 'Category',  
                'foreignKey' => 'father'  
        ));     

    }

and controller:

class CategoriesController extends AppController {

        public function beforeFilter() 
        {
            parent::beforeFilter();
            //$this->Auth->allow('add','logout');
        }

        public function index()
        {
            $res = $this->Category->find('all');
            //$this->set('categories', $this->Category->find('all') );  
            debug($res); die;           
        }   
    }

The debug output is something like this:

array(
    (int) 0 => array(
        'Category' => array(
            'id' => '1',
            'name' => 'catname',
            'father' => '2'
        ),
        'ParentCategory' => array(
            'id' => '2',
            'name' => 'catname',
            'father' => '3'
        ),
        'ChildCategory' => array(
            (int) 0 => array(
                'id' => '161',
                'name' => 'catname',
                'father' => '1'
            )
        )
    ),
    (int) 1 => array(
        'Category' => array(
            'id' => '2',
            'name' => 'catname',
            'father' => '3'
        ),
        'ParentCategory' => array(
            'id' => '3',
            'name' => 'catname',
            'father' => '4'
        ),
        'ChildCategory' => array(
            (int) 0 => array(
                'id' => '1',
                'name' => 'catname',
                'father' => '2'
            ),
            (int) 1 => array(
                'id' => '5',
                'name' => 'catname',
                'father' => '2'
            ),
            (int) 2 => array(
                'id' => '489',
                'name' => 'catname',
                'father' => '2'
            )
        )
    ),
...

So basicly I get array of Category objects (the number of these objects is the number of categories (all, even subcategories). Each category has a parent category and array of child categories...

This is not what I want because I would have to "manually" parse the array to build a category tree and it would be slow as I would have to find categories with specified id in the array (category id is not it's index in array)...

Maybe some1 knows any special trick to get a nice, useful category tree?

tereško
  • 58,060
  • 25
  • 98
  • 150
user606521
  • 14,486
  • 30
  • 113
  • 204

1 Answers1

2

Try having a look at the find method's other parameters. You can try using

$res = $this->Category->find('threaded');

You can find more details at http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#find-threaded.

Arno
  • 1,253
  • 14
  • 21
  • Well this would be great but it requires filed 'parent_id' and I have field 'father' and can't change it - is there any trick to map this field name to 'parent_id'?? this is strange - cake should provide some argument which would be the name of parent_id in table... – user606521 Apr 22 '12 at 18:20
  • 2
    Found anserw -> in CakePHP 2.1 use find('threaded', array('parent' => 'father') ); – user606521 Apr 22 '12 at 21:52