Strumenti utili per i webmaster (pagerank, search engine position e altro...)

In rete è possibile trovare degli strumenti gratuiti utilissimi per chi gestisce un sito web.

La prima cosa che ormai un webmaster fa quando vuole effettuare un'analisi di un sito è controllare il pagerank. Su internet si trovano tantissimi siti che offrono gratuitamente tale servizio, tanto per nominarne qualcuno:
- http://www.prchecker.info/check_page_rank.php

- http://www.sito.me/ che riporta anche i backlinks ed una valutazione (molto ottimistica) del sito in termini di valore monetario.

Ormai il calcolo del pagerank è diventato quasi un'ossesione per la maggior parte dei webmaster è per questo che vi segnalo un utilissimo sito che vi permette di tracciare il pagerank, quindi la sua storia, dei vostri siti e vi invia un'email di avviso quando avviene una modifica allo stesso. Il sito è http://pagerankalert.com/. Tramite una registrazione semplice è possibile inserire l'elenco dei propri URL e immediatamente avremo una panoramica dei loro pagerank e saremo sicuri che ogni modifica ci verrà prontamente segnalata.

Un altro utilissimo tool è disponibile all'indirizzo http://www.iwebtool.com/search_engine_position e vi permetterà di verificare la posizione del vostro sito su google data una determinata parola utilizzata nella ricerca. Un'altro sito con la stessa funzionalità è http://www.marketleap.com/verify/default.htm.
Buona analisi! Continua a leggere...

L'architettura di Opencart: Model View Controller (MVC)


Nell'articolo precedente ho illustrato una nuova funzionalità di Opencart da me implementata, ma non avevo ancora spiegato l'archiettura di questo software e-commerce.

Gli sviluppatori di tale applicativo hanno utilizzato per la sua implementazione la metodologia del Model View Controller (MVC), basata sulla suddivisione dei componenti in 3 ruoli principali:

1) il model, fornisce i metodi per accedere ai dati (si interfaccia direttamente con il Database);
2) il controller, accede ai dati forniti dal model e li rende disponibili al view (contiene la parte "funzionale" del codice);
3) il view visualizza i dati forniti dal controller e si occupa dell'interazione con l'utente (attraverso il controller).

Questo schema permette di separare la logica applicativa/funzionale, a carico del controller e del model, dall'interfaccia utente a carico del view.

Nel caso pratico di Opencart ognuna delle 3 componenti sopra descritte è contenuta dentro un'omonima cartella ed inoltre viene separata la parte del negozio (catalog) dalla parte di amministrazione (admin). Quindi riassumendo la struttura delle cartelle di Opencart è così composta:

-> catalog
-> model
-> view
-> controller

-> admin
-> model
-> view
-> controller
Prendendo come esempio pratico la funzionalità di alert descritta nell'articolo precendente, la componente model è definita nel file catalog\model\catalog\alert.php e contiene le funzioni necessarie per l'accesso ai dati contenuti nel Database. Il componente controller, catalog\controller\product\alert.php, richiama il model tramite la riga $this->load->model('catalog/alert') e ne utilizza le funzioni per rendere disponibili le informazioni al view, implementato nel file catalog\view\theme\default\template\product\alert.tpl. Quest'ultimo file è l'interfaccia con l'utente ed è quindi un misto di codice html e php.
In modo analogo è stata implementata la parte di amministrazione (dentro la cartella admin) che non necessitava però di una componente view essendo una funzionalità di back-end.

Continua a leggere...

Realizzazione di un sito web di ecommerce

