Come ottenere una lista di tutti i componenti e relative actions
Grazie a questo component, è facilissimo !
http://cakebaker.42dh.com/2006/07/21/how-to-list-all-controllers/
Grazie a questo component, è facilissimo !
http://cakebaker.42dh.com/2006/07/21/how-to-list-all-controllers/
Grazie al suggerimento di Tox che ha + fiuto del cane di Lycos nello scovare risorse in rete, ho provato il LinkableBehavior per risolvere un problema con una query che con Containable non riuscivo a rendere efficente.
Problema
Ho il seguente schema di modelli:
Regions hasMany District hasMany City hasMany Customer.
Ho necesità di ottenere l’elenco dei clienti (Customer) che risiedono nella provincia (District) di Torino (id=1).
Soluzione con LinkableBehavior
Model:
var $actsAs = array('Linkable');
Codice:
$customers = $this->District->City->Customer->find('all',array(
'link'=>array('City'=>array('District')),
'conditions'=>array('District.id'=>$id),
'fields'=>array('Customer.id','Customer.nome','Customer.cognome','City.name')))
Risultato:
Array
(
[0] => Array
(
[Customer] => Array
(
[id] => 1
[nome] => Giuseppe
[cognome] => De Santis
)
[City] => Array
(
[name] => Buttigliera Alta
)
)
)
Query eseguita (unica):
SELECT `Customer`.`id`, `Customer`.`nome`, `Customer`.`cognome`, `City`.`name` FROM `customers` AS `Customer` LEFT JOIN `cities` AS `City` ON (`City`.`id` = `Customer`.`city_id`) LEFT JOIN `districts` AS `District` ON (`District`.`id` = `City`.`district_id`) WHERE `District`.`id` = 1
Meglio di così….
Risorsa utile: http://planetcakephp.org/aggregator/items/891-linkable-behavior-taking-it-easy-in-your-db
Con CakePHP 1.3 è possibile sfruttare altri framework Javascript oltre all’accoppiata Prototype/Scriptaculous utilizzando il JsHelper.
Per utilizzare JQuery è sufficiente seguire le istruzioni del manuale on line http://book.cakephp.org/view/1592/Js che riassumo di seguito.
echo $this->Html->script('jquery-1.4.2.min');
nella sezione <head></head>.
echo $js->writeBuffer();
prima del tag </body>
var $helpers = array('Js' => array('Jquery'));
A questo punto siamo pronti per utilizzare gli effetti di JQuery nelle nostre views
Nella view inseriamo il seguente codice che permette di mostrare o nascondere un DIV con effetto slide.
Creiamo i link e il box
<a href="#" id="apri">Apri il box</a> | <a href="#" id="chiudi">Chiudi il box</a> <div id="box" style=" border: 1px solid green; height:200px; width:100px; display:none"></div>
e poi aggiungiamo il codice PHP
$apri = $js->get("#box")->effect('slideIn');
$chiudi = $js->get("#box")->effect('slideOut');
$js->get("#apri")->event('click', $apri );
$js->get("#chiudi")->event('click', $chiudi );
Volendo includere un effetto non disponibile con JsHelper è possibile inserire del codice nativo JQuery e riutilizzarlo nel seguente modo
$codice = '$("#box").toggle("blind",{},500);';
$js->get("#toggle")->event('click', $codice );
Un editor leggero e veloce che uso al posto del classico blocco note e anche per eseguire delle piccole modifiche su semplici progetti.
Per progetti in php + complessi uso Eclipse con plugin legati al PHP.
Utilizzando massicciamente i template con i vari sistemi da me utilizzati (Smarty, CakePHP, ecc), mi trovo di fronte a estensioni del tipo tpl, thtml, che non contengono altro che codice HTML, ma che non sono riconosciuti dall’editor come tali e quindi non viene attivata la colorazione del codice.
Per Notepad++ è sufficente aggiungere l’estensione nel file langs.xml che si trova nella directory di installazione del programma.
La dove è definito il linguaggio html
E’ sufficente aggiungere le estensioni da associare all’HTML
e poi registrare le due estensioni selezionando da menu:
CONFIGURAZIONE > OPZIONI > ASSOCIAZIONE TIPI DI FILE > CUSTOMIZE
e inserire nel campo le estensioni “thtml” e “ctp” per poi trasferirle con la freccietta

