<?php
if (!defined('_PS_VERSION_')) {
exit;
}

class OffreSpecialeBadge extends Module
{
const BADGE_TYPES = array('BF10', 'BF20', 'BF30');

public function __construct()
{
$this->name = 'offrespecialebadge';
$this->tab = 'front_office_features';
$this->version = '1.0.1';
$this->author = 'Greg';
$this->need_instance = 0;

parent::__construct();

$this->displayName = $this->l('Offre Spéciale Badge');
$this->description = $this->l('Ajoute des badges d\'offre spéciale (BF10, BF20, BF30) sur des produits spécifiques');
}

public function install()
{
// Créer la table
$sql = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'offre_speciale_products` (
`id_product` int(11) NOT NULL,
`badge_type` varchar(10) NOT NULL,
`date_add` datetime NOT NULL,
PRIMARY KEY (`id_product`),
KEY `badge_type` (`badge_type`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;';

return parent::install()
&& Db::getInstance()->execute($sql)
&& $this->registerHook('displayProductListReviews')
&& $this->registerHook('displayProductAdditionalInfo')
&& $this->registerHook('header')
&& $this->registerHook('displayAfterBodyOpeningTag')
&& $this->registerHook('actionOutputHTMLBefore');
}

public function uninstall()
{
// Supprimer la table
$sql = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'offre_speciale_products`';

return parent::uninstall()
&& Db::getInstance()->execute($sql);
}

public function hookHeader()
{
// Ajouter le CSS
$this->context->controller->addCSS($this->_path . 'views/css/offrespeciale.css');

// Ajouter le JavaScript pour gérer les shortcodes côté client
$this->context->controller->addJS($this->_path . 'views/js/offrespeciale.js');

// Récupérer TOUS les badges pour injection en JavaScript
$allBadges = $this->getAllBadgesForJS();

// Injecter les données des badges en JavaScript
$idProduct = 0;
if (isset($this->context->controller->php_self) && $this->context->controller->php_self == 'product') {
$idProduct = (int)Tools::getValue('id_product');
}

$badgeData = $this->getBadgeForProduct($idProduct);

Media::addJsDef(array(
'offreSpecialeBadgeData' => array(
'currentProductId' => $idProduct,
'currentBadge' => $badgeData,
'allBadges' => $allBadges,
'ajaxUrl' => $this->context->link->getModuleLink('offrespecialebadge', 'ajax', array(), true)
)
));
}

/**
* Récupère tous les badges pour injection JavaScript
*/
private function getAllBadgesForJS()
{
$badges = Db::getInstance()->executeS('
SELECT id_product, badge_type
FROM `' . _DB_PREFIX_ . 'offre_speciale_products`
');

$badgesArray = array();
if ($badges) {
foreach ($badges as $badge) {
$badgesArray[$badge['id_product']] = $badge['badge_type'];
}
}

return $badgesArray;
}

/**
* Hook pour remplacer les shortcodes dans le HTML avant affichage
*/
public function hookActionOutputHTMLBefore($params)
{
if (isset($params['html'])) {
$params['html'] = $this->processShortcodes($params['html']);
}
}

/**
* Traite les shortcodes dans le contenu HTML
*/
private function processShortcodes($html)
{
// Pattern pour {offre_badge} ou {offre_badge id=123}
$pattern = '/\{offre_badge(?:\s+id=(\d+))?\}/';

$html = preg_replace_callback($pattern, function($matches) {
$idProduct = isset($matches[1]) ? (int)$matches[1] : 0;

// Si pas d'ID fourni, essayer de récupérer le produit actuel
if (!$idProduct && isset($this->context->controller->php_self) && $this->context->controller->php_self == 'product') {
$idProduct = (int)Tools::getValue('id_product');
}

if ($idProduct) {
return $this->displayBadge($idProduct);
}

return '<span class="offre-badge-placeholder" data-product-id="current"></span>';
}, $html);

return $html;
}

private function getBadgeForProduct($productId)
{
if (!$productId) {
return null;
}

$badge = Db::getInstance()->getRow('
SELECT badge_type
FROM `' . _DB_PREFIX_ . 'offre_speciale_products`
WHERE id_product = ' . (int)$productId
);

return $badge ? $badge['badge_type'] : null;
}

public function getContent()
{
$output = '';

// Traitement de l'ajout de produits
if (Tools::isSubmit('submitOffreSpecialeProducts')) {
$badgeType = Tools::getValue('BADGE_TYPE');
$products = Tools::getValue('OFFRE_PRODUCTS');

if (!in_array($badgeType, self::BADGE_TYPES)) {
$output .= $this->displayError($this->l('Type de badge invalide'));
} else {
$result = $this->addProducts($products, $badgeType);

if ($result['success']) {
$output .= $this->displayConfirmation(
sprintf($this->l('%d produit(s) ajouté(s) avec le badge %s'), $result['added'], $badgeType)
);
}
if ($result['errors'] > 0) {
$output .= $this->displayWarning(
sprintf($this->l('%d produit(s) déjà présent(s) ou invalide(s)'), $result['errors'])
);
}
}
}

// Traitement de la suppression d'un badge spécifique
if (Tools::isSubmit('submitClearBadge')) {
$badgeType = Tools::getValue('clear_badge_type');
if ($this->clearBadgeProducts($badgeType)) {
$output .= $this->displayConfirmation(
sprintf($this->l('Tous les produits du badge %s ont été supprimés'), $badgeType)
);
}
}

// Traitement de la suppression totale
if (Tools::isSubmit('submitClearAll')) {
if ($this->clearAllProducts()) {
$output .= $this->displayConfirmation($this->l('Tous les produits ont été supprimés'));
}
}

// Traitement de la suppression d'un produit spécifique
if (Tools::isSubmit('deleteProduct')) {
$idProduct = (int)Tools::getValue('id_product');
if ($this->removeProduct($idProduct)) {
$output .= $this->displayConfirmation($this->l('Produit supprimé'));
}
}

return $output . $this->displayShortcodeInfo() . $this->displayForm() . $this->displayCurrentProducts();
}

public function displayShortcodeInfo()
{
$html = '<div class="alert alert-info">
<h4><i class="icon-code"></i> ' . $this->l('Utilisation des shortcodes dans Creative Elements') . '</h4>
<p><strong>' . $this->l('Pour afficher le badge d\'un produit spécifique :') . '</strong></p>
<code>{offre_badge id=5139}</code>
<p style="margin-top: 10px;"><strong>' . $this->l('Pour afficher le badge du produit actuel (page produit) :') . '</strong></p>
<code>{offre_badge}</code>
<p style="margin-top: 10px;"><strong>' . $this->l('Alternative avec balise HTML (fonctionne partout) :') . '</strong></p>
<code>&lt;span class="offre-badge-shortcode" data-product-id="5139"&gt;&lt;/span&gt;</code>
<p style="margin-top: 5px;"><em>' . $this->l('Pour le produit actuel :') . '</em></p>
<code>&lt;span class="offre-badge-shortcode" data-product-id="current"&gt;&lt;/span&gt;</code>
</div>';

return $html;
}

public function displayForm()
{
$badgeOptions = array();
foreach (self::BADGE_TYPES as $badge) {
$badgeOptions[] = array(
'id' => $badge,
'name' => $badge
);
}

$fields_form = array(
'form' => array(
'legend' => array(
'title' => $this->l('Ajouter des produits avec badge'),
'icon' => 'icon-tag'
),
'input' => array(
array(
'type' => 'select',
'label' => $this->l('Type de badge'),
'name' => 'BADGE_TYPE',
'required' => true,
'options' => array(
'query' => $badgeOptions,
'id' => 'id',
'name' => 'name'
)
),
array(
'type' => 'textarea',
'label' => $this->l('IDs des produits'),
'desc' => $this->l('Entrez les IDs séparés par des virgules, espaces ou retours à la ligne (ex: 1, 5, 12, 45)'),
'name' => 'OFFRE_PRODUCTS',
'rows' => 5,
'cols' => 60,
'required' => true,
),
),
'submit' => array(
'title' => $this->l('Ajouter les produits'),
'class' => 'btn btn-default pull-right',
'icon' => 'process-icon-plus'
),
'buttons' => array(
array(
'href' => AdminController::$currentIndex . '&configure=' . $this->name . '&submitClearAll=1&token=' . Tools::getAdminTokenLite('AdminModules'),
'title' => $this->l('Tout supprimer'),
'icon' => 'process-icon-eraser',
'class' => 'btn btn-danger',
'js' => 'return confirm(\'' . $this->l('Êtes-vous sûr de vouloir supprimer tous les produits ?') . '\');'
)
)
),
);

$helper = new HelperForm();
$helper->module = $this;
$helper->name_controller = $this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name;
$helper->submit_action = 'submitOffreSpecialeProducts';

return $helper->generateForm(array($fields_form));
}

public function displayCurrentProducts()
{
$html = '';

foreach (self::BADGE_TYPES as $badgeType) {
$products = $this->getProductsByBadge($badgeType);

$html .= '<div class="panel">
<div class="panel-heading">
<i class="icon-tag"></i> ' . sprintf($this->l('Produits avec badge %s'), $badgeType) . ' (' . count($products) . ')
<span class="panel-heading-action">
<a href="' . AdminController::$currentIndex . '&configure=' . $this->name
. '&submitClearBadge=1&clear_badge_type=' . $badgeType
. '&token=' . Tools::getAdminTokenLite('AdminModules') . '"
class="btn btn-default btn-sm"
onclick="return confirm(\'' . sprintf($this->l('Supprimer tous les produits du badge %s ?'), $badgeType) . '\');">
<i class="icon-eraser"></i> ' . $this->l('Vider ce badge') . '
</a>
</span>
</div>';

if (empty($products)) {
$html .= '<div class="alert alert-info" style="margin: 10px;">'
. sprintf($this->l('Aucun produit avec le badge %s'), $badgeType)
. '</div>';
} else {
$html .= '<table class="table"><thead><tr>
<th>ID</th>
<th>' . $this->l('Nom du produit') . '</th>
<th>' . $this->l('Référence') . '</th>
<th>' . $this->l('Date d\'ajout') . '</th>
<th>' . $this->l('Actions') . '</th>
</tr></thead><tbody>';

foreach ($products as $product) {
$productObj = new Product($product['id_product'], false, $this->context->language->id);
$html .= '<tr>
<td>' . (int)$product['id_product'] . '</td>
<td>' . ($productObj->name ?: $this->l('Produit introuvable')) . '</td>
<td>' . $productObj->reference . '</td>
<td>' . $product['date_add'] . '</td>
<td>
<a href="' . AdminController::$currentIndex . '&configure=' . $this->name
. '&deleteProduct=1&id_product=' . (int)$product['id_product']
. '&token=' . Tools::getAdminTokenLite('AdminModules') . '"
class="btn btn-default btn-sm" onclick="return confirm(\'' . $this->l('Supprimer ce produit ?') . '\');">
<i class="icon-trash"></i>
</a>
</td>
</tr>';
}

$html .= '</tbody></table>';
}

$html .= '</div>';
}

return $html;
}

private function addProducts($productsString, $badgeType)
{
// Nettoyer et extraire les IDs
$productsString = preg_replace('/[^0-9,\s\n\r]/', '', $productsString);
$productIds = preg_split('/[\s,\n\r]+/', $productsString, -1, PREG_SPLIT_NO_EMPTY);
$productIds = array_unique(array_map('intval', $productIds));

$added = 0;
$errors = 0;

foreach ($productIds as $idProduct) {
if ($idProduct <= 0) {
$errors++;
continue;
}

// Vérifier si le produit existe
if (!Product::existsInDatabase($idProduct, 'product')) {
$errors++;
continue;
}

// Supprimer l'ancien badge si existant
Db::getInstance()->delete('offre_speciale_products', 'id_product = ' . (int)$idProduct);

// Insérer le nouveau
$result = Db::getInstance()->insert('offre_speciale_products', array(
'id_product' => (int)$idProduct,
'badge_type' => pSQL($badgeType),
'date_add' => date('Y-m-d H:i:s')
));

if ($result) {
$added++;
} else {
$errors++;
}
}

return array('success' => $added > 0, 'added' => $added, 'errors' => $errors);
}

private function clearAllProducts()
{
return Db::getInstance()->execute('TRUNCATE TABLE `' . _DB_PREFIX_ . 'offre_speciale_products`');
}

private function clearBadgeProducts($badgeType)
{
return Db::getInstance()->delete('offre_speciale_products', 'badge_type = "' . pSQL($badgeType) . '"');
}

private function removeProduct($idProduct)
{
return Db::getInstance()->delete('offre_speciale_products', 'id_product = ' . (int)$idProduct);
}

private function getProductsByBadge($badgeType)
{
return Db::getInstance()->executeS('
SELECT id_product, badge_type, date_add
FROM `' . _DB_PREFIX_ . 'offre_speciale_products`
WHERE badge_type = "' . pSQL($badgeType) . '"
ORDER BY date_add DESC
');
}

public function hookDisplayProductListReviews($params)
{
if (!isset($params['product']['id_product'])) {
return;
}

return $this->displayBadge($params['product']['id_product']);
}

public function hookDisplayProductAdditionalInfo($params)
{
if (!isset($params['product']['id_product'])) {
return;
}

return $this->displayBadge($params['product']['id_product']);
}

public function displayBadge($productId)
{
$badge = Db::getInstance()->getRow('
SELECT badge_type
FROM `' . _DB_PREFIX_ . 'offre_speciale_products`
WHERE id_product = ' . (int)$productId
);

if ($badge && isset($badge['badge_type'])) {
$badgeType = $badge['badge_type'];
$badgeClass = 'badge-offre-' . strtolower($badgeType);

return '<span class="badge-offre-speciale ' . $badgeClass . '">' . $badgeType . '</span>';
}

return '';
}
}

Team GlissEvolution – Experts Sports Nautiques

Sélection du Team

Il y a 1 produit.

Les News du Blog Glissevolution

L’Équipe GlissEvolution – Expertise & Passion des Sports de Glisse

Une Team 100 % Glisse à Votre Service

Chez GlissEvolution, chaque membre de notre équipe incarne la passion des sports nautiques.
Grâce à leurs expériences variées, ils vous conseillent dans le choix du meilleur matériel et partagent avec vous leur amour du kitesurf, surf, wingfoil, SUP et wakeboard.

Découvrez les profils de notre team et leurs sélections de matériel testées et approuvées.

Greg Nicholls – Fondateur & Visionnaire