Dovendo realizzare un sito di e-commerce ho iniziato effettuando uno scouting nella rete alla ricerca di un software free, scritto in php, che risultasse semplice da customizzare. Cercando tra i tantissimi script in php, mi sono soffermato su due in particolare: Magento (http://www.magentocommerce.com/it/) e Opencart (http://www.opencart.com/ e http://www.opencart.it).
Li ho installati entrambi in localhost per testarne le funzionalità e capirne la struttura con la quale sono stati sviluppati in modo da comprendere come poter effettuare delle modifiche al codice esistente.

Le mie conclusioni sono le seguenti:
- Magento è sicuramente molto più completo e ricco di funzionalità, ma proprio per questo mi è sembrato più lento nel caricamento e più complicato da modificare a proprio piacimento.
- Opencart si contraddistingue per la semplicità, possiede le funzionalità di base per un sito di ecommerce e, dopo un breve studio sul codice, non è stato difficile adeguarlo alle mie esigenze e scrivere codice aggiuntivo per nuove funzionalità.
In base a quanto detto ho deciso di usare Opencart per il sito di ecommerce che sto sviluppando, se volete vedere il risultato ad oggi (è ancora in fase di completamento) potete andare qui: http://www.biocosmetica.it

Di Opencart ho utilizzato la versione 1.2.8, ma da pochi giorni è già uscita la versione 1.2.9. A breve cercherò di utilizzare questa nuove versione.

Una funzionalità da me implementa per la versione 1.2.8 di Opencart, che voglio condividere con voi è la possibilità per il cliente di ricevere un'email di avviso se un prodotto che gli interessa è stato riassortito. Mi spiego meglio: se un prodotto non è disponibile, invece del pulsante "Aggiungi al carrello" comparirà "Avvisami quando sarà disponibile!". Tramite tale funzionalità il cliente ha quindi la possibilità di inserire la sua email per ricevere l'avviso di avvenuto riassortimento. Queste email di avviso vengono inviate automaticamente quando dal pannello di controllo la quantità del prodotto diventa maggiore di zero. Per vedere un esempio di quanto implementato (almeno per la parte utente) potete vederlo sul sito http://www.biocosmetica.it

Per introdurre la funzionalità sopra descritta nel vostro sito Opencart (lo script l'ho sviluppato per la versione 1.2.8, ma ho già notato che con qualche piccola modifica funzionerebbe anche sulla nuova versione 1.2.9) occorre eseguire i seguenti passi:

1) creazione della tabella product_alert

Tale tabella permette di memorizzare le informazioni sull'associazione prodotto/email e gli invii correlati.
Ecco l'sql da eseguire per la creazione della tabella:
CREATE TABLE `product_alert` ( `id` int(10) unsigned NOT NULL auto_increment, `product_id` int(11) unsigned NOT NULL, `email` varchar(100) collate utf8_unicode_ci NOT NULL, `date_add` datetime NOT NULL default '0000-00-00 00:00:00', `date_send` datetime NOT NULL default '0000-00-00 00:00:00', `status` int(1) unsigned NOT NULL, PRIMARY KEY USING BTREE (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC;

2) modificare i seguenti file

a) catalog\language\italian\italian.php (o catalog\language\english\english.php se avete la versione solo in inglese)
Inserire alla fine del file ( ovviamente prima del ?> ) la seguente riga:
$_['button_avvisami'] = 'Avvisami quando sarà disponibile!';

b) admin\controller\catalog\product.php
Tale file va modificato per inserire l'invio automatico delle email quando viene modificata la quantità disponibile del prodotto.
Dopo la riga $this->load->model('catalog/product'); inserire la seguente:
$this->load->model('catalog/alert');
Dopo la riga $this->model_catalog_product->editProduct($this->request->get['product_id'], $this->request->post); inserire le seguenti:
if($this->request->post['quantity']>0){
$alerts = $this->model_catalog_alert->getProductAlerts($this->request->get['product_id']);
$prod_desc = $this->model_catalog_alert->getProductDesc($this->request->get['product_id']);
foreach ($alerts as $alert){

$subject = sprintf($this->language->get('mail_subject'), $prod_desc['name']);
$message = $this->language->get('mail_line_1') . "\n\n";
$message .= sprintf($this->language->get('mail_line_2'), $prod_desc['name']) . "\n";
$message .= $this->language->get('mail_url') . $this->request->get['product_id'] . "\n\n";
$message .= $this->language->get('mail_line_3') . "\n\n";
$message .= $this->config->get('config_store');

$mail = new Mail();
$mail->setTo($alert['email']);
$mail->setFrom($this->config->get('config_email'));
$mail->setSender($this->config->get('config_store'));
$mail->setSubject($subject);
$mail->setText($message);
$mail->send();

$this->model_catalog_alert->updateProductAlert($this->request->get['product_id'],$alert['email']);
}
}
c) admin\language\italian\catalog\product.php (anche qui al posto di italian -> english se avete la versione solo inglese)
Inserite alla fine del file le seguenti righe (modificate la variabile mail_url inserendo l'url del vostro sito):
// Mail
$_['mail_subject'] = '%s - E\' ora disponibile!';
$_['mail_line_1'] = 'Grazie per la tua pazienza.';
$_['mail_line_2'] = 'Il prodotto %s e\' ora disponibile e puo\' essere acquistato al seguente indirizzo: ';
$_['mail_line_3'] = 'Questa e\' un avviso unico, non riceverai nuovamente questa e-mail.';
$_['mail_url'] = 'http://www.biocosmetica.it/index.php?route=product/product&product_id=';
d) catalog\controller\product\product.php
Dopo la riga $this->data['button_add_to_cart'] = $this->language->get('button_add_to_cart'); inserire la seguente riga:
$this->data['button_avvisami'] = $this->language->get('button_avvisami');
Dopo la riga $this->data['stock'] = ($product_info['quantity'] > 0)? $this->language->get('text_instock') : $product_info['stock']; inserire la seguente:
$this->data['quantity']=$product_info['quantity'];
e) catalog\view\theme\default\template\product\product.tpl
Occorre sostituire il seguente codice:
<?php echo $text_qty; ?>
<input type="text" name="quantity" size="3" value="1" />
<a onclick="$('#product').submit();" id="add_to_cart" class="button"><span><?php echo $button_add_to_cart; ?></span></a></div>


