Gestione Albero Categorie

Ciao a tutti

Sto procedendo a piccoli passi con zend framework...moooolto piccoli per il momento...

Io avevo pensato ad una tabella del database del genere:

id - parent - title - path - description

e qualche altra colonna...

parent rappresenta l'id del nodo padre.

Ora avevo iniziato a creare un modello per gestire le categorie...ed ovviamente qui casca l'asino...

public function GetFathers()
    {
        return $this->_db->fetchAll('select * from '.$this->_name.' where parent = 0 order by title asc');
    }
    static public function GetSons($idParent)
    {
        $conn = Zend_Registry::get('db');
        return $conn->fetchAll('select * from categories where parent = '.$idParent.' order by title asc');
    }

La view che ho usato come test:

<div id="categorie">
    <h1>Categorie</h1>
<br /><br />
<?php
//var_dump($this->categories);
foreach($this->categories as $cat):
    echo $this->escape($cat['title']);
    $son = application_models_Categoria::GetSons($cat['id']);
?>
    <br>
<?php
if(count($son))
    foreach($son as $figlio):
        echo '&nbsp;|___&nbsp;'.$figlio['title'].'<br />';
        //print_r($son);
    endforeach;
    ?>
    <br><br>
<?php
endforeach;
?>

La funziona GetFathers() la chiamavo dal controller index...

mentre la prendi figlio direttamente dalla view...

Ho detto qui casca l'asino perchè cosi funziona ma funziona su un solo livello, io vorrei ottenere un qualcosa di indipendente dai livello per ottenere una stampa di qualcosa del genere (solita roba quando si parla di alberi penso)

cat1

|___cat3

|___cat4

        |___cat7

cat2

cat5

|___cat6

Chi mi può aiutare a ragionarci su per trovare il modo migliore di ottenere questa cosa con il minimo consumo di energie?? Questo perchè ho letto che la ricorsività sfrutta un sacco di risorse...ma ad ogni modo andrebbe bene lo stesso. Esiste se no modo di aiutarsi anche con delle query particolarmente articolate?? o boh...

Spero qualcuno possa aiutarmi....  :crazy:

inviato 6 anni fa
paulpetta
X 0 X

1) temo tu non abbia creato correttamente il tuo model, non capisco a cosa ti possa servire:

        $conn = Zend_Registry::get('db');

2) preferisci avere tante query ed accessi al database o meno? Conta che tanti accessi al database fanno perdere tempo e sono uno spreco di banda, se hai pochi "figli" è il sistema più veloce, simile a quello che hai implementato te, altrimenti meglio creare una query unica ed estrarre tutti i campi, poi con un cicli vari e controlli si può "in tabellare" il tutto.

risposto 6 anni fa
Mario Santagiuliana
X 0 X

Ciao

1) quella riga mi serve perchè richiamandola in modo statico  non passo dal costruttore  e quindi devo richiamare la connessione al DB (o almeno dovrebbe essere cosi :) ) perchè in realtà ho messo solo le due funzioni a cui mi riferivo, ci sono giusto un paio di altre cosine tipo costruttore e alcune proprietà...

2) beh l'albero non è costruito, ma in maniera astratta deve funzionare sia che abbia 10 figli sia che ne abbia 1000... Io adesso come adesso prendo solo il primo figlio, ma non ho proprio idea di come fare per ottenere / costruire tutto l'albero...voi che mi consigliate?? la soluzione migliore ovvio eheheheh ;) non so proprio dove sbatteer il muso...

ciauuuu

risposto 6 anni fa
paulpetta
modificato 6 anni fa
X 0 X

1) Non ho capito, ma stai creando una applicazione col paradigma MVC? Con la struttura standard dello Zend Framework?

2) Un suggerimento, leggi anche questa discussione per trovare una semisoluzione:

http://www.phpnews.it/forum/programmazione-php/ordinamento-lista-oggetti/

Se hai tanti figli da dover strutturare ad albero credo sia meglio utilizzare più query, l'algoritmo di estrazione di intabellamento mi sembra più semplice.

