sabato 29 novembre 2014

Magento, verificare il controller utilizzato

Ottenere il nome del controller con la classe Mage_Core_Model_Url

Verificare il nome del controller attivo può essere utile per far comparire un output diverso a seconda delle situazioni.

Ad esempio immaginiamo di voler attribuire una classe CSS ad un tag a seconda che ci troviamo sulla home page o nella pagina del prodotto.

Verifica del controller nei file template (.phtml)

Possiamo ottenere il nome del controller che sta utilizzando Magento in questo modo:
$this->getRequest()->getControllerName();
Quindi se ci troviamo sulla home page otterremo "index", se ci troviamo nella scheda prodotto otterremo "product".

In questo modo avremo:
$controller=$this->getRequest()->getControllerName();
if( $controller=="index" ):
//sono sulla home page quindi
  $class="stile1";
elseif( $controller=="product" ):
//sono nella scheda prodotto
  $class="stile2";
endif;
echo '<span class="'.$class.'">Nome prodotto</span>
L'oggetto Request può anche restituire altre utili informazioni, ad esempio:
//nome della funzione usata dal controller
$this->getRequest()->getActionName();

//indirizzo della route corrente
$this->getRequest()->getRouteName();

//nome del modulo corrente
$this->getRequest()->getModuleName();

Richiamare il controller all'interno delle classi

getRequest può essere richiamato da $this solo nei file .phtml, ma se ci troviamo all'interno di una classe, $this restituirà la classe stessa, quindi il metodo getRequest() non sarà disponibile.

Per ottenere le informazioni sopra descritte sarà quindi necessario utilizzare Mage::app() al posto di $this.

La classe che ci viene in aiuto per ottenere queste informazioni è Mage_Core_Model_Url. Possiamo verificare il contenuto dell'oggetto con un print_r():

You can explore all requests with print_r.

echo "<pre>";
    print_r(Mage::app()->getRequest());
echo "</pre>";

domenica 16 novembre 2014

Magento - caricare un blocco statico tramite codice

Come caricare un blocco statico in un file phtml?

Per caricare un blocco statico all'interno di una pagina su Magento, potrebbe essere comodo effettuare direttamente una modifica all'interno di un file .phtml anzichè andare a modificare i layout XML.

Questa operazione può essere facilmente eseguita, dopo aver creato il blocco statico nel CMS.

Ad esempio, se vogliamo visualizzare il contenuto di un blocco che si chiama block_left_top possiamo utilizzare la seguente istruzione:
<?php echo Mage::app()->getLayout()->createBlock('cms/block')->setBlockId('block_left_top')->toHtml(); ?>
Vediamo insieme da cosa è composta:

  • Mage::app() mi permette di utilizzare il metodo statico app() della classe Mage, da cui partono tutte le chiamate al framework di Magento.
  • Mage::app() crea un oggetto app che tramite il metodo getLayout() crea un oggetto LAYOUT.
  • L'oggetto ottenuto tramite il metodo getLayout() può a sua volte utlizzare il metodo createBlock a cui passo il valore 'cms/block' per indicare che voglio che tipo di oggetto voglio utilizzare;
  • Il nuovo oggetto potrà poi assegnare il blocco statico all'oggetto Blocco creato per scegliere assegnare utilizzo li metodo setBlockId() a cui passerò come parametro l'identificatore del blocco, in questo caso ("block_left_top");
  • L'oggetto ottenuto può generare un output in HTML tramite appunto il metodo toHtml();
  • L'output generato può essere inserito in una variabile da utilizzare successivamente oppure stampato direttamente con echo;
Posso ottenere lo stesso risultato con un codice più compatto utilizzando il metodo statico getBlockSingleton che mi permette di creare direttamente un blocco, a cui poi assegnerò il tipo e l'identificatore prima di ottenere il rendering in formato HTML.

sabato 8 novembre 2014

Ottenere le informazioni dello store in Magento

Come ottenere il codice dello negozio (store) corrente su Magento tramite PHP?

Per accedere alle proprietà dello store attivo su Magento si instanzia l'oggetto store tramite il metodo app della classe statica Mage:

$app=Mage::app();

Poi lo store può essere richiamato con il metodo getStore

