Uncaught exception ‚Exception‘ with message ‚Serialization of ‚SimpleXMLElement‘ is not allowed‘

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Joacim
Člen | 229
+
0
-

Zdravím, potřebuji si uložit do session xml element

if (file_exists($xml1_path)) {
            $this->xml1 = simplexml_load_file($xml1_path);
        } else {
            throw new Nette\InvalidArgumentException('neexistuje');
        }

$data = new ArrayHash();
        $data->xml1= $this->xml1;
        ....

        return $data;

Ale dostanu hlášku Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed' in [no active file]:0 Stack trace: #0 {main} thrown in [no active file] on line 0

nebo

Exception

Serialization of 'SimpleXMLElement' is not allowed

Potřebuji si tento objekt uložit do session abych jej po redirectu mohl znovu použít, nevím jak jinak to udělat.

Mám HomepagePresenter kde mám loadFormSucceeded (form je na default.latte HomePresenteru) a renderExport.
V loadFormSucceeded zpracuji data z formuláře a uložím xml objekt.
V renderExport zpracuji xml objekt.

$this->helper = $this->merger->loadData($xml_1_path, $xml_2_path);
 \Tracy\Debugger::barDump($this->helper);
 $this->redirect("Homepage:export");

Editoval Joacim (23. 2. 2016 11:42)

David Matějka
Moderator | 6445
+
0
-

a proc chces do session ukladat cele xml? nebude ti stacit cesta?

Joacim
Člen | 229
+
0
-

David Matějka napsal(a):

a proc chces do session ukladat cele xml? nebude ti stacit cesta?

puvodne jsem chtěl jen cestu, ale tmp cesta po redirecru na stránku renderExport je NULL

public function loadFormSucceeded(Form $form) {
    $values = $form->getValues();

    try {
        $xml_1_path = $values->xml_1->getTemporaryFile();
        $xml_2_path = $values->xml_2->getTemporaryFile();

        $this->sessionSection->xml = $this->merger->loadData($xml_1_path, $xml_2_path);

        $this->redirect("Homepage:export");
    } catch (Nette\InvalidArgumentException $e) {
        $this->flashMessage($e->getMessage(), "error");
        $this->redirect("Homepage:default");
    }
}

public function renderExport() {

    try {

        $xml_string = $this->merger->mergeXml($this->sessionSection->xml->1, $this->sessionSection->xml->2);
        $this->template->text = 'Data';
        $this->merger->export($xml_string);

    } catch (Nette\InvalidArgumentException $e) {
        $this->flashMessage($e->getMessage(), "danger");
        $this->redirect("Homepage:default");
    }
}

Tohle všechno dělám jen kvuli tomu aby se mi na stránce export zobrazila hláška že byl soubor vyexportován a poté přes

public function export($xml_string) {

    // force download
    header("Content-Type: application/force-download");
    header("Content-Type: application/octet-stream");
    header("Content-Type: application/download");

    // disposition / encoding on response body
    header('Content-Disposition: attachment; filename=export_kontrolni_hlaseni-' . (new DateTime)->format('Y_m_d') . '.xml');
    header("Content-Transfer-Encoding: binary");
    header("Cache-control: private"); //use this to open files directly
    header('Expires: 0');
    header("Pragma: no-cache");
    header("Connection: close");

    echo $xml_string;

    $this->terminate();
}

Nabídnu soubor k uložení, bohužel na export latte se to vůbec nepřeredirectuje
XML objekt uložím do session takhle (je to spíš string objektu) $this->xml_lkn->asXML(); a pak jej ze session načtu takto simplexml_load_string($this->sessionSection->xml->lkn)

Celou dobu mi jde jen o to aby po kliknutí na submit (onSuccess), načetl data z formuláře jinde, kde nabídnu i soubor ke stažení

EDIT
Napsal jsem si XmlResponse

<?php

namespace App\Model;

use Nette;

/**
 * Description of XmlResponse
 *
 * @author xxx
 */
class XmlResponse extends Nette\Object implements Nette\Application\IResponse {

    /** @var mixed */
    private $source;

    /** @var bool */
    private $forceDownload;

    /** @var string */
    private $name;

    /** @var string */
    private $contentType;

    /**
     * @param  mixed  renderable variable
     */
    public function __construct($source, $name = NULL, $contentType = NULL, $forceDownload = TRUE) {
        $this->source = $source;
        $this->name = $name;
        $this->contentType = $contentType ? $contentType : 'application/octet-stream';
        $this->forceDownload = $forceDownload;
    }

    /**
     * Returns the file name.
     * @return string
     */
    public function getName() {
        return $this->name;
    }

    /**
     * Returns the MIME content type of a downloaded file.
     * @return string
     */
    public function getContentType() {
        return $this->contentType;
    }

    /**
     * @return mixed
     */
    public function getSource() {
        return $this->source;
    }

    /**
     * Sends response to output.
     * @return void
     */
    public function send(Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse) {

        $httpResponse->setHeader('Content-Disposition', ($this->forceDownload ? 'attachment' : 'inline')
                . '; filename="' . $this->name . '"'
                . '; filename*=utf-8\'\'' . rawurlencode($this->name));

        $httpResponse->setContentType($this->contentType);

        $httpResponse->setHeader('Pragma', "public");
        $httpResponse->setHeader('Expires', 0);
        $httpResponse->setHeader('Cache-Control', "must-revalidate, post-check=0, pre-check=0");
        $httpResponse->setHeader('Content-Transfer-Encoding', "binary");
        $httpResponse->setHeader('Content-Description', "File Transfer");
        $httpResponse->setHeader('Content-Length', strlen($this->source));

        if ($this->source instanceof Nette\Application\UI\ITemplate) {
            $this->source->render();
        } else {
            echo $this->source;
        }

    }

}

který jsem si chtěl zavolat v modelu Merge metodě export(), jenže v modelu neznám sendResponce

//$this->sendResponse(new XmlResponse($xml_string, 'merge.xml', array('application/octet-stream', 'application/force-download', 'application/download')));
        return (new XmlResponse($xml_string, 'merge.xml', array('application/octet-stream', 'application/force-download', 'application/download')));

takže si vracím objekt do presenteru kde si volám v renderExport

           $this->sendResponse($this->merger->export($xml_string));
$this->terminate();

Od prohlížeče obdržím GET http://server/xml_merger/homepage/export net::ERR_INVALID_RESPONSE
a to se snažím už 4 dny zprovoznit aby mi nette stahovalo soubory ze serveru

Soubor s dialog oknem dostanu pokud mám ve fci export třídy MargeManager toto

// force download
       header("Content-Type: application/force-download");
       header("Content-Type: application/octet-stream");
       header("Content-Type: application/download");

       // disposition / encoding on response body
       header('Content-Disposition: attachment; filename=export_kontrolni_hlaseni-' . (new DateTime)->format('Y_m_d') . '.xml');
       header("Content-Transfer-Encoding: binary");
       header("Cache-control: private"); //use this to open files directly
       header('Expires: 0');
       header("Pragma: no-cache");
       header("Connection: close");

       echo $xml_string;
       exit();

Tedy chci pouze 2 věci:

  1. Po odeslání formuláře vyrenderovat export page a ihned poté vygenerovat okno se staženám sloučeného souboru
  2. Generovat soubor ze serveru pomocí Nette

Editoval Joacim (23. 2. 2016 13:20)