Jump to content

[solved]Product class override passing variable with product-list.tpl


Recommended Posts

Hi,

I use prestashop version 1.5.4.1.

I read hundred of posts and manual, but still didn't find how to assign and exchange a variable between the overriding Product.php file and product-list.tpl file.

I wish to create a custom function to truncate the $product.description_short to say 100 chars but keeping the html tags. I found some examples of solution, but don't succeed to pass the result to the template file product-list.tpl!

After many tests to search for right syntax, I succeed to see with debug console, that my function is called and executed in my overriding Product.php file but dying after maximum execution time because of deadend loop in my function. So I just succeed to assign a variable in template file and display it this way

{assign var=my_var value='test'} then display it with

{$my_var}

Now to just test passing a variable, I tried these ways, always using {$my_var} in template product-list.tpl:

<?php
class Product extends ProductCore
{
//public  $my_var; 
//public static $my_var = 'test';
//$smarty->assign('my_var', function1($args));
//assign($my_var, value='test');
//$smarty->assign('my_var', 'test');


 public function get_position($content, $position, $chars = 100)
 {
   ...
   return $var1;
 }
public function function1($content, $chars = 50)
 {
    $position = 0; $data=array();
    while(...){
     ...$next_position = $this->get_position($content, $position, $chars );
    $data[] = substr($content, $position, $next_position);
    }
    ...
   return $data;
 }
public function __construct($id_product = null, $full = false, $id_lang = null, $id_shop = null, Context $context = null)
 {
    parent::__construct($id_product, $full, $id_lang);
    //$this->my_var= 'test' ; 
    //$this->my_var= $smarty->get_template_vars('my_var');;
    //$this->context->smarty->assign('my_var', $this->my_var);
    //$this->assign('my_var', $this->my_var);
    //$this->my_var = $this->function1('testtesttesttest',10);
    //self::$smarty->assign('my_var',function1('testtesttesttest',10));
    //self::$smarty->assign('my_var','test);
 }
}
?>

(In the code above, I comment all syntax tests, of course I uncomment one at a time to test it.)

In the debug console I see that $content and $chars take right value, this means functions are called.

 

But I don't find the right syntax to assign my_var in product.php so it is readable in product-list.tpl. Most of the tests give syntax error or "Notice: Undefined index:my_var in..." if I don't assign my_var in product-list.tpl

Of course, I also need in Product.php file to read arguments coming from product-list.tpl call..

Thanks in advance for any help

Meanwhile I look for custom function using plugin... but I read that custom plugin should be placed in a "plugins" directory but documentation is not clear about where to install this directory. By default it is said that smarty will look in default smarty "plugins" directory in smarty_dir, but I don't know where is this default directory. I noticed in debug console that it is rootdir\tools\smarty\plugins\ is it right?

Thanks again

 

Edited by smr (see edit history)
Link to comment
Share on other sites

I suceed with using plugin! 

I had to create a function.truncHtml.php file that I saved in rootdir/tools/smarty/plugins/

(there is a lot of plugins to read as examples!)

the content of this file is:

<?php
/*
 * Smarty plugin
 * -------------------------------------------------------------
 * File:     function.truncHtml.php
 * Type:     function
 * Name:     truncHtml
 * Purpose:  truncate string to a length keeping Html tags and outputs a response
 * -------------------------------------------------------------
 */


function smarty_function_truncHtml($params, &$smarty, $patternsReplace = false) {
    $string=$params['mystring'] ; $length= $params['chars'] ;
    $i = 0;
    $count = 0;
    $isParagraphCut = false;
    $htmlOpen = false;
    $openTag = false;
    $tagsStack = array();


    while ($i < strlen($string)) {
        $char = substr($string, $i, 1);
        if ($count >= $length) {
            $isParagraphCut = true;
            break;
        }


        if ($htmlOpen) {
            if ($char === ">") {
                $htmlOpen = false;
            }
        } else {
            if ($char === "<") {
                $j = $i;
                $char = substr($string, $j, 1);


                while ($j < strlen($string)) {
                    if($char === '/'){
                        $i++;
                        break;
                    }
                    elseif ($char === ' ') {
                        $tagsStack[] = substr($string, $i, $j);
                    }
                    $j++;
                }
                $htmlOpen = true;
            }
        }


        if (!$htmlOpen && $char != ">") {
            $count++;
        }


        $i++;
    }


    if ($isParagraphCut) {
        $j = $i;
        while ($j > 0) {
            $char = substr($string, $j, 1);
            if ($char === " " || $char === ";" || $char === "." || $char === "," || $char === "<" || $char === "(" || $char === "[") {
                break;
            } else if ($char === ">") {
                $j++;
                break;
            }
            $j--;
        }
        $string = substr($string, 0, $j);
        foreach($tagsStack as $tag){
            $tag = strtolower($tag);
            if($tag !== "img" && $tag !== "br"){
                $string .= "</$tag>";
            }
        }
        $string .= "...";
    }


    if ($patternsReplace) {
        foreach ($patternsReplace as $value) {
            if (isset($value['pattern']) && isset($value["replace"])) {
                $string = preg_replace($value["pattern"], $value["replace"], $string);
            }
        }
    }
    return $string;
}
?>