Con il seguente:

<?php if($quantity>0){ ?>
<?php echo $text_qty; ?>
<input type="text" name="quantity" size="3" value="1" />
<a onclick="$('#product').submit();" id="add_to_cart" class="button"><span><?php echo $button_add_to_cart; ?></span></a>
<?php } else { ?>
<a href="index.php?route=product/alert&product_id=<?php echo $product_id; ?>" id="alert" class="button"><span><?php echo $button_avvisami; ?></span></a>
<?php } ?>
</div>

f) catalog\model\catalog\product.php
Inserire alla fine del file, prima delle righe di chiusura } ?> la seguente funzione:
public function addProductAlert($product_id, $data) {
$this->db->query("INSERT INTO product_alert SET email = '" . $this->db->escape($data['email']) . "', product_id = '" . (int)$product_id . "', date_added = NOW()");
}

3) creare i seguenti nuovi file

a) admin\model\catalog\alert.php
<?php
class ModelCatalogAlert extends Model {
public function getProductAlerts($product_id) {
$query = $this->db->query("SELECT DISTINCT email FROM product_alert WHERE product_id = '" . (int)$product_id . "' and status = 0");

return $query->rows;
}

public function updateProductAlert($product_id, $email) {
$this->db->query("UPDATE product_alert SET date_send = NOW(), status = 1 WHERE product_id = '" . (int)$product_id . "' and email = '" .$email . "'");

}

public function getProductDesc($product_id) {
$query = $this->db->query("SELECT DISTINCT name FROM product_description WHERE product_id = '" . (int)$product_id . "'");

return $query->row;
}
}
?>

b) catalog\controller\product\alert.php

<?php
class ControllerProductAlert extends Controller {
private $error = array();

public function index() {
$this->load->language('product/alert');
$this->load->model('catalog/alert');

$this->document->title = $this->language->get('heading_title');

if (($this->request->server['REQUEST_METHOD'] == 'POST') && ($this->validate())) {
$this->model_catalog_alert->addProductAlert($this->request->post['product_id'], $this->request->post);
$this->redirect($this->url->https('product/alert/success'));
}

$this->document->breadcrumbs = array();

$this->document->breadcrumbs[] = array(
'href' => $this->url->http('common/home'),
'text' => $this->language->get('text_home'),
'separator' => FALSE
);

$this->document->breadcrumbs[] = array(
'href' => $this->url->http('product/alert'),
'text' => $this->language->get('heading_title'),
'separator' => $this->language->get('text_separator')
);

$this->data['heading_title'] = $this->language->get('heading_title');

$this->data['entry_email'] = $this->language->get('entry_email');

$this->data['entry_verification'] = $this->language->get('entry_verification');

$this->data['error_email'] = @$this->error['email'];

$this->data['error_verification'] = @$this->error['verification'];

$this->data['error_presente'] = @$this->error['presente'];

$this->data['button_continue'] = $this->language->get('button_continue');

$this->data['action'] = $this->url->http('product/alert');
$this->data['store'] = $this->config->get('config_store');
$this->data['email'] = @$this->request->post['email'];
$this->data['verification'] = @$this->request->post['verification'];

$this->id = 'content';
$this->template = $this->config->get('config_template') . 'product/alert.tpl';
$this->layout = 'common/layout';

$this->render();
}

public function success() {
$this->load->language('product/alert');

$this->document->title = $this->language->get('heading_title');

$this->document->breadcrumbs = array();

$this->document->breadcrumbs[] = array(
'href' => $this->url->http('common/home'),
'text' => $this->language->get('text_home'),
'separator' => FALSE
);

$this->document->breadcrumbs[] = array(
'href' => $this->url->http('product/alert'),
'text' => $this->language->get('heading_title'),
'separator' => $this->language->get('text_separator')
);

$this->data['heading_title'] = $this->language->get('heading_title');

$this->data['text_message'] = $this->language->get('text_message');

$this->data['button_continue'] = $this->language->get('button_continue');

$this->data['continue'] = $this->url->http('common/home');

$this->id = 'content';
$this->template = $this->config->get('config_template') . 'common/success.tpl';
$this->layout = 'common/layout';

$this->render();
}

public function verification() {
$this->load->library('verification');

$verification = new Verification();

$this->session->data['verification'] = $verification->getCode();

$verification->showImage();
}

private function validate() {

if (!eregi('^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,3})$', $this->request->post['email'])) {
$this->error['email'] = $this->language->get('error_email');
}

if (@$this->session->data['verification'] != $this->request->post['verification']) {
$this->error['verification'] = $this->language->get('error_verification');
}

@$presente = $this->model_catalog_alert->checkProductAlert($this->request->post['product_id'], $this->request->post);
if($presente>0){
$this->error['presente'] = $this->language->get('error_presente');
}

if (!$this->error) {
return TRUE;
} else {
return FALSE;
}
}
}
?>


