Jump to content

How to add another field to stores for store locator page


Ray UK

Recommended Posts

Hi,

Does anybody have any idea how to add another field to the stores.

I want to go to "Store Contacts" and when adding a store, I want to put in a link to their specific CMS Page ( which has more info about their store ),plus a few other fields for facebook page, twitter page etc.

 

Also, on that CMS page I want to find a way of grabbing the information from the database relating to that specific store ( ie, opening times, address, phone number etc.)

Are these variable already available of do I have to add some additional code somewhere ?

 

reason: im just trying to make the stores page better and then have a link to a CMS page relating to that store.

 

The pic here is my current stores page.

 

post-404663-0-54459600-1431693632_thumb.jpg

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

Hi

 

We've done this for all of our sites as we had to filter them by particular criteria as well as show additional information on the popup, eg email address, website link, type of shop, etc..

 

1. Modify StoresController.php to include the additional field(s) in the database selection and stores list, or create an override for this (don't know if I tried this).

 

2. Modify stores.js to include new fields on list and in popup.

 

3. Add additional fields to ps_store table using PHPMyAdmin.

 

It's definitely possible to do this.

Link to comment
Share on other sites

Hi, firstly thanks for your help.

 

Im getting there but now stuck.

 

I added the fields to the database ( facebook, twitter, cmspage ), then added info into 1 store for testing.

 

in AdminStoresController.php I added

 

Inside  "class AdminStoresControllerCore extends AdminController"

 

            'facebook' => array('title' => $this->l('Facebook')),
            'twitter' => array('title' => $this->l('Twitter')),
            'cmspage' => array('title' => $this->l('CMS Page')),
 

Inside "public function renderForm()"

 

                array(
                    'type' => 'text',
                    'label' => $this->l('Facebook'),
                    'name' => 'facebook'
                ),
                array(
                    'type' => 'text',
                    'label' => $this->l('Twitter'),
                    'name' => 'twitter'
                ),
                array(
                    'type' => 'text',
                    'label' => $this->l('CMS Page'),
                    'name' => 'cmspage'
                ),
 

and inside "protected function _getDefaultFieldsContent()"

 

            'PS_SHOP_FACEBOOK' => array(
                'title' => $this->l('Facebook'),
                'validation' => 'isGenericName',
                'type' => 'text'
            ),
            'PS_SHOP_TWITTER' => array(
                'title' => $this->l('Twitter'),
                'validation' => 'isGenericName',
                'type' => 'text'
            ),
            'PS_SHOP_CMSPAGE' => array(
                'title' => $this->l('CMS Page'),
                'validation' => 'isGenericName',
                'type' => 'text'
            ),

 

Then in stores.tpl I added:

 

In "function searchLocationsNear(center)"

            var facebook = markerNodes.getAttribute('facebook');
            var twitter = markerNodes.getAttribute('twitter');
            var cmspage = markerNodes.getAttribute('cmspage');
 

and

 

<div class="storesocial"><small>'+facebook+' '+twitter+'</small></div>
 

The result so far.

 

In the stores list I have the data showing

post-404663-0-86372100-1431854374_thumb.jpg

 

But when I edit that store

post-404663-0-14118800-1431854444_thumb.jpg

 

And on the map

post-404663-0-80973900-1431854506_thumb.jpg

 

So the data is read on the stores list in the BO, but editing that store the info doesnt show, and null is returned on the stores Front page.

 

 

Link to comment
Share on other sites

Hi

 

Well done so far. Almost there I think. My apologies for missing out AdminStoresController.php.

 

To get these fields to show in BO, create an override for Store.php in /override/classes. Copy the whole script as below:

class Store extends StoreCore
{
	/** @var integer Country id */
	public $id_country;

	/** @var integer State id */
	public $id_state;

	/** @var string Store name */
	public $name;

	/** @var string Address first line */
	public $address1;

	/** @var string Address second line (optional) */
	public $address2;

	/** @var string Postal code */
	public $postcode;

	/** @var string City */
	public $city;

	/** @var float Latitude */
	public $latitude;

	/** @var float Longitude */
	public $longitude;

	/** @var string Store hours (PHP serialized) */
	public $hours;

	/** @var string Phone number */
	public $phone;

	/** @var string Fax number */
	public $fax;

	/** @var string Note */
	public $note;

	/** @var string e-mail */
	public $email;

	/** @var string Object creation date */
	public $date_add;

	/** @var string Object last modification date */
	public $date_upd;

	/** @var boolean Store status */
	public $active = true;

        /** Additional fields for map - 17/05/2015 */
        public $extra1;
        public $extra2;
        public $extra3;

	/**
	 * @see ObjectModel::$definition
	 */
	public static $definition = array(
		'table' => 'store',
		'primary' => 'id_store',
		'fields' => array(
			'id_country' => 	array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
			'id_state' => 		array('type' => self::TYPE_INT, 'validate' => 'isNullOrUnsignedId'),
			'name' => 			array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 128),
			'address1' => 		array('type' => self::TYPE_STRING, 'validate' => 'isAddress', 'required' => true, 'size' => 128),
			'address2' => 		array('type' => self::TYPE_STRING, 'validate' => 'isAddress', 'size' => 128),
			'postcode' => 		array('type' => self::TYPE_STRING, 'size' => 12),
			'city' => 			array('type' => self::TYPE_STRING, 'validate' => 'isCityName', 'required' => true, 'size' => 64),
			'latitude' => 		array('type' => self::TYPE_FLOAT, 'validate' => 'isCoordinate', 'size' => 13),
			'longitude' =>		array('type' => self::TYPE_FLOAT, 'validate' => 'isCoordinate', 'size' => 13),
			'hours' => 			array('type' => self::TYPE_STRING, 'validate' => 'isSerializedArray', 'size' => 254),
			'phone' => 			array('type' => self::TYPE_STRING, 'validate' => 'isPhoneNumber', 'size' => 16),
			'fax' => 			array('type' => self::TYPE_STRING, 'validate' => 'isPhoneNumber', 'size' => 16),
			'note' => 			array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml', 'size' => 65000),
			'email' => 			array('type' => self::TYPE_STRING, 'validate' => 'isEmail', 'size' => 128),
			'active' => 		        array('type' => self::TYPE_BOOL, 'validate' => 'isBool', 'required' => true),
			'date_add' => 		        array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
			'date_upd' => 		        array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
			'extra1' => 	                array('type' => self::TYPE_STRING), // 17/05/2015. New field.
			'extra2' => 	                array('type' => self::TYPE_STRING), // 17/05/2015. New field.
			'extra3' => 	                array('type' => self::TYPE_STRING) // 17/05/2015. New field.
		),
	);

	protected	$webserviceParameters = array(
		'fields' => array(
			'id_country' => array('xlink_resource'=> 'countries'),
			'id_state' => array('xlink_resource'=> 'states'),
			'hours' => array('getter' => 'getWsHours', 'setter' => 'setWsHours'),
		),
	);

Link to comment
Share on other sites

Ahh sorry, I have the stores front page working ok now

 

post-404663-0-69848300-1431856660_thumb.jpg

 

I edited the AdminStoresController instead of StoresController

 

Anyhow, after editing the AdminStoresController, the Admin Stores page shows the fields, but doesnt fill them in.

Also, I tried adding info into the fields on the Stores BO and it doesnt save them to database.

 

Cheers for your help

Link to comment
Share on other sites

Added that info here and they still not showing in BO

 

 

post-404663-0-99059900-1431857407_thumb.jpg

 

is that the correct directory?

 

Plus deleted that cach file, it recreated but this path is blank ?

 

  'Store' =>
  array (
    'path' => '',
    'type' => 'class',
    'override' => false,
  ),
  'StoreCore' =>
  array (
    'path' => 'classes/Store.php',
    'type' => 'class',
    'override' => false,
  ),
  'StoresController' =>
  array (
    'path' => '',
    'type' => 'class',
    'override' => false,
  ),
  'StoresControllerCore' =>
  array (
    'path' => 'controllers/front/StoresController.php',
    'type' => 'class',
    'override' => false,
  ),
 

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

Yes done both of those. Its ps 1.6.014 by the way, dont know if latest version has differences.

 

I do have to nip out now, so i may continue to try later if im back in time, otherwise monday.

 

Cheers for your help, its Sunday so take a break :)

 

