XF 2.0 Having trouble extending \XF\FileWrapper. Can anyone spot my problem?

Earl

Well-known member
  • What I'm trying to do is:

I wanna add some metadata to a file and modify it as soon as it uploads as an attachment. (before hash calculations etc)

So I thought overriding beforeNewAttachment method in AbstractHandler would do the trick.

XF\Attachment\AbstractHandler
PHP:
public function beforeNewAttachment(\XF\FileWrapper $file, array &$extra = [])
{
   return;
}

As you can see that method uses \XF\FileWrapper class

Then again, Having my code inside of new method called "addMetaData" in \XF\FileWrapper class would allow me to execute my code.

I mean by doing something like this (I will use attachment handler in XenForo Resource Manager to illustrate the idea here):
MyAddon\XFRM\Attachment\ResourceUpdate
PHP:
namespace MyAddon\XFRM\Attachment;

class ResourceVersion extends XFCP_ResourceUpdate
{
    /**
     * @param \MyAddon\XF\FileWrapper $file
     * @param array $extra
     */
    public function beforeNewAttachment(\XF\FileWrapper $file, array &$extra = [])
    {
        parent::beforeNewAttachment($file, $extra);
        $file->addMetaData();
    }
}
MyAddon/XF/FileWrapper
PHP:
namespace MyAddon\XF;


class FileWrapper extends XFCP_FileWrapper
{
    /**
     * Add watermark to images
     * @return $this|bool
     */
    public function addMetaData()
    {

        //my code here

    }

Would allow me to run my code in each "attachment handlers" as opposed to repeating my code inside of beforeNewAttachment method in every attachment handlers (you can't extend abstract classes)

  • My problem:
Problem: My Class Extension for MyAddon/XF/FileWrapper doesn't seem work.
But Class Extionsionfor MyAddon\XFRM\Attachment\ResourceUpdate works perfectly. (in my case MyAddon\XF\Attachment\Post)

When I call addMetaData() method (as in first code)
$file->addMetaData(); //after this line

It jumps into an error
Debug screenshots:
1516724725935.webp

Then after pressing f7 (Jump into) next line:

1516724933952.webp

Exception: Call to undefined method XF\FileWrapper::addMetaData()

o_Oo_O

Strange right?
Namespace looks fine:
1516725598869.webp
And class extensions in admincp:
1516725334488.webp

The craziest thing is:
I tried adding breakpoints to extension.php too

1516725746014.webp

As you can see, it loads both class extensions in __construct method of \XF\Extension class when I debug.

and It only loads the attachment handler class extension with the class proxy system, But not the FileWrapper extension when I running the debugger here:

\XF\Extension
PHP:
// XFCP = XenForo Class Proxy, in case you're wondering


$nsSplit = strrpos($extendClass, '\\');

if ($nsSplit !== false && $ns = substr($extendClass, 0, $nsSplit))

{

   $proxyClass = $ns . '\\XFCP_' . substr($extendClass, $nsSplit + 1);

}

else

{

   $proxyClass = 'XFCP_' . $extendClass;

}


// TODO: there may be a situation where this fails. If we've changed the extensions after classes have

// been loaded, it's possible these classes will already be loaded with a different config. Figure out

// how to handle that if possible. Remains to be seen if it comes up (mostly relating to add-on imports).
 
The XF\FileWrapper class isn't designed to be extended and therefore isn't run through the class extension system.

You would have to find somewhere else to add your custom code.
 
The XF\FileWrapper class isn't designed to be extended and therefore isn't run through the class extension system.

You would have to find somewhere else to add your custom code.
Oohhh I see. so there are classes that we can't extend. I lost lots of hair when I was trying to extend this class :LOL:
How do we find if a class is extensible or not?
And Thank you for the fast response. Truly appreciate it.
 
Easiest way is to search the XF files for instances of the class name.

In this case, you'll find it is instantiated directly inside the Upload object:
PHP:
$wrapper = new \XF\FileWrapper($this->tempFile, $this->fileName);

If it was extendable, we'd run the class name through the extendClass method first, similar to this:
PHP:
$class = \XF::extendClass('XF\FileWrapper');
$wrapper = new $class($this->tempFile, $this->fileName);
 
Easiest way is to search the XF files for instances of the class name.

In this case, you'll find it is instantiated directly inside the Upload object:
PHP:
$wrapper = new \XF\FileWrapper($this->tempFile, $this->fileName);

If it was extendable, we'd run the class name through the extendClass method first, similar to this:
PHP:
$class = \XF::extendClass('XF\FileWrapper');
$wrapper = new $class($this->tempFile, $this->fileName);
Got it. Thank you for helping me out with this one. Really appreceate your support. :coffee:
 
Top Bottom