osCommerce : optimiser son site

En me plongeant dans le code d'osCommerce force a été de constater combien ce scipt était ancien ! Je passe sur l'ossature en tableaux, difficile à modifier. Je passe également sur les nombreux fichiers inclus, souvent avec une logique discutable*.
Je propose ici l'essentiel des modifications importantes (outre celle des titres de page) que j'ai souhaité réaliser.

(*) rien ne vaut une structure en 3 parties : header, body, footer où tous les fichiers nécessaires (dont header et footer) sont inclus dans body.

Répertoire des images produits, LightBox et vignettes

C'est ici crucial pour deux raisons : s'y retrouver dans le répertoire /images et pouvoir nettoyer les images obsolètes par lot. Par exemple avec l'add-on Remove unused images.

Il faut tout d'abord créer/modifier 2 constantes : DIR_WS_CATALOG_IMAGES et DIR_FS_CATALOG_IMAGES dans les fichiers configure.php

// ./include/configure.php
define('DIR_WS_CATALOG_IMAGES', DIR_WS_IMAGES . 'products/');
// ./admin/include/configure.php
define('DIR_FS_CATALOG_IMAGES', DIR_FS_CATALOG . 'images/products/');
define('DIR_WS_CATALOG_IMAGES', DIR_WS_CATALOG . 'images/products/');

et remplacer DIR_WS_IMAGES partout où c'est nécessaire, c'est à dire en cherchant cette occurrence 'products_image' avec les guillemets simples, afin de bypasser les champs de requête SQL.

// remplacer DIR_WS_IMAGES par DIR_WS_CATALOG_IMAGES
// exemple 1
tep_image(DIR_WS_CATALOG_IMAGES . $reviews['products_image'], $reviews['products_name'], SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT)
// exemple 2
<a href="<?=DIR_WS_IMAGES . $product_info['products_image']?>" target="_blank" title="<?=addslashes($product_info['products_name'])?>"><?=tep_image(DIR_WS_IMAGES . $product_info['products_image'], addslashes($product_info['products_name']), SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT, '')?></a>

Voici un exemple, qui montre également l'implémentation de lighbox (pop-up AJAX) et de la classe SimpleImage (implémentation des vignettes ou thumbnails) :

<html>
<head>
[...]
<!-- feuille de styles et javascript LightBox -->
<link rel="stylesheet" href="lightbox/lightbox.css" type="text/css" media="screen" />
<script type="text/javascript" src="lightbox/lightbox.js"></script>
</head>
[...]
<span class="vignette"><!-- style spécifique permettant de caler la vignette et le texte -->
	<!-- "_HR_" est le tag utilisé (au lieu de "Big") pour pop-up image grand format -->
	<a href="<?=DIR_WS_CATALOG_IMAGES . "_HR_" . $product_info['products_image']?>" target="_blank" rel="lightbox" title="<?=addslashes($product_info['products_name'])?>">
		<!-- sinon on affiche la vignette -->
		<?=tep_image(DIR_WS_CATALOG_IMAGES . $product_info['products_image'], addslashes($product_info['products_name']), SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT, '')?>
	</a>
	<br><?=TEXT_CLICK_TO_ENLARGE?>
</span>

La conjonction de ces 3 tweaks autorise :

Installer un WYSIWYG : CKeditor

Il manque cruellement à osCommerce un affichage What You See Is What You Get. A mon sens le meilleur est FCKeditor ou son pendant plus moderne (mais plus totalement gratuit) CKeditor. Il est très simple à mettre en place en 4 étapes :

1. télécharger l'add-on javascript sur la page CKeditor et décompacter le répertoire ckeditor/ à la racine du répertoire admin/ de votre boutique

2. admin/includes/functions/html_output.php : ajouter la fonction tep_draw_textarea_ckeditor

// function textarea avec CKEDITOR
// remplacements : $HTTP_GET_VARS par $_GET et $HTTP_POST_VARS par $_POST
function tep_draw_textarea_ckeditor($name, $wrap, $width, $height, $text = '', $parameters = '', $reinsert_value = true) {
    //global $HTTP_GET_VARS, $_POST;
    if ($width < 100) $width = 700;
    if ($height < 100) $height = 200;
    $field = '<textarea name="' . tep_output_string($name) . '" ';
    if (tep_not_null($parameters)) $field .= ' ' . $parameters;
    $field .= '>';
    if ( ($reinsert_value == true) && ( (isset($_GET[$name]) && is_string($_GET[$name])) || (isset($_POST[$name]) && is_string($_POST[$name])) ) ) {
      if (isset($_GET[$name]) && is_string($_GET[$name])) {
        $field .= tep_output_string_protected(stripslashes($_GET[$name]));
      } elseif (isset($_POST[$name]) && is_string($_POST[$name])) {
        $field .= tep_output_string_protected(stripslashes($_POST[$name]));
      }
    } elseif (tep_not_null($text)) {
      $field .= tep_output_string_protected($text);
    }
    $field .= '</textarea>';
        $field .=     '<script type="text/javascript">
        CKEDITOR.replace( \''.tep_output_string($name).'\',
    {
        resize_minWidth : 500 ,
        resize_maxWidth : 850 ,
        width : '.$width.',
        height : '.$height.'
    });
            </script>';
    return $field;
}