c) catalog\model\catalog\alert.php

<?php
class ModelCatalogAlert extends Model {

public function addProductAlert($product_id, $data) {
$this->db->query("INSERT INTO product_alert SET email = '" . $this->db->escape($data['email']) . "', product_id = '" . (int)$product_id . "', date_add = NOW(), status = 0");
}

public function checkProductAlert($product_id, $data) {
$query = $this->db->query("select count(*) as total from product_alert where email = '" . $this->db->escape($data['email']) . "' and product_id = '" . (int)$product_id . "' and status = 0");
return $query->row['total'];
}
}
?>


d) catalog\view\theme\default\template\product\alert.tpl



<div class="top">
<h1><?php echo $heading_title; ?></h1>
</div>
<div class="middle">
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="alert">
<input type="hidden" name="product_id" value="<?php echo $this->request->get['product_id']; ?>" />
<div style="background: #F7F7F7; border: 1px solid #DDDDDD; padding: 10px; margin-bottom: 10px;">
<?php echo $entry_email; ?><br />
<input type="text" name="email" value="<?php echo $email; ?>" />
<br />
<?php if ($error_email) { ?>
<span class="error"><?php echo $error_email; ?></span>
<?php } ?>
<br />
<?php if ($error_presente) { ?>
<span class="error"><?php echo $error_presente; ?></span>
<?php } ?>
<br />
<?php echo $entry_verification; ?><br />
<input type="text" name="verification" value="<?php echo $verification; ?>" />
<br />
<?php if ($error_verification) { ?>
<span class="error"><?php echo $error_verification; ?></span>
<?php } ?>
<img src="index.php?route=product/alert/verification" /></div>
<div class="buttons">
<table>
<tr>
<td align="right"><a onclick="$('#alert').submit();" class="button"><span><?php echo $button_continue; ?></span></a></td>
</tr>
</table>
</div>
</form>
</div>
<div class="bottom">&nbsp;</div>

e) catalog\language\italian\product\alert.php
<?php
// Heading
$_['heading_title'] = 'Avvisami';

// Text
$_['text_message'] = '<p>Grazie per l'attesa! <br><br>Ti faremo sapere non appena il prodotto sar&agrave; di nuovo disponibile.</p>';

// Entry Fields
$_['entry_email'] = 'Indirizzo E-Mail:';
$_['entry_verification'] = 'Scrivi il codice che leggi nell'immagine qui sotto:';

// Errors
$_['error_email'] = 'L'indirizzo E-Mail non &egrave; un indirizzo valido!';
$_['error_verification'] = 'Il codice di verifica inserito non &egrave; corretto!';
$_['error_presente'] = 'Sei gi&agrave; in lista di notifica per questo prodotto.'
?>

Fatemi sapere se riscontrate errori o semplicemente per dare il vostro contributo. Continua a leggere...

Benvenuti nel mio blog!

Intanto mi presento: sono una persona che ha come hobby la realizzazione "completa" di siti web; in particolare, mi occupo sia della parte grafica sia la parte funzionale/applicativa, quindi della programmazione (php, javascript e qualunque linguaggio utile allo scopo).
Ho creato questo blog al fine di poter discutere con voi di questi temi e per poter condividere insieme a voi alcuni dei lavori svolti. Mi piacerebbe che voi foste parte attiva del blog quindi scrivetemi pure i vostri pareri. BENVENUTI!
Continua a leggere...