1<?php 2 3/* 4 * This file is part of the symfony package. 5 * (c) Fabien Potencier <fabien.potencier@symfony-project.com> 6 * (c) Jonathan H. Wage <jonwage@gmail.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12/** 13 * Base sfDoctrineRecord extends the base Doctrine_Record in Doctrine to provide some 14 * symfony specific functionality to Doctrine_Records 15 * 16 * @package symfony 17 * @subpackage doctrine 18 * @author Fabien Potencier <fabien.potencier@symfony-project.com> 19 * @author Jonathan H. Wage <jonwage@gmail.com> 20 * @version SVN: $Id$ 21 */ 22abstract class sfDoctrineRecord extends Doctrine_Record 23{ 24 static protected 25 $_defaultCulture = 'en'; 26 27 /** 28 * Initializes internationalization. 29 * 30 * @see Doctrine_Record 31 */ 32 public function construct() 33 { 34 if ($this->getTable()->hasRelation('Translation')) 35 { 36 // only add filter to each table once 37 if (!$this->getTable()->getOption('has_symfony_i18n_filter')) 38 { 39 $this->getTable() 40 ->unshiftFilter(new sfDoctrineRecordI18nFilter()) 41 ->setOption('has_symfony_i18n_filter', true) 42 ; 43 } 44 } 45 } 46 47 /** 48 * Listens to the user.change_culture event. 49 * 50 * @param sfEvent An sfEvent instance 51 */ 52 static public function listenToChangeCultureEvent(sfEvent $event) 53 { 54 self::$_defaultCulture = $event['culture']; 55 } 56 57 /** 58 * Sets the default culture 59 * 60 * @param string $culture 61 */ 62 static public function setDefaultCulture($culture) 63 { 64 self::$_defaultCulture = $culture; 65 } 66 67 /** 68 * Return the default culture 69 * 70 * @return string the default culture 71 */ 72 static public function getDefaultCulture() 73 { 74 if (!self::$_defaultCulture) 75 { 76 throw new sfException('The default culture has not been set'); 77 } 78 79 return self::$_defaultCulture; 80 } 81 82 /** 83 * Returns the current record's primary key. 84 * 85 * This a proxy method to {@link Doctrine_Record::identifier()} for 86 * compatibility with a Propel-style API. 87 * 88 * @return mixed The value of the current model's last identifier column 89 */ 90 public function getPrimaryKey() 91 { 92 $identifier = (array) $this->identifier(); 93 return end($identifier); 94 } 95 96 /** 97 * Function require by symfony >= 1.2 admin generators. 98 * 99 * @return boolean 100 */ 101 public function isNew() 102 { 103 return ! $this->exists(); 104 } 105 106 /** 107 * Returns a string representation of the record. 108 * 109 * @return string A string representation of the record 110 */ 111 public function __toString() 112 { 113 $guesses = array('name', 114 'title', 115 'description', 116 'subject', 117 'keywords', 118 'id'); 119 120 // we try to guess a column which would give a good description of the object 121 foreach ($guesses as $descriptionColumn) 122 { 123 try 124 { 125 return (string) $this->get($descriptionColumn); 126 } catch (Exception $e) {} 127 } 128 129 return sprintf('No description for object of class "%s"', $this->getTable()->getComponentName()); 130 } 131 132 /** 133 * Provides getter and setter methods. 134 * 135 * @param string $method The method name 136 * @param array $arguments The method arguments 137 * 138 * @return mixed The returned value of the called method 139 */ 140 public function __call($method, $arguments) 141 { 142 $failed = false; 143 try { 144 if (in_array($verb = substr($method, 0, 3), array('set', 'get'))) 145 { 146 $name = substr($method, 3); 147 148 $table = $this->getTable(); 149 if ($table->hasRelation($name)) 150 { 151 $entityName = $name; 152 } 153 else if ($table->hasField($fieldName = $table->getFieldName($name))) 154 { 155 $entityNameLower = strtolower($fieldName); 156 if ($table->hasField($entityNameLower)) 157 { 158 $entityName = $entityNameLower; 159 } else { 160 $entityName = $fieldName; 161 } 162 } 163 else 164 { 165 $underScored = $table->getFieldName(sfInflector::underscore($name)); 166 if ($table->hasField($underScored) || $table->hasRelation($underScored)) 167 { 168 $entityName = $underScored; 169 } else if ($table->hasField(strtolower($name)) || $table->hasRelation(strtolower($name))) { 170 $entityName = strtolower($name); 171 } else { 172 $camelCase = $table->getFieldName(sfInflector::camelize($name)); 173 $camelCase = strtolower($camelCase[0]).substr($camelCase, 1, strlen($camelCase)); 174 if ($table->hasField($camelCase) || $table->hasRelation($camelCase)) 175 { 176 $entityName = $camelCase; 177 } else { 178 $entityName = $underScored; 179 } 180 } 181 } 182 183 return call_user_func_array( 184 array($this, $verb), 185 array_merge(array($entityName), $arguments) 186 ); 187 } else { 188 $failed = true; 189 } 190 } catch (Exception $e) { 191 $failed = true; 192 } 193 if ($failed) 194 { 195 try 196 { 197 return parent::__call($method, $arguments); 198 } catch (Doctrine_Record_UnknownPropertyException $e2) {} 199 200 if (isset($e) && $e) 201 { 202 throw $e; 203 } else if (isset($e2) && $e2) { 204 throw $e2; 205 } 206 } 207 } 208 209 /** 210 * Get the Doctrine date value as a PHP DateTime object, null if the value is not set 211 * 212 * @param string $dateFieldName The field name to get the DateTime object for 213 * 214 * @return DateTime|null $dateTime The instance of PHPs DateTime 215 * @throws sfException if the field is not one of date, datetime, or timestamp types 216 */ 217 public function getDateTimeObject($dateFieldName) 218 { 219 $type = $this->getTable()->getTypeOf($dateFieldName); 220 if ($type == 'date' || $type == 'timestamp' || $type == 'datetime') 221 { 222 $datetime = $this->get($dateFieldName); 223 if ($datetime) 224 { 225 return new DateTime($datetime); 226 } 227 } 228 else 229 { 230 throw new sfException('Cannot call getDateTimeObject() on a field that is not of type date or timestamp.'); 231 } 232 } 233 234 /** 235 * Set the Doctrine date value by passing a valid PHP DateTime object instance 236 * 237 * @param string $dateFieldName The field name to set the date for 238 * @param DateTime $dateTimeObject The DateTime instance to use to set the value 239 * 240 * @return sfDoctrineRecord 241 * @throws sfException if the field is not one of date, datetime, or timestamp types 242 */ 243 public function setDateTimeObject($dateFieldName, DateTime $dateTimeObject = null) 244 { 245 $type = $this->getTable()->getTypeOf($dateFieldName); 246 if ($type == 'date' || $type == 'timestamp' || $type == 'datetime') 247 { 248 if (null === $dateTimeObject) 249 { 250 return $this->set($dateFieldName, null); 251 } 252 return $this->set($dateFieldName, $dateTimeObject->format('Y-m-d H:i:s')); 253 } 254 else 255 { 256 throw new sfException('Cannot call setDateTimeObject() on a field that is not of type date or timestamp.'); 257 } 258 } 259} 260