Be careful that the name of the php plugin file must be "smarty_function_nameofyourfunction.php" and the name of your main function must have the same name syntax so the first line of function is

"function smarty_function_nameofyourfunction($params..."

where $params is the variable sent by your template file (product-list.tpl in my case) when it is invoking this custom function. $params may be an array of variables ; in my case I call the function like this in product-list.tpl

{truncHtml mystring=$product.description_short chars=250}

I found this plugin creation syntax here 

and I found the truncHtml function here it is said it is not perfect but enough for my case.

It is not clear how many and what parameters to write in the function defintion. I tried with a single parameter and it is ok like this

function smarty_function_truncHtml($params) {
  $string=$params['mystring'] ; $length= $params['chars'] ; $patternsReplace = false ;

But it is not ok with three parameters this way

function smarty_function_truncHtml($params, $patternsReplace = false, &$smarty) {

it seems &$smarty must be the second parameter if there are three parameters (or two)

Still no solution with overriding

Edited by smr (see edit history)
Link to comment
Share on other sites

thanks for your help.

problem is I don't see where to place this statement.

I tried in my Product.php overriding file but this give syntax errors

I tried in a new ProductController.php overriding file, this way

<?php
class ProductController extends ProductControllerCore
{
 public function initContent()
 {
    $this->context->smarty->assign(array('test' => 'this is test'));  
    parent::initContent();
 } 
}
?>

no syntax error, but my $test variable is not visible in product-list.tpl...

Edited by smr (see edit history)
Link to comment
Share on other sites

Sure it is more clear when we know the solution,

I did so and progressed by transmitting a variable from CategoryController override file to product-list.tpl, either directly or through a function this way

<?php
class CategoryController extends CategoryControllerCore
{
 public function initContent()
 {
     function Test($params){ return $params; }
     $this->context->smarty->assign(array('var1' => 'this is test'));
     $this->context->smarty->assign('var2',Test('this is another test' ));  
    parent::initContent();
 }
}
?>

and in product-list.tpl 

{$var1} or {$var2}

but I didn't find yet how to pass a variable from product-list.tpl to CategoryController, to be used in a function, something like

{Test, 'this is a test'}

or my target usage:

{Test, $product.description_short, 100}

Thanks again

Link to comment
Share on other sites

I got it! Here how to code the controller:

<?php
class CategoryController extends CategoryControllerCore
{
 public function initContent()
 {
  function Test($params){ return $params;}
     
  function mytruncHtml($string,$length) {
    $patternsReplace = false ;
    $i = 0;
    $count = 0;
    $isParagraphCut = false;
    $htmlOpen = false;
    $openTag = false;
    $tagsStack = array();


    while ($i < strlen($string)) {
        $char = substr($string, $i, 1);
        if ($count >= $length) {
            $isParagraphCut = true;
            break;
        }


        if ($htmlOpen) {
            if ($char === ">") {
                $htmlOpen = false;
            }
        } else {
            if ($char === "<") {
                $j = $i;
                $char = substr($string, $j, 1);


                while ($j < strlen($string)) {
                    if($char === '/'){
                        $i++;
                        break;
                    }
                    elseif ($char === ' ') {
                        $tagsStack[] = substr($string, $i, $j);
                    }
                    $j++;
                }
                $htmlOpen = true;
            }
        }


        if (!$htmlOpen && $char != ">") {
            $count++;
        }


        $i++;
    }


    if ($isParagraphCut) {
        $j = $i;
        while ($j > 0) {
            $char = substr($string, $j, 1);
            if ($char === " " || $char === ";" || $char === "." || $char === "," || $char === "<" || $char === "(" || $char === "[") {
                break;
            } else if ($char === ">") {
                $j++;
                break;
            }
            $j--;
        }
        $string = substr($string, 0, $j);
        foreach($tagsStack as $tag){
            $tag = strtolower($tag);
            if($tag !== "img" && $tag !== "br"){
                $string .= "</$tag>";
            }
        }
        $string .= "...";
    }


    if ($patternsReplace) {
        foreach ($patternsReplace as $value) {
            if (isset($value['pattern']) && isset($value["replace"])) {
                $string = preg_replace($value["pattern"], $value["replace"], $string);
            }
        }
    }
    return $string;
  } 
    parent::initContent();
 }
}
?>

and here is how to call the function in product-list.tpl

 

{call_user_func_array('mytruncHtml', array($product.description_short,230))}

or for a simple function with one argument

{call_user_func('Test', 'my new test')}

 

Thanks for helps

 

  • Like 1
Link to comment
Share on other sites

 

I got it! Here how to code the controller:

<?php
class CategoryController extends CategoryControllerCore
{
 public function initContent()
 {
  function Test($params){ return $params;}
     
  function mytruncHtml($string,$length) {
    $patternsReplace = false ;
    $i = 0;
    $count = 0;
    $isParagraphCut = false;
    $htmlOpen = false;
    $openTag = false;
    $tagsStack = array();


    while ($i < strlen($string)) {
        $char = substr($string, $i, 1);
        if ($count >= $length) {
            $isParagraphCut = true;
            break;
        }


        if ($htmlOpen) {
            if ($char === ">") {
                $htmlOpen = false;
            }
        } else {
            if ($char === "<") {
                $j = $i;
                $char = substr($string, $j, 1);


                while ($j < strlen($string)) {
                    if($char === '/'){
                        $i++;
                        break;
                    }
                    elseif ($char === ' ') {
                        $tagsStack[] = substr($string, $i, $j);
                    }
                    $j++;
                }
                $htmlOpen = true;
            }
        }


        if (!$htmlOpen && $char != ">") {
            $count++;
        }


        $i++;
    }


    if ($isParagraphCut) {
        $j = $i;
        while ($j > 0) {
            $char = substr($string, $j, 1);
            if ($char === " " || $char === ";" || $char === "." || $char === "," || $char === "<" || $char === "(" || $char === "[") {
                break;
            } else if ($char === ">") {
                $j++;
                break;
            }
            $j--;
        }
        $string = substr($string, 0, $j);
        foreach($tagsStack as $tag){
            $tag = strtolower($tag);
            if($tag !== "img" && $tag !== "br"){
                $string .= "</$tag>";
            }
        }
        $string .= "...";
    }


    if ($patternsReplace) {
        foreach ($patternsReplace as $value) {
            if (isset($value['pattern']) && isset($value["replace"])) {
                $string = preg_replace($value["pattern"], $value["replace"], $string);
            }
        }
    }
    return $string;
  } 
    parent::initContent();
 }
}
?>

and here is how to call the function in product-list.tpl

 

{call_user_func_array('mytruncHtml', array($product.description_short,230))}

or for a simple function with one argument

{call_user_func('Test', 'my new test')}

 

Thanks for helps

 

 

give exemple use this technology 

Link to comment
Share on other sites

What kind of exemple you wish, this is a trial, no web site yet with this solution. Here is the code in product-list.tpl, from line 40 to 50

 

<div class="center_block">
<a href="{$product.link|escape:'htmlall':'UTF-8'}" class="product_img_link" title="{$product.name|escape:'htmlall':'UTF-8'}">
<div class="product_desc">  
         <img src="{$link->getImageLink($product.link_rewrite, $product.id_image, 'home_default')|escape:'html'}" alt="{$product.legend|escape:'htmlall':'UTF-8'}" {if isset($homeSize)} width="{$homeSize.width}" height="{$homeSize.height}"{/if} />
{if isset($product.new) && $product.new == 1}<span class="new">{l s='New'}</span>{/if}
   
<span>{if isset($product.pack_quantity) && $product.pack_quantity}{$product.pack_quantity|intval|cat:' x '}{/if}{$product.name|truncate:35:'...'|escape:'htmlall':'UTF-8'}</span>
{call_user_func_array('mytruncHtml', array($product.description_short,230))}
        </div>
        </a>
</div>
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...