1<?php
2
3declare(strict_types=1);
4
5namespace Sabre\Xml;
6
7/**
8 * Context Stack.
9 *
10 * The Context maintains information about a document during either reading or
11 * writing.
12 *
13 * During this process, it may be neccesary to override this context
14 * information.
15 *
16 * This trait allows easy access to the context, and allows the end-user to
17 * override its settings for document fragments, and easily restore it again
18 * later.
19 *
20 * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
21 * @author Evert Pot (http://evertpot.com/)
22 * @license http://sabre.io/license/ Modified BSD License
23 */
24trait ContextStackTrait
25{
26    /**
27     * This is the element map. It contains a list of XML elements (in clark
28     * notation) as keys and PHP class names as values.
29     *
30     * The PHP class names must implement Sabre\Xml\Element.
31     *
32     * Values may also be a callable. In that case the function will be called
33     * directly.
34     *
35     * @var array
36     */
37    public $elementMap = [];
38
39    /**
40     * A contextUri pointing to the document being parsed / written.
41     * This uri may be used to resolve relative urls that may appear in the
42     * document.
43     *
44     * The reader and writer don't use this property, but as it's an extremely
45     * common use-case for parsing XML documents, it's added here as a
46     * convenience.
47     *
48     * @var string|null
49     */
50    public $contextUri;
51
52    /**
53     * This is a list of namespaces that you want to give default prefixes.
54     *
55     * You must make sure you create this entire list before starting to write.
56     * They should be registered on the root element.
57     *
58     * @var array
59     */
60    public $namespaceMap = [];
61
62    /**
63     * This is a list of custom serializers for specific classes.
64     *
65     * The writer may use this if you attempt to serialize an object with a
66     * class that does not implement XmlSerializable.
67     *
68     * Instead it will look at this classmap to see if there is a custom
69     * serializer here. This is useful if you don't want your value objects
70     * to be responsible for serializing themselves.
71     *
72     * The keys in this classmap need to be fully qualified PHP class names,
73     * the values must be callbacks. The callbacks take two arguments. The
74     * writer class, and the value that must be written.
75     *
76     * function (Writer $writer, object $value)
77     *
78     * @var array
79     */
80    public $classMap = [];
81
82    /**
83     * Backups of previous contexts.
84     *
85     * @var array
86     */
87    protected $contextStack = [];
88
89    /**
90     * Create a new "context".
91     *
92     * This allows you to safely modify the elementMap, contextUri or
93     * namespaceMap. After you're done, you can restore the old data again
94     * with popContext.
95     */
96    public function pushContext()
97    {
98        $this->contextStack[] = [
99            $this->elementMap,
100            $this->contextUri,
101            $this->namespaceMap,
102            $this->classMap,
103        ];
104    }
105
106    /**
107     * Restore the previous "context".
108     */
109    public function popContext()
110    {
111        list(
112            $this->elementMap,
113            $this->contextUri,
114            $this->namespaceMap,
115            $this->classMap
116        ) = array_pop($this->contextStack);
117    }
118}
119