2

I'm having some trouble trying to write a plugin. I'm trying to create a simple fieldtype that I'm going to use inside a matrix block. So far the public function getInputHtml of my fieldtype class, contains only:

var_dump($this->element)

And it shows me, as expected:

object(Craft\MatrixBlockModel)#1121 (25){["elementType":protected]=> string(11) "MatrixBlock" [.......]

The problem is that, as I try to change the previous

var_dump($this->element)

with a

var_dump($this->element->getOwner())

(or any other method/property of the MatrixBlockModel class), I obtain:

"Call to a member function getOwner() on a non-object"

Any suggestion? Could it have something to do with the magic methods (maybe __call) inherited by CComponent class?

1
  • 1
    If you setup xDebug (xdebug.org) and force step into the $this->element->getOwner() line, you'll be able to see if any magic methods are being called on it.
    – Brad Bell
    Aug 5 '14 at 16:42
2

Matrix initializes its blocks’ field types multiple times – once for each existing block in the field, and one last time to get the initial input HTML that should be used when new blocks are added.

For existing blocks, $this->element will be set on the field types, referring back to the existing MatrixBlockModel objects representing each of those blocks.

That won’t be the case the time that your field type is just telling Matrix what the initial input HTML should be, however, since no corresponding Matrix block exists yet.

When you call this:

var_dump($this->element);

it’s not giving you any errors because $this->element will just be null when there is no element set, and there’s nothing wrong with dumping a null variable.

But when you call this;

var_dump($this->element->getOwner())

now you’re trying to access a method on $this->element, which won’t necessarily be set, and that’s when you’re getting that exception.

So what you need to do is ensure that $this->element is actually set before trying to access getOwner():

if (isset($this->element))
{
    $owner = $this->element->getOwner();

    if ($owner)
    {
        // ...
    }
}

Note that I’m also not assuming that getOwner() will actually return anything, because that’s not a certainty either. For example if you create/save a new entry but there are validation errors, when the Edit Entry page reloads, you will have MatrixBlockModel objects for each of the blocks you had created, which $this->element will point to, but they won’t actually have IDs nor an owner yet.

4
  • I resolved putting my code inside a if(is_object($this->element)) Your suggestion, anyway, has been very valuable. Thank you. Aug 6 '14 at 16:29
  • Yeah that will work for the most part, but as noted above, even if $element is set, getOwner() won’t necessarily return anything. Aug 6 '14 at 18:47
  • You are right, but,anyway, now I can better check errors, putting everything inside a try/catch. Consider that "call to a member function of a non object" is a non catchable error (there is an rfc: wiki.php.net/rfc/catchable-call-to-member-of-non-object) Aug 7 '14 at 9:27
  • In this case it’s catchable - the exception is being thrown by Yii’s \CComponent class. You just need to remember that \CComponent is in the root namespace, whereas your code is in the Craft namespace, so you need to remember to type the “\” in catch (\Exception $e). Aug 7 '14 at 10:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.