XF 2.1 Class extension and return parent:: ?

Mr. Jinx

Well-known member
I have extended the follow class:
XF/ModeratorLog/Post
Code:
namespace MrJinx\LogAllModActions\XF\ModeratorLog;
use XF\Mvc\Entity\Entity;

class Post extends XFCP_Post
{
        public function isLoggable(Entity $content, $action, \XF\Entity\User $actor)
        {
                $options = \XF::options();
                switch ($action)
                {
                        case 'edit':
                                if (($actor->user_id == $content->user_id) && (!$options->MrJinx_LogAllModActions_OwnActions))
                                {
                                        return false;
                                }
                }

                return parent::isLoggable($content, $action, $actor);
        }
}

The original Post looks like this:
Code:
class Post extends AbstractHandler
{
        public function isLoggable(Entity $content, $action, \XF\Entity\User $actor)
        {
                switch ($action)
                {
                        case 'edit':
                                if ($actor->user_id == $content->user_id)
                                {
                                        return false;
                                }
                }

                return parent::isLoggable($content, $action, $actor);
        }
}

And AbstractHandler:
Code:
        public function isLoggable(Entity $content, $action, \XF\Entity\User $actor)
        {
                return true;
        }

My problem is the last part "return parent::isLoggable($content, $action, $actor);"
If I am correct, this will call the parent function isLoggable, so in this case it would call isLoggable from the original Post class.
The problem is that this would undo my modification.
If "$options->MrJinx_LogAllModActions_OwnActions" is set, it would call parent::isLoggable from the original Post function (I think).

Ofcource I could just return true, but what should be the proper way to extent a function like this?
 
Perhaps try calling the parent first:
Code:
$parent = parent::isLoggable($content, $action, $actor);

if ($parent && $action == 'edit')
{
    if ($actor->user_id == $content->user_id && \XF::options()->MrJinx_LogAllModActions_OwnActions)
    {
        return false;
    }
}

return $parent;
 
My problem is the last part "return parent::isLoggable($content, $action, $actor);"
If I am correct, this will call the parent function isLoggable, so in this case it would call isLoggable from the original Post class.
The problem is that this would undo my modification.

No, it won't undo your modification because you are returning false from your logic block - thus stopping execution. The parent would not be called in that case. The parent is only called if your truth test fails.

Whether you should be calling the parent function before or after your logic depends on the outcome you want - either could be correct.

You might need to map out the logic to validate your choice.

For your original example:

  1. if (action = 'edit') && ($actor->user_id == $content->user_id) && ($options->MrJinx_LogAllModActions_OwnActions == false) then your modification returns isLoggable = false
  2. if (action = 'edit') && ($actor->user_id == $content->user_id) && ($options->MrJinx_LogAllModActions_OwnActions == true) then your modification does nothing and execution passes to the parent, which will also return isLoggable = false
... which I'm not sure achieves what you want to achieve?

Don't you want it to return true if the MrJinx_LogAllModActions_OwnActions is set to true?

If so, just change your original code to the following:

PHP:
namespace MrJinx\LogAllModActions\XF\ModeratorLog;
use XF\Mvc\Entity\Entity;

class Post extends XFCP_Post
{
        public function isLoggable(Entity $content, $action, \XF\Entity\User $actor)
        {
                $options = \XF::options();
                switch ($action)
                {
                        case 'edit':
                                if (($actor->user_id == $content->user_id) && ($options->MrJinx_LogAllModActions_OwnActions))
                                {
                                        return true;
                                }
                }

                return parent::isLoggable($content, $action, $actor);
        }
}

... you want it to log the action if your MrJinx_LogAllModActions_OwnActions option is set to true, right?
 
Spot on @Sim, the situation as you described it is exactly what is happening.
... you want it to log the action if your MrJinx_LogAllModActions_OwnActions option is set to true, right?
Yes, correct! Your example gives the desired result. Thanks for your explanation.
I had some trouble understanding the effect from 'return parent'. Now I understand.

Perhaps try calling the parent first:
Thanks for this example! This is another approach but I had to change 'return false' to 'return true' to give it the desired result. I probably wasn't clear about that.
 
Top Bottom