XF 2.1 How to override a property?

Earl

Well-known member
You can extend a class and override its methods by having the same name then call it's parent method with this line return parent:methodName();
but how do you override a property?

I have this code
PHP:
namespace Earl\AddOn\XF\Searcher;


class User extends XFCP_User
{
    protected $allowedRelations = ['Option', 'Profile', 'Privacy', 'Custom'];

}

well, clearly it overrides $allowedRelations, but I just want to add new element Custom to the parent property $allowedRelations as opposed to hard coding all elements like that.
How do you do it?
 
Solution
PHP:
namespace Earl\AddOn\XF\Searcher;

use XF\Mvc\Entity\Manager;

class User extends XFCP_User
{
    public function __construct(Manager $em, array $criteria = null)
    {
        $this->allowedRelations[] = 'Custom';
        parent::__construct($em, $criteria);
    }
}
This will work.

The constructor itself calls filterCriteria and you were modifying allowed relations after the parent constructor had already run. This will add the allowed relation first.
It very much depends on the specific class you're extending but in this case $allowedRelations isn't written to anywhere so it is safe to set its value pretty much at any time.

The earliest point in time that you will be able to set a class property is when the class is instantiated so I'd probably recommend this:
PHP:
namespace Earl\AddOn\XF\Searcher;

use XF\Mvc\Entity\Manager;

class User extends XFCP_User
{
    public function __construct(Manager $em, array $criteria = null)
    {
        parent::__construct($em, $criteria);
        $this->allowedRelations[] = 'Custom';
    }
}
 
It very much depends on the specific class you're extending but in this case $allowedRelations isn't written to anywhere so it is safe to set its value pretty much at any time.

The earliest point in time that you will be able to set a class property is when the class is instantiated so I'd probably recommend this:
PHP:
namespace Earl\AddOn\XF\Searcher;

use XF\Mvc\Entity\Manager;

class User extends XFCP_User
{
    public function __construct(Manager $em, array $criteria = null)
    {
        parent::__construct($em, $criteria);
        $this->allowedRelations[] = 'Custom';
    }
}
Thank you for that @Chris D
 
Aaah! I found that code isn't working

It seems like the __construct(Manager $em, array $criteria = null) method doesn't get executed before the the filterCriteria(array $criteria, $relation = null) method in abstractSearcher.php

(See this debug screenshot)
1593840444359.webp

this works:
PHP:
 protected $allowedRelations = ['Option', 'Profile', 'Privacy', 'Custom'];

This doesn't
PHP:
namespace Earl\AddOn\XF\Searcher;

use XF\Mvc\Entity\Manager;

class User extends XFCP_User
{
    public function __construct(Manager $em, array $criteria = null)
    {
        parent::__construct($em, $criteria);
        $this->allowedRelations[] = 'Custom';
    }
}

This also doesn't work
PHP:
namespace Earl\AddOn\XF\Searcher;

use XF\Mvc\Entity\Manager;

class User extends XFCP_User
{
    public function __construct(Manager $em, array $criteria = null)
    {
        parent::__construct($em, $criteria);
        $this->allowedRelations = ['Option', 'Profile', 'Privacy', 'Custom'];
    }
}
 
PHP:
namespace Earl\AddOn\XF\Searcher;

use XF\Mvc\Entity\Manager;

class User extends XFCP_User
{
    public function __construct(Manager $em, array $criteria = null)
    {
        $this->allowedRelations[] = 'Custom';
        parent::__construct($em, $criteria);
    }
}
This will work.

The constructor itself calls filterCriteria and you were modifying allowed relations after the parent constructor had already run. This will add the allowed relation first.
 
Solution
Top Bottom