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.

Data Model Questions /

[SOLVED] Accessing a DataObject from an unrelated class


Reply


7 Posts   1770 Views

Avatar
nekranox

Community Member, 31 Posts

27 May 2010 at 3:05am

Edited: 28/05/2010 2:33am

Hey guys,

Relativley new to SS, I've read "Silverstripe: The complete guide to CMS development" and I'm adapting the Jobs module that I've created whilst reading the book.

I basically want to access the "Jobs" DataObject from my "HomePage" class so that I can show the latest 5 jobs on the home page. Here's whats going on in my HomePage.php

<?php
class HomePage extends Page {

   public static $db = array(
   );
   
   static $has_many = array(
      'Jobs' => 'Job',
   );

}
class HomePage_Controller extends Page_Controller {

   function LastestJobs() {
      return DataObject::get("Jobs");
   }

}
?>

So I'm assuming that in order to access the contents of the "Jobs" DataObject I need to first create a one-to-many relationship between my "HomePage" class and the "Jobs" DataObject since the home page can list many (well up to 5) jobs and any one job will only be listed on the home page once.

Heres the relevent code in HomePage.ss

      <ul>
      <% control LatestJobs %>
         <li class="job" id="Job{$ID}">
            <h3><a href="$Link">$Title</a></h3>
            <p class="description">Description: $Description</p>
         </li>
      <% end_control %>
      </ul>

When I view the page, I'm seeing a single loop over the markup inside the control block with blank spaces where all of the data from the the variables should be. What am I doing wrong?

Apologies if I'm making a really noob mistake here, I've spent the whole day trying to find an anwser myself. Fail :(

-Robbie

Avatar
mark_s

Community Member, 78 Posts

27 May 2010 at 5:50pm

Hi.

For what you're doing, you don't need a one to many relationship from HomePage to Jobs. A one-to-many relationship is used typically where you've got objects that own a set of other objects (e.g. customer has orders). In this case, there is only one home page, and it logically doesn't own the job objects, it just presents them.

You have most of what you need already:
- a method on HomePage that returns the jobs you want to display
- a <% control LatestJobs %> in the template to iterate over the jobs.
- remove the $has_many

Inside the control loop, references like $Title refer to properties of the item in the set being iterated over, so in this case properties of the Job objects returned by LatestJobs. You need to look at what properties are defined on the Job object. If Job derives from Page, it should have a Title property, but if it derives from DataObject (directly or indirectly) but not from Page, it may not have these properties.

In the LatestJobs method, you can filter what jobs are returned for display on the home page (this is from memory so it may require tweaking):

return DataObject::get("Job", null, "DateListed desc", array("start" => 0, "limit" => 5));

This assumes the Job object has a DateListed property. It will list the most recent 5.

In your post, your method says DataObject::get("Jobs"), plural, I'm not sure if that's just a typo, or if you were thinking you could return the has_many property by name, but might be why the code didn't work. The first parameter of DataObject::get is the name of a class, so if the class is Job, it should be "Job". (As an issue of style, name your classes the singular, e.g. Job or Order, rather than Jobs or Orders). If you were using a has_many, LatestJobs would contain:

return $this->Jobs(); // this is how to refer to items in a has_many.

Hope this helps
Mark

Avatar
nekranox

Community Member, 31 Posts

27 May 2010 at 10:11pm

Thanks for your reply Mark,

I totally understand about the one-to-many relationship and that I don't need it in this instance, thanks for clearing that up! Also to anwser your question, the Job class is sub-classed from DataObject not Page.

I've updated my code as per your suggestions. I've also added an if condition to my template to test if the function is even returning a result. It doesn't appear to be as my else condition fires every time no matter what I do to the arguments passed to DataObject::get.

It must be the arguments that I've got wrong, I've included all of the code below including the begging of the Job class. Would you mind having a look again?

HomePage.php

<?php
class HomePage extends Page {

   public static $db = array(
   );

}
class HomePage_Controller extends Page_Controller {

   function LastestJobs() {
      return DataObject::get("Job", null, "ID desc", array("start" => 0, "limit" => 5));
   }

}
?>

HomePage.ss

   <% if Menu(2) %>
      <% include SubBar %>
   <% end_if %>

<div id="content">
      <ul>
      <% if LatestJobs %>
      <% control LatestJobs %>
         <li class="job" id="Job{$ID}">
            <h3><a href="$Link">$Title</a></h3>
            <p class="description">Description: $Description</p>
         </li>
      <% end_control %>
      <% else %>
         <li>Computer says no</li>
      <% end_if %>
      </ul>

      $Content
      $Form
      $PageComments
</div>

Job.php

<?php
class Job extends DataObject {
   
   static $db = array(
      'Title' => 'Text',
      'Description' => 'Text',
      'HoursPerWeek' => 'Text',
      'Location' => 'Text',
      'Sector' => 'Text',
      'RequiredRoutewayCourse' => 'Text',
      'HourlyWageOrSalary' => 'Currency',
      'ExpiryDate' => 'Date',
   );
   
   static $has_one = array(
      'JobCategory' => 'JobCategory',
      'Author' => 'Member',
   );
   
   static $singular_name = 'Job';
   
   static $plural_name = 'Jobs';

// ...

Avatar
nekranox

Community Member, 31 Posts

28 May 2010 at 1:04am

Edited: 28/05/2010 1:04am

One thing I've noticed is that DataObject::get was missing an argument, it should have had 5 and I was passing 4. I've corrected this but it hasn't changed the result. LastestJobs just isn't returning any objects to the template. :(

Avatar
nekranox

Community Member, 31 Posts

28 May 2010 at 2:32am

Stupidity award goes to OP for misspelling the function call in his controller class.

Avatar
mark_s

Community Member, 78 Posts

28 May 2010 at 6:01pm

Hey, glad to hear you got it working :-)

Avatar
santosmateo

Community Member, 11 Posts

3 September 2011 at 11:01am

Edited: 03/09/2011 11:04am

hola!

I'm trying to do the same but I am unable to do so, this is the code:

barqTipoProyecto.php:

<?php

class barqTipoProyecto extends DataObject {

static $db = array(
'Tipo' => 'Text',
);

static $belongs_many_many = array(
'tipoProyecto' => 'barqProyecto'
);

function getCMSfields_forPopup() {
$fields = new FieldSet();
$fields->push( new TextField( 'Tipo' ) );

return $fields;
}

}

cabecera.php:

<?php

class cabecera extends Page {}

class cabecera_Controller extends Page_Controller {

function TipoProyecto() {
return DataObject::get("barqTipoProyecto"); // the dataobject class where I want to get the data
}
}

cabecera.ss:

<ul>
<% control TipoProyecto %>
<li>$Tipo</li> <!-- a row into barqtipoproyecto table. (in Windows server the table names are lowercase. -->
<% end_control %>
</ul>

very thanks!