3. admin/categories.php : ajouter le code suivant entre les balises <head> et </head>

<?php 
// chargement CKEDITOR optionnel
if ($action == 'new_product' || $information_action == 'Added' || $information_action == 'Edit' )
    echo "<script type='text/javascript' src='ckeditor/ckeditor.js'></script>\n"; 
?>

4. admin/categories.php : modifier le champ d'édition de la description en recherchant tep_draw_textarea_field

<?php 
// chargement CKEDITOR optionnel selon le choix utilisateur
if ($action == 'new_product' || $information_action == 'Added' || $information_action == 'Edit' )
	echo tep_draw_textarea_ckeditor('products_description[' . $languages[$i]['id'] . ']', 'soft', '70', '15', (isset($products_description[$languages[$i]['id']]) ? str_replace('& ', '&amp; ', trim(stripslashes($products_description[$languages[$i]['id']]))) : tep_get_products_description($pInfo->products_id, $languages[$i]['id'])));
// sinon on charge le champ classique
else
	echo tep_draw_textarea_field('products_description[' . $languages[$i]['id'] . ']', 'soft', '70', '15', (isset($products_description[$languages[$i]['id']]) ? stripslashes($products_description[$languages[$i]['id']]) : tep_get_products_description($pInfo->products_id, $languages[$i]['id'])));
?>

Il reste ensuite à configurer l'éditeur lui-même (barre d'outils, etc.) en consultant la doc dédiée. Notez qu'il fonctionne très bien tel quel !
Concernant les éventuels trous de sécurité d'un éditeur WYSIWYG, il en existe régulièrement mais corrigés assez vite. Sachant que le répertoire admin/ est (doit être) protégé par le fichier .htaccess conjugué à un mot de passe complexe.

Limiter les accès base de données : who's on line et gestion de bannières

Outre les add-ons tels que Configuration Cache (indispensable et complémentaire), SimpleImage (génération de vignettes) et Ultimate SEO URLs 5 qui permettent, notamment, de ménager le serveur MySQL et gagner de la bande passante, voici une proposition ultra simple pour activer ou désactiver la fonction Who's on line qui ne me paraît pas cruciale. Tout d'abord on ajoute une entrée en bdd, qui va s'ajouter au groupe Ma boutique (groupe 1) de l'interface admin :

INSERT INTO `configuration` (`configuration_id`, `configuration_title`, `configuration_key`, `configuration_value`, `configuration_description`, `configuration_group_id`, `sort_order`, `last_modified`, `date_added`, `use_function`, `set_function`) 
VALUES ('', 'Qui est en ligne ?', 'WHOS_ONLINE', 'false', 'Activer le suivi des utilisateurs en ligne<br>Voir le menu Outils si actif', 1, 33, NULL, '2010-06-09 19:00:00', NULL, 'tep_cfg_select_option(array(''true'',''false''), ');

Ensuite on modifie includes/application_top.php en ajoutant simplement une condition :

// include the who's online functions
if(WHOS_ONLINE=='true') {
	require(DIR_WS_FUNCTIONS . 'whos_online.php');
	tep_update_whos_online();
}

Cerise sur le gâteau (option non essentielle) on modifie la boîte admin/includes/boxes/tools.php afin de ne pas proposer la visualisation des utilisateurs... qui ne sont plus en ligne virtuellement !

if ($selected_box == 'tools') {
	// commenter ou supprimer tout ce qu'il y a dans la condition et ajouter ceci
	$listeMenu = 
		'<a href="' . tep_href_link(FILENAME_BACKUP) . '" class="menuBoxContentLink">' . BOX_TOOLS_BACKUP . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_BANNER_MANAGER) . '" class="menuBoxContentLink">' . BOX_TOOLS_BANNER_MANAGER . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_CACHE) . '" class="menuBoxContentLink">' . BOX_TOOLS_CACHE . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_DEFINE_LANGUAGE) . '" class="menuBoxContentLink">' . BOX_TOOLS_DEFINE_LANGUAGE . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_FILE_MANAGER) . '" class="menuBoxContentLink">' . BOX_TOOLS_FILE_MANAGER . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_MAIL) . '" class="menuBoxContentLink">' . BOX_TOOLS_MAIL . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_NEWSLETTERS) . '" class="menuBoxContentLink">' . BOX_TOOLS_NEWSLETTER_MANAGER . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_SERVER_INFO) . '" class="menuBoxContentLink">' . BOX_TOOLS_SERVER_INFO . '</a>';
	// si la fonction est seulement activée on affiche qui est en ligne
	if(WHOS_ONLINE=='true')
		$listeMenu .= '<br><a href="' . tep_href_link(FILENAME_WHOS_ONLINE) . '" class="menuBoxContentLink">' . BOX_TOOLS_WHOS_ONLINE . '</a>';
	$contents[] = array('text' => $listeMenu);
	// fin de modification
}