$store = $app->getStore();

Naturalmente posso eseguire tutto in un'unica operazione:

$store = Mage::app()->getStore();

A questo punto avrà accesso all'oggetto Mage_Core_Store_Model, un modello che mi permetterà di ottenere le seguenti informazioni:

//il nome del negozio
$name = $store->getName();

//il codice del negozio
$code = $store->getCode();

e, utilizzando i metodi del modello, tante altre utili info, ecco i più importanti esempi:

//il Website Id
websiteid=$store->getWebsiteId();

//se il negozio è attivo
$attivo=$store->getIsActive();

//l'url della home page del negozio
$home=getStore()->getHomeUrl();


martedì 4 novembre 2014

Aggiungere un prefisso a tutte le tabelle di un database Magento (e più in generale su MySQL)

Come aggiungere un prefisso alle tabelle del DB di Magento

In alcuni casi può capitare di dover sfruttare uno stesso database per più applicazione.

La soluzione: utilizzate un prefisso

Sia che le applicazioni siano di tipo diverso (ad esempio Magento e Drupal) che, a maggior ragione dello stesso tipo (due installazioni di Magento), potrebbero esserci delle tabelle con lo stesso nome, da qui la necessità di aggiungere un prefisso per evitare che una o più tabelle vadano a "sovrapporsi" e salti l'integrità dei dati.

Aggiungere il prefisso a tutte le tabelle tramite SQL

In fase di installazione possiamo specificare il prefisso delle tabelle, quindi il problema si risolve nella fase iniziale.


Come comportarsi nel caso di un DB esistente?

Nel caso in cui non si debba effettuare una nuova installazione e l'unica operazione fosse dover importare solo i db la situazione diventerebbe però un po' problematica. 

In questo caso sarebbe opportuno aggiungere il prefisso ad ogni tabella prima del primo database prima di importare il secondo.

Per effettuare questa operazione le opzioni a disposizione sarebbero le seguenti:

1) aprire il file dump con un editor di testo rinominare a mano tutte le tabelle con un copia/incolla del prefisso desiderato (molto esoso in termini di tempo e con un alto rischio di imprecisione);

2) aprire sempre il file, ma rinominare le tabelle con un trova/sostituisci aggiungedo il prefisso (elevatissimo rischio di imprecisione perchè le tabelle possono trovarsi in varie situazioni, CREATE, LOCK, etc.. e quindi difficilmente potremmo individuarle tutte)

3) utilizzare SQL e un po' di PHP

Ovviamente a mio avviso la soluzione 3) è l'unica praticabile.

Oltretutto l'operazione può essere eseguita in due step:

PRIMO STEP: ESEGUIRE UNA QUERY SQL

La seguente query creerà le istruzioni SQL da eseguire successivamente:

SELECT Concat('ALTER TABLE ', TABLE_NAME, ' RENAME TO hors_', TABLE_NAME, ';') FROM information_schema.tables WHERE table_schema = 'Sql718613_3'

Se usate PhpMyadmin (tipica situazione di partenza su tutti gli i principali servizi hosting), potete eseguire la query e poi esportare i risultati in un file SQL.

risultati query

Esportazione dei risultati

Il file ottenuto potrà essere reimportato su phpmyadmin ( o da riga di comando ) per essere eseguito, e tutte le tabelle saranno rinominate.





domenica 2 novembre 2014

Magento, cercare articoli non assegnati a nessuna categoria

Come cercare tutti gli articoli su Magento che non sono stati assegnati ad una categoria?

Avete inserito i prodotti del Vostro catalogo e volete creare un report della situazione relativa a quelli non assegnati a nessuna categoria?

Su Magento potete avere questa informazioni relativamente alla situazione di una categoria, per farlo è sufficiente andare nel backend:

tutti i prodotti della categoria corrente
Come fare per avere un report relativo a tutte le categorie?

Non esiste un'interfaccia nel backend di Magento che ci permetta di farlo, però può venirci in aiuto l'SQL.

La query da eseguire

