Jump to content

Module public function hookDisplayComments no parameters


Recommended Posts

I'm searching crazy why I don't get the $params array with the product id ($params['product']->id).
I have created a module to view video's and all related comments from customers.  In the main-class (video.php) I have normal __construct and in the install-part I have added the right hooks. But when I want to receive the selected product (in my case video), I only get the first array-vakues. That is: 

<?php
declare(strict_types=1);

if(!defined('_PS_VERSION_'))
{
    exit;
}

//require_once __DIR__.'/vendor/autoload.php';
use PrestaShop\PrestaShop\Adapter\SymfonyContainer;
use Video\Classes\VersionUtils;

class Video extends Module
{
	public function __construct()
	{
		$this->name = 'video';
        $this->version = '1.1.0';
        $this->tab = 'front_office_features';
        $this->author = 'Paul Albers';
        $this->need_instance = 0;
        $this->controllers = array('display');
        $this->ps_versions_compliancy = [
            'min' => '1.7.0.0',
            'max' => '8.99.99'
        ];
        $this->bootstrap = true;
        
        parent::__construct();
        
        $this->checkUploadFolders();
        $this->displayName = $this->trans('Video module', [], 'Modules.Video.Admin');
        $this->description = $this->trans('Play video\'s and view customers comments', [], 'Modules.Video.Admin');
        $this->confirmUninstall = $this->trans('Are you sure you want to uninstall?', [], 'Modules.Video.Video');
        $this->templateFile = 'module:video/views/templates/hook/video.tpl';

        if (!Configuration::get('VIDEO')) {
            $this->warning = $this->trans('No name provided', [], 'Modules.Video.Video');
        }
	}

	public function install() {
        if(Shop::isFeatureActive())
        {
            Shop::setContext(Shop::CONTEXT_ALL);
        }

        if(!file_exists(dirname(__FILE__) . '/sql/' . $this->sql_file))
        {
            return $this->displayError($this->l('Unable to find the Sql-file'));
        } elseif(!$sql = file_get_contents(dirname(__FILE__) . '/sql/' . $this->sql_file))
        {
            return $this->displayError($this->l('Unable to get the contents of the sql-file..'));
        }

        $hookAdd = $this->hookCreate();
        return (parent::install() &&
                $this->registerHook('displayProductBeforeThumbs') &&
                $this->registerHook('displayNav2') &&
                $this->registerHook('displayVideoComments') &&
                $this->registerHook('actionFrontControllerSetMedia') &&
                $this->registerHook('actionObjectAddBefore') &&
                $this->registerHook('actionObjectAddAfter') &&
                $this->registerHook('displayAdminProductsExtra') &&
                //$this->registerHook('displayHeader') &&
                $this->registerHook('displayCustomerAccount'));
    }

