XF 2.2 Class extend not work with some function?

ZixDev

Member
Hello,
I have 3rd addon, and it has a function:
Code:
<?php

namespace Abc\Xyz\Job;

use XF\Job\AbstractRebuildJob;

class MathJaxParser extends AbstractRebuildJob
{
    public static function isContainsMathJax(string $message): bool
    {
        return preg_match('/(\\\()(.*?)(\\\))|\$([^\$]+)\$|\$\$([^\$]+)\$\$/ism', $message) === 1;
    }
    ... another function
}

I extend this class and rewrite that function like that (of course, I created an extension in ACP).
Code:
<?php

namespace LilTee\Tools\Abc\Xyz\Job;

class MathJaxParser extends XFCP_MathJaxParser
{
    public static function isContainsMathJax(string $message): bool
    {
        return true;
    }
}

But it seems that function not overridden.
What am I wrong?
 
Looking at the code, jobs should be extendable in the normal instantiation path, so I can only guess that there's a mistake somewhere in the extension?
 
Looking at the code, jobs should be extendable in the normal instantiation path, so I can only guess that there's a mistake somewhere in the extension?
Hello Mike, thank you for your reply.
Base code:
PHP:
<?php

namespace Abc\Xyz\Job;

use XF\Job\AbstractRebuildJob;
use Abc\Xyz\XF\Entity\Post;

class MathJaxParser extends AbstractRebuildJob
{
    public static function isContainsMathJax(string $message): bool
    {
        return preg_match('/(\\\()(.*?)(\\\))|\$([^\$]+)\$|\$\$([^\$]+)\$\$/ism', $message) === 1;
    }

    /**
     * @param mixed $start
     * @param mixed $batch
     * @return array
     */
    protected function getNextIds($start, $batch)
    {
        return $this->app->db()->fetchAllColumn($this->app->db()->limit('
            SELECT post_id
            FROM xf_post
            WHERE post_id > ?
            ORDER BY post_id
        ', $batch), $start);
    }

    /**
     * @param mixed $id
     * @return void
     */
    protected function rebuildById($id)
    {
        /** @var Post|null $post */
        $post = $this->app->em()->find('XF:Post', $id);
        if ($post === null) {
            return;
        }

        $post->set('is_embed_webview', static::isContainsMathJax($post->message));
        $post->saveIfChanged();
    }

    /**
     * @return \XF\Phrase
     */
    protected function getStatusType()
    {
        return \XF::phrase('posts');
    }
}

Extend code:
PHP:
<?php

namespace LilTee\Tools\Abc\Xyz\Job;

class MathJaxParser extends XFCP_MathJaxParser
{
    public static function isContainsMathJax(string $message): bool
    {
        return false;
    }
}

Extension
1619518973023.webp

Place use this extend function
PHP:
<?php

namespace Abc\Xyz\XF\Entity;

use XF\Mvc\Entity\Structure;
use Abc\Xyz\Job\MathJaxParser;

class Post extends XFCP_Post
{
    public static function getStructure(Structure $structure)
    {
        $structure = parent::getStructure($structure);

        $structure->columns['is_embed_webview'] = [
            'type' => self::BOOL,
            'default' => false,
            'api' => true,
        ];

        return $structure;
    }

    protected function _postSave()
    {
        parent::_postSave();

        if ($this->isChanged('message')) {
            $this->fastUpdate(
                'is_embed_webview',
                MathJaxParser::isContainsMathJax($this->message)
            );
        }
    }
}

Content to test when submitting a post:
'Some thing' => will return false
' $something$ ' => will return true.
If function isContainsMathJax replace the parent, it must always return false.
But when I submitting a post '$something$ ' => It still returns true.

I tested many times, and don't know what am I wrong.
 
I missed that the methods were static, though that isn't fundamentally the issue as internally you use late static binding for your call. It's your call from outside the class that's the problem -- you're just calling a specific class method.

The class extension system really only relates to object instantiation. Since you're calling MathJaxParser::isContainsMathJax, you're not using any of that. I suppose you could do something like this:

Code:
$finalClass = \XF::extendClass($baseClassName);
$result = $finalClass::isContainsMathJax(...);

I'm not sure if that will work as written (replacing class name and arguments as necessary), but I believe it should. Saying that, I don't really think it's a pattern we'd use. We would generally try to avoid a static call if it was something we were expecting to be extended. For example, you could make your method isContainsMathJax part of the post entity itself, which would allow a more direct override (even if you did decide to put the regex that does the validation in a helper method elsewhere).
 
Top Bottom