Andate su phpmyadmin (o da riga di comando) ed eseguite la seguente query:
SELECT e.entity_id, e.sku FROM catalog_product_entity AS e LEFT JOIN catalog_category_product AS l ON l.product_id = e.entity_id WHERE l.category_id IS NULL
Nei risultati potete cambiare i campi della select per conoscere informazioni differenti, di norma lo sku è sufficiente per evitare query più complesse nel database EAV di Magento che potrebbero richiedervi numerose e articolate JOIN.

Se usate phpMyAdmin potete esportare i risultati in CSV per una più agevole lettura.


martedì 2 settembre 2014

Verificare in Magento se un modulo è installato e attivo

Come verificare su Magento la presenza di un modulo?

In alcuni casi può essere utile, su Magento, controllare se è stato installato oppure no un modulo.

Ad esempio potrebbe essere utile far comportare il proprio tema in un modo o in un altro nel caso sia installato un modulo.

Immaginate di avere installato un modulo aggiuntivo che sostituisce il checkout, ma quando viene aggiunto un prodotto al carrello, il redirect di default rimanda l'utente al checkout normale.

Naturalmente potreste modificare il comportamente del tasto ADDTOCART, ma potrebbero esserci in giro dei link che avete creato in precedenza. Con questo codice è possibile intercettare l'installazione del modulo Magestore_onestepcheckout e redirezionare l'utente alla giusta pagina.

Il codice da usare a questo scopo è questo:

$modules = Mage::getConfig()->getNode('modules')->children();
$modulesArray = (array)$modules;

if(isset($modulesArray['Magestore_onestepcheckout '])) {
    $url=$this->getCheckoutUrl();
    Mage::app()->getFrontController()->getResponse()->setRedirect($url);

}   
Oppure:
if( $modules->Magestore_Onestepcheckout->active==true ) {
    $url=$this->getCheckoutUrl();
    Mage::app()->getFrontController()->getResponse()->setRedirect($url);
}   
Sostanzialmente la stessa cosa.

Verifica del modulo installato attraverso il framework di Magento

In realtà è anche disponibile una soluzione migliore, usando però il metodo isModuleEnabled dell'helper della classe Mage:

Mage::helper('core')->isModuleEnabled('Magestore_onestepcheckout ');

In questo questo post di Stackoverflow potete trovare ulteriori alternative:

http://stackoverflow.com/questions/4307407/magento-checking-if-a-module-is-installed


lunedì 1 settembre 2014

Cosa fare se avete gli indici bloccati su Magento

Come sbloccare gli indici su Magento

Cosa fare se in un sito Magento quando ricostruite gli indici non vanno in stato PRONTO?

Le cause possono essere varie, in generale il timeout dello script causato da tempi di elaborazione troppo lunghi. Questo problema a sua volta può essere causato da risorse insufficienti nel momento in cui viene effettuata l'operazione, specie se nel sito ci sono molti prodotti.

Nel caso in cui il le risorse del server su cui è pubblicato il vostro sito siano sufficienti per l'ordinaria amministrazione potrebbe succedere abbastanza raramente, ma nel caso in cui l'operazione venga eseguita in contemporanea con un'altra che sta già impegnando una quantità importante di risorse gli indici potrebbero restare bloccati in fase di elaborazione come nella seguente schermata:


A questo punto nel momento in cui tentiate di ricostruirli nuovamente l'operazione potrebbe non andare a buon fine a causa del fatto che una parte degli indici resta BLOCCATA.

Sbloccare gli indici di Magento

A parte aumentare i tempi di timeout di PHP nel php.ini, una soluzione manuale potrebbe essere la seguente procedura:

1) cancellate gli indici svuotando la cartella /var/locks (solo il contenuto, non cancellate la cartella);
2) andate database e cercate la tabella index_process, modificate quindi i valori del campo status in che non sono pending in stato pending
3) a questo punto ricostruite nuovamente gli indici

Ricostruire gli indici del database di Magento da riga di comando

Se il problema non è risolto potete tentare di ricostruire gli indici dala riga di comando (dovete però avere accesso al terminale).

Per avviare l'operazione potete andare nella cartella /shell del sito web, troverete un file indexer.php che può essere eseguito da riga di comando tramite la classe Mage_Shell_Compiler.

