Configurable.php 12.1 KB
Newer Older
lsmith's avatar
lsmith committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<?php
/*
 *  $Id$
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information, see
 * <http://www.phpdoctrine.com>.
 */
21

lsmith's avatar
lsmith committed
22 23 24 25 26 27
/**
 * Doctrine_Configurable
 * the base for Doctrine_Table, Doctrine_Manager and Doctrine_Connection
 *
 *
 * @package     Doctrine
28
 * @subpackage  Configurable
lsmith's avatar
lsmith committed
29 30 31 32 33 34
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link        www.phpdoctrine.com
 * @since       1.0
 * @version     $Revision$
 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
 */
35
abstract class Doctrine_Configurable extends Doctrine_Locator_Injectable
lsmith's avatar
lsmith committed
36
{
lsmith's avatar
lsmith committed
37 38 39
    /**
     * @var array $attributes               an array of containing all attributes
     */
zYne's avatar
zYne committed
40
    protected $attributes = array();
41

lsmith's avatar
lsmith committed
42
    /**
zYne's avatar
zYne committed
43
     * @var Doctrine_Configurable $parent   the parent of this component
lsmith's avatar
lsmith committed
44
     */
zYne's avatar
zYne committed
45
    protected $parent;
46

zYne's avatar
zYne committed
47 48
    /**
     * @var array $_impl                    an array containing concrete implementations for class templates
49
     *                                      keys as template names and values as names of the concrete
zYne's avatar
zYne committed
50 51 52
     *                                      implementation classes
     */
    protected $_impl = array();
53

lsmith's avatar
lsmith committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
    /**
     * setAttribute
     * sets a given attribute
     *
     * <code>
     * $manager->setAttribute(Doctrine::ATTR_PORTABILITY, Doctrine::PORTABILITY_ALL);
     *
     * // or
     *
     * $manager->setAttribute('portability', Doctrine::PORTABILITY_ALL);
     * </code>
     *
     * @param mixed $attribute              either a Doctrine::ATTR_* integer constant or a string
     *                                      corresponding to a constant
     * @param mixed $value                  the value of the attribute
     * @see Doctrine::ATTR_* constants
     * @throws Doctrine_Exception           if the value is invalid
     * @return void
     */
lsmith's avatar
lsmith committed
73 74
    public function setAttribute($attribute,$value)
    {
zYne's avatar
zYne committed
75 76
        if (is_string($attribute)) {
            $upper = strtoupper($attribute);
77

zYne's avatar
zYne committed
78 79 80 81 82 83 84
            $const = 'Doctrine::ATTR_' . $attribute;
            if (defined($const)) {
                $this->_state = constant($const);
            } else {
                throw new Doctrine_Exception('Unknown attribute ' . $attribute);
            }
        }
lsmith's avatar
lsmith committed
85
        switch ($attribute) {
86
            case Doctrine::ATTR_FETCHMODE:
87
                throw new Doctrine_Exception('Deprecated attribute. See http://doctrine.pengus.net/doctrine/manual/new/?chapter=configuration');
88 89 90 91 92 93 94
            case Doctrine::ATTR_LISTENER:
                $this->setEventListener($value);
                break;
            case Doctrine::ATTR_COLL_KEY:
                if ( ! ($this instanceof Doctrine_Table)) {
                    throw new Doctrine_Exception("This attribute can only be set at table level.");
                }
zYne's avatar
zYne committed
95
                if ($value !== null && ! $this->hasColumn($value)) {
96 97 98
                    throw new Doctrine_Exception("Couldn't set collection key attribute. No such column '$value'");
                }
                break;
zYne's avatar
zYne committed
99
            case Doctrine::ATTR_CACHE:
zYne's avatar
zYne committed
100 101 102
                if ($value !== null) {
                    if ( ! ($value instanceof Doctrine_Cache_Interface)) {
                        throw new Doctrine_Exception('Cache driver should implement Doctrine_Cache_Interface');
zYne's avatar
zYne committed
103
                    }
zYne's avatar
zYne committed
104 105
                }
                break;
106
            case Doctrine::ATTR_VALIDATE:
107 108 109 110
            case Doctrine::ATTR_QUERY_LIMIT:
            case Doctrine::ATTR_QUOTE_IDENTIFIER:
            case Doctrine::ATTR_PORTABILITY:
            case Doctrine::ATTR_DEFAULT_TABLE_TYPE:
zYne's avatar
zYne committed
111
            case Doctrine::ATTR_EMULATE_DATABASE:
112
            case Doctrine::ATTR_USE_NATIVE_ENUM:
zYne's avatar
zYne committed
113
            case Doctrine::ATTR_DEFAULT_SEQUENCE:
zYne's avatar
zYne committed
114
            case Doctrine::ATTR_EXPORT:
zYne's avatar
zYne committed
115
            case Doctrine::ATTR_DECIMAL_PLACES:
116
            case Doctrine::ATTR_LOAD_REFERENCES:
117
            case Doctrine::ATTR_RECORD_LISTENER:
zYne's avatar
zYne committed
118
            case Doctrine::ATTR_THROW_EXCEPTIONS:
lsmith's avatar
lsmith committed
119

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
                break;
            case Doctrine::ATTR_SEQCOL_NAME:
                if ( ! is_string($value)) {
                    throw new Doctrine_Exception('Sequence column name attribute only accepts string values');
                }
                break;
            case Doctrine::ATTR_FIELD_CASE:
                if ($value != 0 && $value != CASE_LOWER && $value != CASE_UPPER)
                    throw new Doctrine_Exception('Field case attribute should be either 0, CASE_LOWER or CASE_UPPER constant.');
                break;
            case Doctrine::ATTR_SEQNAME_FORMAT:
            case Doctrine::ATTR_IDXNAME_FORMAT:
                if ($this instanceof Doctrine_Table) {
                    throw new Doctrine_Exception('Sequence / index name format attributes cannot be set'
                                               . 'at table level (only at connection or global level).');
                }
                break;
            default:
                throw new Doctrine_Exception("Unknown attribute.");
zYne's avatar
zYne committed
139
        }
lsmith's avatar
lsmith committed
140 141 142 143

        $this->attributes[$attribute] = $value;

    }
144

zYne's avatar
zYne committed
145 146 147 148 149 150 151 152 153 154 155 156 157
    /**
     * setImpl
     * binds given class to given template name
     *
     * this method is the base of Doctrine dependency injection
     *
     * @param string $template      name of the class template
     * @param string $class         name of the class to be bound
     * @return Doctrine_Configurable    this object
     */
    public function setImpl($template, $class)
    {
        $this->_impl[$template] = $class;
158

zYne's avatar
zYne committed
159 160
        return $this;
    }
161

zYne's avatar
zYne committed
162 163 164 165 166 167 168 169
    /**
     * getImpl
     * returns the implementation for given class
     *
     * @return string   name of the concrete implementation
     */
    public function getImpl($template)
    {
zYne's avatar
zYne committed
170
        if ( ! isset($this->_impl[$template])) {
zYne's avatar
zYne committed
171
            if (isset($this->parent)) {
zYne's avatar
zYne committed
172
                return $this->parent->getImpl($template);
zYne's avatar
zYne committed
173 174 175
            }
            return null;
        }
zYne's avatar
zYne committed
176
        return $this->_impl[$template];
zYne's avatar
zYne committed
177
    }
178

zYne's avatar
zYne committed
179 180 181 182 183 184 185 186 187 188
    /**
     * getCacheDriver
     *
     * @return Doctrine_Cache_Interface
     */
    public function getCacheDriver()
    {
        if ( ! isset($this->attributes[Doctrine::ATTR_CACHE])) {
            throw new Doctrine_Exception('Cache driver not initialized.');
        }
189

zYne's avatar
zYne committed
190 191
        return $this->attributes[Doctrine::ATTR_CACHE];
    }
192

lsmith's avatar
lsmith committed
193 194 195 196
    /**
     * @param Doctrine_EventListener $listener
     * @return void
     */
lsmith's avatar
lsmith committed
197 198
    public function setEventListener($listener)
    {
lsmith's avatar
lsmith committed
199 200
        return $this->setListener($listener);
    }
201

202 203 204 205 206 207 208 209 210
    /**
     * addRecordListener
     *
     * @param Doctrine_EventListener_Interface|Doctrine_Overloadable $listener
     * @return mixed        this object
     */
    public function addRecordListener($listener, $name = null)
    {
        if ( ! isset($this->attributes[Doctrine::ATTR_RECORD_LISTENER]) ||
211
             ! ($this->attributes[Doctrine::ATTR_RECORD_LISTENER] instanceof Doctrine_Record_Listener_Chain)) {
212

213 214 215 216 217 218
            $this->attributes[Doctrine::ATTR_RECORD_LISTENER] = new Doctrine_Record_Listener_Chain();
        }
        $this->attributes[Doctrine::ATTR_RECORD_LISTENER]->add($listener, $name);

        return $this;
    }
219

220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
    /**
     * getListener
     *
     * @return Doctrine_EventListener_Interface|Doctrine_Overloadable
     */
    public function getRecordListener()
    {
        if ( ! isset($this->attributes[Doctrine::ATTR_RECORD_LISTENER])) {
            if (isset($this->parent)) {
                return $this->parent->getRecordListener();
            }
            return null;
        }
        return $this->attributes[Doctrine::ATTR_RECORD_LISTENER];
    }
235

236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
    /**
     * setListener
     *
     * @param Doctrine_EventListener_Interface|Doctrine_Overloadable $listener
     * @return Doctrine_Configurable        this object
     */
    public function setRecordListener($listener)
    {
        if ( ! ($listener instanceof Doctrine_Record_Listener_Interface)
            && ! ($listener instanceof Doctrine_Overloadable)
        ) {
            throw new Doctrine_Exception("Couldn't set eventlistener. Record listeners should implement either Doctrine_Record_Listener_Interface or Doctrine_Overloadable");
        }
        $this->attributes[Doctrine::ATTR_RECORD_LISTENER] = $listener;

        return $this;
    }
253

lsmith's avatar
lsmith committed
254 255 256
    /**
     * addListener
     *
257
     * @param Doctrine_EventListener_Interface|Doctrine_Overloadable $listener
258
     * @return mixed        this object
lsmith's avatar
lsmith committed
259
     */
lsmith's avatar
lsmith committed
260 261
    public function addListener($listener, $name = null)
    {
zYne's avatar
zYne committed
262
        if ( ! isset($this->attributes[Doctrine::ATTR_LISTENER]) ||
zYne's avatar
zYne committed
263
             ! ($this->attributes[Doctrine::ATTR_LISTENER] instanceof Doctrine_EventListener_Chain)) {
264

lsmith's avatar
lsmith committed
265 266 267 268 269 270
            $this->attributes[Doctrine::ATTR_LISTENER] = new Doctrine_EventListener_Chain();
        }
        $this->attributes[Doctrine::ATTR_LISTENER]->add($listener, $name);

        return $this;
    }
271

lsmith's avatar
lsmith committed
272 273 274
    /**
     * getListener
     *
275
     * @return Doctrine_EventListener_Interface|Doctrine_Overloadable
lsmith's avatar
lsmith committed
276
     */
lsmith's avatar
lsmith committed
277 278
    public function getListener()
    {
lsmith's avatar
lsmith committed
279 280 281 282 283 284 285 286
        if ( ! isset($this->attributes[Doctrine::ATTR_LISTENER])) {
            if (isset($this->parent)) {
                return $this->parent->getListener();
            }
            return null;
        }
        return $this->attributes[Doctrine::ATTR_LISTENER];
    }
287

lsmith's avatar
lsmith committed
288 289 290
    /**
     * setListener
     *
291
     * @param Doctrine_EventListener_Interface|Doctrine_Overloadable $listener
zYne's avatar
zYne committed
292
     * @return Doctrine_Configurable        this object
lsmith's avatar
lsmith committed
293
     */
lsmith's avatar
lsmith committed
294 295
    public function setListener($listener)
    {
lsmith's avatar
lsmith committed
296 297 298
        if ( ! ($listener instanceof Doctrine_EventListener_Interface)
            && ! ($listener instanceof Doctrine_Overloadable)
        ) {
299
            throw new Doctrine_EventListener_Exception("Couldn't set eventlistener. EventListeners should implement either Doctrine_EventListener_Interface or Doctrine_Overloadable");
lsmith's avatar
lsmith committed
300 301 302 303 304
        }
        $this->attributes[Doctrine::ATTR_LISTENER] = $listener;

        return $this;
    }
305

lsmith's avatar
lsmith committed
306 307 308 309 310 311
    /**
     * returns the value of an attribute
     *
     * @param integer $attribute
     * @return mixed
     */
lsmith's avatar
lsmith committed
312 313
    public function getAttribute($attribute)
    {
lsmith's avatar
lsmith committed
314 315
        $attribute = (int) $attribute;

zYne's avatar
zYne committed
316
        if ($attribute < 0) {
lsmith's avatar
lsmith committed
317
            throw new Doctrine_Exception('Unknown attribute.');
zYne's avatar
zYne committed
318
        }
lsmith's avatar
lsmith committed
319 320 321 322 323 324 325 326 327

        if ( ! isset($this->attributes[$attribute])) {
            if (isset($this->parent)) {
                return $this->parent->getAttribute($attribute);
            }
            return null;
        }
        return $this->attributes[$attribute];
    }
328

lsmith's avatar
lsmith committed
329 330 331 332 333 334
    /**
     * getAttributes
     * returns all attributes as an array
     *
     * @return array
     */
lsmith's avatar
lsmith committed
335 336
    public function getAttributes()
    {
lsmith's avatar
lsmith committed
337 338
        return $this->attributes;
    }
339

lsmith's avatar
lsmith committed
340 341 342 343 344 345 346
    /**
     * sets a parent for this configurable component
     * the parent must be configurable component itself
     *
     * @param Doctrine_Configurable $component
     * @return void
     */
lsmith's avatar
lsmith committed
347 348
    public function setParent(Doctrine_Configurable $component)
    {
lsmith's avatar
lsmith committed
349 350
        $this->parent = $component;
    }
351

lsmith's avatar
lsmith committed
352 353 354 355 356 357
    /**
     * getParent
     * returns the parent of this component
     *
     * @return Doctrine_Configurable
     */
lsmith's avatar
lsmith committed
358 359
    public function getParent()
    {
lsmith's avatar
lsmith committed
360 361
        return $this->parent;
    }
362
}