Product listing in prestashop - prestashop

I have a site that runs on Prestashop 1.6. We were able to install and set up the default shop as well as a couple of multishops. The issue that we are having is that as we continue to create multishops for our locations and add products onto these shops, we want these products to display on our default "Master" shop. Is there a way to get this done?

I'm sure this kind of customization have to be done in code, but it is not very hard. You can built a module to query the products and display it in any of the display hooks, say displayLeftColumnProduct or displayHome.
The second way is to use override. Overriding Product class or the ProductController might also works, but here I show you how to do this with overriding.
Looking at the Product class, in the getProducts method (https://github.com/PrestaShop/PrestaShop/blob/1.6/classes/Product.php#L1069) there is a call to Shop::addSqlAssociation('product', 'p') to create the JOIN for shop. To by pass that, we need to override the Shop::addSqlAssociation method (https://github.com/PrestaShop/PrestaShop/blob/1.6/classes/shop/Shop.php#L954) and check if the current shop is the "Master", for example:
class Shop extends ShopCore {
public static function addSqlAssociation($table, $alias, $inner_join = true, $on = null, $force_not_default = false)
{
// It better to check using URL
if (self::$context_id_shop == 1) return '';
return parent::addSqlAssociation($table, $alias, $inner_join, $on, $force_not_default);
}
}

Related

Prestashop: How to check if product is on a wishlist

Does anyone know how to take advantage of any of the functions of the wishlist module to have a variable to use in tpl to know if a product is already added to a wishlist?
If I do not exist, I imagine that some function can be used because when you add a product, if you already have it in the default list, it adds a nity instead of adding it as a new product.
Ideally, for the function you would need, it would be to make a tour not only in the list by default but in all, it is necessary to know if it is already added to a list or not.
The function would be to show an icon or another according to whether a product is already on a list or not.
Has someone developed it or could you help me out?
Thanks!
Prestashop 1.6.1.16
Thank you very much for the contribution.
I gave the code that I put below and it always gives me a "1" (and if you notice, I invented the product id (which does not exist, since I only have 8 products at the moment).
I made an override of the php of the module:
class BlockWishListOverride extends BlockWishList
{
function checkProductIsInWishlist()
{
$customer_wishlists = getByIdCustomer($this->context->customer->id);
$id_product_to_check = 424554224; // Replace by the current product id
foreach ($customer_wishlists as $cw) {
$check_product_wl = WishList::getProductByIdCustomer((int)$cw['id_wishlist'], (int)$this->context->customer->id,
(int)$this->context->language->id, (int)$id_product_to_check);
if (count($check_product_wl)) {
$this->smarty->assign('is_in_wishlist', true);
}
}
}
}
And in my product.tpl:
<p>Is in whislist: {$is_in_wishlist|print_r}</p>
Result on Front:
Result $is_in_wishlist on front
Thanks
You can use the following methods:
public static function getByIdCustomer($id_customer)
public static function getProductByIdCustomer($id_wishlist, $id_customer, $id_lang, $id_product = null, $quantity = false)
which are available in /modules/blockwishlist/WishList.php
In your controller file (on the front-end), you could do something like this:
$customer_wishlists = WishList::getByIdCustomer($this->context->customer->id);
$id_product_to_check = 42; // Replace by the current product id
foreach ($customer_wishlists as $cw) {
$check_product_wl = WishList::getProductByIdCustomer((int)$cw['id_wishlist'], (int)$this->context->customer->id,
(int)$this->context->language->id, (int)$id_product_to_check);
if (count($check_product_wl)) {
$this->smarty->assign('is_in_wishlist', true);
}
}
And then check the {$is_in_wishlist} variable in your Smarty product.tpl template.

Pretashop get new order details in a custom module

I am creating a custom module in Prestashop. In that module I want to get
the order details when a new order has been made on the store. So I want
to know which hook should I use and how to get new order details along with
customer details when a new order has been made. Any help and suggestions will be really appreciable.
Use a hook actionValidateOrder. Hook gives you params array which includes Order, Cart, Customer, Currency and OrderState objects associated with it.
With them you can now get customer and order details.
public function hookActionValidateOrder($params) {
$order = $params['order'];
$customer = $params['customer'];
$order_details = $order->getOrderDetailList();
}
Hook needs to be registered in module install.
public function install() {
return parent::install && $this->registerHook('actionValidateOrder');
}
You can use displayOrderConfirmation hook in your main controller to get details of any order.
Following code can help you:
public function hookDisplayOrderConfirmation($params = null)
{
$id_customer = $params['objOrder']->id_customer;
//Get all other details using the $params['objOrder'] order object
}

Laravel dynamic return from controller?

I need to return a different view from a controller depending on the route that is requested.
For example: in my application I have clients, devices and campaigns. All have CRUD's created, but in some cases I want to do something like "view clients, delete his campaign and returning to the clients view" but my campaignsController#delete returns to campaigns by default.
The idea is not rewrite the same controller only changing the route of returning, does Laravel have something to help with this?
Thank you
Laravel will not control the whole flow of your application. If you have a campaign delete router:
Route::delete('campaign/{id}');
and it returns to campaigns
class CampaignController extends Controller {
public function delete($id)
{
$c = Campaign::find($id);
$c->delete();
return Redirect::route('campaigns');
}
}
You will have to trick your route to make it go to wherever you need to, there should be dozens of ways of doing that, this is a very simple one:
Route::delete('campaign/{id}/{returnRoute?}');
class CampaignController extends Controller {
public function delete($id, $returnRoute = null)
{
$returnRoute = $returnRoute ?: 'campaigns';
$c = Campaign::find($id);
$c->delete();
return Redirect::route($returnRoute);
}
}
And create the links in those pages by using the return route option:
link_to_route('campaign.delete', 'Delete Campaign', ['id' => $id, 'returnRoute' => 'clients'])

Laravel Eloquent ORM - Why do I need to call the 'parent model' before I'm able to access it's relations?

I think I might be missing a concept here so feel free to tell me what I'm doing is wrong and point me in a better direction.
I've a simple couple of models that look like this:
class Customer extends Eloquent
{
public function contacts()
{
return $this->hasMany('Contact');
}
}
class Contact extends Eloquent
{
protected $table = "customers_contacts";
}
My problem happens when it comes to deleting a contact from a customer... In my controller:
public function delete_contact($contact_id)
{
if ($contact_id > 0)
{
$customer = new Customer;
Contact::find($contact_id)->delete();
Session::flash('success', 'Contact deleted');
return true;
}
}
For some reason this wont work without the new Customer line. To me it makes sense to just be able to call the delete function of the Contact model, however if I remove my new Customer line I get an error telling me the Contact class can't be found.
What am I missing here?
Ah ha, as crynobone and Surt eluded to I was trying to be tidy and had a few class definitions grouped in one file. Makes a lot of sense thinking about it.
I did some research on the PSR-0 standard and auto loading in laravel and everything is now working beautifully.
No special reason for that to happend. Is the "Contact" model accesible (loadable) by itself?
Maybe you set Contact and Customer on the same file and Contact is not loaded because is not in the psr0?

Zend framework common code for all the controllers

I have a login button in the header of the website. This header's html is programmed into Zend framework views/layouts/home.phtml.
I have a hidden form in this layout that is triggered by jQuery thickbox inline content display integration. Reason, I dont want to make a ajax call to just fetch a small login form.
I create the form using Zend_Form and the problem is that I have to do it in all the controllers after checking if the user is logged in or not. I want to place this form generation in one single place, say in bootstrap and then have a logic in bootstrap to say that if user is logged in dont generate the form.
I don't know if bootstrap is the right place to do so or should I do it in some other place.
So, where should I instantiate the form so that its available everywhere if user is not logged in.
Create your own base controller which extends Zend_Controller_Action then have your controllers extend off of your base controller. I don't know what "jQuery thickbox inline content display integration" is...but you have several sections you can put it in depending when you need your code to run. init(), preDispatch(), postDispatch() etc... Just make sure when you extend off your base controller that you do sthing like:
parent::init()
parent::preDispatch()
parent::postDispatch()
etc... within each section so that the base code runs as well...
Be careful about Pradeep Sharma's solution (the answer he wrote himself and accepted below).
All the code code below is for ZF 1.12, and not ZF 2.0
In the bootstrap, Zend_Layout's MVC instance might not have been created yet. You should use Zend_Layout::startMvc() instead :
$view = Zend_Layout::startMvc()->getView() ;
And tbh I prefer executing this code in the preDispatch() function. New users of ZF might be interested in this :
application/plugins/HeaderForm.php :
class Application_Plugin_HeaderForm extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$view = Zend_Layout::startMvc()->getView() ;
$view->headerForm = new Application_Form_HeaderForm() ;
}
}
Calling new Application_Form_HeaderForm() will autoload by default into application/forms/ folder. You can also create the form directly into the plugin with new Zend_Form(), and addElement() etc. but it won't be reusable.
Of course, you need to register this plugin in your bootstrap!
application/Bootstrap.php :
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initPlugin()
{
$front = Zend_Controller_Front::getInstance() ;
$front->registerPlugin(new Application_Plugin_HeaderForm()) ;
}
}
Calling new Application_Plugin_HeaderForm() will autoload by default into application/plugins/ folder
I did it in a different way, extendingZend_Controller_Plugin_Abstract to implement a plugin and register it with front controller.
public function routeStartup(Zend_Controller_Request_Abstract $request) { }
generated the form inside the above mentioned method and by setting the form in $view object.
$view can be retrived using :
$view = Zend_Layout :: getMvcInstance()->getView();