Ray

Link to comment
Share on other sites

Hi, ive just got back and thought to try putting your code directly in the Stores.php file, and it works (I know its not ideal incase I upgrade in the future)

 

So the code is fine, it just seems that the override isnt loading.

 

Looking at Nemo's writeup here, its looks like things may have changed since 1.6.0.11

 

http://nemops.com/override-prestashop-modules-core/#.VVjAIJNRpbw

 

Im going to try adding info using the BO now and see if that works

Link to comment
Share on other sites

All seems to be working ok.

 

Here is my progress so far... http://www.no-match.co.uk/stores

 

There is 1 other thing im attempting to do.

 

The CMS page that each store links to, I have to manually enter the same info that in the BO for the stores.

Also if any shop opening times, etc change, then I have to edit them currently in both places.

 

Would there be any way to fetch that info from the database to use on the cms page ?

 

I understand I may need to state the store_id variable to indicate which store details im going to use.

 

Thanks

 

Ray

Link to comment
Share on other sites

Hi

 

Looking good. Well done.

 

Rather than linking to a CMS page for each store, which as you know would mean you have to create a page for each one, another idea may be to create a controller and template, and as you say, pass in the id of the store to the controller, lookup the database and get the information, and then reformat on the template page.

 

Easy for me to say, but should be do-able.

 

