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.

Data Model Questions /

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

DOD - Odd behavior with function name same as class name


Go to End


10 Posts   7173 Views

Avatar
Hamish

Community Member, 712 Posts

20 August 2009 at 1:39pm

Quick Q about an odd decorator behavior..

If a decorator has a method of the same name as it's class, it seems to get executed under certain situations.

For example:

class Foo extends DataObjectDecorator {

	function Foo() {
		return $this->owner->name;
	}
}

During build (or whenever singleton(ownerobject)) is called, it seems to execute Foo() and fail because it doesn't have an owner.

Is this expected behaviour?

Example Trace:

    * Extent->Extent()
      Line 1 of Object.php(455) : eval()'d code
    * eval
      Line 455 of Object.php
    * Object->__construct()
      Line 209 of DataObject.php
    * DataObject->__construct(,1)
    * ReflectionClass->newInstanceArgs(Array)
      Line 114 of Object.php
    * Object::strong_create(SiteCategory,,1)
      Line 258 of Core.php
    * singleton(SiteCategory)
      Line 2461 of DataObject.php
    * DataObject::get_one(SiteCategory,`SiteCategory`.`ID` = 1)
      Line 2556 of DataObject.php
    * DataObject::get_by_id(SiteCategory,1)
      Line 21 of CategorySelectionPage.php
    * CategorySelectionPage_Controller->init()
      Line 11 of AssetRegisterPage.php
    * AssetRegisterPage_Controller->init()
      Line 113 of Controller.php
    * Controller->handleRequest(HTTPRequest)
      Line 29 of ModelAsController.php
    * ModelAsController->handleRequest(HTTPRequest)
      Line 44 of RootURLController.php
    * RootURLController->handleRequest(HTTPRequest)
      Line 277 of Director.php
    * Director::handleRequest(HTTPRequest,Session)
      Line 121 of Director.php
    * Director::direct(/)
      Line 118 of main.php

Avatar
ajshort

Community Member, 244 Posts

20 August 2009 at 1:51pm

I suspect that it may be because PHP would be recognising Foo as a PHP4 style constructor, and calling that instead of __construct - which assigns the owner.

Avatar
Hamish

Community Member, 712 Posts

20 August 2009 at 2:04pm

I was just thinking that it looked like it was using it as a constructor.

Ok, when I give it a constructor it works.

public function __construct() {
	parent::__construct();
}

Thanks AJ!

(btw Spy sapping your sentry? :P)

Avatar
Mohamed

Community Member, 4 Posts

28 March 2010 at 5:21pm

Hi Hamish and AJ.. Sorry did not mean to hijack the thread but I thought this is related to the same issue I am facing hence I am submitting this reply.

I am trying to create a constructor for a StudentsPage Class that extends Page with parameters taking DataObject as a value in order to create pages for students (which were created in tutorial 5 using the Student class extending a dataobject) automatically as an instance of the StudentsHolder class is created as I am trying to create pages for the Student DataObjects. So in a nutshell, I am trying to do this by creating pages of type StudentPages dynamically when StudentsHolder Pages (or instances) are created.

My problem is in making a construct for the StudentsPage class. I have had errors to do with "[Warning] Bad class value NULL passed to ClassInfo::ancestry()". Here is a sample of my code, your assistance will be very much appreciated:

Class StudentsHolder extends Page{
function StudentsHolder(){
$allStudents = DataObject::get("Student"); //get all the records for the instances of the class Student from the database

foreach($allStudents as $row){
//create a new page with the details extracted from the database
new StudentsPage($row);
}
}

}

.....

Class StudentsPage extends Page{

Public function StudentsPage(DataObject $dObj){
//create the pages with the attributes passed by the DataObject in parameters passed.
$this->MenuTitle = $dObj['MenuTitle'];
$this->Title = $dObj['Title'];
$this->MetaTitle = $dObj['MetaTitle'];
$this->ParentID = 40; //this is the ParentID of the StudentsHolder Class in the database
}
}

Avatar
Hamish

Community Member, 712 Posts

29 March 2010 at 1:56pm

Yeah it will be the same cause. In your case it will be trying to use ClassInfo methods before the manifest is processed.

Rename the method and it should work.

Avatar
Mohamed

Community Member, 4 Posts

29 March 2010 at 5:50pm

Thank you for replying :). It is very much appreciated.
Sorry Hamish, I am trying to get my head around this. Is there a way to use a constructor while getting around this problem? Using the constructor is pivotal to what I am trying to do (Creating instances of StudentsPage as soon as StudentsHolder are created while having StudentsPage instances the children of StudentsHolder.)

Avatar
ajshort

Community Member, 244 Posts

29 March 2010 at 8:35pm

You should be using PHP 5 style constructors which need to call the parent constructor. However, in this instance it would be more appropriate for you to use the static $defaults array or define a populateDefaults() method on your object.

public static $defaults = array(
  'Field' => 'Value'
);

public function populateDefaults() {
  $this->Field = 'value';
  parent::populateDefaults();
}

Avatar
Mohamed

Community Member, 4 Posts

29 March 2010 at 10:50pm

AJ and Hamish, I appreciate your reply. I am not sure if you both got me. Sorry if I am a little unclear.

In tutorial 5, Student Class was extending a DataObject, where an interface was created in the CMS to add Students relations to Mentors (the Mentor class was extends Page). But in tutorial 5 they did not have the mechanism to add Student Pages so I created a new Class StudentsPage which extends Page and another Class called StudentsHolder which extends page as well. I am trying to design the application so that when StudentsHolder Page is created, StudentsPages are created automatically from the data available in the database (the Student dataobjects that were created earlier in tutorial 5.) underneath the StudentsHolder so that the StudentsPages are children of StudentsHolder. Please refer to the attachment for an illustration of what I mean.

So if you look at the image attached, it shows the CMS. What I want to do is as soon as I create a StudentsHolder page, all the StudentsPages would be created from underneath it. To be able to do this I will have to know the ParentID beforehand to put in the StudentsPage class (as shown in the code submitted in the reply before.).

Attached Files
Go to Top