Il file shell/indexer.php accetta come argomento il nome dell'indice. Potete scegliere di ricostruire un indice alla volta oppure tutti gli 8 indici insieme. Naturalmente se avete risorse abbondanti potete scegliere la seconda ipotesi, ma in questo caso non dovreste essere arrivati a questo articolo!

Quindi per risparmiare risorse e rendere il procedimento di ricostruzione più veloce e meno accidentato vi consiglio di ricostruirne uno alla volta tramite questa istruzione:
php -f indexer.php -- -reindex catalog_url
I nomi degli indici sono quelli che trovate nel campo index_process.indexer_code.

Oppure potete scegliere di ricostruire tutto, in questo modo:
php -f indexer.php -- -reindexall
Per ogni indice ricostruito riceverete un messaggio di conferma.



L'elenco completo


Approfondimenti

Per un ulteriore approfondimento potete andare su questo link http://inchoo.net/ecommerce/magento/executing-magento-indexer-from-shell/

domenica 31 agosto 2014

Magento - rimozione della cartella per il negozio predefinito (pubblicazione di tutte le url sulla root)

Magento - Pubblicazione degli url sulla root per il negozio predefinito

Per varie ragioni principalmente legate alla SEO può essere necessario (o comunque preferibile) mettere tutti gli indirizzi del negozio predefinito sulla root del sito web anzichè su una sottocartella (tipicamente /it/ per i siti italiani).

Questo significa far gestire a Magento gli url senza aggiungere il codice negozio per avere gli url sulla root e poi forzarne il caricamento su sottocartelle create appositamente per i restanti codici negozio.

Disabilitiamo su Magento l'aggiunta del Codice del Negozio agli URLs

Innanzitutto disabilitiamo quindi l'aggiunta del codice negozio agli Url:



A questo punto tutti gli url saranno sulla root.

Creazione della cartella con il codice negozio per il negozio NON predefinito

Ora creiamo una cartella per ogni negozio NON PREDEFINITO, utilizzeremo il codice negozio per nominare la cartella. In ciascuna di queste cartelle copieremo i seguenti file dalla root di Magento:

* .htaccess
* index.php



In seguito vedremo quali modifiche vanno effettuate ai due file.

Impostazione dell'url per ogni negozio

Ora per ogni negozio dovremo specificare manualmente l'indirizzo del sito web.



Le differenze rispetto alle normali configurazioni è che:

* per URL di base inseriamo http://www.ilmiositoweb.it/en/ che è il percorso effettivo del sito web;
* per Skin URL di base andiamo ad inserire al posto della solita variabile {{unsecure_base_url}} l'indirizzo del sito web http://www.ilmiositoweb.it/skin. Lo stesso discorso vale per i campi Media URL di base e JavaScript URL di base;

Questo perchè ogni store deve utilizzare come root la cartella fisica corrispondente al codice negozio, ma deve prendere dalla root principale del sito  i CSS, le immagini e i JavaScript.

La stessa procedura vale per gli indirizzi sicuri, se utilizzate una sessione HTTPS.

MODIFICA DEL FILE index.php

Ora che abbiamo modificato detto a Magento di usare come root per ogni store NON PREDEFINITO le cartelle fisiche nominate come i codici negozio, dobbiamo modificare file .htaccess e index.php per far funzionare l'entry point principale del software.



a questo punto dobbiamo modificare l'entry point di Magento, il file index.php contenuto nella cartella /en/ appena creata, non quello sulla root.

Andiamo alla fine del file, qui troveremo il seguente codice:

/* Store or website code */
$mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : '';
/* Run store or run website */
$mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store';
Mage::run($mageRunCode, $mageRunType);

inseriremo quindi le seguenti variabili prima dell'ultima riga:
$mageRunCode="en";
$mageRunType="store";
Mage::run($mageRunCode, $mageRunType);
In questo modo le variabili $mageRunCode e $mageRunType anzichè essere impostate dinamicamente avranno sempre lo stesso valore a seconda della cartella dove si trovano.

Ora dobbiamo dire a Magento i percorsi giusti per le variabili:

* $compilerConfig
* $mageFilename

e indicare il percorso giusto per il file errors/503.php

