Coverage for Doctrine_Configurable

Back to coverage report

1 <?php
2 /*
3  *  $Id: Configurable.php 3917 2008-03-01 07:48:15Z jwage $
4  *
5  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16  *
17  * This software consists of voluntary contributions made by many individuals
18  * and is licensed under the LGPL. For more information, see
19  * <http://www.phpdoctrine.org>.
20  */
21
22 /**
23  * Doctrine_Configurable
24  * the base for Doctrine_Table, Doctrine_Manager and Doctrine_Connection
25  *
26  *
27  * @package     Doctrine
28  * @subpackage  Configurable
29  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
30  * @link        www.phpdoctrine.org
31  * @since       1.0
32  * @version     $Revision: 3917 $
33  * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
34  */
35 abstract class Doctrine_Configurable extends Doctrine_Locator_Injectable
36 {
37     /**
38      * @var array $attributes               an array of containing all attributes
39      */
40     protected $attributes = array();
41
42     /**
43      * @var Doctrine_Configurable $parent   the parent of this component
44      */
45     protected $parent;
46
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
50      *                                      implementation classes
51      */
52     protected $_impl = array();
53     
54     /**
55      * @var array $_params                  an array of user defined parameters
56      */
57     protected $_params = array();
58
59     /**
60      * getAttributeFromString
61      *
62      * Will accept the name of an attribute and return the attribute value
63      * Example: ->getAttributeFromString('portability') will be converted to Doctrine::ATTR_PORTABILITY
64      * and returned
65      *
66      * @param string $stringAttributeName 
67      * @return void
68      */
69     public function getAttributeFromString($stringAttributeName)
70     {
71       if (is_string($stringAttributeName)) {
72           $upper = strtoupper($stringAttributeName);
73
74           $const = 'Doctrine::ATTR_' . $upper; 
75
76           if (defined($const)) {
77               return constant($const);
78           } else {
79               throw new Doctrine_Exception('Unknown attribute: "' . $stringAttributeName . '"');
80           }
81       } else {
82         return false;
83       }
84     }
85
86     /**
87      * getAttributeValueFromString
88      *
89      * Will get the value for an attribute by the string name
90      * Example: ->getAttributeFromString('portability', 'all') will return Doctrine::PORTABILITY_ALL
91      *
92      * @param string $stringAttributeName 
93      * @param string $stringAttributeValueName 
94      * @return void
95      */
96     public function getAttributeValueFromString($stringAttributeName, $stringAttributeValueName)
97     {
98         $const = 'Doctrine::' . strtoupper($stringAttributeName) . '_' . strtoupper($stringAttributeValueName);
99
100         if (defined($const)) {
101             return constant($const);
102         } else {
103             throw new Doctrine_Exception('Unknown attribute value: "' . $value . '"');
104         }
105     }
106
107     /**
108      * setAttribute
109      * sets a given attribute
110      *
111      * <code>
112      * $manager->setAttribute(Doctrine::ATTR_PORTABILITY, Doctrine::PORTABILITY_ALL);
113      *
114      * // or
115      *
116      * $manager->setAttribute('portability', Doctrine::PORTABILITY_ALL);
117      *
118      * // or
119      *
120      * $manager->setAttribute('portability', 'all');
121      * </code>
122      *
123      * @param mixed $attribute              either a Doctrine::ATTR_* integer constant or a string
124      *                                      corresponding to a constant
125      * @param mixed $value                  the value of the attribute
126      * @see Doctrine::ATTR_* constants
127      * @throws Doctrine_Exception           if the value is invalid
128      * @return void
129      */
130     public function setAttribute($attribute, $value)
131     {
132         if (is_string($attribute)) {
133             $stringAttribute = $attribute;
134             $attribute = $this->getAttributeFromString($attribute);
135             $this->_state = $attribute;
136         }
137
138         if (is_string($value) && isset($stringAttribute)) {
139             $value = $this->getAttributeValueFromString($stringAttribute, $value);
140         }
141
142         switch ($attribute) {
143             case Doctrine::ATTR_FETCHMODE:
144                 throw new Doctrine_Exception('Deprecated attribute. See http://www.phpdoctrine.org/documentation/manual?chapter=configuration');
145             case Doctrine::ATTR_LISTENER:
146                 $this->setEventListener($value);
147                 break;
148             case Doctrine::ATTR_COLL_KEY:
149                 if ( ! ($this instanceof Doctrine_Table)) {
150                     throw new Doctrine_Exception("This attribute can only be set at table level.");
151                 }
152                 if ($value !== null && ! $this->hasField($value)) {
153                     throw new Doctrine_Exception("Couldn't set collection key attribute. No such field '$value'");
154                 }
155                 break;
156             case Doctrine::ATTR_CACHE:
157             case Doctrine::ATTR_RESULT_CACHE:
158             case Doctrine::ATTR_QUERY_CACHE:
159                 if ($value !== null) {
160                     if ( ! ($value instanceof Doctrine_Cache_Interface)) {
161                         throw new Doctrine_Exception('Cache driver should implement Doctrine_Cache_Interface');
162                     }
163                 }
164                 break;
165             case Doctrine::ATTR_VALIDATE:
166             case Doctrine::ATTR_QUERY_LIMIT:
167             case Doctrine::ATTR_QUOTE_IDENTIFIER:
168             case Doctrine::ATTR_PORTABILITY:
169             case Doctrine::ATTR_DEFAULT_TABLE_TYPE:
170             case Doctrine::ATTR_EMULATE_DATABASE:
171             case Doctrine::ATTR_USE_NATIVE_ENUM:
172             case Doctrine::ATTR_DEFAULT_SEQUENCE:
173             case Doctrine::ATTR_EXPORT:
174             case Doctrine::ATTR_DECIMAL_PLACES:
175             case Doctrine::ATTR_LOAD_REFERENCES:
176             case Doctrine::ATTR_RECORD_LISTENER:
177             case Doctrine::ATTR_THROW_EXCEPTIONS:
178             case Doctrine::ATTR_DEFAULT_PARAM_NAMESPACE:
179             case Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES:
180             case Doctrine::ATTR_MODEL_LOADING:
181
182                 break;
183             case Doctrine::ATTR_SEQCOL_NAME:
184                 if ( ! is_string($value)) {
185                     throw new Doctrine_Exception('Sequence column name attribute only accepts string values');
186                 }
187                 break;
188             case Doctrine::ATTR_FIELD_CASE:
189                 if ($value != 0 && $value != CASE_LOWER && $value != CASE_UPPER)
190                     throw new Doctrine_Exception('Field case attribute should be either 0, CASE_LOWER or CASE_UPPER constant.');
191                 break;
192             case Doctrine::ATTR_SEQNAME_FORMAT:
193             case Doctrine::ATTR_IDXNAME_FORMAT:
194             case Doctrine::ATTR_TBLNAME_FORMAT:
195                 if ($this instanceof Doctrine_Table) {
196                     throw new Doctrine_Exception('Sequence / index name format attributes cannot be set'
197                                                . 'at table level (only at connection or global level).');
198                 }
199                 break;
200             default:
201                 throw new Doctrine_Exception("Unknown attribute.");
202         }
203
204         $this->attributes[$attribute] = $value;
205     }
206
207     public function getParams($namespace = null)
208     {
209      if ($namespace == null) {
210          $namespace = $this->getAttribute(Doctrine::ATTR_DEFAULT_PARAM_NAMESPACE);
211      }
212     
213      if ( ! isset($this->_params[$namespace])) {
214          return null;
215      }
216
217         return $this->_params[$namespace];
218     }
219     
220     public function getParamNamespaces()
221     {
222         return array_keys($this->_params);
223     }
224
225     public function setParam($name, $value, $namespace = null) 
226     {
227      if ($namespace == null) {
228          $namespace = $this->getAttribute(Doctrine::ATTR_DEFAULT_PARAM_NAMESPACE);
229      }
230     
231      $this->_params[$namespace][$name] = $value;
232     
233      return $this;
234     }
235     
236     public function getParam($name, $namespace = null) 
237     {
238      if ($namespace == null) {
239          $namespace = $this->getAttribute(Doctrine::ATTR_DEFAULT_PARAM_NAMESPACE);
240      }
241     
242         if ( ! isset($this->_params[$name])) {
243             if (isset($this->parent)) {
244                 return $this->parent->getParam($name, $namespace);
245             }
246             return null;
247         }
248         
249         return $this->_params[$namespace][$name];
250     }
251     /**
252      * setImpl
253      * binds given class to given template name
254      *
255      * this method is the base of Doctrine dependency injection
256      *
257      * @param string $template      name of the class template
258      * @param string $class         name of the class to be bound
259      * @return Doctrine_Configurable    this object
260      */
261     public function setImpl($template, $class)
262     {
263         $this->_impl[$template] = $class;
264
265         return $this;
266     }
267
268     /**
269      * getImpl
270      * returns the implementation for given class
271      *
272      * @return string   name of the concrete implementation
273      */
274     public function getImpl($template)
275     {
276         if ( ! isset($this->_impl[$template])) {
277             if (isset($this->parent)) {
278                 return $this->parent->getImpl($template);
279             }
280             return null;
281         }
282         return $this->_impl[$template];
283     }
284     
285     
286     public function hasImpl($template)
287     {
288         if ( ! isset($this->_impl[$template])) {
289             if (isset($this->parent)) {
290                 return $this->parent->hasImpl($template);
291             }
292             return false;
293         }
294         return true;
295     }
296
297     /**
298      * @param Doctrine_EventListener $listener
299      * @return void
300      */
301     public function setEventListener($listener)
302     {
303         return $this->setListener($listener);
304     }
305
306     /**
307      * addRecordListener
308      *
309      * @param Doctrine_EventListener_Interface|Doctrine_Overloadable $listener
310      * @return mixed        this object
311      */
312     public function addRecordListener($listener, $name = null)
313     {
314         if ( ! isset($this->attributes[Doctrine::ATTR_RECORD_LISTENER]) ||
315              ! ($this->attributes[Doctrine::ATTR_RECORD_LISTENER] instanceof Doctrine_Record_Listener_Chain)) {
316
317             $this->attributes[Doctrine::ATTR_RECORD_LISTENER] = new Doctrine_Record_Listener_Chain();
318         }
319         $this->attributes[Doctrine::ATTR_RECORD_LISTENER]->add($listener, $name);
320
321         return $this;
322     }
323
324     /**
325      * getListener
326      *
327      * @return Doctrine_EventListener_Interface|Doctrine_Overloadable
328      */
329     public function getRecordListener()
330     {
331         if ( ! isset($this->attributes[Doctrine::ATTR_RECORD_LISTENER])) {
332             if (isset($this->parent)) {
333                 return $this->parent->getRecordListener();
334             }
335             return null;
336         }
337         return $this->attributes[Doctrine::ATTR_RECORD_LISTENER];
338     }
339
340     /**
341      * setListener
342      *
343      * @param Doctrine_EventListener_Interface|Doctrine_Overloadable $listener
344      * @return Doctrine_Configurable        this object
345      */
346     public function setRecordListener($listener)
347     {
348         if ( ! ($listener instanceof Doctrine_Record_Listener_Interface)
349             && ! ($listener instanceof Doctrine_Overloadable)
350         ) {
351             throw new Doctrine_Exception("Couldn't set eventlistener. Record listeners should implement either Doctrine_Record_Listener_Interface or Doctrine_Overloadable");
352         }
353         $this->attributes[Doctrine::ATTR_RECORD_LISTENER] = $listener;
354
355         return $this;
356     }
357
358     /**
359      * addListener
360      *
361      * @param Doctrine_EventListener_Interface|Doctrine_Overloadable $listener
362      * @return mixed        this object
363      */
364     public function addListener($listener, $name = null)
365     {
366         if ( ! isset($this->attributes[Doctrine::ATTR_LISTENER]) ||
367              ! ($this->attributes[Doctrine::ATTR_LISTENER] instanceof Doctrine_EventListener_Chain)) {
368
369             $this->attributes[Doctrine::ATTR_LISTENER] = new Doctrine_EventListener_Chain();
370         }
371         $this->attributes[Doctrine::ATTR_LISTENER]->add($listener, $name);
372
373         return $this;
374     }
375
376     /**
377      * getListener
378      *
379      * @return Doctrine_EventListener_Interface|Doctrine_Overloadable
380      */
381     public function getListener()
382     {
383         if ( ! isset($this->attributes[Doctrine::ATTR_LISTENER])) {
384             if (isset($this->parent)) {
385                 return $this->parent->getListener();
386             }
387             return null;
388         }
389         return $this->attributes[Doctrine::ATTR_LISTENER];
390     }
391
392     /**
393      * setListener
394      *
395      * @param Doctrine_EventListener_Interface|Doctrine_Overloadable $listener
396      * @return Doctrine_Configurable        this object
397      */
398     public function setListener($listener)
399     {
400         if ( ! ($listener instanceof Doctrine_EventListener_Interface)
401             && ! ($listener instanceof Doctrine_Overloadable)
402         ) {
403             throw new Doctrine_EventListener_Exception("Couldn't set eventlistener. EventListeners should implement either Doctrine_EventListener_Interface or Doctrine_Overloadable");
404         }
405         $this->attributes[Doctrine::ATTR_LISTENER] = $listener;
406
407         return $this;
408     }
409
410     /**
411      * returns the value of an attribute
412      *
413      * @param integer $attribute
414      * @return mixed
415      */
416     public function getAttribute($attribute)
417     {
418         if (is_string($attribute)) {
419             $upper = strtoupper($attribute);
420
421             $const = 'Doctrine::ATTR_' . $upper; 
422
423             if (defined($const)) {
424                 $attribute = constant($const);
425                 $this->_state = $attribute;
426             } else {
427                 throw new Doctrine_Exception('Unknown attribute: "' . $attribute . '"');
428             }
429         }
430
431         $attribute = (int) $attribute;
432
433         if ($attribute < 0) {
434             throw new Doctrine_Exception('Unknown attribute.');
435         }
436
437         if (isset($this->attributes[$attribute])) {
438             return $this->attributes[$attribute];
439         }
440         
441         if (isset($this->parent)) {
442             return $this->parent->getAttribute($attribute);
443         }
444         return null;
445     }
446
447     /**
448      * getAttributes
449      * returns all attributes as an array
450      *
451      * @return array
452      */
453     public function getAttributes()
454     {
455         return $this->attributes;
456     }
457
458     /**
459      * sets a parent for this configurable component
460      * the parent must be configurable component itself
461      *
462      * @param Doctrine_Configurable $component
463      * @return void
464      */
465     public function setParent(Doctrine_Configurable $component)
466     {
467         $this->parent = $component;
468     }
469
470     /**
471      * getParent
472      * returns the parent of this component
473      *
474      * @return Doctrine_Configurable
475      */
476     public function getParent()
477     {
478         return $this->parent;
479     }
480 }