Altrimenti puoi fare un'unica query, estrai tutti i tuoi dati, l'array contenente i dati lo riordini (un po' come nella discussione che ti ho suggerito di leggere).

Devi scegliere te quale è l'approccio migliore per le caratteristiche del tuo applicativo. Altre soluzioni al momento non mi vengono in mente...

risposto 6 anni fa
Mario Santagiuliana
X 0 X

ciao

1) ???

In teoria....

Scusa ma invece che dirmi perchè faccio così o cosà, non potresti indicarmi perfavore la via migliore?? Visto che sono ai primi passi...non conosco magari ne i metodi migliori ne le finezze di chi lo uso da tanto tempo...

2) appena ho un'attimo proverò a leggere quella discussione...

risposto 6 anni fa
paulpetta
X 0 X

1) Ma pure io non lo uso da tanto  ;) ahahah scherzo.

Ti consiglio di leggere questa guida che secondo me è ottima per iniziare (oltre alla guida ufficiale di Zend Framework):

http://akrabat.com/zend-framework-tutorial/

Le domande che ti pongo le faccio per capire cosa stai facendo, seguire un pattern standard di sviluppo può essere utile ma non risultare funzionale per la costruzione di un applicativo. Sono costretto a porti dei quesiti per capire se è una tua scelta mirata o se semplicemente necessiti di un qualche spunto in più di riflessione.

2) Attendiamo notizie :)

risposto 6 anni fa
Mario Santagiuliana
X 0 X

Ciao M

Grazie ai tuoi spunti, anche se inizialmente mi facevi innervosire,  :2funny:  :crazy: mi hai messo la pulce nell'orecchio e ho trovato un metodo setdefaultadapter che ha fatto al caso mio e quindi ora non salvo più la connessione nel registry ma la mia index.php è diventata cosi:

<?php
// Define path to application directory
defined('APPLICATION_PATH')
        || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/application'));

// Define application environment
defined('APPLICATION_ENV')
        || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
            realpath(APPLICATION_PATH . '/library'),
            realpath(dirname(__FILE__) . '/library'),
            get_include_path(),
        )));

/** Zend_Application & Zend_Autoloader*/
require_once 'Zend/Application.php';

// Create application, bootstrap
$application = new Zend_Application(
                APPLICATION_ENV,
                APPLICATION_PATH . '/configs/application.ini'
);

$config = new Zend_Config_Ini(realpath(APPLICATION_PATH . '/configs/application.ini'), 'production');

$modelnamespace = $config->get('app')->namespace->models;
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace($modelnamespace);

    //Apertura del database
    try
    {
        $dbadapter = $config->get('db')->adapter;
        $dbconfig = array('host'     => $config->get('db')->params->host,
                          'username' => $config->get('db')->params->username,
                          'password' => $config->get('db')->params->password,
                          'dbname'   => $config->get('db')->params->dbname);
        $db = Zend_Db::factory($dbadapter, $dbconfig);
        $db->getConnection();
        Zend_Db_Table::setDefaultAdapter($db);
    }
    catch (Zend_Db_Adapter_Exception $e)
    {
        die("Zend_Db_Adapter_Exception: " . $e->getMessage());
    }
    catch (Zend_Exception $e)
    {
        die("Zend_Exception: " . $e->getMessage());
    }

// run
$application->bootstrap()
            ->run();

Ti volevo chiedere, secondo te la connessione nel file index.php è giusta o meglio metterla nel file bootstrap.php???

In ogni caso che pi**a ci si mette nel file bootstrap.php mi sapresti dare indicazioni??

Dopo le modifiche fatte alla connessione ora il mio model categorie è cosi:

<?php
class application_models_Categoria extends Zend_Db_Table_Abstract
{
    protected $_name = 'categories';
   
}
?>

invece il mio indexcontrolle è cosi:

<?php
class IndexController extends Zend_Controller_Action
{

    public function init()
    {
        /* Initialize action controller here */
    }

    public function indexAction()
    {
        $Categorie = new application_models_Categoria;
        $this->view->categories = $Categorie->fetchAll();
        
    }
}

e la mia view per questo esperimento è cosi:

<div id="categorie">
    <h1>Categorie</h1>