Good luck.

Link to comment
Share on other sites

Hi,

 

Yes that would be the ideal solution.. .as you say, easy for you lol

 

If you can give me any indication where to start that would be awesome.

As you know, any change I currently make to the layout has to be done on 40+ cms pages at the moment... which is tiresome.

 

Ill try a bit of googling for help also.

 

But will try with the help of Nemops again :)
http://nemops.com/creating-new-pages-in-prestashop/#.VVoLnJNRpbw

 

Cheers

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

Hi

 

Probably a good starting point is to clone a controller. The StoresController.php would be ideal as its got most of the database code you need, then clone the stores.tpl in your theme. In the controller "initContent" function, this is where you would get the id of the store to then lookup the database, then set the template. You could probably strip out a lot of the code in the controller as it would be redundant.

 

Nemo may also have a tut for exactly this reason.

 

Let me know how you get on.

Link to comment
Share on other sites

Hi, Im going to give it a go.. .1st time trying something like this.

 

Ive made storedetails.tpl and StoreDetailsController.php

 

in StoreDetailsController.php i have ammended the class to

 

class StoreDetailsControllerCore extends FrontController

 

and stuck already lol.

 

I turned off friendly url for now and entered http://www.no-match.co.uk/index.php?id_store=6&controller=storedetails but get a blank page.

Is it the wrong url, and what would the url be with friendly urls turned on ? would it be http://www.no-match.co.uk/storedetails/6

Cheers

Link to comment
Share on other sites

Hi

 

You want to go through the controller and replace anything that's pointing to Store with StoreDetails, eg:

 

 

class StoreDetailsControllerCore extends FrontController
{
    public $php_self = 'storedetails';

 

 

To show the page:

 

- go to Backoffice->Preferences->SEO & URLs.

 

- click on the add button in the top left of this screen.

 

- once on the "add" screen, drop-down the "Page" list and you should see your new controller (page). Add details and save taking note of the rewritten url field, eg this-stores-details.

 

- delete the cache/class_index.php file.

 

- on the same page under the list of SEO & URL files you can create/recreate the .htaccess file. Click "No" on Friendly URL and save. Then click "Yes" on Friendly URL and save.

 

- go to your site and type in the name of the new page, eg  http://www.no-match-co.uk/this-stores-details

 

See what you get.

 

Did you try the Nemo tut? Looks pretty good. There is also tuts on the PS documentation pages which you may want to look at as well.

Link to comment
Share on other sites

Hi again,

 

- go to Backoffice->Preferences->SEO & URLs was the bit I didnt do, so the page showed as soon as I done that.

 

However, I am stuck. Ive tried most of today but cant get any variables ( apart from the global ones ), ie <td><span class="tel">{$shop_phone}</span></td> shows the main contact number.

 

I dont know how to retrived the store_id=6 from the url, and grab just that stores variables.

 

my last effort was like

 

