Usare "Custom Field" nel content
Cercando di scrivere il mio plugin per wordpress mi sono imbattuto in un problema che, all'apparenza stupido, di stupido ha poco ( a mio modesto parere ovviamente!). Sarà sicuramente capitato anche a voi, di aver visto plugin che una volta attivati,per la visualizzazione dei dati, pretendono di avere pagine a loro dedicate nelle quali sono presenti tag in questo formato : "[tag]".
Come questi plugin a capire quando sono interpellati?! Bene, me lo sono chiesto e sinceramente non credo ancora di averlo capito, ma CREDO che procedano così:
add_filter('the_content','ricerca_tag');
creo un filtro per cui ogni volta che viene chiamato in wordpress "the content"(praticamente ad ogni visualizzazione di pagine o articoli) viene chiamata la mia funzione ricerca_tag.
function ricerca_tag($content) {
if (substr_count($content, '[TAG]'))
$content=str_ireplace('[TAG]',TEST_TAG(),$content);
return $content;
}function TEST_TAG() {
return "HA FUNZIONATO!!";
}
semplicemente ricerco all'interno di quello che sto per stampare se è presente il mio "[TAG]", e se lo trova lo rimpiazza con quello che ritorna la funzione TEST_TAG, che altro non fa che ritornare una stringa di testo!
Ovviamente questo metodo non so se è il metodo giusto, o il più efficace, è quello che sto usando io
ATTENZIONE bisogna far attenzione nella stesura del codice poichè una funzione "ricerca_tag" troppo pesante o gravosa (esempio ricerca di 100 tag) potrebbe causare rallentamenti consistenti del blog.
Contatori e qualche tips su tabelle
In Mysql esiste una proprietà del campo int che si chiama AUTO_INCREMENT, che permette senza nessun tipo di sforzo di gestire ID univoci, senza bisogno di nessun altro accorgimento.
A questo punto che senso ha parlare di auto_increment? ![]()
Questa proprietà offre numerosi vantaggi, ma per utilizzarla appieno bisogna conoscerne almeno anche qualche caratteristica, il contatore parte per default da 1, e memorizza il max(id) così da immettere automaticamente un id che non è stato mai usato prima, ma se ho ad esempio 5 campi numerati da 1 a 5 e cancello i record con id 4,5 che numero avrà l'id successivo? ovvio: 6! ![]()
e se volessi ricominciare dal primo numero dopo X? a questo punto ci viene comodo sapere che esiste una "variabile" dedicata alla tabella nella quale specificare il numero dal quale incominciare per iniziare una numerazione:
ALTER TABLE nomeTabella AUTO_INCREMENT = X
Se invece, come mi capita spesso, ho un campo id con valori veramente distribuiti a caso, il modo più veloce che conosco è, per non modificare l'ordine dei record, aggiungere una colonna ID_TMP auto_increment e successivamente cancellare la vecchia..
per prima cosa quindi, visto che non possiamo avere due primary key in una tabella eliminiamo il riferimento alla primary key del vecchio id con
ALTER TABLE `test` CHANGE `ID` `ID` INT( 11 ) NOT NULL ;
ALTER TABLE `test` DROP PRIMARY KEY
la prima riga serve perchè una colonna con valore automatico DEVE essere una chiave della tabella ![]()
poi aggiungiamo un nuovo campo autoincrementale
ALTER TABLE `test` ADD `ID_TMP` INT NOT NULL AUTO_INCREMENT ,ADD PRIMARY KEY(`ID_TMP`)
eliminiamo il vecchio id e cambiamo nome al temp e il gioco è fatto!
ALTER TABLE `test` DROP `ID`
ALTER TABLE `test` CHANGE `ID_TMP` `ID` INT NOT NULL AUTO_INCREMENT
a questo punto la domanda è lecita.. e se volessimo partire da 0?
la procedura è pressocchè la stessa,ma dobbiamo stare attenti ad un paio di cose, quando creiamo l'indice ausiliario lo dobbiamo dichiarare INT e basta:
ALTER TABLE `test` ADD `ID_TMP` INT
poi mettiamo a 0 il suo indice più basso:
select MIN(`ID`) from `test` into @a;
UPDATE `test` SET `ID_TMP` = '0' WHERE `test`.`ID` = @a
quindi eliminiamo il primary key ed auto_increment dell' ID vecchio
ALTER TABLE `test` CHANGE `ID` `ID` INT( 11 ) NOT NULL ;
ALTER TABLE `test` DROP PRIMARY KEY
e l'impostiamo al nuovo facendo attenzione alla prima riga! infatti stiamo dicendo a mysql di non auto_suggerirci un nuovo valore quando incontra lo 0:
SET sql_mode="NO_AUTO_VALUE_ON_ZERO";
ALTER TABLE `test` MODIFY `ID_TMP` INT NOT NULL AUTO_INCREMENT ,ADD PRIMARY KEY(`ID_TMP`)
poi procediamo come prima, eliminiamo la colonna ID e rinominiamo ID_TMP in ID
ALTER TABLE `test` DROP `ID`;
ALTER TABLE `test` CHANGE `ID_TMP` `ID` INT NOT NULL AUTO_INCREMENT
et voià! il gioco è fatto!
EDIT:
mi sono scordato una cosa "importante" e cioè rimettere l'ID della tabella come primo campo!!
ALTER TABLE test MODIFY COLUMN ID int FIRST
questo è un comando non tanto conosciuto, ma comodo.. ricordatevi però di mettere il valore del campo in modo giusto!! (int per i numeri varchar per i campi alfanumerici )
intanto che ci siamo vi illustro anche come mettere un campo prima o dopo un altro, se per caso l'ordine di una tabella fosse: secondo,primo,ID potremmo agevolmente con il primo comando mettere l'id all'inizio e poi con questo:
ALTER TABLE test MODIFY COLUMN secondo varchar(255) AFTER primo
ripristinare l'ordine naturale: ID,primo,secondo
GROUP_CONCAT tips 2 – il ritorno
un modo produttivo per usare i group_concat è creare delle views specifiche avendo così tutti i dati in un unica "tabella", ma come fare per fare delle select sui valori ritornati da group_concat?
il campo è considerato varchar fino al valore di group_concat_max_len è maggiore di 512, altrimenti è considerato BLOB, quindi si può usare una clausola where in questo modo:
select * from vestiti
where (taglie like 'l' or taglie like '%,l,%' or taglie like '%,l' or taglie like 'l,%' ) and (colori like 'rosso' or colori like '%,rosso,%' or colori like '%,rosso' or colori like 'rosso,%' )
p.s.
vestiti è la nostra view, in questo caso specifico voglio avere tutti i vestiti che hanno taglia L e colore rosso
GROUP_CONCAT tips
l'altro giorno mi sono imbattuto in un piccolo "problema" di visualizzazione di risultati di una query..
in particolare, cosa succede quando ho una relazione molti a molti su due tabelle? in generale si crea una tabella "intermediario"
nella quale si gestiscono le varie relazioni.. è qui che sorge il "problema" e cioè: normalmente cosa succede quando si fa una select?
i risultati vengono spianati su varie righe, proprio perchè (per definizione) ad un record della tabella 1
corrispondono più record della tabella 2!
ma vediamo in particolare con un esempio come funziona questa comoda funzione (non standard)
le tabelle saranno:
CREATE TABLE `prodotti` (
`ID` int(10) unsigned NOT NULL auto_increment,
`nome` varchar(255) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8CREATE TABLE `valori_attributo` (
`ID` int(10) unsigned NOT NULL auto_increment,
`valore` varchar(255) NOT NULL,
`tipo` varchar(255) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8CREATE TABLE `valori_prodotti` (
`ID` int(10) unsigned NOT NULL auto_increment,
`ID_prodotto` int(10) unsigned NOT NULL default '0',
`ID_valore_attributo` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
popoliamo un pò il db:
insert into valori_attributo values (NULL,'rosso','colore'),(NULL,'blu','colore'),(NULL,'verde','colore'),(NULL,'giallo','colore'),(NULL,'M','taglia'),(NULL,'S','taglia'),(NULL,'L','taglia'),(NULL,'XL','taglia')
insert into prodotti values (NULL,'maglia corta'),(NULL,'maglia maniche lunghe'),(NULL,'pullover')
insert into valori_prodotti values (NULL,(select ID from prodotti where nome = 'pullover'),(select ID from valori_attributo where valore = 'XL')),(NULL,(select ID from prodotti where nome = 'pullover'),(select ID from valori_attributo where valore = 'S')),(NULL,(select ID from prodotti where nome = 'pullover'),(select ID from valori_attributo where valore = 'L')),(NULL,(select ID from prodotti where nome = 'pullover'),(select ID from valori_attributo where valore = 'rosso')),(NULL,(select ID from prodotti where nome = 'pullover'),(select ID from valori_attributo where valore = 'blu')),(NULL,(select ID from prodotti where nome = 'pullover'),(select ID from valori_attributo where valore = 'verde')),(NULL,(select ID from prodotti where nome = 'maglia corta'),(select ID from valori_attributo where valore = 'giallo')),(NULL,(select ID from prodotti where nome = 'maglia corta'),(select ID from valori_attributo where valore = 'M'))
in questo esempio se avessimo voluto tutti i prodotti con a lato i relativi valori attributo la cosa più naturale da scrivere
sarebbe qualcosa del tipo:
select (select nome from prodotti where ID = ID_prodotto) as prodotto,(select valore from valori_attributo where ID = ID_valore_attributo) as valore from valori_prodotti
che produce un risultato simile a questo:
prodotto valore pullover XL pullover S pullover L pullover rosso pullover blu pullover verde maglia corta giallo maglia corta M
mentre con questa bellissima istruzione:
select prodotti.nome, GROUP_CONCAT(DISTINCT (select valore from valori_attributo where valori_prodotti.ID_valore_attributo = valori_attributo.ID and valori_attributo.tipo = 'colore') SEPARATOR ',') as colore, GROUP_CONCAT(DISTINCT (select valore from valori_attributo where valori_prodotti.ID_valore_attributo = valori_attributo.ID and valori_attributo.tipo = 'taglia') SEPARATOR ',') as taglie from valori_prodotti,prodotti
where valori_prodotti.ID_prodotto = prodotti.ID group by prodotti.ID
avremo questo risultato:
nome colore taglie maglia corta giallo M pullover rosso,blu,verde XL,S,L
carino no?
Parsare html nel blog
Blogcrowds fornisce un comodo parser di html per pubblicare del codice html sul proprio blog
http://blogcrowds.com/resources/parse_html.php
Array di checkbox in php
ecco un semplice modo per gestire checkbox multipli
<form method="post" action="form.php">
<input name="taglie[]" value="L" type="checkbox">
<input name="taglie[]" value="M" type="checkbox">
<input type="submit">
</form>
e per recuperare i valori:
for ($i=0; $i < sizeof($HTTP_POST_VARS['taglie']); $i++)
echo $HTTP_POST_VARS['taglie'][$i];
ovviamente può essere un metodo utilizzabile non solo per le chechbox ma per qualsiasi tipo di dato!
Schedulare procedure in MySQL usando SLEEP() e EXECUTE
un interessantissimo articolo del "guru" informatico Roland Bouman che spiega in dettaglio come automatizzare procedure in MySQL 5.0 (in MySQL 5.1 è supportato nativamente)
in sostanza crea una tabella "job" nella quale verranno memorizzati i processi, e usa una procedura job&run che in loop attiva/disattiva i processi..
http://rpbouman.blogspot.com/2005/10/scheduling-procedure-execution-in.html
p.s.
non ho idea del carico di lavoro che la procedura job&run possa arrecare al server, se avrò modo di provarla vi farò sapere
Query dinamiche con MySQL
con questa procedura è possibile automatizzare diversi tipi di procedure,l'unico mio problema ora è che se inserita all'interno di trigger non va a buon fine..funzionalità non ancora implementata in MySQL 5.0.51?
tutti i tipi di procedure che non hanno al loro interno codice sql dinamico..
CREATE DEFINER=`root`@`localhost` PROCEDURE `eseguiQuery`(queryT VARCHAR(255))
BEGIN
set @sql_text:=queryT;
PREPARE stmt1 FROM @sql_text;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END$$
l'utilizzo è semplicissimo es:
(ovviamente qui è usata all'interno di un altra procedura)
set queryAtt = CONCAT("ALTER TABLE `db`.`PROVA` MODIFY COLUMN `colonna` SET('a','b','c','d') DEFAULT NULL;");
CALL `db`.eseguiQuery(queryAtt);
set queryAtt = CONCAT("select * from test.tabella");
CALL `db`.eseguiQuery(queryAtt);
Ciao mondo!!
Benvenuto in WordPress. Questo è il tuo primo articolo. Modificalo o cancellalo e inizia a creare il tuo blog!