I have a module and I want to display the "blocknewproducts" inside of it. What is the best option?
Thanks!
Ok, we lack some more info but i will share a way to do it in Prestashop 1.6.x:
Your module :
Given you have a custom hook named displayMyModule in your module install method :
public function install() {
if (!parent::install() || !$this->registerHook('displayMyModule')) {
return false;
} else {
return true;
}
}
Now, where you want to display the content of this hook is up to you. For example if it's on a category page, in category.tpl you add
{hook::exec('displayMyModule')}
Block new Products
Now to display the blocknewproducts we will create an override of this core module and register the displayMyModule hook :
in /override/modules/blocknewproducts/blocknewproducts.php :
if (!defined('_PS_VERSION_'))
exit;
class BlockNewProductsOverride extends BlockNewProducts
{
public function install()
{
$success = (parent::install()
&& $this->registerHook('displayMyModule'));
return $success;
}
public function hookDisplayMyModule($params)
{
return $this->hookRightColumn($params);
}
}
In hookDisplayMyModule we simply return the hookRightColumn method to not rewrite code.
Don't forget to go into back-office/modules and reinitialize blocknewproducts module
And that's about it... but keep in mind that you could also just override the blocknewproducts module to register hooks that already exist like shown above.
TLDR: Maybe you don't need a module if you just want to show block new products elsewhere.
Related
I create a custom module in prestashop 1.7, and I would like to apply the layout of products list on my module and display products what I want. What I have to do ?
My initContent function is
class TestModuleDisplayModuleFrontController extends ModuleFrontController{
public function initContent()
{
parent::initContent();
$this->setTemplate('products.tpl');
}
}
Thanks you
Hi Varag and welcome to Stackoverflow.
Your answer is here waiting for you : https://devdocs.prestashop.com/1.7/modules/concepts/controllers/front-controllers/
For instance your function must look like that :
public function initContent()
{
// In the template, we need the vars paymentId & paymentStatus to be defined
$this->context->smarty->assign(
array(
'paymentId' => Tools::getValue('id'), // Retrieved from GET vars
));
// Will use the file modules/cheque/views/templates/front/validation.tpl
$this->setTemplate('module:cheque/views/templates/front/validation.tpl');
}
I think that you have to use array instead of object:
$listing['products'] = json_decode(json_encode($your_products), true); // convert object to array
$this->context->smarty->assign("listing", $listing);
$this->setTemplate('module:mymodule/views/templates/front/mytemplate.tpl');
I am trying to build a module for Prestashop 1.6 that would redirect the user if the targeted URL is present in a database.
What I'm going to do is the following:
public function checkRedirection ($url) {
$line = Db::getInstance()->executeS('SELECT * FROM ps_custom_redirection WHERE url = ' . pSQL($url));
if (!sizeof($line)) {
return null;
}
header('Location: ' . $line[0]['destination']);
http_response_code($line[0]['http_code']);
exit();
}
Now, I could run this function when the displayTop hook is fired. But I would rather launch this function at the beginning of the request's process.
Does Prestashop provide such a hook? If not, can I create one? Where should I write the code to fire it?
The fist hook executed is actionDispatcher – you can use it if you want.
You'll find this hook executed in /classes/Dispatcher.php. Search for the code Hook::exec('actionDispatcher', $params_hook_action_dispatcher);.
If you want to add this hook to your module, you need to use its name in the main module file like this:
public function install() {
return parent::install()
&& $this->registerHook('actionDispatcher');
}
public function hookActionDispatcher($params) {
// your code
Tools::redirect($url);
}
In Prestashop Tools::redirect($url); is used if redirecting.
Laravel 5.1 has just been released, I would like to know how could I tell the AuthController to get the login & register view from a custom directory? the default is: resources/views/auth...
The trait AuthenticateAndRegisterUsers only has this:
trait AuthenticatesAndRegistersUsers
{
use AuthenticatesUsers, RegistersUsers {
AuthenticatesUsers::redirectPath insteadof RegistersUsers;
}
}
The code you're showing there only fills one function: it tells our trait to use the redirectPath from the AuthenticatesUsers trait rather than the one from RegistersUsers.
If you check inside the AuthenticatesUsers trait instead, you will find a getLogin() method. By default, this one is defined as
public function getLogin()
{
return view('auth.login');
}
All you have to do to get another view is then simply overwriting the function in your controller and returning another view. If you for some reason would like to load your views from a directory other than the standard resources/Views, you can do so by calling View::addLocation($path) (you'll find this defined in the Illuminate\View\FileViewFinder implementation of the Illuminate\View\ViewFinderInterface.
Also, please note that changing the auth views directory will do nothing to change the domain or similar. That is dependent on the function name (as per the definition of Route::Controller($uri, $controller, $names=[]). For more details on how routing works, I'd suggest just looking through Illuminate\Routing\Router.
for those who is using laravel 5.2, you only need to override property value of loginView
https://github.com/laravel/framework/blob/5.2/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php
public function showLoginForm()
{
$view = property_exists($this, 'loginView')
? $this->loginView : 'auth.authenticate';
if (view()->exists($view)) {
return view($view);
}
return view('auth.login');
}
so to override the login view path, you only need to do this
class yourUserController {
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
.....
protected $loginView = 'your path';
}
I'm trying to test a controller function...
I want to test a couple of things:
A) That it throws an invalid request exception when a certain argument is used
B) That it works correctly when the correct argument is made.
I've written some unit tests and those all seem cool. The only documentation I can find on this is http://book.cakephp.org/3.0/en/development/testing.html but the integration testing, whilst interesting and potentially useful, I can't seem to get how I am suppose to be implement it without using fixtures (which I don't want to do necessarily).
namespace App\Test\TestCase\Controller;
use Cake\ORM\TableRegistry;
use Cake\TestSuite\IntegrationTestCase;
class MusterControllerTest extends IntegrationTestCase
{
public function testIn()
{
$this->in();
$this->setExpectedException('Invalid request');
}
}
class MusterController extends AppController {
public $helpers = array('Address');
public function beforeFilter(Event $event) {
$this->Auth->allow('in');
$this->layout = 'blank';
$this->autoRender = false;
$this->loadComponent('Rule');
parent::beforeFilter($event);
}
public function in($param = null){
if (!$this->request->is(array('post', 'put')) || $this->request->data('proc')!='yada' || is_null($param)){
throw new NotFoundException(__('Invalid request'));
}
$this->processRequest($this->request->data('hit'), $this->request->data('proc'), $param);
}
Pointers appreciated.
The IntegrationTestCase class, as its name implies, is meant for integration testing. That is, it will be testing the interaction between the controller and any other class it uses for rendering a response.
There is another way of testing controller, which is more difficult to accomplish, but allows you to test controller methods in isolation:
public function testMyControllerMethod()
{
$request = $this->getMock('Cake\Network\Request');
$response = $this->getMock('Cake\Network\Response');
$controller = new MyController($request, $response);
$controller->startupProcess();
// Add some assertions and expectations here
// For example you could assing $controller->TableName to a mock class
// Call the method you want to test
$controller->myMethod('param1', 'param2');
}
I want to create a maintenance Page for my cake website by checking a Database Table for a maintenance flag using a sub-function of my AppController "initilize()" method. If the flag is set, i throw my custom MaintenanceException(Currently containing nothing special):
class MaintenanceException extends Exception{
}
To handle it, I implemented a custom App Exception Renderer:
class AppExceptionRenderer extends ExceptionRenderer {
public function maintenance($error)
{
return "MAINTENANCE";
}
}
I am able to see this maintenance Text on my website if I set my DB flag to true, but I could not find any information in cake's error handling documentation (http://book.cakephp.org/3.0/en/development/errors.html) on how I can actually tell the Exception renderer to render view "maintenance" with Template "infopage".
Can I even us that function using the ExceptionRenderer without a custom error controller? And If not, how should a proper ErrorController implementation look like? I already tried this:
class AppExceptionRenderer extends ExceptionRenderer {
protected function _getController(){
return new ErrorController();
}
public function maintenance($error)
{
return $this->_getController()->maintenanceAction();
}
}
together with:
class ErrorController extends Controller {
public function __construct($request = null, $response = null) {
parent::__construct($request, $response);
if (count(Router::extensions()) &&
!isset($this->RequestHandler)
) {
$this->loadComponent('RequestHandler');
}
$eventManager = $this->eventManager();
if (isset($this->Auth)) {
$eventManager->detach($this->Auth);
}
if (isset($this->Security)) {
$eventManager->detach($this->Security);
}
$this->viewPath = 'Error';
}
public function maintenanceAction(){
return $this->render('maintenance','infopage');
}
}
But this only throws NullPointerExceptions and a fatal error. I am really dissapointed by the cake manual as well, because the code examples there are nowhere close to give me an impression of how anything could be done and what functionality I actually have.
Because I had some more time today, I spent an hour digging into the cake Source and found a solution that works well for me (and is propably the way it should be done, altough the cake documentation does not really give a hint):
Step 1: Override the _template(...)-Method of the ExceptionRenderer in your own class. In my case, I copied the Method of the parent and added the following Code at the beginning of the method:
$isMaintenanceException = $exception instanceof MaintenanceException;
if($isMaintenanceException){
$template = 'maintenance';
return $this->template = $template;
}
This tells our Renderer, that the error Template called "maintentance"(which should be located in Folder: /Error) is the Error Page content it should render.
Step 2: The only thing we have to do now (And its is kinda hacky in my opinion, but proposed by the cake documentation in this exact way) is to set the layout param in our template to the name of the base layout we want to render with. So just add the following code on top of your error template:
$this->layout = "infopage";
The error controller I created is actually not even needed with this approach, and I still don't know how the cake error controller actually works. maybe I will dig into this if I have more time, but for the moment.