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.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Archive /

Our old forums are still available as a read-only archive.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo

Help on Data Object Relations


Go to End


6 Posts   5727 Views

Avatar
Davis

Community Member, 5 Posts

22 May 2007 at 3:03pm

Edited: 22/05/2007 3:20pm

Hi Team,

Here is my situation.

I have created a class HostelPage where I want to link in a single value for lattitude/longitude within the LatLng class. That value needs to be set via the HostelPage within the cms admin. I want the lattitude/longitude data to be loaded into and set from a hidden field. I will set the hidden field value via an interactive map loaded in by javascript.

So far I have a HostelPage class extending the Page class. Within that class I have put in a has_one relationship to LatLng:
static $has_one = array(
'LatLng' => 'LatLng'
)

Within the getCMSFields() function of the HostelPage class I have inserted:
$fields->addFieldToTab("Root.Content.Map", new LatLngField('LatLngString'), 'LatLng');

Within my LatLngField Class I set up functionality to return a hidden field and then update that value via javascript.

I have created a LatLng class like this:
class LatLng extends DataObject {
static $db = array(
'LatLngString' => 'Text'
);
}

This is not working. I am unsure of the has_one relationship or if I need to use something else; about whether I need belongs_many_many within the LatLng class; and whether I need to do an explicit DataObject::get() to retrieve the LatLngString.

Any help would be most appreciated.

Thanks,
Davis

Avatar
Sam

Administrator, 690 Posts

22 May 2007 at 9:29pm

If the LatLng field is being saved into a string, it might be simpler to make LatLng a subclass of Text or Varchar.

Each MySQL field type is represented as a subclass of DBField - Text, Varchar, and Int are examples of these. You can further subclass these core types to add extra behaviour to your fields. For example, Currency is a subclass of Decimal that has a Nice() method for formatting.

So if you had this class:

class LatLng extends Varchar {
function Map() {
return "<some html for a map of this location using $this->value>";
}
}

You can then use it in your HostelPage in the $db list. It's db, not has_one, because it's a field type rather than a relation to another table.

class HostelPage extends Page {
$db = array(
"Location" => "LatLng",
);
...
}

You can then put this into your HostelPage.ss:

$Location.Map

It's a bit of a different tack, but it removes the need for an extra table. Does this give you something to go on?

Avatar
Davis

Community Member, 5 Posts

23 May 2007 at 9:28am

Thanks for the reply Sam,

That bit about extending the Varchar type will definitely help in future project management.

Unfortunetely, I do need a seperate LatLng table because I'll be having values for many different kinds of points on the map--hostel locations being just one type.

Considering that each hostel row in the HostelPage table will have exactly one tie in with a single row in the LatLng and that I need to put the ability to update that LatLng value within the HostelPage admin section what would you recommend?

Avatar
Sam

Administrator, 690 Posts

23 May 2007 at 2:01pm

In that case, your LatLng table sounds appropriate.

You're going to need to create a saveInto(DataObject $record) method on your LatLngField class. This method will be called when it's time to save the field. It will need to do one of the following:

* Create a new LatLng object and set $record->LatLngID to its ID.
* Update the LatLng object referred to by $record->LatLng() with the new LatLngString value.

I suggest that you make the constructor new LatLngField('LatLng')
Then you can you can use these values inside your saveInto method.

$hasoneMethod = $this->name;
$idField = $this->name . 'ID';

Your saveInto() method will need to make reference to LatLngString itself. However, why not have separate Lat and Lng fields in your LatLng DataObject? :-) You might also want to add ReferringClass and ReferringID fields, so that you have a bidirectional link between the two objects - useful if you're querying the LatLng table and want to know who added that point to the database.

Another thing you might want to do is create a page type, LocatedPage, and make HostelPage and your other page types with LatLng values subclasses of LocatedPage. Then you could have the location logic added to the LocatedPage class, and won't have to copy it onto the different page types.

Avatar
Davis

Community Member, 5 Posts

24 May 2007 at 12:22pm

Thanks once again Sam,

I took your advice of utilizing the saveInto method within the LatLngField class. It worked out beautifuly. I am now well on my way of getting this map integrated into the cms.

By the way, I noticed that Ofir Picazo is working on some sort of a google map interfacing into the system. I assume you are in contact with him and know better about how far along he is. I would be happy to exchange some of what I am developing with him to help us both get to our goals faster.

Thanks once again

Avatar
Sam

Administrator, 690 Posts

27 May 2007 at 11:58am

The summer of code program starts on June 1st, so I haven't heard of any progress from Ofir yet. However, we're going to be encouraging the team to post their progress to the Google Summer of Code forum, and it would be great for you to post a patch or something there, to help Ofir get started :-)

http://www.silverstripe.com/google-summer-of-code-forum/