Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Zip Code Store Locator or Google Map Store Locator


Go to End
Reply


16 Posts   7153 Views

Avatar
socks

Community Member, 190 Posts

28 September 2009 at 5:05pm

Edited: 28/09/2009 5:09pm

I need to figure out how to do a Store Locator with Address or Zip Code input (and just list out the stores in simple text) or preferably implement the [url=http://code.google.com/apis/maps/articles/phpsqlsearch.html]Google Map Store Locator[/url].

It seems all the code is there for the Google example, I just need help translating that into SilverStripe.

I have a StoreLocationsPage and am using the DataObjectManager module to add Stores with this information: Store ID, Address, City, State, Zip, & maybe Latitude & Longitude.

1. Create markers table
I assume this means:

class Markers extends DataObject {}

2. Populate table
Using DataObjectManager

3. Find nearby locations w/ MySQL
Not sure how to do this

4. Outputting XML with PHP
I think this is achieved with the api stuff placed in the DataObject (Markers)

static $api_access = true;
   
   function canEdit() {
      return true;
   }
   function canView() {
      return true;
   }
   function canCreate() {
      return true;
   }

5. Creating the map
Don't understand what I need to do here also. There's mention of geocoding. It would be nice (but not necessary) if it used geocoding automatically, but nice if I enter Lat & Lng info into the DataObject, it would override the geocode (sometimes those red markers on the map aren't super accurate).

Thanks

Avatar
socks

Community Member, 190 Posts

6 October 2009 at 1:24pm

Edited: 05/11/2009 7:58pm

I know someone out there wants to help :-)

So at this point just to get started, I'm just trying to get a map with multiple markers with an Info Window for each. Once I get this, I'll try to add more functionality.

I've discovered that the XML that's being spit out of SS is incompatible with the Google map...

SS XML:

<DataObjectSet totalSize="4">
   <Marker href="http://localhost:-----/ss233/api/v1/Marker/1.xml">
      <Name>#1</Name>
      <Address>1521 1st Ave</Address>
      <City>Seattle</City>
      <State>Washington</State>
      <Zip></Zip>
      <Lat>47.6089</Lat>
      <Lng>-122.34</Lng>
      <Type>bar</Type>
      <MarkerPageID>20</MarkerPageID>
      <ID>1</ID>
      <MarkerPage linktype="has_one" href="http://localhost:-----/api/v1/MarkerPage/20.xml" id="20"></MarkerPage>
   </Marker>

   <Marker href="http://localhost:-----/api/v1/Marker/2.xml">
      <Name>#2</Name>
      <Address>2222 2nd Ave</Address>
      <City>Seattle</City>
      <State>Washington</State>
      <Zip></Zip>
      <Lat>47.6136</Lat>
      <Lng>-122.344</Lng>
      <Type>restaurant</Type>
      <MarkerPageID>20</MarkerPageID>
      <ID>2</ID>
      <MarkerPage linktype="has_one" href="http://localhost----/api/v1/MarkerPage/20.xml" id="20"></MarkerPage>
   </Marker>
</DataObjectSet>

Google XML needs all of the city, state, lat, lng to be in marker like this:

<markers>
   <marker name="Pan Africa Market" address="1521 1st Ave, Seattle, WA" lat="30.0224" lng="-95.4248" type="restaurant"/>
   <marker name="Buddha Thai &amp; Bar" address="2222 2nd Ave, Seattle, WA" lat="47.613590" lng="-122.344391" type="bar"/>
   <marker name="The Melting Pot" address="14 Mercer St, Seattle, WA" lat="47.624561" lng="-122.356445" type="restaurant"/>
   <marker name="Ipanema Grill" address="1225 1st Ave, Seattle, WA" lat="47.606365" lng="-122.337654" type="restaurant"/>
</markers>

Is there any way to modify this Google code so it will accept a differently formatted XML?

GDownloadUrl("api/v1/Marker", function(data) {
   var xml = GXml.parse(data);
    var markers = xml.documentElement.getElementsByTagName("marker","name","lat","lng","type");
    for (var i = 0; i < marker.length; i++) {
   var point = new GLatLng(parseFloat(marker.getElementsByTagName("lat")),
          parseFloat(marker.getElementsByTagName("lng")));
    var marker = createMarker(point, name, address, type);
    map.addOverlay(marker);
    }
});

Avatar
dalesaurus

Community Member, 283 Posts

6 October 2009 at 3:25pm

Wag the tail, not the dog man!

Use a custom SS template to bend the data to a proper GData XML format. Instead of using the plain old getXML() output you will have to whip up a custom template and do:

return $this->customise($mydataobject)->renderWith('mysweetgdataxmltemplate');

More at http://doc.silverstripe.org/doku.php?id=templates#calling_templates_from_php_code

Avatar
socks

Community Member, 190 Posts

31 October 2009 at 7:42pm

Edited: 31/10/2009 7:45pm

Thanks Dalesaurus,

Just to make sure I did this correctly, even with the renderWith line, I still have to create a page in the CMS, correct? And if I do that and set the page type to "My Sweet Gdata Xml Template" then what purpose does the renderWith serve (since I can delete it and it still works)?

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

So, to anyone that cares, this is how my final Map turned out:

- Used DataObjectManager to create the Store Locations (fields included: Address, City, State, Zip, Latitude, Longitude, Phone, Delivery Availability)
- I created a special XML template formatted so Google could read it.
- The Map is similar to the "Google Map Selection Field" http://www.silverstripe.org/google-map-selection-field-module/ but I did not use the module and just hard coded the form field in there.
- The map markers are color coded based on whether the store offered delivery
- The Info Windows on the Map Markers show some info and include a form for driving directions

-- I couldn't figure out the radius select and didn't try to do the sidebar list of stores
-- Also, couldn't figure out how to get driving directions to show up on the same page as the map ( kept getting "undefined locations" )

Avatar
dalesaurus

Community Member, 283 Posts

1 November 2009 at 7:39am

Well you just need to correspond the output with a template. If you create a MySweetPagetype Page and corresponding template, it will be used automatically.

However you could just create a separate mysweetgdatatemplate.ss and create an action in Page.php then tell it to render with that specific template using renderWith.

public function getgdata() {
// Fetch data for map into array or
// ArrayData $data, depending on nesting complexity
return $this->customise($data)->renderWith('mysweetgdatatemplate');
}

Then you can just point your code to yoursweetsite.com/getgdata to fetch the XML, without fussing with pages in the CMS.

Avatar
socks

Community Member, 190 Posts

1 November 2009 at 7:30pm

Guess I'm not doing something right...just get a Page Not Found instead of the XML page.

StoreLocation.php

class StoreLocation extends DataObject {
...
}

Page.php

class Page_Controller extends ContentController {
   public function gmapxml() {      
      return $this->customise('StoreLocation')->renderWith('GoogleMapXml');
      $this->getResponse()->addHeader('Content-Type', 'application/xml; charset="utf-8"');
   }
}

GoogleMapXml.ss
(themes > mytheme > templates > GoogleMapXml.ss)

URL = http://mysite.com/gmapxml

I really appreciate the help. Thank you.

Avatar
dalesaurus

Community Member, 283 Posts

2 November 2009 at 5:13am

You're really close, just a few things out of order.

1. You are doing a return before you set your header (this ends execution of that function prematurely)
2. customise() requires an array keyed/valued like you would normally return to a custom template

class Page_Controller extends ContentController {
public function gmapxml() {
// Change this to get as many of whatever type you want
// Heck you can even use $this->URLParams to get stuff like
// gmapxml/food/34 to pass in IDs or the like

$storeLoc = DataObject::get('StoreLocation','filter stuff');
$data = array('Stores' => $storeLoc); // You will use this as $Stores in your template
$this->getResponse()->addHeader('Content-Type', 'application/xml; charset="utf-8"');
return $this->customise($data)->renderWith('GoogleMapXml');
}
}

Avatar
socks

Community Member, 190 Posts

3 November 2009 at 1:37pm

hmmm....still getting a page not found...
Is there something I need to add to allow a function's name (gmapxml) to be used in the URL?

Go to Top