    public function initContent()
    {
        parent::initContent();
        
        $this->twitter = Configuration::get('twitter'); // assign twitter
        $this->twitter2 = ($store['twitter']); // assign twitter
 

Link to comment
Share on other sites

If your stores url is:

 

- http://www.no-match-co.uk/this-stores-details

 

append the store-id onto the end like:

 

- http://www.no-match-co.uk/this-stores-details?key=6

 

Then within the init function:

 

public function initContent()
{

 

     parent::initContent();
 

     $key = strip_tags(htmlentities($_GET['key'], ENT_QUOTES));

     .

     .

     //Load shop details in $stores array.

 

     $stores = $this->getStores($key);

 

        $this->context->smarty->assign(array(
            'name' => $store['name'],
            'email' => $store['email']
        ));

        $this->setTemplate(_PS_THEME_DIR_.'storedetails.tpl');
    }
 

--------------------------

 

This may not be the ideal way to do this but it should give you a start. You should then be able to access the smarty variables within your template to display the values.

 

I'm at work at the moment and don't have much time to spend on this unfortunately.

Link to comment
Share on other sites

Slowly I am yes lol.

 

But when I add this bit of code, I get a blank page

 

$this->context->smarty->assign(array(
            'name' => $store['name'],
            'email' => $store['email']
        ));

 

Ill leave you to your work and check back in later when im home.

 

Cheers

Link to comment
Share on other sites

After turning friendly url on/off a few times, clearing cache again, etc. The template is now showing again.

Cant suss out the variables still though.

Im thinking its to do with the sql statement in the public function "getStores"

 

Ive tried

 

public function getStores()
    {
        $stores = 'SELECT * FROM '._DB_PREFIX_.'store WHERE id_store=6';
 
hoping to show store 6 ( without specifying the key, to eliminate problems ) but the values are null.

Im guessing that the query is a bit more complex than that
 
I am still learning and pestering google before you, but still no joy :(
 
and
Link to comment
Share on other sites

Try this:

 

$stores = Db::getInstance()->executeS('SELECT * FROM '._DB_PREFIX_.'store WHERE id_store = 6');

$this->context->smarty->assign(array(
       'name'      => $stores[0]['name'],
       'address1'  => $stores[0]['address1'],
       'address2'  => $stores[0]['address2'],
       'city'      => $stores[0]['city'],
       'postcode'  => $stores[0]['postcode'],
       'latitude'  => $stores[0]['latitude'],
       'longitude' => $stores[0]['longitude'],
       'hours'     => $stores[0]['hours'],
       'phone'     => $stores[0]['phone'],
       'fax'       => $stores[0]['fax'],
       'email'     => $stores[0]['email'],
       'note'      => $stores[0]['note'],
));

$this->setTemplate(_PS_THEME_DIR_.'storedetails.tpl');

The results of the query are stored in $stores which is an array which has only one record as you are selecting by id_store. You can then access each array element from there to show on the template. See below for your template file:

 

<p>{$name}</p>
<p>{$address1}</p>
<p>{$address2}</p>
<p>{$city}</p>
<p>{$postcode}</p>
<p>{$latitude}</p>
<p>{$longitude}</p>
<p>{$hours}</p>
<p>{$phone}</p>
<p>{$fax}</p>
<p>{$email}</p>
<p>{$note}</p>
 

I haven't tried this but I think it should work.

Link to comment
Share on other sites

Hi

 

Don't know how you're doing on this but I went through the PS documentation here to create a new module this morning for something I need to do. For a test I fetched the store information and displayed on a template and it all works fine. See here:

 

http://doc.prestashop.com/display/PS16/Creating+a+PrestaShop+Module

 

This is fairly straightforward and got it displaying the information for a store I hardcoded into the controller, so it does work ok.

 

You may want to try this out if you're getting nowhere.

Link to comment
Share on other sites

Hi, I will look at doing a module once ive managed this completely. I think a lot of people may find it handy.

 

I have made good progress so far thanks to you.

 

Im just having trouble exploding the hours variable to use

 

Ive tried things like $hours[1] but doesnt give the correct result.

 

see here http://www.no-match.co.uk/storedetails?storeid=6

 

My store BO now has all these fields

 

post-404663-0-92841500-1432131894_thumb.jpg

 

Cheers

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

Looking fantastic.

 

See below for hours:

 

Controller

------------------

  public function initContent()
  {
    parent::initContent();
    
    $stores = Db::getInstance()->executeS('SELECT * FROM '._DB_PREFIX_.'store WHERE id_store = 6');

    $days = array();
    $days[1] = 'Monday';
    $days[2] = 'Tuesday';
    $days[3] = 'Wednesday';
    $days[4] = 'Thursday';
    $days[5] = 'Friday';
    $days[6] = 'Saturday';
    $days[7] = 'Sunday';

    $days_datas = array();

    if (!empty($stores[0]['hours']))
    {
        $hours = array();
        $hours = array_filter(unserialize($stores[0]['hours']));

//        print_r(array_values($hours));
        
        for ($i = 1; $i < 8; $i++)
        {
            if (isset($hours[(int)($i) - 1]))
            {
                $hours_datas = array();
                $hours_datas['day'] = $days[$i].' - '.$hours[(int)($i) - 1];
                $days_datas[] = $hours_datas;
            }
        }
        $this->context->smarty->assign('days_datas', $days_datas);
    }

    $this->context->smarty->assign(array(
          'name'      => $stores[0]['name'],
          'address1'  => $stores[0]['address1'],
          'address2'  => $stores[0]['address2'],
          'city'      => $stores[0]['city'],
          'postcode'  => $stores[0]['postcode'],
          'latitude'  => $stores[0]['latitude'],
          'longitude' => $stores[0]['longitude'],
          'phone'     => $stores[0]['phone'],
          'fax'       => $stores[0]['fax'],
          'email'     => $stores[0]['email'],
          'note'      => $stores[0]['note'],
    ));

   $this->setTemplate('storedetails.tpl');
   
  }
 

In template:

-----------------

{foreach $days_datas as $days}
   {foreach $days as $key => $val}
     <p>{$val}</p>
   {/foreach}
{/foreach}
 

This should work. You'll probably have to amend the code above to fit in with your controller, but you get the gist.

Link to comment
Share on other sites

Yep looking good now thank you.

 

All of the info is now showing.

 

I used the {$days_datas[0]['day']} for the opening times so it fits in with the table.

I had to do it that way as it highlights the current days opening time.

 

Only things im looking to do to make it better now is an auto geocode and automatically show the nearest 5 stores.

And maybe when clicking the div ( in the list of found stores ), it auto selects the point on the map.

the "i" now links to the new template fine.

Same as the drop down menu does... so its probs just some code from that I need to fit in somewhere.

 

And also set the page meta tags according to one of my other fields ( which I havent created yet )

 

 

Ive learnt quite a bit just from doing this 1 small project.. cheers :)

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

Every day is a schoolday!!

Only things im looking to do to make it better now is an auto geocode and automatically show the nearest 5 stores.

Haven't done this but I'm sure you'll work it out.

And maybe when clicking the div ( in the list of found stores ), it auto selects the point on the map.

I would take a backup of all the code you have, just in case. You'll have to amend the js I think.

 

Good job anyway, and I'm sure you now have a better understanding of how PS works, as have I.

Link to comment
Share on other sites

  • 1 year later...

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