	public function hookDisplayVideoComments(array $params)
    {
        //print_r($params['product']);
        foreach($params as $value => $key)
        {
            echo $value . ' -> ';
        }
        
        $query = 'SELECT c.comment, c.deleted, c.comment_removed, c.votes, c.date_add, c.id_comment, '
                . 'cu.firstname, cu.lastname, v.comment_enabled, c.sticky FROM '._DB_PREFIX_.'video_comment c '
                //. 'LEFT OUTER JOIN '._DB_PREFIX_.'comment_reply cr ON c.id_comment = cr.id_comment '
                . 'LEFT OUTER JOIN ' . _DB_PREFIX_ . 'customer cu ON c.id_user = cu.id_customer '
                . 'INNER JOIN '._DB_PREFIX_.'video v ON c.id_video = v.id_video '
                . 'WHERE c.id_video = 10 ORDER BY c.sticky DESC, c.date_add;';
      
        $res_video = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query);
        $query = 'SELECT cr.id_comment_reply, c.id_comment, cr.id_user, cr.comment_reply, cr.comment_reply_removed, v.comment_enabled, '
                . 'cr.comment_reply_deleted, cr.comment_reply_date_add, cr.comment_reply_votes FROM ' . _DB_PREFIX_ . 'video_comment_reply cr '
                . 'INNER JOIN ' . _DB_PREFIX_ . 'video_comment c ON cr.id_comment = c.id_comment '
                . 'INNER JOIN ' . _DB_PREFIX_ . 'video v ON c.id_video = v.id_video '
                . 'WHERE c.id_video = 10 ORDER BY cr.id_comment, cr.comment_reply_date_add;';
        $res_replies = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query);
        $this->context->smarty->assign(
        [
            'videoreactionsheader' => $this->display(__FILE__, 'views/templates/hook/videoreactionsheader.tpl'),
            'my_module_link' => $this->context->link->getModuleLink('video', 'views/templates/hook/videoreactionsheader.tpl', [], null, null, null, true),        
            'reactionClasses' => 'reaction-class',
            'module_templates' => dirname(__FILE__).'/views/',
            'reactions' => $res_video,
            'replies' => $res_replies,
            'params' => $params,
            'loggedOn' => (bool) $this->context->cookie->id_customer,
            'customerId' => $this->context->customer->id,
        ]
        );
        //$this->context->controller->addJS($this->_path . 'views/js/video.js');
        $this->trans('Video new comment', [], 'Modules.Video.Comments');
        $this->trans('Submit comment', [], 'Modules.Video.Comments');
        $maxdepth = 0;
        $range = '';
        $result = Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->executeS('
			SELECT c.id_parent, c.id_category, cl.name, cl.description, cl.link_rewrite
			FROM `' . _DB_PREFIX_ . 'category` c
			INNER JOIN `' . _DB_PREFIX_ . 'category_lang` cl ON (c.`id_category` = cl.`id_category` AND cl.`id_lang` = ' . (int) $this->context->language->id . Shop::addSqlRestrictionOnLang('cl') . ')
			INNER JOIN `' . _DB_PREFIX_ . 'category_shop` cs ON (cs.`id_category` = c.`id_category` AND cs.`id_shop` = ' . (int) $this->context->shop->id . ')
			WHERE (c.`active` = 1 OR c.`id_category` = ' . (int) Configuration::get('PS_HOME_CATEGORY') . ')
			AND c.`id_category` != ' . (int) Configuration::get('PS_ROOT_CATEGORY') . '
			' . ((int) $maxdepth != 0 ? ' AND `level_depth` <= ' . (int) $maxdepth : '') . '
			' . $range . '
			AND c.id_category IN (
				SELECT id_category
				FROM `' . _DB_PREFIX_ . 'category_group`
				WHERE `id_group` IN (' . implode(', ', Customer::getGroupsStatic((int) $this->context->customer->id)) . ')
			)
			ORDER BY `level_depth` ASC, ' . (Configuration::get('BLOCK_CATEG_SORT') ? 'cl.`name`' : 'cs.`position`') . ' ' . (Configuration::get('BLOCK_CATEG_SORT_WAY') ? 'DESC' : 'ASC'));
        $sql = 'SELECT c.id_parent, c.id_category, cl.name, cl.description, cl.link_rewrite '
                . 'FROM `' . _DB_PREFIX_ . 'category` c '
                . 'INNER JOIN `' . _DB_PREFIX_ . 'category_lang` cl ON (c.`id_category` = cl.`id_category` AND cl.`id_lang` = ' . (int) $this->context->language->id . Shop::addSqlRestrictionOnLang('cl') . ') '
                . 'INNER JOIN `' . _DB_PREFIX_ . 'category_shop` cs ON (cs.`id_category` = c.`id_category` AND cs.`id_shop` = ' . (int) $this->context->shop->id . ') '
                . 'WHERE (c.`active` = 1 OR c.`id_category` = ' . (int) Configuration::get('PS_HOME_CATEGORY') . ') '
                . 'AND c.`id_category` != ' . (int) Configuration::get('PS_ROOT_CATEGORY') . ' ' . ((int) $maxdepth != 0 ? ' AND `level_depth` <= ' . (int) $maxdepth : '') . '
			' . $range . '
			AND c.id_category IN (
				SELECT id_category
				FROM `' . _DB_PREFIX_ . 'category_group`
				WHERE `id_group` IN (' . implode(', ', Customer::getGroupsStatic((int) $this->context->customer->id)) . ')
			)
			ORDER BY `level_depth` ASC, ' . (Configuration::get('BLOCK_CATEG_SORT') ? 'cl.`name`' : 'cs.`position`') . ' ' . (Configuration::get('BLOCK_CATEG_SORT_WAY') ? 'DESC' : 'ASC');
        //echo $query;
        return $this->display(__FILE__, 'views/templates/hook/videoreactions.tpl');
        //return $this->setTemplate('module:video/views/templates/hook/videoreactions.tpl');
    }
}

At module install or reset, all parameters are ok. In the DB I see the hook displayVideoComments which is active and at position 1.
When I run the module, I see the video with all the supplied variables but the comments won't receive the correct data. As you see in the query, I request $params['product']->id which fails. In the foreach-loop, I get the following values: product -> smarty -> cookie -> cart -> altern. But the product-array seems to be empty. When I run the script with a hardcoded value for the query (eg 10), I get the requested results but with the array-var ($params['product']->id) I get an Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax. But in another function, which loads the video-file and other details, it runs just normal and with the same variable.

Anybody an idea?
Thanks!

Link to comment
Share on other sites

here's an idea

You registered displayVideoComments, but the template likely calls it without parameters (e.g., just {hook h='displayVideoComments'}), so $params only contains the default context bits (smarty/cookie/cart), not a product. That’s why $params['product']->id fails. Your forum post text also matches this symptom (product array empty).

your custom hook method must accept $params, and the template that calls your hook must pass the product in. If the template doesn’t pass it, $params['product'] will be empty.

What to change

Module method signature

public function hookDisplayVideoComments(array $params)
{
    if (empty($params['product']) || !isset($params['product']->id)) {
        return ''; // not on a product page or product not provided
    }

    $idProduct = (int) $params['product']->id;

    // ...your query logic (ALWAYS cast to int / avoid string concat SQL)
    // Example:
    // $res_video = Db::getInstance()->executeS(
    //     'SELECT ... WHERE v.id_product = '.(int)$idProduct
    // );

    $this->context->smarty->assign([
        'reactions' => $res_video ?? [],
        'replies'   => $res_replies ?? [],
        'loggedOn'  => (bool) $this->context->cookie->id_customer,
        'customerId'=> (int) $this->context->customer->id,
    ]);

    return $this->display(__FILE__, 'views/templates/hook/videoreactions.tpl');
}

Pass the product when calling the hook

Smarty theme (Classic / 1.7–8.x):

{hook h='displayVideoComments' product=$product}

Twig (Hummingbird / PS 8.1+ and 9):

{{ renderhook('displayVideoComments', {'product': product}) }}

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...