Per abilitare la gestione in Dreamweaver, potete seguire questo tutorial: http://www.techwave.it/blog/2010/03/09/visualizzare-i-files-thtml-e-ctp-in-dreamweaver/

Foto di Danilo Rizzuti
A volte si usano Vendors di terze parti che hanno un proprio accesso al DB, quindi è utile passare i parametri di collegamento al DB specificati in app/config/database.php.
if (class_exists('DATABASE_CONFIG')) {
$dbconfig =& new DATABASE_CONFIG();
}
$host = $dbconfig->default['host'];
$login = $dbconfig->default['login '];
$password= $dbconfig->default['password'];
Il titolo è un po’ contorto, ma non sono riuscito a trovare di meglio.
L’esigenza nasce quando voglio ordinare il risultato di una query che vede interessati vari Model utilizzando un determinato campo per l’ordinamento.
Faccio l’esempio: ho i seguenti model e le seguenti relazioni.
Continent hasMany Country
Country hasMany News
Il modello Continent ha un campo ‘order’ che serve a mantenere un determinato ordine di presentazione per i continenti.
Voglio ottenere una lista di News ordinate per Continent.order.
Poichè il model News ha molte relazioni con altri model (Tag, Area, Comment, ecc. ecc. ), utilizzo il behavior Containable.
A questo punto non è sufficente impostare l’elemento ‘order’ a ‘Continent.order ASC’, perchè la query restituisce un errore. Infatti CakePHP esegue prima una query per ricavare l’elenco delle News e per ogni News ricavata esegue una successiva query per determinare il continente relativo al country.
//
$this->Continent->find('all', array('order' => 'Continent.name')) // Restituisce un errore nell query SQL
//
SOLUZIONI
Una soluzione generica che risolve ampiamente il problema è impiegare questo behavior suggeritomi da fzanardo nel forum, ma che non ho personalmente provato.
Una soluzione light invece è la seguente:
// estraggo gli di dei continenti ordinati in base al campo 'order'
$continents = array_keys($this->News->Country->Continent->find('list',array('fields'=>array('id','order'),'recursive'=>-1,'order'=>'order')));
$lista = $this->News->find('all',array( 'conditions'=>$conditions,
'contain'=>array(
'Area',
'Country'=>array('Continent'),
),
'order' => array('FIELD(Country.continent_id,'.implode(',',$continents).')')
ORDER BY FIELD(Country.continent_id, 1,4,3,6,5,2) sarà l’impostazione del’ordine che consentirà di ottenere l’ordine voluto, mantenendo la query leggera.
Riferimento: http://cakebaker.42dh.com/2008/06/10/order-by-field/
Quando si crea un plugin, si possono utilizzare la maggior parte delle convenzioni comuni, facendo attenzione però al model.
Ad esempio: ho un plugin chiamato categories che mi consente di gestire le categorie strutturate con gerarchia ad albero e in questo plugin dichiaro il model Category.
Se nella mia applicazione voglio creare una relazione con il model Article dovrò fare attenzione di inserire nel campo ‘className’ il nome del plugin anteposto al nome del model, così come nell’esempio riportato qui sotto.
var $belongsTo = array(
'Category' => array(
'className' => 'Categories.Category',
'foreignKey' => 'category_id'
)
);
Riferimento al manuale: http://book.cakephp.org/view/117/Plugin-Models
Se si tenta di utilizzare poEdit per la traduzione di file con estensione .ctp inizialmente si ottiene un messaggio del tipo:
“Poedit non ha trovato alcun file nelle directory analizzate”
Se si va in File > Preferenze > Parser e si modifica PHP si può aggiungere una estensione e si avrà una lista del tipo
“*.php;*.ctp”
Ma questo non basta perchè si otterrebbe un messaggio del tipo:
“xgettext: warning:file `users/login’ extension `ctp’ is unknown;will try C”
Per far processare correttamente i file .ctp da poEdit è sufficente aggiungere una riga nel comando del parser.
--language=php
Riavviare il programma
Per estendere un controller è sufficente importare il controller da inserire prima della dichiarazione della nuova classe che ne è l’estensione.
Esempio:
App::import('Controller', 'Nodes');
class ArticlesController extends NodesController {
var $name = 'Articles';
}
Giusto da far notare che si deve importare “Nodes” e non “NodesController”