  • Un parcours inspirant : passionné depuis son enfance, Greg fonde GlissEvolution en 2005.

  • Expert en kitesurf, wakeboard et wingfoil, il combine innovation et expérience.

  • La sélection de Greg : ailes de kite performantes pour vagues creuses, foils pour vent léger, matériel haut de gamme pour riders exigeants.

Adrien Dahan – Responsable Commercial & Ambassadeur Client

  • Un passionné accessible : originaire de Nantes, Adrien pratique le kitesurf, surf strapless et wingfoil.

  • Depuis 2018, il assure le quotidien du shop et la satisfaction client.

  • La sélection d’Adrien : harnais ergonomiques, ailes de wingfoil polyvalentes, planches adaptées à tous niveaux.

François Pelhuche – Expert Kitesurf & Sports de Glisse

  • Une passion dévorante : découvre le kitesurf en 2008 et en fait sa vocation.

  • Spécialiste wakeboard, kite & wingfoil, il est un conseiller de référence.

  • La sélection de François : barres de kite sécurisées, wakeboards performants, accessoires sans compromis.

Pourquoi Suivre la Sélection de la Team GlissEvolution ?

  • Expertise passionnée : chaque membre teste et approuve le matériel.

  • Choix réfléchi : uniquement des équipements fiables et performants.

  • Expérience unique : conseils personnalisés pour des sessions réussies.

Venez rencontrer l’équipe en boutique à Pornichet ou explorez leur sélection en ligne.

Nos Marques Partenaires

Nous travaillons avec les meilleures marques mondiales pour garantir performance et fiabilité :
Duotone Kiteboarding, Eleveight Kites, HB Surfkite, Slingshot, North Kiteboarding, Sabfoil-Moses, ENSIS, Signature, AK Foil, Airush, Ozone, Mystic, Prolimit, Billabong, et bien d’autres.

Rejoignez l’Aventure GlissEvolution

Avec la team GlissEvolution, vivez votre passion à fond grâce à des équipements premium, des conseils experts et un service irréprochable.


Toutes nos marques
 
École de kitesurf et de wingfoil

Plus d'infos sur l'école