• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Extending a class from another add-on...

farang

Well-known member
#1
Hi there! I've got a simple question.

Would it generally be possible to extend a class from another add-on the same way that I extend core XF classes?

I've created a code event listener and here is the listener function

Code:
        public static function extendTheOtherAddOn($class, array &$extend)
        {
            if ($class == 'AnotherAddOn_XenForo_Model_Thread')
            {
                die("554646"); // well, just to debug ... 
                //$extend[] = 'fgX_LastPostPreview_WidgetFramework_XenForo_Model_Thread';
            }
        }
My problem is that my function is never fired. (Just for debugging, I listen to event load_class without "event hint" )
 

Jake B.

Well-known member
#2
What is the class you're trying to extend?

EDIT: Nevermind, looks like you're trying to extend WidgetFramework_XenForo_Model_Thread which extends XenForo_Model_Thread This isn't possible since that class is l0aded using the XenForo Class Proxy. You'll want to extend XenForo_Model_Thread and adjust the execution order on your listener.
 

farang

Well-known member
#3
Thanks @Jake B. for your kind help. That explains it. :)

I tried to extend that class because I wanted to add to the $threadFetchOptions array before XenForo_Model_Thread::prepareThreadFetchOptions(array $fetchOptions) runs ...

Code:
$threadFetchOptions['fgx_join'] = fgX_LastPostPreview_XenForo_Model_Thread::FETCH_FGX_LAST_POST_PREVIEW;
Currently my add-on extends prepareThreadFetchOptions(array $fetchOptions) and will join a table in case
Code:
($fetchOptions['fgx_join'] & self::FETCH_FGX_LAST_POST_PREVIEW)
Hmmm.. I don't know how to solve that right now. :confused:
 

Liam W

Well-known member
#4
The XenForo_Model_Thread method will always run last, as that's the root class (ignoring the abstract XenForo_Model).

Just make sure you extend it, and when the other classes call the parent method, yours will also be called.

P.S You may want to remove the fetch constant, as if it is called from another class before the class proxy is instantiated, you'll get errors. Obviously, if you only ever read it from itself (or an extension of the class you're extending), it'll be fine.

Liam
 

farang

Well-known member
#5
The XenForo_Model_Thread method will always run last, as that's the root class (ignoring the abstract XenForo_Model).

Just make sure you extend it, and when the other classes call the parent method, yours will also be called.

P.S You may want to remove the fetch constant, as if it is called from another class before the class proxy is instantiated, you'll get errors. Obviously, if you only ever read it from itself (or an extension of the class you're extending), it'll be fine.

Liam
Thanks Liam.

I think I'm a bit stuck here... I'd like to extend the code in the "best pratice" way and I try to avoid hard coding in the join.

I paste the code below and maybe someone can come up with an idea how to do this in a reasonable good way.

Here is how I extended ControllerPublic_Forum _getThreadFetchElements
As you see I assign the fetch constant to $threadFetchOptions['fgx_join'] to flag that a join is needed.

Code:
<?php

/**
* Extending XenForo_ControllerPublic_Forum
*/
class fgX_LastPostPreview_XenForo_ControllerPublic_Forum extends XFCP_fgX_LastPostPreview_XenForo_ControllerPublic_Forum
{
    protected function _getThreadFetchElements(array $forum, array $displayConditions)
    {
        $parentElements = parent::_getThreadFetchElements($forum, $displayConditions);
        $threadFetchConditions = $parentElements['conditions'];

        $threadFetchOptions = $parentElements['options'];

        $threadFetchOptions['fgx_join'] = fgX_LastPostPreview_XenForo_Model_Thread::FETCH_FGX_LAST_POST_PREVIEW;

        return array(
            'conditions' => $threadFetchConditions,
            'options' => $threadFetchOptions
        );
    }
}
And here is my extension of XenForo_Model_Thread

Code:
<?php

class fgX_LastPostPreview_XenForo_Model_Thread extends XFCP_fgX_LastPostPreview_XenForo_Model_Thread
{
    /**
     * Extending XenForo_Model_Thread
     */
    const FETCH_FGX_LAST_POST_PREVIEW = 0x01;

    public function prepareThreadFetchOptions(array $fetchOptions)
    {
        $parentFetchOptions = parent::prepareThreadFetchOptions($fetchOptions);

        if ((!empty($fetchOptions['join']) && ($fetchOptions['join'] & self::FETCH_FIRSTPOST)) ||
        (!empty($fetchOptions['fgx_join']) && ($fetchOptions['fgx_join'] & self::FETCH_FGX_LAST_POST_PREVIEW)))
        {
            $parentFetchOptions['selectFields'] .= ', lastpost.message AS lastpost_message, lastpost.attach_count AS lastpost_attach_count';
            $parentFetchOptions['joinTables'] .=  ' LEFT JOIN xf_post AS lastpost ON
                    (lastpost.post_id = thread.last_post_id)';
        }

        return array(
            'selectFields' => $parentFetchOptions['selectFields'],
            'joinTables'   => $parentFetchOptions['joinTables'],
            'orderClause'  => $parentFetchOptions['orderClause']
        );
       
    }
In the code above, the join will only occur when needed. It works well because XF Core will always run ControllerPublic_Forum _getThreadFetchElements.

However and here's my problem ... Widget Framework doesn't call the ControllerPublic_Forum _getThreadFetchElements. I'd need to make Widget Framework to do something like:
Code:
$threadFetchOptions['fgx_join'] = fgX_LastPostPreview_XenForo_Model_Thread::FETCH_FGX_LAST_POST_PREVIEW;
before prepareThreadFetchOptions() runs.

Obviously I can not extend WidgetFramework_XenForo_Model_Thread since that class is loaded by XenForo Class Proxy. How would You guys approach this problem?

Thank You for your kind help which I appreciate a lot.

//farang