This commit is contained in:
2025-04-01 00:38:54 +02:00
parent d4d4c0c09d
commit 87da06293a
22351 changed files with 5168854 additions and 7538 deletions

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>ybc_specificprices</name>
<displayName><![CDATA[Hot deals]]></displayName>
<version><![CDATA[1.0.1]]></version>
<description><![CDATA[Display specific discounted products on home page]]></description>
<author><![CDATA[YBC-Theme]]></author>
<tab><![CDATA[front_office_features]]></tab>
<is_configurable>1</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>ybc_specificprices</name>
<displayName><![CDATA[Hot deals]]></displayName>
<version><![CDATA[1.0.1]]></version>
<description><![CDATA[Display specific discounted products on home page]]></description>
<author><![CDATA[YBC-Theme]]></author>
<tab><![CDATA[front_office_features]]></tab>
<is_configurable>1</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,36 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,36 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,5 @@
.ets-product-specific {
float: left;
width: 100%;
}

View File

@@ -0,0 +1,36 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,36 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,22 @@
/*!
* The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/)
* Copyright (c) 2016 Edson Hilios
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";function b(a){if(a instanceof Date)return a;if(String(a).match(g))return String(a).match(/^[0-9]*$/)&&(a=Number(a)),String(a).match(/\-/)&&(a=String(a).replace(/\-/g,"/")),new Date(a);throw new Error("Couldn't cast `"+a+"` to a date object.")}function c(a){var b=a.toString().replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1");return new RegExp(b)}function d(a){return function(b){var d=b.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi);if(d)for(var f=0,g=d.length;f<g;++f){var h=d[f].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/),j=c(h[0]),k=h[1]||"",l=h[3]||"",m=null;h=h[2],i.hasOwnProperty(h)&&(m=i[h],m=Number(a[m])),null!==m&&("!"===k&&(m=e(l,m)),""===k&&m<10&&(m="0"+m.toString()),b=b.replace(j,m.toString()))}return b=b.replace(/%%/,"%")}}function e(a,b){var c="s",d="";return a&&(a=a.replace(/(:|;|\s)/gi,"").split(/\,/),1===a.length?c=a[0]:(d=a[0],c=a[1])),Math.abs(b)>1?c:d}var f=[],g=[],h={precision:100,elapse:!1,defer:!1};g.push(/^[0-9]*$/.source),g.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source),g.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source),g=new RegExp(g.join("|"));var i={Y:"years",m:"months",n:"daysToMonth",d:"daysToWeek",w:"weeks",W:"weeksToMonth",H:"hours",M:"minutes",S:"seconds",D:"totalDays",I:"totalHours",N:"totalMinutes",T:"totalSeconds"},j=function(b,c,d){this.el=b,this.$el=a(b),this.interval=null,this.offset={},this.options=a.extend({},h),this.instanceNumber=f.length,f.push(this),this.$el.data("countdown-instance",this.instanceNumber),d&&("function"==typeof d?(this.$el.on("update.countdown",d),this.$el.on("stoped.countdown",d),this.$el.on("finish.countdown",d)):this.options=a.extend({},h,d)),this.setFinalDate(c),this.options.defer===!1&&this.start()};a.extend(j.prototype,{start:function(){null!==this.interval&&clearInterval(this.interval);var a=this;this.update(),this.interval=setInterval(function(){a.update.call(a)},this.options.precision)},stop:function(){clearInterval(this.interval),this.interval=null,this.dispatchEvent("stoped")},toggle:function(){this.interval?this.stop():this.start()},pause:function(){this.stop()},resume:function(){this.start()},remove:function(){this.stop.call(this),f[this.instanceNumber]=null,delete this.$el.data().countdownInstance},setFinalDate:function(a){this.finalDate=b(a)},update:function(){if(0===this.$el.closest("html").length)return void this.remove();var b,c=void 0!==a._data(this.el,"events"),d=new Date;b=this.finalDate.getTime()-d.getTime(),b=Math.ceil(b/1e3),b=!this.options.elapse&&b<0?0:Math.abs(b),this.totalSecsLeft!==b&&c&&(this.totalSecsLeft=b,this.elapsed=d>=this.finalDate,this.offset={seconds:this.totalSecsLeft%60,minutes:Math.floor(this.totalSecsLeft/60)%60,hours:Math.floor(this.totalSecsLeft/60/60)%24,days:Math.floor(this.totalSecsLeft/60/60/24)%7,daysToWeek:Math.floor(this.totalSecsLeft/60/60/24)%7,daysToMonth:Math.floor(this.totalSecsLeft/60/60/24%30.4368),weeks:Math.floor(this.totalSecsLeft/60/60/24/7),weeksToMonth:Math.floor(this.totalSecsLeft/60/60/24/7)%4,months:Math.floor(this.totalSecsLeft/60/60/24/30.4368),years:Math.abs(this.finalDate.getFullYear()-d.getFullYear()),totalDays:Math.floor(this.totalSecsLeft/60/60/24),totalHours:Math.floor(this.totalSecsLeft/60/60),totalMinutes:Math.floor(this.totalSecsLeft/60),totalSeconds:this.totalSecsLeft},this.options.elapse||0!==this.totalSecsLeft?this.dispatchEvent("update"):(this.stop(),this.dispatchEvent("finish")))},dispatchEvent:function(b){var c=a.Event(b+".countdown");c.finalDate=this.finalDate,c.elapsed=this.elapsed,c.offset=a.extend({},this.offset),c.strftime=d(this.offset),this.$el.trigger(c)}}),a.fn.countdown=function(){var b=Array.prototype.slice.call(arguments,0);return this.each(function(){var c=a(this).data("countdown-instance");if(void 0!==c){var d=f[c],e=b[0];j.prototype.hasOwnProperty(e)?d[e].apply(d,b.slice(1)):null===String(e).match(/^[$A-Z_][0-9A-Z_$]*$/i)?(d.setFinalDate.call(d,e),d.start()):a.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi,e))}else new j(this,b[0],b[1])})}});

View File

@@ -0,0 +1,46 @@
$(document).ready(function(){
$('.ets_clock').each(function(){
var id_ets_product = $(this).data('id-product');
var date_to = $(this).data('date-to');
if(date_to != "" && parseInt(id_ets_product) >0){
$(this).countdown(date_to).on('update.countdown', function(event) {
var d = (event.offset.totalDays > 1 ? event.offset.totalDays+' <span class="number">'+days+'</span> ':event.offset.totalDays+' <span class="number">'+day+'</span>');
var h = (event.offset.hours > 1 ? event.offset.hours+' <span class="number">'+hrs+'</span> ':event.offset.hours+' <span class="number">'+hr+'</span>');
var m = (event.offset.minutes > 1 ? event.offset.minutes+' <span class="number">'+mins+'</span> ':event.offset.minutes+' <span class="number">'+min+'</span>');
var s = (event.offset.seconds > 1 ? event.offset.seconds+' <span class="number">'+secs+'</span> ':event.offset.seconds+' <span class="number">'+sec+'</span>');
var $this = $(this).html(event.strftime(''
+ '<span class = "ybc_cd_item">'+d+'</span> '
+ '<span class = "ybc_cd_item">'+h+'</span> '
+ '<span class = "ybc_cd_item">'+m+'</span> '
+ '<span class = "ybc_cd_item">'+s+'</span> '));
});
}
});
var $owl = $('.ets-product-specific');
$owl.owlCarousel({
items : 1,
responsive : {
// breakpoint from 0 up
0 : {
items : 1
},
// breakpoint from 480 up
480 : {
items : 2,
margin: 30,
},
// breakpoint from 768 up
768 : {
items : 1
}
},
nav : true,
loop: $(".ets-product-specific .product-miniature").length > 1,
rewindNav : false,
dots : false,
margin: 0,
navText: ['', ''],
callbacks: true,
});
});

View File

@@ -0,0 +1,95 @@
{**
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*}
{block name='product_miniature_item'}
<article class="product-miniature js-product-miniature" data-id-product="{$product.id_product|escape:'html':'UTF-8'}" data-id-product-attribute="{$product.id_product_attribute|escape:'html':'UTF-8'}" itemscope itemtype="http://schema.org/Product">
<div class="thumbnail-container">
{block name='product_thumbnail'}
<a href="{$product.url|escape:'html':'UTF-8'}" class="thumbnail product-thumbnail">
<img
src = "{$product.cover.bySize.home_default.url|escape:'html':'UTF-8'}"
alt = "{$product.cover.legend|escape:'html':'UTF-8'}"
data-full-size-image-url = "{$product.cover.large.url|escape:'html':'UTF-8'}"
>
</a>
{/block}
<div class="product-description">
{block name='product_name'}
<h3 class="h3 product-title" itemprop="name"><a href="{$product.url|escape:'html':'UTF-8'}">{$product.name|truncate:30:'...'}</a></h3>
{/block}
{block name='product_price_and_shipping'}
{if $product.show_price}
<div class="product-price-and-shipping">
{hook h='displayProductPriceBlock' product=$product type="before_price"}
<span itemprop="price" class="price">{$product.price|escape:'html':'UTF-8'}</span>
{if $product.has_discount}
{hook h='displayProductPriceBlock' product=$product type="old_price"}
<span class="regular-price">{$product.regular_price|escape:'html':'UTF-8'}</span>
{if $product.discount_type === 'percentage'}
<span class="discount-percentage">{$product.discount_percentage|escape:'html':'UTF-8'}</span>
{/if}
{/if}
{hook h='displayProductPriceBlock' product=$product type='unit_price'}
{hook h='displayProductPriceBlock' product=$product type='weight'}
</div>
{/if}
{/block}
{*block name='product_reviews'}
{hook h='displayProductListReviews' product=$product}
{/block*}
</div>
{*block name='product_flags'}
<ul class="product-flags">
{foreach from=$product.flags item=flag}
<li class="{$flag.type|escape:'html':'UTF-8'}">{$flag.label|escape:'html':'UTF-8'}</li>
{/foreach}
</ul>
{/block*}
{*
<div class="highlighted-informations{if !$product.main_variants} no-variants{/if} hidden-sm-down">
{block name='quick_view'}
<a class="quick-view" href="#" data-link-action="quickview">
<i class="material-icons search">&#xE8B6;</i> {l s='Quick view' d='Shop.Theme.Actions'}
</a>
{/block}
{block name='product_variants'}
{if $product.main_variants}
{include file='catalog/_partials/variant-links.tpl' variants=$product.main_variants}
{/if}
{/block}
</div>*}
{if isset($product.specific_prices.to) && $product.specific_prices.to }
<div id="ets_clock_{$product.id_product|intval}" data-id-product="{$product.id_product|intval}" data-date-to="{$product.specific_prices.to|escape:'html':'UTF-8'}" class="ets_clock"></div>
</div>
{/if}
</article>
{/block}

View File

@@ -0,0 +1,12 @@
<div id="ybc_specificprices">
<h3 class="h1 products-section-title text-uppercase">
<span>{$specific_title|escape:'html':'UTF-8'}</span>
</h3>
<div class="ets-product-specific">
{foreach from=$products_list item="product"}
{block name='product_miniature'}
{include file='modules/ybc_specificprices/views/templates/hook/_product.tpl' product=$product}
{/block}
{/foreach}
</div>
</div>

View File

@@ -0,0 +1,33 @@
{*
* 2007-2021 ETS-Soft
*
* NOTICE OF LICENSE
*
* This file is not open source! Each license that you purchased is only available for 1 wesite only.
* If you want to use this file on more websites (or projects), you need to purchase additional licenses.
* You are not allowed to redistribute, resell, lease, license, sub-license or offer our resources to any third party.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs, please contact us for extra customization service at an affordable price
*
* @author ETS-Soft <etssoft.jsc@gmail.com>
* @copyright 2007-2021 ETS-Soft
* @license Valid for 1 website (or project) for each purchase of license
* International Registered Trademark & Property of ETS-Soft
*}
<script type="text/javascript">
function phProductFeedResizeIframe(obj) {
$('iframe').css('height','auto');
setTimeout(function() {
$('iframe').css('opacity',1);
var pHeight = $(obj).parent().height();
$(obj).css('height','540px');
}, 300);
}
</script>
<div id="ph_preview_template_html">
<iframe src="{$url_iframe|escape:'html':'UTF-8'}" style="background: #ffffff ; border : 1px solid #ccc;width:100%;height:0;opacity:0;border-radius:5px" onload="phProductFeedResizeIframe(this)"></iframe>
</div>

View File

@@ -0,0 +1,36 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,10 @@
<script type="text/javascript">
var day = '{l s='day' mod='ybc_specificprices'}';
var hr = '{l s='hour' mod='ybc_specificprices'}';
var min = '{l s='min' mod='ybc_specificprices'}';
var sec = '{l s='sec' mod='ybc_specificprices'}';
var days = '{l s='days' mod='ybc_specificprices'}';
var hrs = '{l s='hrs' mod='ybc_specificprices'}';
var mins = '{l s='mins' mod='ybc_specificprices'}';
var secs = '{l s='secs' mod='ybc_specificprices'}';
</script>

View File

@@ -0,0 +1,36 @@
<?php
/*
* 2007-2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @version Release: $Revision$
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,513 @@
<?php
if (!defined('_PS_VERSION_'))
exit;
use PrestaShop\PrestaShop\Adapter\Image\ImageRetriever;
use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter;
use PrestaShop\PrestaShop\Core\Product\ProductListingPresenter;
use PrestaShop\PrestaShop\Adapter\Product\ProductColorsRetriever;
class Ybc_specificprices extends Module
{
private $errorMessage;
public $configs;
public $baseAdminPath;
private $_html;
public $templates;
public function __construct()
{
$this->name = 'ybc_specificprices';
$this->tab = 'front_office_features';
$this->version = '1.0.1';
$this->author = 'YBC-Theme';
$this->need_instance = 0;
$this->secure_key = Tools::encrypt($this->name);
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Hot deals');
$this->description = $this->l('Display specific discounted products on home page');
$this->ps_versions_compliancy = array('min' => '1.6.0.0', 'max' => _PS_VERSION_);
if(isset($this->context->controller->controller_type) && $this->context->controller->controller_type =='admin')
$this->baseAdminPath = $this->context->link->getAdminLink('AdminModules').'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name;
//Config fields
$this->configs = array(
'YBC_SHOPMSG_TITLE' => array(
'label' => $this->l('Title'),
'type' => 'text',
'lang' => true,
'default' => $this->l('Hot deals'),
'required' => true,
),
'YBC_SHOPMSG_PRODUCT' => array(
'label' => $this->l('Product IDs'),
'name'=>'product_id',
'type' => 'text',
'default' => '1,2,3',
'desc' => $this->l('Separated a comma. Eg: 1,3,4')
)
);
}
/**
* @see Module::install()
*/
public function install()
{
return parent::install()
&& $this->registerHook('displayCustomDiscount')
&& $this->registerHook('displayFooter')//hookDisplayHeader
&& $this->registerHook('displayHeader')
&& $this->_installDb();
}
/**
* @see Module::uninstall()
*/
public function uninstall()
{
return parent::uninstall() && $this->_uninstallDb();
}
public function _installDb()
{
$languages = Language::getLanguages(false);
if($this->configs)
{
foreach($this->configs as $key => $config)
{
if(isset($config['lang']) && $config['lang'])
{
$values = array();
foreach($languages as $lang)
{
$values[$lang['id_lang']] = isset($config['default']) ? $config['default'] : '';
}
Configuration::updateValue($key, $values,true);
}
else
Configuration::updateValue($key, isset($config['default']) ? $config['default'] : '',true);
}
}
return true;
}
private function _uninstallDb()
{
if($this->configs)
{
foreach($this->configs as $key => $config)
{
Configuration::deleteByName($key);
}
}
$dirs = array('config');
foreach($dirs as $dir)
{
$files = glob(dirname(__FILE__).'/images/'.$dir.'/*');
foreach($files as $file){
if(is_file($file))
@unlink($file);
}
}
return true;
}
public function getContent()
{
$this->_postConfig();
//Display errors if have
if($this->errorMessage)
$this->_html .= $this->errorMessage;
//Render views
$this->renderConfig();
return $this->_html.$this->displayIframe();
}
public function displayIframe()
{
switch($this->context->language->iso_code) {
case 'en':
$url = 'https://cdn.prestahero.com/prestahero-product-feed?utm_source=feed_'.$this->name.'&utm_medium=iframe';
break;
case 'it':
$url = 'https://cdn.prestahero.com/it/prestahero-product-feed?utm_source=feed_'.$this->name.'&utm_medium=iframe';
break;
case 'fr':
$url = 'https://cdn.prestahero.com/fr/prestahero-product-feed?utm_source=feed_'.$this->name.'&utm_medium=iframe';
break;
case 'es':
$url = 'https://cdn.prestahero.com/es/prestahero-product-feed?utm_source=feed_'.$this->name.'&utm_medium=iframe';
break;
default:
$url = 'https://cdn.prestahero.com/prestahero-product-feed?utm_source=feed_'.$this->name.'&utm_medium=iframe';
}
$this->smarty->assign(
array(
'url_iframe' => $url
)
);
return $this->display(__FILE__,'iframe.tpl');
}
public function renderConfig()
{
$configs = $this->configs;
$fields_form = array(
'form' => array(
'legend' => array(
'title' => $this->l('Hot deals'),
'icon' => 'icon-AdminAdmin'
),
'input' => array(),
'submit' => array(
'title' => $this->l('Save'),
)
),
);
if($configs)
{
foreach($configs as $key => $config)
{
$confFields = array(
'name' => $key,
'type' => $config['type'],
'label' => $config['label'],
'desc' => isset($config['desc']) ? $config['desc'] : false,
'required' => isset($config['required']) && $config['required'] ? true : false,
'autoload_rte' => isset($config['autoload_rte']) && $config['autoload_rte'] ? true : false,
'options' => isset($config['options']) && $config['options'] ? $config['options'] : array(),
'suffix' => isset($config['suffix']) && $config['suffix'] ? $config['suffix'] : false,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('No')
)
),
'lang' => isset($config['lang']) ? $config['lang'] : false
);
if(!$confFields['suffix'])
unset($confFields['suffix']);
if($config['type'] == 'file')
{
if($imageName = Configuration::get($key))
{
$confFields['display_img'] = $this->_path.'images/config/'.$imageName;
if(!isset($config['required']) || (isset($config['required']) && !$config['required']))
$confFields['img_del_link'] = $this->baseAdminPath.'&delimage=yes&image='.$key;
}
}
$fields_form['form']['input'][] = $confFields;
if($confFields['name']=='YBC_SHOPMSG_DATEFROM' || $confFields['name']=='YBC_SHOPMSG_DATETO')
$this->context->controller->addJqueryUI('ui.datepicker');
}
}
$helper = new HelperForm();
$helper->show_toolbar = false;
$helper->table = $this->table;
$lang = new Language((int)Configuration::get('PS_LANG_DEFAULT'));
$helper->default_form_language = $lang->id;
$helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
$this->fields_form = array();
$helper->module = $this;
$helper->identifier = $this->identifier;
$helper->submit_action = 'saveConfig';
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name.'&control=config';
$helper->token = Tools::getAdminTokenLite('AdminModules');
$language = new Language((int)Configuration::get('PS_LANG_DEFAULT'));
$id_lang_default = (int)Configuration::get('PS_LANG_DEFAULT');
$fields = array();
$languages = Language::getLanguages(false);
$helper->override_folder = '/';
if(Tools::isSubmit('saveConfig'))
{
if($configs)
{
foreach($configs as $key => $config)
{
if(isset($config['lang']) && $config['lang'])
{
foreach($languages as $l)
{
$fields[$key][$l['id_lang']] = Tools::getValue($key.'_'.$l['id_lang'],isset($config['default']) ? $config['default'] : '');
}
}
else
$fields[$key] = Tools::getValue($key,isset($config['default']) ? $config['default'] : '');
}
}
}
else
{
if($configs)
{
foreach($configs as $key => $config)
{
if(isset($config['lang']) && $config['lang'])
{
foreach($languages as $l)
{
$fields[$key][$l['id_lang']] = Configuration::get($key,$l['id_lang']);
}
}
else
$fields[$key] = Configuration::get($key);
}
}
}
$helper->tpl_vars = array(
'base_url' => $this->context->shop->getBaseURL(),
'language' => array(
'id_lang' => $language->id,
'iso_code' => $language->iso_code
),
'fields_value' => $fields,
'languages' => $this->context->controller->getLanguages(),
'id_language' => $this->context->language->id,
);
$this->_html .= $helper->generateForm(array($fields_form));
}
private function _postConfig()
{
$errors = array();
$languages = Language::getLanguages(false);
$id_lang_default = (int)Configuration::get('PS_LANG_DEFAULT');
$configs = $this->configs;
//Delete image
if(Tools::isSubmit('delimage'))
{
$image = Tools::getValue('image');
if(isset($configs[$image]) && !isset($configs[$image]['required']) || (isset($configs[$image]['required']) && !$configs[$image]['required']))
{
$imageName = Configuration::get($image);
$imagePath = dirname(__FILE__).'/images/config/'.$imageName;
if($imageName && file_exists($imagePath))
{
@unlink($imagePath);
Configuration::updateValue($image,'');
}
Tools::redirectAdmin($this->context->link->getAdminLink('AdminModules', true).'&conf=4&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name);
}
else
$errors[] = $configs[$image]['label'].$this->l(' is required');
}
if(Tools::isSubmit('saveConfig'))
{
if($configs)
{
foreach($configs as $key => $config)
{
if(isset($config['lang']) && $config['lang'])
{
if(isset($config['required']) && $config['required'] && $config['type']!='switch' && trim(Tools::getValue($key.'_'.$id_lang_default) == ''))
{
$errors[] = $config['label'].' '.$this->l('is required');
}
}
else
{
if(isset($config['required']) && $config['required'] && isset($config['type']) && $config['type']=='file')
{
if(Configuration::get($key)=='' && !isset($_FILES[$key]['size']))
$errors[] = $config['label'].' '.$this->l('is required');
elseif(isset($_FILES[$key]['size']))
{
$fileSize = round((int)$_FILES[$key]['size'] / (1024 * 1024));
if($fileSize > 100)
$errors[] = $config['label'].$this->l(' can not be larger than 100Mb');
}
}
else
{
if(isset($config['required']) && $config['required'] && $config['type']!='switch' && trim(Tools::getValue($key) == ''))
{
$errors[] = $config['label'].' '.$this->l('is required');
}
elseif(!Validate::isCleanHtml(trim(Tools::getValue($key))))
{
$errors[] = $config['label'].' '.$this->l('is invalid');
}
}
}
}
}
//Custom validation
if(($productIds = Tools::getValue('YBC_SHOPMSG_PRODUCT')) && !preg_match('/^[0-9]+(,[0-9]+)*$/', $productIds))
$errors[] = $this->l('Product IDs is not in valid format');
if(!$errors)
{
if($configs)
{
foreach($configs as $key => $config)
{
if(isset($config['lang']) && $config['lang'])
{
$valules = array();
foreach($languages as $lang)
{
if($config['type']=='switch')
$valules[$lang['id_lang']] = (int)trim(Tools::getValue($key.'_'.$lang['id_lang'])) ? 1 : 0;
else
$valules[$lang['id_lang']] = trim(Tools::getValue($key.'_'.$lang['id_lang'])) ? trim(Tools::getValue($key.'_'.$lang['id_lang'])) : trim(Tools::getValue($key.'_'.$id_lang_default));
}
Configuration::updateValue($key,$valules,true);
}
else
{
if($config['type']=='switch')
{
Configuration::updateValue($key,(int)trim(Tools::getValue($key)) ? 1 : 0,true);
}
if($config['type']=='file')
{
//Upload file
if(isset($_FILES[$key]['tmp_name']) && isset($_FILES[$key]['name']) && $_FILES[$key]['name'])
{
$salt = sha1(microtime());
$type = Tools::strtolower(Tools::substr(strrchr($_FILES[$key]['name'], '.'), 1));
$imageName = $salt.'.'.$type;
$fileName = dirname(__FILE__).'/images/config/'.$imageName;
if(file_exists($fileName))
{
$errors[] = $config['label'].$this->l(' already exists. Try to rename the file then reupload');
}
else
{
$imagesize = @getimagesize($_FILES[$key]['tmp_name']);
if (!$errors && isset($_FILES[$key]) &&
!empty($_FILES[$key]['tmp_name']) &&
!empty($imagesize) &&
in_array($type, array('jpg', 'gif', 'jpeg', 'png'))
)
{
$temp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS');
if ($error = ImageManager::validateUpload($_FILES[$key]))
$errors[] = $error;
elseif (!$temp_name || !move_uploaded_file($_FILES[$key]['tmp_name'], $temp_name))
$errors[] = $this->l('Can not upload the file');
elseif (!ImageManager::resize($temp_name, $fileName, null, null, $type))
$errors[] = $this->displayError($this->l('An error occurred during the image upload process.'));
if (isset($temp_name))
@unlink($temp_name);
if(!$errors)
{
if(Configuration::get($key)!='')
{
$oldImage = dirname(__FILE__).'/images/config/'.Configuration::get($key);
if(file_exists($oldImage))
@unlink($oldImage);
}
Configuration::updateValue($key, $imageName,true);
}
}
}
}
//End upload file
}
else
Configuration::updateValue($key,trim(Tools::getValue($key)),true);
}
}
}
}
Tools::clearSmartyCache('display_product.tpl');
if (count($errors))
{
$this->errorMessage = $this->displayError(implode('<br />', $errors));
}
else
Tools::redirectAdmin($this->context->link->getAdminLink('AdminModules', true).'&conf=4&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name);
}
}
public function hookDisplayHeader($params)
{
if(($page = Tools::strtolower(trim(Tools::getValue('controller')))) && $page && !in_array($page, array('index')))
return;
$this->context->controller->addJS($this->_path.'views/js/jquery.countdown.min.js');
$this->context->controller->addJS($this->_path.'views/js/specific_prices.js');
return $this->display(__FILE__, 'renderJs.tpl');
}
public function hookDisplayFooter($params)
{
/*if(($page = Tools::strtolower(trim(Tools::getValue('controller')))) && $page && !in_array($page, array('index')))
return;
return $this->hookDisplayCustomDiscount($params);*/
}
public function hookDisplayCustomDiscount($params)
{
if(($products = explode(",",Configuration::get('YBC_SHOPMSG_PRODUCT'))) && (!$products || $products && !is_array($products)))
return;
$products_list = array();
$db = Db::getInstance(_PS_USE_SQL_SLAVE_);
$id_lang = $this->context->language->id;
$product_pool = Configuration::get('YBC_SHOPMSG_PRODUCT');
$product_pool = ((strpos($product_pool, ',') === false) ? (' = '.(int)$product_pool.' ') : (' IN ('.rtrim($product_pool, ',').') '));
$sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity,
pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`name`,
image_shop.`id_image` id_image, il.`legend`, m.`name` manufacturer_name,
DATEDIFF(
p.`date_add`,
DATE_SUB(
"'.date('Y-m-d').' 00:00:00",
INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY
)
) > 0 new'.(Combination::isFeatureActive() ? ', product_attribute_shop.minimal_quantity AS product_attribute_minimal_quantity, IFNULL(product_attribute_shop.`id_product_attribute`,0) id_product_attribute' : '').'
FROM '._DB_PREFIX_.'product p
'.Shop::addSqlAssociation('product', 'p').'
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').'
)
'.(Combination::isFeatureActive() ? 'LEFT JOIN `'._DB_PREFIX_.'product_attribute_shop` product_attribute_shop
ON (p.`id_product` = product_attribute_shop.`id_product` AND product_attribute_shop.`default_on` = 1 AND product_attribute_shop.id_shop='.(int)$this->context->shop->id.')':'').'
'.Product::sqlStock('p', 0).'
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
LEFT JOIN `'._DB_PREFIX_.'image_shop` image_shop
ON (image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop='.(int)$this->context->shop->id.')
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (image_shop.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
WHERE p.`id_product` '.$product_pool.'
GROUP BY product_shop.id_product';
$result = $db->executeS($sql, true, false);
$products_list = Product::getProductsProperties((int)$id_lang, $result);
$assembler = new ProductAssembler($this->context);
$presenterFactory = new ProductPresenterFactory($this->context);
$presentationSettings = $presenterFactory->getPresentationSettings();
$presenter = new ProductListingPresenter(
new ImageRetriever(
$this->context->link
),
$this->context->link,
new PriceFormatter(),
new ProductColorsRetriever(),
$this->context->getTranslator()
);
$products_for_template = [];
foreach ($products_list as $rawProduct) {
$products_for_template[] = $presenter->present(
$presentationSettings,
$assembler->assembleProduct($rawProduct),
$this->context->language
);
}
$this->smarty->assign(array(
'products_list'=>$products_for_template,
'specific_title' => Configuration::get('YBC_SHOPMSG_TITLE',$this->context->language->id),
));
return $this->display(__FILE__, 'display_product.tpl');
}
}