Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature TR-4391 ensure PHP 8.1 support by the legacy release #321

Merged
merged 11 commits into from
Jul 18, 2022
Prev Previous commit
Next Next commit
feat: Add serialization support to SerializableDomDocument
  • Loading branch information
kilatib committed Jul 18, 2022
commit 6ec11d292efa3dfa6be4000bdb9803bdf91113ac
142 changes: 134 additions & 8 deletions qtism/common/dom/SerializableDomDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2017-2020 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
* Copyright (c) 2017-2022 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*
* @author Jérôme Bogaerts <jerome@taotesting.com>
* @license GPLv2
Expand All @@ -24,27 +24,153 @@
namespace qtism\common\dom;

use DOMDocument;
use DOMDocumentType;
use DOMElement;
use DOMImplementation;
use DOMDocumentFragment;
use DOMComment;
use DOMCDATASection;
use DOMProcessingInstruction;
use DOMText;
use DOMAttr;
use DOMEntityReference;
use DOMNode;
use DOMNodeList;
use Error;

/**
* Serializable DOM Document
*
* This class is a PHP Serializable DOMDocument implementation.
*
* @property string|null $actualEncoding
* @property $config
* @property DOMDocumentType|null $doctype
* @property DOMElement|null $documentElement
* @property string|null $documentURI
* @property string|null $encoding
* @property DOMImplementation $implementation
* @property bool $preserveWhiteSpace
* @property bool $recover
* @property bool $resolveExternals
* @property bool $standalone
* @property bool $strictErrorChecking
* @property bool $substituteEntities
* @property bool $validateOnParse
* @property string|null $version
* @property string|null $xmlEncoding
* @property bool $xmlStandalone
* @property string|null $xmlVersion
* @property int $childElementCount
* @property DOMElement|null $lastElementChild
* @property DOMElement|null $firstElementChild
*
* @method createElement(string $localName, string $value)
* @method DOMDocumentFragment createDocumentFragment()
* @method DOMText|false createTextNode(string $data)
* @method DOMComment|false createComment(string $data)
* @method DOMCDATASection|false createCDATASection(string $data)
* @method DOMProcessingInstruction|false createProcessingInstruction(string $target, string $data)
* @method DOMAttr|false createAttribute(string $localName)
* @method DOMEntityReference|false createEntityReference(string $name)
* @method DOMNodeList|false getElementsByTagName(string $qualifiedName)
* @method DOMNodeList|false importNode(DOMNode $node, bool $deep = false)
* @method DOMElement|false createElementNS(string|null $namespace, string $qualifiedName, string $value)
* @method DOMAttr|false createAttributeNS(string|null $namespace, string $qualifiedName)
* @method DOMNodeList getElementsByTagNameNS(string|null $namespace, string $localName)
* @method DOMElement|null getElementById(string $elementId)
* @method DOMNode adoptNode(DOMNode $elementId)
* @method append(...$nodes)
* @method prepend(...$nodes)
* @method normalizeDocument()
* @method renameNode(DOMNode $node, $namespace, $qualifiedName)
* @method DOMDocument|bool load(string $filename, ?int $options = null)
* @method int|false save($filename, $options = null)
* @method string|false saveXML(?DOMNode $node = null, int $options = null)
* @method bool validate()
* @method int|false xinclude(int $options = null)
* @method DOMDocument|bool loadHTML(string $source, int $options=0)
* @method DOMDocument|bool loadHTMLFile(string $filename, int $options=0)
* @method string|false saveHTML(DOMNode $node = null)
* @method int|false saveHTMLFile(string $filename)
* @method bool schemaValidate($filename, $options = null)
* @method bool schemaValidateSource($source, $flags)
* @method bool relaxNGValidate(string $filename)
* @method bool relaxNGValidateSource(string $source)
* @method bool registerNodeClass(string $baseClass, string $extendedClass)
*/
class SerializableDomDocument extends DOMDocument
class SerializableDomDocument
{
/** need to keep php 7.1 support */
private $xmlData;
private $version;
private $encoding;

private $dom;

public function __construct(string $version = '1.0', string $encoding = '')
{
$this->dom = new DOMDocument($version, $encoding);
}

/**
* @return array
*/
public function __sleep()
{
$this->xmlData = $this->saveXML();
return ['xmlData'];
$this->version = (string)$this->dom->xmlVersion;
$this->encoding = (string)$this->dom->encoding;
$this->xmlData = (string)$this;

return ['version', 'encoding', 'xmlData'];
}

public function __wakeup()
{
$this->loadXML($this->xmlData);
$this->dom = new DOMDocument($this->version, $this->encoding);
$this->dom->loadXML($this->xmlData);
}

public function __serialize(): array
{
return [
'version' => (string)$this->dom->xmlVersion,
'encoding' => (string)$this->dom->encoding,
'xmlData' => (string)$this,
];
}

public function __unserialize(array $data): void
{
$this->dom = new DOMDocument($data['version'], $data['encoding']);
$this->dom->loadXML($data['xmlData']);
}

public function __toString(): string
{
$xml = $this->dom->saveXML();
return $xml ? : '';
}

public function __call($name, $arguments)
{
if (!method_exists($this->dom, $name)) {
throw new Error(sprintf('Call to undefined method %s::%s()', __CLASS__, $name));
}

return call_user_func_array([$this->dom, $name], $arguments);
}

public function __get($name)
{
if (!property_exists($this->dom, $name)) {
trigger_error(sprintf('Undefined property: %s::%s', __CLASS__, $name), E_USER_WARNING);
}

return $this->dom->$name ?? null;
}

public function __set($name, $value)
{
$this->dom->$name = $value;

return $this->dom;
}
}