<br /><br />
<?php
//var_dump($this->categories);
foreach($this->categories as $cat):
    echo $this->escape($cat['title']);
    //$son = application_models_Categoria::GetSons($cat['id']);
?>
    <br>
<?php
endforeach;
?>
</div>

A questo punto suppongo di aver compiuto la mia prima mini ottttttttimizzazione :D

ma il mio problema di stampare l'albero rimane...

cosa mi suggerisci?? esiste già qualche strumento in zend che possa aiutarmi???

Onestamente sono un po' lontanino dal avere il mio algoritmo in testa e farlo in php...

Aiutooooooooooooo!! :)

dai dai so che puoi aiutarmi... :smitten:

aspetto con ansia una risposta... 8)

Ciauuuuuuu

PS: Dimenticavo la struttura di cartelle che uso al momento è quella classica eccetto per la cartella public che non faceva al caso mio e che ho spostato il contenuto di un livello per ottenere questo:

(DIR) application

(DIR) library

(FILE)  index.php

(FILE) .htaccess

1) Ma pure io non lo uso da tanto  ;) ahahah scherzo.

Ti consiglio di leggere questa guida che secondo me è ottima per iniziare (oltre alla guida ufficiale di Zend Framework):

http://akrabat.com/zend-framework-tutorial/

Le domande che ti pongo le faccio per capire cosa stai facendo, seguire un pattern standard di sviluppo può essere utile ma non risultare funzionale per la costruzione di un applicativo. Sono costretto a porti dei quesiti per capire se è una tua scelta mirata o se semplicemente necessiti di un qualche spunto in più di riflessione.

2) Attendiamo notizie :)

risposto 6 anni fa
paulpetta
X 0 X

Lo spostamento del contenuto della cartella public ci può stare...se però hai una directory root non accessibile dal web ti è più conveniente spostare le cartelle della libreria, l'application ecc la e lasciare il contenuto della cartella public sul web.

Per creare una semplice connessione al database non ti serve modificare l'index.php...

Il tutorial che ti ho dato spiega molto bene come creare un semplice model per connettersi al database.

Non capisco perchè sei andato a fare quella modifica...non mi raccapezzo.

Per la questione dell'intabellamento...Alcuni spinti te li ho dati prima. Zend Framework non ha una classe nello specifico, però ti potrebbe risultare utile Zend Paginator:

http://framework.zend.com/manual/en/zend.paginator.html

risposto 6 anni fa
Mario Santagiuliana
X 0 X

maremmaaaaaaaaaaaaaaaaa  :crazy:

ehehehe

sono riuscito a fare andare tutto in versione standard :)

ovvero senza questo:

$config = new Zend_Config_Ini(realpath(APPLICATION_PATH . '/configs/application.ini'), 'production');

$modelnamespace = $config->get('app')->namespace->models;
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace($modelnamespace);

    //Apertura del database
    try
    {
        $dbadapter = $config->get('db')->adapter;
        $dbconfig = array('host'     => $config->get('db')->params->host,
                          'username' => $config->get('db')->params->username,
                          'password' => $config->get('db')->params->password,
                          'dbname'   => $config->get('db')->params->dbname);
        $db = Zend_Db::factory($dbadapter, $dbconfig);
        $db->getConnection();
        Zend_Db_Table::setDefaultAdapter($db);
    }
    catch (Zend_Db_Adapter_Exception $e)
    {
        die("Zend_Db_Adapter_Exception: " . $e->getMessage());
    }
    catch (Zend_Exception $e)
    {
        die("Zend_Exception: " . $e->getMessage());
    }

 :D :D

Ok dici che ora sono a posto ?? :D

giusto poi guardo quella conversazione e anche paginator...

In tanto grazie :)

ma tranquillo non ti sei ancora liberato di me :D

Ciauuuuuuuuuuuuuu

risposto 6 anni fa
paulpetta
X 0 X
Ok dici che ora sono a posto ?? :D

Direi di si  ;)

Facci sapere su come hai deciso di risolvere il problema dell'albero.

risposto 6 anni fa
Mario Santagiuliana
X 0 X
Effettua l'accesso o registrati per rispondere a questa domanda