XF 2.0 Empty XML on export

CMTV

Well-known member
Hi!

I am learning how to export things in XenForo: trying to export my test "heroes" entities.

That is how my actionExport looks like:

PHP:
public function actionExport()
{
    $heroes = $this->finder('ExportImport:Hero');

    return $this->plugin('XF:Xml')->actionExport($heroes, 'ExportImport:Hero\Export');
}

Next, I created a class called Export inside ExportImport\Service\Hero folder:

PHP:
<?php

namespace ExportImport\Service\Hero;

use XF\Mvc\Entity\Finder;
use XF\Service\AbstractXmlExport;

class Export extends AbstractXmlExport
{
    public function getRootName()
    {
        return 'heroes_export';
    }

    public function export(Finder $finder)
    {
        $document = $this->createXml();
        $rootNode = $document->createElement($this->getRootName());
        $document->appendChild($rootNode);

        return $document;
    }
}

The problem is that the XML code itself is not generated. Clicking on "Export" button redirects me to an empty page:
1541497298284.webp
Nothing gets dowloading!

---

I even tried to replace default smilies export call with my own line:
PHP:
$this->plugin('XF:Xml')->actionExport($smilies, 'ExportImport:Hero\Export');

Same result... Working for smilies, showing empty page for my heroes.
 
Last edited:
The problem is your export method. You are overwriting a huge portion of the logic which actually does "stuff" :)

For a simpler example (simpler than the Smilies process, at least) check out the XF\Service\Banning\Ips\Export service class. Note you probably shouldn't need to override the export method at all, and it's likely just exportEntry that you want to do stuff in.
 
Nope. The following code is not working too:

PHP:
class Export extends AbstractXmlExport
{
    public function getRootName()
    {
        return 'heroes_export';
    }

    protected function exportEntry(Entity $entity, \DOMElement $node)
    {
        $node->appendChild($node->ownerDocument->createElement('test', 'kek'));
    }
}

:cry:

Also, this one:
PHP:
$document = $this->createXml();
$rootNode = $document->createElement($this->getRootName());
$document->appendChild($rootNode);

return $document;

works well if I put it in smilie export() function...
 
I can't say I see anything obvious in the code you've shown (aside what was mentioned about overriding export which shouldn't normally be needed), but I do note that your browser screenshot is routing to smilies/export rather than your own controller.
 
routing to smilies/export
Yes. I firstly tried my own admin page. After having an empty page I tried to use smilies controller because there could be something wrong with my own page. The same emptiness in both cases(
 
Oh, you need to make a view class to render your XML out to the client. (See the XML plugin's return line.)
 
@Mike hmm I can't find a directory which contains view classes. And the actionExport reutrn is:
PHP:
return $this->view($viewClass ?: $serviceClass, '', $viewParams);

So it uses an empty template name.
 
Got it. I needed to create an Export class that inherits View in Admin\View folder. Thank you!

PHP:
namespace ExportImport\Admin\View\Hero;

use XF\Mvc\View;

class Export extends View
{
    public function renderXml()
    {
        /** @var \DOMDocument $document */
        $document = $this->params['xml'];

        $this->response->setDownloadFileName('test.xml');

        return $document->saveXml();
    }
}
 
src/XF/Admin/View/* is where the default view classes are kept.

We don't need to render a template so the template name being empty is correct.
 
Yes, but the service short name becomes the view name (if you don't override it). Templates only apply for HTML output types. Views are in the <prefix>\<app_type>\View\<suffix> namespace. Look at XF\Admin\View\Smilie\Export as an example.
 
Top Bottom