Per fare questo, dato che sarà il file /en/index.php il nuovo entry point, avremo bisogno di modificare i percorsi dicendogli di salire di un livello e andare sulla root.

Modifica del file .htaccess



Alla riga 123 del file .htaccess (se non sono state effettuate altre modifiche al file) troveremo la riga
# RewriteBase /magento/
decommentiamola e inseriamo al posto di /magento/ il percorso della cartella su cui vogliamo inserire la root del sito web. in questo modo:
RewriteBase /en/
In questo modo varemo modificato correttamente il percorso dei negozio.

Ordine degli store

Sulle vecchie versioni di Magento (1.7 e precedenti) occorre indicare come store predefinito in SISTEMA -> GESTIONE NEGOZI-> NOME VISTA NEGOZIO l'ordine di caricamento del negozio. Nelle versioni più recenti (1.8 e successive) occorre inserire sempre in SISTEMA -> GESTIONE NEGOZI-> NOME VISTA NEGOZIO la vista negozio di default.

Localizzazione

Infine in SISTEMA -> CONFIGURAZIONE -> GENERALE non dimentichiamoci di impostare come lingua predefinita quella del negozio predefinito.


sabato 23 agosto 2014

Eliminazione delle immagini dal Database MySql e struttura EAV del database di Magento

Eliminazione delle immagini dal Database MySql di Magento

Su Magento può capitare di voler eliminare le immagini dei prodotti direttamente dal database. Per farlo occorre modificare i dati delle seguenti tabelle coinvolte sono:
  • catalog_product_entity_varchar
  • catalog_product_entity_media_gallery
  • catalog_product_entity_media_gallery_value

Le tabelle della galleria

Le seguenti tabelle:
  • catalog_product_entity_media_gallery
  • catalog_product_entity_media_gallery_value
contengono le immagini della galleria, per eliminare tutti i record è quindi sufficiente eseguire le seguenti query:
DELETE FROM catalog_product_entity_media_gallery_value
DELETE FROM catalog_product_entity_media_gallery
A causa delle Foreign Key un comando TRUNCATE non funzionerebbe.

Infine si possono eliminare le immagini dalla tabella:


  • catalog_product_entity_varchar

E' possibile utilizzare la seguente istruzione SQL:
DELETE FROM `catalog_product_entity_varchar` WHERE `attribute_id`=85 OR `attribute_id`=86 OR `attribute_id`=87
I valori 85 - 86 - 87 della clausola WHERE rappresentano i vari formati di immagine disponibili per il prodotto su Magento (image, thumb, small).

Osservazioni sulla struttura della tabella catalog_product_entity_varchar e sul database EAV di Magento 

Questa tabella contiene gli attributi di tipo VARCHAR dei prodotti inseriti. In Magento la maggior parte delle informazioni relative ai prodotti sono gestite come attributi. Quindi un'istruzione DELETE senza nessuna WHERE specificata come nel caso delle tabelle relative alla galleria delle immagini cancellerebbe, non solo i riferimenti ai file delle immagini dei prodotti ma anche altre informazioni.

I campi della tabella sono i seguenti:

* value_id, la chiave primaria della tabella
* entity_type_id, il tipo di entità, nel caso dei prodotti del catalogo il valore è sempre 4
* attribute_id, il tipo di attributo da cancellare
* store_id, l'id del negozio (sarà sempre 1 se non gestite un sito multilingua o un multistore)
* entity_id, l'id del recordprodotto
* value, il valore effettivamente inserito

Se volete verificare quali informazioni sono disponibili per un singolo prodotto (supponiamo quello con id 363) potete quindi eseguire la seguente query:
SELECT * FROM  `catalog_product_entity_varchar` WHERE  `entity_id` =363;
troverete tutti gli attributi assegnati a quel prodotto. Per conoscere a cosa corrisponde il valore dell'attribute_id, è sufficiente andare nel pannello di controllo su CATALOGO->ATTRIBUTI->GESTIONE ATTRIBUTI e  verificare il valore dell'attributo.

Se filtrerete i nomi degli attributi con i seguenti codici attributo:

* thumbnail
* image
* small_image

troverete appunto gli id 85, 86 e 87.

Per saperne di più sulla struttura EAV del database di Magento: