Desirable tool :
---------
client FileZilla - ftp-client for possible move images on hosting
Notepad++ - program for possible edit php-pages
Desirable parameters to hosting :
---------
VDS - hosting
for MySql - set all privileges to the user
========
- necessary do changes for Mysql server. Need set some changes for work with big database and with import big files (all values are approximate and depend on the parameters of your hosting) :
sort_buffer_size=4M # for work with memory
key_buffer_size = 256M # for work with memory
key_buffer = 32M # for work with memory
max_allowed_packet = 256M # for work with big files
table_open_cache = 256 # for work with memory
read_buffer_size = 2M # for work with memory
read_rnd_buffer_size = 4M # for work with memory
myisam_sort_buffer_size = 64M # for work with memory
thread_cache_size = 8 # for work with memory
query_cache_size= 16M # for work with memory
connect_timeout = 2400 # longer delay due to work with large amounts of data
max_heap_table_size = 256M # for work with temp files
tmp_table_size = 256M # for work with temp files
group_concat_max_len = 400000 # to be able to grouping data on base engine Mysql-server
wait_timeout = 2400 # longer delay due to work with large amounts of data
innodb_buffer_pool_size = 256M # for work with memory
innodb_additional_mem_pool_size = 20M # for work with memory
***********************************************************************************************
Changes that need to be undertaken to accelerate the operation of the site
- you must disable unused or little used modules for [Modules]->[Front Office Features]
- disable module "Categories block" or setting value to Maximum depth (set = 1)
- setting or disable module "Top horizontal menu"
- and etc ...
========
- specify settings for increased performance :
- setting to search weight [PREFERENCES]->[SEARCH]->[WEIGHT] (for example, specify a value of zero for all values except "Tags weight", that enables to search by code of analog parts)
- setting to [ADVANCED PARAMETERS]->[PERFORMANCE]->[OPTIONAL FEATURES] (for example, disable values "Combinations" and "Customer Groups")
- setting to [ADVANCED PARAMETERS]->[PERFORMANCE]->[CACHING] : disable caching.
========
- add new index(s)
- add INDEX to field "link_rewrite" to table "_product_lang"
- change PRIMARY KEY to table "_feature_product", where need set new PRIMARY KEY as [id_feature]&[id_product]$[id_feature_value]
- to table "_tag" add new field "`id_manufacturer` int(10) default null"
- change PRIMARY KEY to table "_tag", where need set new PRIMARY KEY as [id_tag]&[id_lang]
... All these changes make the program automatically on the page[UPLOAD DATA INTO THE STORE]=>button[CLEAN INSTALLATION] ... but automatic change of necessary data depends on the privileges of your user Mysql
========
- Changes for Prestashop version from 1.6.1.x
- change for table "image" : need delete UNIQUE INDEX "id_product_cover"
- change for table "image_shop" : need delete all UNIQUE INDEX | add new INDEX for column "id_product"
... All these changes make the program automatically on the page[UPLOAD DATA INTO THE STORE]=>button[CLEAN INSTALLATION] ... but automatic change of necessary data depends on the privileges of your user Mysql
========
Solution of problem connection to TecDoc in version 04/2015
Need install service pack for TecDoc 04/2015 ...
- file http://www.tecdoc.de/fileadmin/downloads/tecdoc/Alles/TecDoc-Analyzer.exe
- page description this and other problems http://www.tecdoc.de/en/home/products/faq/tecdoc-catalog.html
========
- for search capabilities by cross-reference code you need to change the fileS
--------
... /controllers/front/SearchController.php
instead of ...
elseif (($query = Tools::getValue('search_query', Tools::getValue('ref'))) && !is_array($query))
{
$this->productSort();
$this->n = abs((int)(Tools::getValue('n', Configuration::get('PS_PRODUCTS_PER_PAGE'))));
$this->p = abs((int)(Tools::getValue('p', 1)));
$original_query = $query;
$query = Tools::replaceAccentedChars(urldecode($query));
$search = Search::find($this->context->language->id, $query, $this->p, $this->n, $this->orderBy, $this->orderWay);
foreach ($search['result'] as &$product)
$product['link'] .= (strpos($product['link'], '?') === false ? '?' : '&').'search_query='.urlencode($query).'&results='.(int)$search['total'];
Hook::exec('actionSearch', array('expr' => $query, 'total' => $search['total']));
$nbProducts = $search['total'];
$this->pagination($nbProducts);
$this->addColorsToProductList($search['result']);
$this->context->smarty->assign(array(
'products' => $search['result'], // DEPRECATED (since to 1.4), not use this: conflict with block_cart module
'search_products' => $search['result'],
'nbProducts' => $search['total'],
'search_query' => $original_query,
'homeSize' => Image::getSize(ImageType::getFormatedName('home'))));
}
replaced by :
elseif (($query = Tools::getValue('search_query', Tools::getValue('ref'))) && !is_array($query))
{
$tag=$query;
$tag=trim(str_replace(array('_', '-', '*', '.', ',', ' ', '+', '/', '|'), '', $tag));
$nbProducts = (int)(Search::searchTag($this->context->language->id, $tag, true));
$this->pagination($nbProducts);
$result = Search::searchTag($this->context->language->id, $tag, false, $this->p, $this->n, $this->orderBy, $this->orderWay);
Hook::exec('actionSearch', array('expr' => $tag, 'total' => count($result)));
$this->context->smarty->assign(array(
'search_tag' => $tag,
'products' => $result, // DEPRECATED (since to 1.4), not use this: conflict with block_cart module
'search_products' => $result,
'nbProducts' => $nbProducts,
'homeSize' => Image::getSize(ImageType::getFormatedName('home'))));
}
--------
.../classes/Tag.php
instead of ...
WHERE `name` LIKE \'%'.pSQL($name).'%\' AND `id_lang` = '.(int)$id_lang);
replaced by :
WHERE `name` = \''.pSQL($name).'\' AND `id_lang` = '.(int)$id_lang);
--------
.../classes/Search.php
edit public static function "searchTag"
for querys where are string
t.`name` LIKE \'%'.pSQL($tag).'%\'
replaced by :
t.`name` = \''.pSQL($tag).'\'
--------
.../classes/Search.php
editing public static function "searchTag", comment out the call "if (Group::isFeatureActive())"
public static function searchTag($id_lang, $tag, $count = false, $pageNumber = 0, $pageSize = 10, $orderBy = false, $orderWay = false,
$useCookie = true, Context $context = null)
{
...
/*if (Group::isFeatureActive())
{
$groups = FrontController::getCurrentCustomerGroups();
$sql_groups = 'AND cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1');
}*/
...
}
editing public static function "searchTag", editing for queries ... comment out
'./*(Group::isFeatureActive() ? 'LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = cp.`id_category`)' : '').*/'
--------
========
- improved search by cross-ref numbers, with sending ID Manufacturer ...
--------
/controllers/front/SearchController.php
...
elseif (($query = Tools::getValue('search_query', Tools::getValue('ref'))) && !is_array($query))
{
...
$tag=$query;
$tag=trim(str_replace(array('_', '-', '*', '.', ',', ' ', '+', '/', '|'), '', $tag));
// add checking value "braid"
$braid=Tools::getValue('braid');
$nbProducts = (int)(Search::searchTag($braid, $this->context->language->id, $tag, true)); // <--- edit here, add $braid
...
$result = Search::searchTag($braid, $this->context->language->id, $tag, false, $this->p, $this->n, $this->orderBy, $this->orderWay); // <--- edit here, add $braid
...
}
...
--------
.../classes/Search.php
editing head for function "searchTag"
public static function searchTag($id_lang, $tag, $count = false, $pageNumber = 0, $pageSize = 10, $orderBy = false, $orderWay = false,
$useCookie = true, Context $context = null)
change in, add "$braid = null"
public static function searchTag($braid = null, $id_lang, $tag, $count = false, $pageNumber = 0, $pageSize = 10, $orderBy = false, $orderWay = false,
$useCookie = true, Context $context = null)
--------
.../classes/Search.php
editing function "searchTag"
public static function searchTag($braid = null, $id_lang, $tag, $count = false, $pageNumber = 0, $pageSize = 10, $orderBy = false, $orderWay = false,
$useCookie = true, Context $context = null)
{
// add
$tag_bra_id = '';
IF ($braid != null && $braid != '') {$tag_bra_id = ' AND t.`id_manufacturer` = '.(int)$braid.' ';};
...
}
--------
.../classes/Search.php
editing queries for function "searchTag", where are "AND t.`name` = \''.pSQL($tag).'\'" need change on "AND t.`name` = \''.pSQL($tag).'\' '.$tag_bra_id.'"
instead of ...
AND t.`name` = \''.pSQL($tag).'\'
replaced by :
AND t.`name` = \''.pSQL($tag).'\' '.$tag_bra_id.'
--------
.../classes/Tag.php
editing function "getProductTags", for SELECT add t.`id_manufacturer` and "$result[$tag['id_lang']][]" change on "$result[$tag['id_lang']][] = $tag['brand'].'|'.$tag['name'].'|'.$tag['id_manufacturer'];"
instead of ...
public static function getProductTags($id_product)
{
if (!$tmp = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT t.`id_lang`, t.`name`, (select m.`name` from '._DB_PREFIX_.'manufacturer as m where m.`id_manufacturer` = t.`id_manufacturer`) as brand
FROM '._DB_PREFIX_.'tag t
LEFT JOIN '._DB_PREFIX_.'product_tag pt ON (pt.id_tag = t.id_tag)
WHERE pt.`id_product`='.(int)$id_product.' ORDER BY brand, name'))
return false;
$result = array();
foreach ($tmp as $tag)
$result[$tag['id_lang']][] = $tag['brand'].'|'.$tag['name'];
return $result;
}
replaced by :
public static function getProductTags($id_product)
{
if (!$tmp = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT t.`id_lang`, t.`name`, t.`id_manufacturer`, (select m.`name` from '._DB_PREFIX_.'manufacturer as m where m.`id_manufacturer` = t.`id_manufacturer`) as brand
FROM '._DB_PREFIX_.'tag t
LEFT JOIN '._DB_PREFIX_.'product_tag pt ON (pt.id_tag = t.id_tag)
WHERE pt.`id_product`='.(int)$id_product.' ORDER BY brand, name'))
return false;
$result = array();
foreach ($tmp as $tag)
$result[$tag['id_lang']][] = $tag['brand'].'|'.$tag['name'].'|'.$tag['id_manufacturer'];
return $result;
}
========
- the ability to check the brand for search number, as like http://demoprestashop.ttc.bovsoft.com/search?controller=search&orderby=position&orderway=desc&search_query=C422&submit_search=
first need do change which is in description for "improved search by cross-ref numbers, with sending ID Manufacturer ..."
--------
... /classes/Search.php
add new function for view panel (new class="list-of-brands-for-search" for css) list of brands
public static function searchListBrandsForTag($id_lang, $tagg)
{
if (!$tmp = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT /* DISTINCT */
t.`name`,
t.`id_manufacturer`,
(select m.`name` from '._DB_PREFIX_.'manufacturer as m where m.`id_manufacturer` = t.`id_manufacturer`) as brand
,(SELECT
MIN(cl.name)
FROM '._DB_PREFIX_.'category_lang as cl
JOIN '._DB_PREFIX_.'product as p on (cl.id_category = p.id_category_default)
JOIN '._DB_PREFIX_.'product_tag as pt on (p.id_product = pt.id_product)
WHERE pt.id_tag = t.id_tag
and cl.id_lang = '.(int)$id_lang.'
) as nameparts
FROM '._DB_PREFIX_.'tag t
WHERE t.`name`= \''.$tagg.'\' AND t.`id_lang` = '.(int)$id_lang.' GROUP BY brand, name '))
return null;
$result = '
Select a brand for which has been specified search cross-ref number
';
foreach ($tmp as $tag)
$result=$result.'
'.$tag['brand'].' |
'.$tag['name'].' |
'.$tag['nameparts'].' |
';
$result=$result.'
';
return $result;
}
--------
... /controllers/front/SearchController.php
...
elseif (($query = Tools::getValue('search_query', Tools::getValue('ref'))) && !is_array($query))
{
...
// add
$listbrands = Search::searchListBrandsForTag($this->context->language->id, $tag);
$this->context->smarty->assign(array(
...
'listbrands' => $listbrands, // add
'braid' => $braid, // add
...
'homeSize' => Image::getSize(ImageType::getFormatedName('home'))));
}
...
--------
... yourtemes/search.tpl
{if !$nbProducts}
...
{else}
{if isset($instant_search) && $instant_search}
{if $nbProducts == 1}{l s='%d result has been found.' sprintf=$nbProducts|intval}{else}{l s='%d results have been found.' sprintf=$nbProducts|intval}{/if}
{/if}
{include file="$tpl_dir./product-sort.tpl"}
{if !isset($instant_search) || (isset($instant_search) && !$instant_search)}
{include file="./nbr-product-page.tpl"}
{/if}
{include file="$tpl_dir./product-list.tpl" products=$search_products}
{/if}
replaced by :
{if !$nbProducts}
...
{else}
{if $braid == ''}
{$listbrands}
{else}
{if isset($instant_search) && $instant_search}
{if $nbProducts == 1}{l s='%d result has been found.' sprintf=$nbProducts|intval}{else}{l s='%d results have been found.' sprintf=$nbProducts|intval}{/if}
{/if}
{include file="$tpl_dir./product-sort.tpl"}
{if !isset($instant_search) || (isset($instant_search) && !$instant_search)}
{include file="./nbr-product-page.tpl"}
{/if}
{include file="$tpl_dir./product-list.tpl" products=$search_products}
{/if}
{/if}
--------
========
- for the possibility of displaying a list of cross-references codes on the product page
--------
... /classes/Tag.php
instead of ...
public static function getProductTags($id_product)
{
if (!$tmp = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT t.`id_lang`, t.`name`
FROM '._DB_PREFIX_.'tag t
LEFT JOIN '._DB_PREFIX_.'product_tag pt ON (pt.id_tag = t.id_tag)
WHERE pt.`id_product`='.(int)$id_product))
return false;
$result = array();
foreach ($tmp as $tag)
$result[$tag['id_lang']][] = $tag['brand'].'|'.$tag['name'];
return $result;
}
replaced by :
public static function getProductTags($id_product)
{
if (!$tmp = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT t.`id_lang`, t.`name`, (select m.`name` from '._DB_PREFIX_.'manufacturer as m where m.`id_manufacturer` = t.`id_manufacturer`) as brand
FROM '._DB_PREFIX_.'tag t
LEFT JOIN '._DB_PREFIX_.'product_tag pt ON (pt.id_tag = t.id_tag)
WHERE pt.`id_product`='.(int)$id_product.' ORDER BY brand, name'))
return false;
$result = array();
foreach ($tmp as $tag)
$result[$tag['id_lang']][] = $tag['brand'].'|'.$tag['name'];
return $result;
}
--------
... /themes/yourthemes/product.tpl
add new panel (for example insert after panel "Data sheet")
{if $product->tags}
CROSS REFERENCES NUMBERS
{foreach from=$product->tags item=tag1}
{foreach from=$tag1 item=tag}
{if isset($tag)}
{$tag_1=strtok($tag, '|')}
{$tag_2=strtok('|')}
{$tag_3=strtok('|')}
{if $tag_2 == ''}
{$tag_2 = $tag_1}
{$tag_1 = '---'}
{/if}
{$tag_1|escape:'html':'UTF-8'} |
{$tag_2} |
{/if}
{/foreach}
{/foreach}
{/if}
--------
========
- for the possibility of displaying a list of vehicles for which are used a specified spare part
--------
/classes/Product.php
add new public value to class "ProductCore"
class ProductCore extends ObjectModel
{
...
/*** @var array aplicability */
public $aplicability;
...
}
--------
/classes/Product.php
add new function "getProductAplicability" for create list vehicle for which are used the spare part
public static function getProductAplicability($id_product)
{
$id_lang = (int)Context::getContext()->language->id;
$id_shop = (int)Context::getContext()->shop->id;
$result = array();
$tmp = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT DISTINCT
T2.id_category AS ID,
(select min(M4.NAME) from '._DB_PREFIX_.'category_lang as M4 where (M4.id_shop = '.(int)$id_shop.') AND (M4.id_lang = '.(int)$id_lang.') and (M4.id_category = T4.id_category)) AS nameCAT_1,
(select min(M3.NAME) from '._DB_PREFIX_.'category_lang as M3 where (M3.id_shop = '.(int)$id_shop.') AND (M3.id_lang = '.(int)$id_lang.') and (M3.id_category = T3.id_category)) AS nameCAT_2,
(select min(M2.NAME) from '._DB_PREFIX_.'category_lang as M2 where (M2.id_shop = '.(int)$id_shop.') AND (M2.id_lang = '.(int)$id_lang.') and (M2.id_category = T2.id_category)) AS nameCAT_3
FROM '._DB_PREFIX_.'category_lang AS M
join '._DB_PREFIX_.'category_product as CatProd on (M.id_category = CatProd.id_category)
JOIN '._DB_PREFIX_.'category AS T ON (T.id_category = M.id_category)
JOIN '._DB_PREFIX_.'category AS T1 ON (T1.id_category = T.id_parent)
JOIN '._DB_PREFIX_.'category AS T2 ON (T2.id_category = T1.id_parent)
JOIN '._DB_PREFIX_.'category AS T3 ON (T3.id_category = T2.id_parent)
JOIN '._DB_PREFIX_.'category AS T4 ON (T4.id_category = T3.id_parent)
WHERE CatProd.id_product = '.(int)$id_product.'
and (M.id_shop = '.(int)$id_shop.') AND (M.id_lang = '.(int)$id_lang.')
ORDER BY nameCAT_1, nameCAT_2, nameCAT_3 LIMIT 30');
if ($tmp)
foreach ($tmp as $aplic)
$result[] = $aplic['nameCAT_1'].'^'.$aplic['nameCAT_2'].'^'.$aplic['nameCAT_3'].'^'.$aplic['ID'];
return $result;
}
--------
/classes/Product.php
edit of function "__construct" for add a call new function "getProductAplicability"
public function __construct($id_product = null, $full = false, $id_lang = null, $id_shop = null, Context $context = null)
{ ...
...
if ($full && $this->id)
{
...
// ADD
if ($this->id)
$this->aplicability = Product::getProductAplicability((int)$this->id);
// *****************************************************************************
...
}
...
}
--------
... /themes/yourthemes/product.tpl
add new panel (for example insert after panel "Data sheet")
APLICABILITY
{foreach from=$product->aplicability item=tag1}
{foreach from=$tag1 item=tag}
{if isset($tag)}
{$tag_1=strtok($tag, '^')}
{$tag_2=strtok('^')}
{$tag_3=strtok('^')}
{$tag_4=strtok('^')}
{if ($tag_4 != '' && $tag_1 != 'Root') }
{$tag_1|escape:'html':'UTF-8'} |
{$tag_2|escape:'html':'UTF-8'} |
{$tag_3|escape:'html':'UTF-8'} |
{/if}
{/if}
{/foreach}
{/foreach}
--------
========
- error correction (long download time to pages) PrestaShop in time creating a list of categories,
because that PrestaShop doing checks all categories for links with user groups
(this error occurs on pages that work with controller "category")
--------
/classes/category.php
correction of query for obtain of list of categories
change for function ...
public static function getNestedCategories($root_category = null, $id_lang = false, $active = true, $groups = null,
$use_shop_restriction = true, $sql_filter = '', $sql_sort = '', $sql_limit = '')
{
...
if (!Cache::isStored($cache_id))
{
$result = Db::getInstance()->executeS('
SELECT c.*, cl.*
FROM `'._DB_PREFIX_.'category` c
'.($use_shop_restriction ? Shop::addSqlAssociation('category', 'c') : '').'
LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON c.`id_category` = cl.`id_category`'.Shop::addSqlRestrictionOnLang('cl').'
'.(isset($groups) && Group::isFeatureActive() ? 'LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON c.`id_category` = cg.`id_category`' : '').'
'.(isset($root_category) ? 'RIGHT JOIN `'._DB_PREFIX_.'category` c2 ON c2.`id_category` = '.(int)$root_category.' AND c.`nleft` >= c2.`nleft` AND c.`nright` <= c2.`nright`' : '').'
WHERE 1 '.$sql_filter.' '.($id_lang ? 'AND `id_lang` = '.(int)$id_lang : '').'
'.($active ? ' AND c.`active` = 1' : '').'
'.(isset($groups) && Group::isFeatureActive() ? ' AND cg.`id_group` IN ('.implode(',', $groups).')' : '').'
'.(!$id_lang || (isset($groups) && Group::isFeatureActive()) ? ' GROUP BY c.`id_category`' : '').'
'.($sql_sort != '' ? $sql_sort : ' ORDER BY c.`level_depth` ASC').'
'.($sql_sort == '' && $use_shop_restriction ? ', category_shop.`position` ASC' : '').'
'.($sql_limit != '' ? $sql_limit : '')
);
...
}
...
}
replaced by :
public static function getNestedCategories($root_category = null, $id_lang = false, $active = true, $groups = null,
$use_shop_restriction = true, $sql_filter = '', $sql_sort = '', $sql_limit = '')
{
...
if (!Cache::isStored($cache_id))
{
$result = Db::getInstance()->executeS('
SELECT c.*, cl.*
FROM `'._DB_PREFIX_.'category` c
'.($use_shop_restriction ? Shop::addSqlAssociation('category', 'c') : '').'
LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON c.`id_category` = cl.`id_category`'.Shop::addSqlRestrictionOnLang('cl').'
'.(isset($root_category) ? 'RIGHT JOIN `'._DB_PREFIX_.'category` c2 ON c2.`id_category` = '.(int)$root_category.' AND c.`nleft` >= c2.`nleft` AND c.`nright` <= c2.`nright`' : '').'
WHERE (c.`id_parent` <= 4) '.$sql_filter.' '.($id_lang ? 'AND `id_lang` = '.(int)$id_lang : '').'
'.($active ? ' AND c.`active` = 1' : '').'
'.($sql_sort != '' ? $sql_sort : ' ORDER BY c.`level_depth` ASC').'
'.($sql_sort == '' && $use_shop_restriction ? ', category_shop.`position` ASC' : '').'
'.($sql_limit != '' ? $sql_limit : '')
);
...
}
...
}
--------
/classes/category.php
correction of query for obtain of list of categories
change for function (comment out the function call) ...
public function getSubCategories($id_lang, $active = true)
{
...
if (Group::isFeatureActive())
{
$sql_groups_join = 'LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = c.`id_category`)';
$groups = FrontController::getCurrentCustomerGroups();
$sql_groups_where = 'AND cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '='.(int)Group::getCurrent()->id);
}
...
}
replaced by :
public function getSubCategories($id_lang, $active = true)
{
...
/*if (Group::isFeatureActive())
{
$sql_groups_join = 'LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = c.`id_category`)';
$groups = FrontController::getCurrentCustomerGroups();
$sql_groups_where = 'AND cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '='.(int)Group::getCurrent()->id);
}*/
...
}
--------
/classes/category.php
correction of query
change for function ...
public function checkAccess($id_customer)
{
$cache_id = 'Category::checkAccess_'.(int)$this->id.'-'.$id_customer.(!$id_customer ? '-'.(int)Group::getCurrent()->id : '');
if (!Cache::isStored($cache_id))
{
if (!$id_customer)
$result = (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT ctg.`id_group`
FROM '._DB_PREFIX_.'category_group ctg
WHERE ctg.`id_category` = '.(int)$this->id.' AND ctg.`id_group` = '.(int)Group::getCurrent()->id);
else
$result = (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT ctg.`id_group`
FROM '._DB_PREFIX_.'category_group ctg
INNER JOIN '._DB_PREFIX_.'customer_group cg on (cg.`id_group` = ctg.`id_group` AND cg.`id_customer` = '.(int)$id_customer.')
WHERE ctg.`id_category` = '.(int)$this->id);
Cache::store($cache_id, $result);
}
return Cache::retrieve($cache_id);
}
replaced by :
public function checkAccess($id_customer)
{
return true;
}
--------
========
- Sort subcategories by name
--------
/classes/category.php
edit query for function[getSubCategories]->value[$result]->edit row with "ORDER BY"
instead of ...
ORDER BY `level_depth` ASC, category_shop.`position` ASC');
replaced by :
ORDER BY cl.`name`, `level_depth` ASC, category_shop.`position` ASC');
--------
========
- Ability to display the "top menu" bar
--------
/modules/blocktopmenu/blocktopmenu.php
edit private function "generateCategoriesMenu"
private function generateCategoriesMenu($categories, $is_children = 0)
{
$html = '';
foreach ($categories as $key => $category)
{
...
// add link for category
$link = $this->context->link->getCategoryLink((int)$category['id_category']);
...
if (isset($category['children']) && !empty($category['children']))
{
...
instead of ...
$html .= $this->generateCategoriesMenu($category['children'], 1);
replaced by :
if ($is_children == 0) // bovsoft
$html .= $this->generateCategoriesMenu($category['children'], 1);
...
}
...
}
...
}
--------
/modules/blocktopmenu/blocktopmenu.php
edit private function "customGetNestedCategories"
instead of ...
public function customGetNestedCategories($shop_id, $root_category = null, $id_lang = false, $active = true, $groups = null, $use_shop_restriction = true, $sql_filter = '', $sql_sort = '', $sql_limit = '')
{
...
if (!Cache::isStored($cache_id))
{
...
$result = Db::getInstance()->executeS('
SELECT c.*, cl.*
FROM `'._DB_PREFIX_.'category` c
INNER JOIN `'._DB_PREFIX_.'category_shop` category_shop ON (category_shop.`id_category` = c.`id_category` AND category_shop.`id_shop` = "'.(int)$shop_id.'")
LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (c.`id_category` = cl.`id_category` AND cl.`id_shop` = "'.(int)$shop_id.'")
WHERE 1 '.$sql_filter.' '.($id_lang ? 'AND cl.`id_lang` = '.(int)$id_lang : '').'
'.($active ? ' AND (c.`active` = 1 OR c.`is_root_category` = 1)' : '').'
'.(isset($groups) && Group::isFeatureActive() ? ' AND cg.`id_group` IN ('.implode(',', $groups).')' : '').'
'.(!$id_lang || (isset($groups) && Group::isFeatureActive()) ? ' GROUP BY c.`id_category`' : '').'
'.($sql_sort != '' ? $sql_sort : ' ORDER BY c.`level_depth` ASC').'
'.($sql_sort == '' && $use_shop_restriction ? ', category_shop.`position` ASC' : '').'
'.($sql_limit != '' ? $sql_limit : '')
);
...
}
...
}
replaced by :
public function customGetNestedCategories($shop_id, $root_category = null, $id_lang = false, $active = true, $groups = null, $use_shop_restriction = true, $sql_filter = '', $sql_sort = '', $sql_limit = '')
{
...
if (!Cache::isStored($cache_id))
{
...
$result = Db::getInstance()->executeS('
SELECT c.*, cl.*
FROM `'._DB_PREFIX_.'category` c
INNER JOIN `'._DB_PREFIX_.'category_shop` category_shop ON (category_shop.`id_category` = c.`id_category` AND category_shop.`id_shop` = "'.(int)$shop_id.'")
LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (c.`id_category` = cl.`id_category` AND cl.`id_shop` = "'.(int)$shop_id.'")
WHERE (c.`id_parent` <= 4) '.$sql_filter.' '.($id_lang ? 'AND cl.`id_lang` = '.(int)$id_lang : '').'
'.($active ? ' AND (c.`active` = 1 OR c.`is_root_category` = 1)' : '').'
order by c.`id_parent`, cl.`name`
'.($sql_limit != '' ? $sql_limit : '')
);
...
}
...
}
--------
/yourthemes/category.tpl
Ability to display subcategories (need disable module "Categories block", as there is error with display categories in query for load list categories)
edit block "" ... disable scanning to display subcategories
{if (isset($display_subcategories) && $display_subcategories eq 1) || !isset($display_subcategories) }
--------
========
- editing class "Product", allowing enable some modules for works with products, for example module "New Products"
--------
/classes/Product.php
editing public static function "getNewProducts",comment out the call "if (Group::isFeatureActive())"
public static function getNewProducts($id_lang, $page_number = 0, $nb_products = 10, $count = false, $order_by = null, $order_way = null, Context $context = null)
{
...
/*if (Group::isFeatureActive())
{
$groups = FrontController::getCurrentCustomerGroups();
$sql_groups = 'AND p.`id_product` IN (
SELECT cp.`id_product`
FROM `'._DB_PREFIX_.'category_group` cg
LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_category` = cg.`id_category`)
WHERE cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1').'
)';
}*/
...
/*if (Group::isFeatureActive())
$sql->where('p.`id_product` IN (
SELECT cp.`id_product`
FROM `'._DB_PREFIX_.'category_group` cg
LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_category` = cg.`id_category`)
WHERE cg.`id_group` '.$sql_groups.'
)');*/
...
}
--------
/classes/Product.php
editing public static function "getRandomSpecial"
public static function getRandomSpecial($id_lang, $beginning = false, $ending = false, Context $context = null)
{
...
if ($product_reductions)
{
...
$sql = 'SELECT product_shop.id_product, MAX(product_attribute_shop.id_product_attribute) id_product_attribute
FROM `'._DB_PREFIX_.'product` p
'.Shop::addSqlAssociation('product', 'p').'
LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (product_shop.id_product = pa.id_product)
'.Shop::addSqlAssociation('product_attribute', 'pa', false, 'product_attribute_shop.default_on = 1').'
WHERE product_shop.`active` = 1
'.(($ids_product) ? $ids_product : '').'
AND p.`id_product` IN (
SELECT cp.`id_product`
FROM `'._DB_PREFIX_.'category_group` cg
LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_category` = cg.`id_category`)
WHERE cg.`id_group` '.$sql_groups.'
)
'.($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '').'
GROUP BY product_shop.id_product
ORDER BY RAND()';
...
}
}
replaced by :
public static function getRandomSpecial($id_lang, $beginning = false, $ending = false, Context $context = null)
{
...
if ($product_reductions)
{
...
$sql = 'SELECT product_shop.id_product, MAX(product_attribute_shop.id_product_attribute) id_product_attribute
FROM `'._DB_PREFIX_.'product` p
'.Shop::addSqlAssociation('product', 'p').'
LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (product_shop.id_product = pa.id_product)
'.Shop::addSqlAssociation('product_attribute', 'pa', false, 'product_attribute_shop.default_on = 1').'
WHERE product_shop.`active` = 1
'.(($ids_product) ? $ids_product : '').'
'.($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '').'
GROUP BY product_shop.id_product
ORDER BY RAND()';
...
}
}
--------
/classes/Product.php
editing public static function "getPricesDrop", comment out the call "if (Group::isFeatureActive())"
public static function getPricesDrop($id_lang, $page_number = 0, $nb_products = 10, $count = false,
$order_by = null, $order_way = null, $beginning = false, $ending = false, Context $context = null)
{
...
/*if (Group::isFeatureActive())
{
$groups = FrontController::getCurrentCustomerGroups();
$sql_groups = 'AND p.`id_product` IN (
SELECT cp.`id_product`
FROM `'._DB_PREFIX_.'category_group` cg
LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_category` = cg.`id_category`)
WHERE cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1').'
)';
}*/
...
}
--------
/classes/Product.php
editing public function "checkAccess"
public function checkAccess($id_customer)
{
if (!Group::isFeatureActive())
return true;
$cache_id = 'Product::checkAccess_'.(int)$this->id.'-'.(int)$id_customer.(!$id_customer ? '-'.(int)Group::getCurrent()->id : '');
if (!Cache::isStored($cache_id))
{
if (!$id_customer)
$result = (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT ctg.`id_group`
FROM `'._DB_PREFIX_.'category_product` cp
INNER JOIN `'._DB_PREFIX_.'category_group` ctg ON (ctg.`id_category` = cp.`id_category`)
WHERE cp.`id_product` = '.(int)$this->id.' AND ctg.`id_group` = '.(int)Group::getCurrent()->id);
else
$result = (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT cg.`id_group`
FROM `'._DB_PREFIX_.'category_product` cp
INNER JOIN `'._DB_PREFIX_.'category_group` ctg ON (ctg.`id_category` = cp.`id_category`)
INNER JOIN `'._DB_PREFIX_.'customer_group` cg ON (cg.`id_group` = ctg.`id_group`)
WHERE cp.`id_product` = '.(int)$this->id.' AND cg.`id_customer` = '.(int)$id_customer);
Cache::store($cache_id, $result);
}
return Cache::retrieve($cache_id);
}
replaced by :
public function checkAccess($id_customer)
{
return true;
}
--------
========
- ABILITY TO DISPLAY FOR DESCRIPTION OF THE CONDITIONS OF APPLICATION OF SPARE PARTS FOR THE SELECTED CATEGORY
1. first need fill database sql-data which was creating on page "Export data"
2. create empty table with your prefix
CREATE TABLE IF NOT EXISTS `ps_TermOfUseFromTecDoc` (`id_category` int(10) NOT NULL, `id_product` int(10) NOT NULL, `id_lang` int(10) NOT NULL, `id_feature` int(10) DEFAULT '0', `value` varchar(255) DEFAULT NULL, KEY `idcat_idprod` (`id_category`, `id_product`), KEY `id_product` (`id_product`));
... create table "TermsOfUse" http://ttc.bovsoft.com/download/creatorforprestashop_ver_1.2.5.jpg
--------
/classes/Category.php
change query for function "getProducts"
$sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity, MAX(product_attribute_shop.id_product_attribute) id_product_attribute, product_attribute_shop.minimal_quantity AS product_attribute_minimal_quantity, pl.`description`, pl.`description_short`, pl.`available_now`,
pl.`available_later`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, MAX(image_shop.`id_image`) id_image,
il.`legend`, m.`name` AS manufacturer_name, cl.`name` AS category_default,
DATEDIFF(product_shop.`date_add`, DATE_SUB(NOW(),
INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).'
DAY)) > 0 AS new, product_shop.price AS orderprice
FROM `'._DB_PREFIX_.'category_product` cp
LEFT JOIN `'._DB_PREFIX_.'product` p
ON p.`id_product` = cp.`id_product`
'.Shop::addSqlAssociation('product', 'p').'
LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa
ON (p.`id_product` = pa.`id_product`)
'.Shop::addSqlAssociation('product_attribute', 'pa', false, 'product_attribute_shop.`default_on` = 1').'
'.Product::sqlStock('p', 'product_attribute_shop', false, $context->shop).'
LEFT JOIN `'._DB_PREFIX_.'category_lang` cl
ON (product_shop.`id_category_default` = cl.`id_category`
AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').')
LEFT JOIN `'._DB_PREFIX_.'product_lang` pl
ON (p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').')
LEFT JOIN `'._DB_PREFIX_.'image` i
ON (i.`id_product` = p.`id_product`)'.
Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').'
LEFT JOIN `'._DB_PREFIX_.'image_lang` il
ON (image_shop.`id_image` = il.`id_image`
AND il.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m
ON m.`id_manufacturer` = p.`id_manufacturer`
WHERE product_shop.`id_shop` = '.(int)$context->shop->id.'
AND cp.`id_category` = '.(int)$this->id
.($active ? ' AND product_shop.`active` = 1' : '')
.($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '')
.($id_supplier ? ' AND p.id_supplier = '.(int)$id_supplier : '')
.' GROUP BY product_shop.id_product';
replaced by :
$sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity, MAX(product_attribute_shop.id_product_attribute) id_product_attribute, product_attribute_shop.minimal_quantity AS product_attribute_minimal_quantity, pl.`description`, pl.`description_short`, pl.`available_now`,
pl.`available_later`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, MAX(image_shop.`id_image`) id_image,
il.`legend`, m.`name` AS manufacturer_name, cl.`name` AS category_default,
DATEDIFF(product_shop.`date_add`, DATE_SUB(NOW(),
INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).'
DAY)) > 0 AS new, product_shop.price AS orderprice
,(SELECT DISTINCT
GROUP_CONCAT(CONCAT(fln.`name`," :: ",fval.`value`) SEPARATOR "
")
FROM '._DB_PREFIX_.'feature_product as fpr
JOIN '._DB_PREFIX_.'feature_lang as fln ON (fln.`id_feature` = fpr.`id_feature`)
JOIN '._DB_PREFIX_.'feature_value_lang fval ON (fval.`id_feature_value` = fpr.`id_feature_value`)
where (id_product = p.`id_product`)
AND (fln.`id_lang` = '.(int)$id_lang.')
AND (fval.`id_lang` = '.(int)$id_lang.')
) AS feature
,(SELECT DISTINCT
GROUP_CONCAT(CONCAT(fln2.`name`," :: ",tuse.`value`) SEPARATOR "
")
FROM '._DB_PREFIX_.'TermOfUseFromTecDoc as tuse
LEFT JOIN '._DB_PREFIX_.'feature_lang as fln2 ON (fln2.`id_feature` = tuse.`id_feature` AND fln2.`id_lang` = '.(int)$id_lang.')
JOIN '._DB_PREFIX_.'category AS T1 ON (tuse.id_category = T1.id_category)
JOIN '._DB_PREFIX_.'category AS T2 ON (T1.id_category = T2.id_parent)
JOIN '._DB_PREFIX_.'category AS T3 ON (T2.id_category = T3.id_parent)
where (tuse.`id_product` = p.`id_product`)
AND (T3.`id_category` = '.(int)$this->id.')
AND (tuse.`id_lang` = '.(int)$id_lang.')
) AS termsofuse
FROM `'._DB_PREFIX_.'category_product` cp
LEFT JOIN `'._DB_PREFIX_.'product` p
ON p.`id_product` = cp.`id_product`
'.Shop::addSqlAssociation('product', 'p').'
LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa
ON (p.`id_product` = pa.`id_product`)
'.Shop::addSqlAssociation('product_attribute', 'pa', false, 'product_attribute_shop.`default_on` = 1').'
'.Product::sqlStock('p', 'product_attribute_shop', false, $context->shop).'
LEFT JOIN `'._DB_PREFIX_.'category_lang` cl
ON (product_shop.`id_category_default` = cl.`id_category`
AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').')
LEFT JOIN `'._DB_PREFIX_.'product_lang` pl
ON (p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').')
LEFT JOIN `'._DB_PREFIX_.'image` i
ON (i.`id_product` = p.`id_product`)'.
Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').'
LEFT JOIN `'._DB_PREFIX_.'image_lang` il
ON (image_shop.`id_image` = il.`id_image`
AND il.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m
ON m.`id_manufacturer` = p.`id_manufacturer`
WHERE product_shop.`id_shop` = '.(int)$context->shop->id.'
AND cp.`id_category` = '.(int)$this->id
.($active ? ' AND product_shop.`active` = 1' : '')
.($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '')
.($id_supplier ? ' AND p.id_supplier = '.(int)$id_supplier : '')
.' GROUP BY product_shop.id_product';
--------
/classes/Search.php
change query for function "searchTag"
$sql = 'SELECT DISTINCT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity, pl.`description_short`, pl.`link_rewrite`, pl.`name`,
MAX(image_shop.`id_image`) id_image, il.`legend`, m.`name` manufacturer_name, 1 position,
DATEDIFF(
p.`date_add`,
DATE_SUB(
NOW(),
INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY
)
) > 0 new
FROM `'._DB_PREFIX_.'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').'
)
'.Shop::addSqlAssociation('product', 'p', false).'
LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product`)'.
Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').'
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
LEFT JOIN `'._DB_PREFIX_.'product_tag` pt ON (p.`id_product` = pt.`id_product`)
LEFT JOIN `'._DB_PREFIX_.'tag` t ON (pt.`id_tag` = t.`id_tag` AND t.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_product` = p.`id_product`)
'.(Group::isFeatureActive() ? 'LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = cp.`id_category`)' : '').'
LEFT JOIN `'._DB_PREFIX_.'category_shop` cs ON (cp.`id_category` = cs.`id_category` AND cs.`id_shop` = '.(int)$id_shop.')
'.Product::sqlStock('p', 0).'
WHERE product_shop.`active` = 1
AND cs.`id_shop` = '.(int)Context::getContext()->shop->id.'
'.$sql_groups.'
AND t.`name` = \''.pSQL($tag).'\'
GROUP BY product_shop.id_product
ORDER BY position DESC'.($orderBy ? ', '.$orderBy : '').($orderWay ? ' '.$orderWay : '').'
LIMIT '.(int)(($pageNumber - 1) * $pageSize).','.(int)$pageSize;
replaced by :
$sql = 'SELECT DISTINCT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity, pl.`description_short`, pl.`link_rewrite`, pl.`name`,
MAX(image_shop.`id_image`) id_image, il.`legend`, m.`name` manufacturer_name, 1 position,
DATEDIFF(
p.`date_add`,
DATE_SUB(
NOW(),
INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY
)
) > 0 new
,(SELECT DISTINCT
GROUP_CONCAT(CONCAT(fln.`name`," :: ",fval.`value`) SEPARATOR "
")
FROM '._DB_PREFIX_.'feature_product as fpr
JOIN '._DB_PREFIX_.'feature_lang as fln ON (fln.`id_feature` = fpr.`id_feature`)
JOIN '._DB_PREFIX_.'feature_value_lang fval ON (fval.`id_feature_value` = fpr.`id_feature_value`)
where (id_product = p.`id_product`)
AND (fln.`id_lang` = '.(int)$id_lang.')
AND (fval.`id_lang` = '.(int)$id_lang.')
) AS feature
FROM `'._DB_PREFIX_.'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').'
)
'.Shop::addSqlAssociation('product', 'p', false).'
LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product`)'.
Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').'
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
LEFT JOIN `'._DB_PREFIX_.'product_tag` pt ON (p.`id_product` = pt.`id_product`)
LEFT JOIN `'._DB_PREFIX_.'tag` t ON (pt.`id_tag` = t.`id_tag` AND t.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_product` = p.`id_product`)
'.(Group::isFeatureActive() ? 'LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = cp.`id_category`)' : '').'
LEFT JOIN `'._DB_PREFIX_.'category_shop` cs ON (cp.`id_category` = cs.`id_category` AND cs.`id_shop` = '.(int)$id_shop.')
'.Product::sqlStock('p', 0).'
WHERE product_shop.`active` = 1
AND cs.`id_shop` = '.(int)Context::getContext()->shop->id.'
'.$sql_groups.'
AND t.`name` = \''.pSQL($tag).'\'
GROUP BY product_shop.id_product
ORDER BY position DESC'.($orderBy ? ', '.$orderBy : '').($orderWay ? ' '.$orderWay : '').'
LIMIT '.(int)(($pageNumber - 1) * $pageSize).','.(int)$pageSize;
--------
\themes\yourtemes\product-list.tpl
change class "product-desc", add 2 rows
...
{if isset($product.termsofuse)}{$product.termsofuse}
{/if}
{$product.feature}
...
--------
========
- for opportunity to correct display "breadcrumb"-string
--------
/classes/Product.php
add new public value to class "breadcrumb_path"
class ProductCore extends ObjectModel
{
...
// add
public $breadcrumb_path;
...
}
--------
/classes/Product.php
add new procedure getBreadcrumbPath
public static function getBreadcrumbPath($id_product)
{
$id_lang = (int)Context::getContext()->language->id;
$id_shop = (int)Context::getContext()->shop->id;
$tmp = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT DISTINCT
T1.id_category AS ID1,
T2.id_category AS ID2,
T.id_category AS ID3,
(select min(M4.NAME) from '._DB_PREFIX_.'category_lang as M4 where (M4.id_shop = '.(int)$id_shop.') AND (M4.id_lang = '.(int)$id_lang.') and (M4.id_category = T4.id_category)) AS nameCAT_1,
(select min(M3.NAME) from '._DB_PREFIX_.'category_lang as M3 where (M3.id_shop = '.(int)$id_shop.') AND (M3.id_lang = '.(int)$id_lang.') and (M3.id_category = T3.id_category)) AS nameCAT_2,
(select min(M2.NAME) from '._DB_PREFIX_.'category_lang as M2 where (M2.id_shop = '.(int)$id_shop.') AND (M2.id_lang = '.(int)$id_lang.') and (M2.id_category = T2.id_category)) AS nameCAT_3,
(select min(M1.NAME) from '._DB_PREFIX_.'category_lang as M1 where (M1.id_shop = '.(int)$id_shop.') AND (M1.id_lang = '.(int)$id_lang.') and (M1.id_category = T1.id_category)) AS nameCAT_4,
M.name AS nameCAT_5
FROM '._DB_PREFIX_.'category_lang AS M
JOIN '._DB_PREFIX_.'product as CatProd on (M.id_category = CatProd.id_category_default)
JOIN '._DB_PREFIX_.'category AS T ON (T.id_category = M.id_category)
JOIN '._DB_PREFIX_.'category AS T1 ON (T1.id_category = T.id_parent)
JOIN '._DB_PREFIX_.'category AS T2 ON (T2.id_category = T1.id_parent)
JOIN '._DB_PREFIX_.'category AS T3 ON (T3.id_category = T2.id_parent)
JOIN '._DB_PREFIX_.'category AS T4 ON (T4.id_category = T3.id_parent)
WHERE CatProd.id_product = '.(int)$id_product.' AND CatProd.id_category_default IS NOT NULL
AND (M.id_shop = '.(int)$id_shop.') AND (M.id_lang = '.(int)$id_lang.')
LIMIT 1');
if ($tmp)
foreach ($tmp as $aplic)
$result = $aplic['nameCAT_3'].'^'.$aplic['ID2'].'^'.$aplic['nameCAT_4'].'^'.$aplic['ID1'].'^'.$aplic['nameCAT_5'].'^'.$aplic['ID3'];
return $result;
}
--------
/classes/Product.php
initialization data ...
public function __construct($id_product = null, $full = false, $id_lang = null, $id_shop = null, Context $context = null)
{
...
if ($full && $this->id)
{
...
// add
if ($this->id)
$this->breadcrumb_path = Product::getBreadcrumbPath((int)$this->id);
...
}
...
}
--------
/classes/Category.php
add new public value to class "breadcrumb_path"
class CategoryCore extends ObjectModel
{
...
// add
public $breadcrumb_path;
...
}
--------
/classes/Category.php
add new procedure getBreadcrumbPath
public static function getBreadcrumbPath($id_category)
{
$id_lang = (int)Context::getContext()->language->id;
$id_shop = (int)Context::getContext()->shop->id;
$tmp = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT DISTINCT
T6.id_category AS ID0,
T5.id_category AS ID1,
T4.id_category AS ID2,
T3.id_category AS ID3,
T2.id_category AS ID4,
T1.id_category AS ID5,
(select min(M6.NAME) from '._DB_PREFIX_.'category_lang as M6 where (M6.id_shop = '.(int)$id_shop.') AND (M6.id_lang = '.(int)$id_lang.') and (M6.id_category = T6.id_category)) AS nameCAT_0,
(select min(M5.NAME) from '._DB_PREFIX_.'category_lang as M5 where (M5.id_shop = '.(int)$id_shop.') AND (M5.id_lang = '.(int)$id_lang.') and (M5.id_category = T5.id_category)) AS nameCAT_1,
(select min(M4.NAME) from '._DB_PREFIX_.'category_lang as M4 where (M4.id_shop = '.(int)$id_shop.') AND (M4.id_lang = '.(int)$id_lang.') and (M4.id_category = T4.id_category)) AS nameCAT_2,
(select min(M3.NAME) from '._DB_PREFIX_.'category_lang as M3 where (M3.id_shop = '.(int)$id_shop.') AND (M3.id_lang = '.(int)$id_lang.') and (M3.id_category = T3.id_category)) AS nameCAT_3,
(select min(M2.NAME) from '._DB_PREFIX_.'category_lang as M2 where (M2.id_shop = '.(int)$id_shop.') AND (M2.id_lang = '.(int)$id_lang.') and (M2.id_category = T2.id_category)) AS nameCAT_4,
(select min(M1.NAME) from '._DB_PREFIX_.'category_lang as M1 where (M1.id_shop = '.(int)$id_shop.') AND (M1.id_lang = '.(int)$id_lang.') and (M1.id_category = T1.id_category)) AS nameCAT_5
FROM '._DB_PREFIX_.'category AS T1
left JOIN '._DB_PREFIX_.'category AS T2 ON (T2.id_category = T1.id_parent)
left JOIN '._DB_PREFIX_.'category AS T3 ON (T3.id_category = T2.id_parent)
left JOIN '._DB_PREFIX_.'category AS T4 ON (T4.id_category = T3.id_parent)
left JOIN '._DB_PREFIX_.'category AS T5 ON (T5.id_category = T4.id_parent)
left JOIN '._DB_PREFIX_.'category AS T6 ON (T6.id_category = T5.id_parent)
WHERE T1.id_category = '.(int)$id_category.'
LIMIT 1');
if ($tmp)
foreach ($tmp as $aplic)
$result = $aplic['nameCAT_0'].'^'.$aplic['ID0'].'^'.$aplic['nameCAT_1'].'^'.$aplic['ID1'].'^'.$aplic['nameCAT_2'].'^'.$aplic['ID2'].'^'.$aplic['nameCAT_3'].'^'.$aplic['ID3'].'^'.$aplic['nameCAT_4'].'^'.$aplic['ID4'].'^'.$aplic['nameCAT_5'].'^'.$aplic['ID5'];
return $result;
}
--------
/classes/Category.php
initialization data ...
public function __construct($id_category = null, $id_lang = null, $id_shop = null)
{
...
// add
$this->breadcrumb_path = Category::getBreadcrumbPath((int)$id_category);
}
--------
yourthemes/breadcrumb.tpl
change pattern to display data ... change for ""
{if isset($path) AND $path}
id_category) && $category->id_category == 1}style="display:none;"{/if}>{$navigationPipe|escape:'html':'UTF-8'}
{if !$path|strpos:'span'}
{$path}
{else}
{$path}
{/if}
{/if}
replaced by :
{$navigationPipe|escape:'html':'UTF-8'}
{if $product->breadcrumb_path}
{$tag = $product->breadcrumb_path}
{if isset($tag)}
{$tag_1=strtok($tag, '^')}
{$tag_2=strtok('^')}
{$tag_3=strtok('^')}
{$tag_4=strtok('^')}
{$tag_5=strtok('^')}
{$tag_6=strtok('^')}
{$tag_1|escape:'html':'UTF-8'}
{$navigationPipe|escape:'html':'UTF-8'}
{$tag_3|escape:'html':'UTF-8'}
{$navigationPipe|escape:'html':'UTF-8'}
{$tag_5|escape:'html':'UTF-8'}
{$navigationPipe|escape:'html':'UTF-8'}
{/if}
{else}
{if $category->breadcrumb_path}
{$tag = $category->breadcrumb_path}
{if isset($tag)}
{$tag_1=strtok($tag, '^')}
{$tag_2=strtok('^')}
{$tag_3=strtok('^')}
{$tag_4=strtok('^')}
{$tag_5=strtok('^')}
{$tag_6=strtok('^')}
{$tag_7=strtok('^')}
{$tag_8=strtok('^')}
{$tag_9=strtok('^')}
{$tag_10=strtok('^')}
{$tag_11=strtok('^')}
{$tag_12=strtok('^')}
{if ($tag_2 != '' && $tag_1 != 'Root' && $tag_1 != 'Home') }
{$tag_1|escape:'html':'UTF-8'}
{$navigationPipe|escape:'html':'UTF-8'}
{/if}
{if ($tag_4 != '' && $tag_3 != 'Root' && $tag_3 != 'Home') }
{$tag_3|escape:'html':'UTF-8'}
{$navigationPipe|escape:'html':'UTF-8'}
{/if}
{if ($tag_6 != '' && $tag_5 != 'Root' && $tag_5 != 'Home') }
{$tag_5|escape:'html':'UTF-8'}
{$navigationPipe|escape:'html':'UTF-8'}
{/if}
{if ($tag_8 != '' && $tag_7 != 'Root' && $tag_7 != 'Home') }
{$tag_7|escape:'html':'UTF-8'}
{$navigationPipe|escape:'html':'UTF-8'}
{/if}
{if ($tag_10 != '' && $tag_9 != 'Root' && $tag_9 != 'Home') }
{$tag_9|escape:'html':'UTF-8'}
{$navigationPipe|escape:'html':'UTF-8'}
{/if}
{if ($tag_12 != '' && $tag_11 != 'Root' && $tag_11 != 'Home') }
{$tag_11|escape:'html':'UTF-8'}
{$navigationPipe|escape:'html':'UTF-8'}
{/if}
{/if}
{/if}
{/if}
========
- Changing the scheme obtain link to the product image
--------
/classes/Link.php
instead of ...
public function getImageLink($name, $ids, $type = null)
{
$not_default = false;
// legacy mode or default image
$theme = ((Shop::isFeatureActive() && file_exists(_PS_PROD_IMG_DIR_.$ids.($type ? '-'.$type : '').'-'.(int)Context::getContext()->shop->id_theme.'.jpg')) ? '-'.Context::getContext()->shop->id_theme : '');
if ((Configuration::get('PS_LEGACY_IMAGES')
&& (file_exists(_PS_PROD_IMG_DIR_.$ids.($type ? '-'.$type : '').$theme.'.jpg')))
|| ($not_default = strpos($ids, 'default') !== false))
{
if ($this->allow == 1 && !$not_default)
$uri_path = __PS_BASE_URI__.$ids.($type ? '-'.$type : '').$theme.'/'.$name.'.jpg';
else
$uri_path = _THEME_PROD_DIR_.$ids.($type ? '-'.$type : '').$theme.'.jpg';
}
else
{
// if ids if of the form id_product-id_image, we want to extract the id_image part
$split_ids = explode('-', $ids);
$id_image = (isset($split_ids[1]) ? $split_ids[1] : $split_ids[0]);
$theme = ((Shop::isFeatureActive() && file_exists(_PS_PROD_IMG_DIR_.Image::getImgFolderStatic($id_image).$id_image.($type ? '-'.$type : '').'-'.(int)Context::getContext()->shop->id_theme.'.jpg')) ? '-'.Context::getContext()->shop->id_theme : '');
if ($this->allow == 1)
$uri_path = __PS_BASE_URI__.$id_image.($type ? '-'.$type : '').$theme.'/'.$name.'.jpg';
else
$uri_path = _THEME_PROD_DIR_.Image::getImgFolderStatic($id_image).$id_image.($type ? '-'.$type : '').$theme.'.jpg';
}
return $this->protocol_content.Tools::getMediaServer($uri_path).$uri_path;
}
replaced by :
public function getImageLink($name, $ids, $type = null)
{
$not_default = false;
// legacy mode or default image
$theme = ((Shop::isFeatureActive() && file_exists(_PS_PROD_IMG_DIR_.$ids.($type ? '-'.$type : '').'-'.(int)Context::getContext()->shop->id_theme.'.jpg')) ? '-'.Context::getContext()->shop->id_theme : '');
if ((Configuration::get('PS_LEGACY_IMAGES')
&& (file_exists(_PS_PROD_IMG_DIR_.$ids.($type ? '-'.$type : '').$theme.'.jpg')))
|| ($not_default = strpos($ids, 'default') !== false))
{
if ($this->allow == 1 && !$not_default)
$uri_path = __PS_BASE_URI__.$ids.($type ? '-'.$type : '').$theme.'/'.$name.'.jpg';
else
$uri_path = _THEME_PROD_DIR_.$ids.($type ? '-'.$type : '').$theme.'.jpg';
return $this->protocol_content.Tools::getMediaServer($uri_path).$uri_path;
}
else
{
$linkimg='';
$split_ids = explode('-', $ids);
$id_image = (isset($split_ids[1]) ? $split_ids[1] : $split_ids[0]);
$tmp = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("
SELECT CONCAT(img.sup_id, '/', img.art_id,img.prefixs,'.',img.ext) AS linkimg
FROM "._DB_PREFIX_."image_from_bovsoft as img
WHERE (img.id_image = ".(int)$id_image.")
LIMIT 1");
if ($tmp)
foreach ($tmp as $aplic)
$linkimg=$aplic['linkimg'];
if ($linkimg != '')
{
$uri_path=$this->getBaseLink((int)Context::getContext()->shop->id).'img/p_from_bovsoft/'.$linkimg;
return $uri_path;
}
else
{
if ($this->allow == 1 && !$not_default)
$uri_path = __PS_BASE_URI__.$ids.($type ? '-'.$type : '').$theme.'/'.$name.'.jpg';
else
$uri_path = _THEME_PROD_DIR_.$ids.($type ? '-'.$type : '').$theme.'.jpg';
return $this->protocol_content.Tools::getMediaServer($uri_path).$uri_path;
};
}
}
--------
=================================
!!!! AFTER ALL THE NECESSARY CHANGES NEED TO CLEAR ALL CACHES INCLUDING SMARTY (CACHE AND COMPILE) !!!!
- samples php-files which was changed for PrestaShop ver 1.6.0.9 http://ttc.bovsoft.com/download/CHANGES_PAGES_FOR_PRESTASHOP.rar (you can use all the files for your store after filling the database, you only need to check the version and template structure and use files from a folder "themes->yourtheme" if they correspond to your files, or to do the same changes in your files ...)
- sample for displaying of cross-references codes on the product page and list of vehicles for which are used a specified spare part http://demoprestashop.ttc.bovsoft.com/index.php?id_product=6278&controller=product
- sample for displaying of terms of use http://demoprestashop.ttc.bovsoft.com/index.php?id_category=2087&controller=category
p.s. all changes have been made at your own risk if you have a vast knowledge of web programming, you can make changes according to your knowledge