L'économie représente 3 accès bdd à chaque chargement de page.

Afin d'en gagner 3 de plus (ce qui fait déjà 6 requêtes !) virons la gestion de bannières publicitaires. Au préalable, ajout d'une autres entrée en bdd, toujours au groupe Ma boutique de l'interface admin :

INSERT INTO `configuration` (`configuration_id`, `configuration_title`, `configuration_key`, `configuration_value`, `configuration_description`, `configuration_group_id`, `sort_order`, `last_modified`, `date_added`, `use_function`, `set_function`) 
VALUES ('', 'Gestion banni&egrave;re', 'BANNER_MANAGEMENT', 'false', 'Administration des banni&egrave;res publicitaires<br>Voir le menu Outils si actif', 1, 30, NULL, '2010-06-09 19:00:00', NULL, 'tep_cfg_select_option(array(''true'',''false''), ');

Puis on modifie includes/application_top.php en ajoutant la condition qui va bien

// auto activate and expire banners
if(BANNER_MANAGEMENT=='true') {
	require(DIR_WS_FUNCTIONS . 'banner.php');
	tep_activate_banners();
	tep_expire_banners();
}

On rend l'affichage doublement conditionnel dans includes/footer.php

<?php
if(BANNER_MANAGEMENT=='true' && $banner = tep_banner_exists('dynamic', '468x50')) {
	echo "<div id='banner'>\n";
	echo tep_display_banner('static', $banner);
	echo "</div>\n";
} 
?>

On note au passage la simplification par un conteneur géré en CSS. Et la touche finale pour la boîte admin/includes/boxes/tools.php

if ($selected_box == 'tools') {
	$listeMenu = 
		'<a href="' . tep_href_link(FILENAME_BACKUP) . '" class="menuBoxContentLink">' . BOX_TOOLS_BACKUP . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_CACHE) . '" class="menuBoxContentLink">' . BOX_TOOLS_CACHE . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_DEFINE_LANGUAGE) . '" class="menuBoxContentLink">' . BOX_TOOLS_DEFINE_LANGUAGE . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_FILE_MANAGER) . '" class="menuBoxContentLink">' . BOX_TOOLS_FILE_MANAGER . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_MAIL) . '" class="menuBoxContentLink">' . BOX_TOOLS_MAIL . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_NEWSLETTERS) . '" class="menuBoxContentLink">' . BOX_TOOLS_NEWSLETTER_MANAGER . '</a><br>' .
		'<a href="' . tep_href_link(FILENAME_SERVER_INFO) . '" class="menuBoxContentLink">' . BOX_TOOLS_SERVER_INFO . '</a>';
	// si la fonction est activée on gère les bannières
	if(BANNER_MANAGEMENT=='true')
		$listeMenu .= '<br><a href="' . tep_href_link(FILENAME_BANNER_MANAGER) . '" class="menuBoxContentLink">' . BOX_TOOLS_BANNER_MANAGER . '</a>';
	// si la fonction est activée on affiche qui est en ligne
	if(WHOS_ONLINE=='true')
		$listeMenu .= '<br><a href="' . tep_href_link(FILENAME_WHOS_ONLINE) . '" class="menuBoxContentLink">' . BOX_TOOLS_WHOS_ONLINE . '</a>';
	$contents[] = array('text' => $listeMenu);
	// fin de modification
}

Alléger le serveur SQL avec Faster Page Loads, Less DB queries

La contribution Configuration Cache (aka Faster Page Loads, Less DB queries) bien qu'indispensable, n'est pas conforme à la syntaxe PHP.

En effet elle ne sauvegarde pas les constantes correctement, c'est à dire entre guillemets (simples ou doubles).
Dans le fichier admin/includes/configuration_cache.php remplacer la ligne :

$config_cache_output .= 'define(' . $configuration['cfgKey'] . ',\'' . addslashes($configuration['cfgValue']) . '\'); ' . "\n";

par celle-ci :

$config_cache_output .= "define('".$configuration['cfgKey']."','". addslashes($configuration['cfgValue']) ."');\n";

http://dev.ppan.net [Haut de page]