1<?php
2
3/**
4 * Generic property list implementation
5 */
6class HTMLPurifier_PropertyList
7{
8    /**
9     * Internal data-structure for properties.
10     * @type array
11     */
12    protected $data = array();
13
14    /**
15     * Parent plist.
16     * @type HTMLPurifier_PropertyList
17     */
18    protected $parent;
19
20    /**
21     * Cache.
22     * @type array
23     */
24    protected $cache;
25
26    /**
27     * @param HTMLPurifier_PropertyList $parent Parent plist
28     */
29    public function __construct($parent = null)
30    {
31        $this->parent = $parent;
32    }
33
34    /**
35     * Recursively retrieves the value for a key
36     * @param string $name
37     * @throws HTMLPurifier_Exception
38     */
39    public function get($name)
40    {
41        if ($this->has($name)) {
42            return $this->data[$name];
43        }
44        // possible performance bottleneck, convert to iterative if necessary
45        if ($this->parent) {
46            return $this->parent->get($name);
47        }
48        throw new HTMLPurifier_Exception("Key '$name' not found");
49    }
50
51    /**
52     * Sets the value of a key, for this plist
53     * @param string $name
54     * @param mixed $value
55     */
56    public function set($name, $value)
57    {
58        $this->data[$name] = $value;
59    }
60
61    /**
62     * Returns true if a given key exists
63     * @param string $name
64     * @return bool
65     */
66    public function has($name)
67    {
68        return array_key_exists($name, $this->data);
69    }
70
71    /**
72     * Resets a value to the value of it's parent, usually the default. If
73     * no value is specified, the entire plist is reset.
74     * @param string $name
75     */
76    public function reset($name = null)
77    {
78        if ($name == null) {
79            $this->data = array();
80        } else {
81            unset($this->data[$name]);
82        }
83    }
84
85    /**
86     * Squashes this property list and all of its property lists into a single
87     * array, and returns the array. This value is cached by default.
88     * @param bool $force If true, ignores the cache and regenerates the array.
89     * @return array
90     */
91    public function squash($force = false)
92    {
93        if ($this->cache !== null && !$force) {
94            return $this->cache;
95        }
96        if ($this->parent) {
97            return $this->cache = array_merge($this->parent->squash($force), $this->data);
98        } else {
99            return $this->cache = $this->data;
100        }
101    }
102
103    /**
104     * Returns the parent plist.
105     * @return HTMLPurifier_PropertyList
106     */
107    public function getParent()
108    {
109        return $this->parent;
110    }
111
112    /**
113     * Sets the parent plist.
114     * @param HTMLPurifier_PropertyList $plist Parent plist
115     */
116    public function setParent($plist)
117    {
118        $this->parent = $plist;
119    }
120}
121
122// vim: et sw=4 sts=4
123