| [ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 3 /* 4 * $Id: PHP5ComplexObjectBuilder.php 378 2006-05-27 01:14:41Z hans $ 5 * 6 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 7 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 8 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 9 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 10 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 11 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 12 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 13 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 14 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 16 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17 * 18 * This software consists of voluntary contributions made by many individuals 19 * and is licensed under the LGPL. For more information please see 20 * <http://propel.phpdb.org>. 21 */ 22 23 require_once 'propel/engine/builder/om/php5/PHP5BasicObjectBuilder.php'; 24 25 /** 26 * Generates a PHP5 base Object class with complex object model methods. 27 * 28 * This class adds on to the PHP5BasicObjectBuilder class by adding more complex 29 * logic related to relationships to methods like the setters, and save method. Also, 30 * new get*Join*() methods are added to fetch related rows. 31 * 32 * @author Hans Lellelid <hans@xmpl.org> 33 * @package propel.engine.builder.om.php5 34 */ 35 class PHP5ComplexObjectBuilder extends PHP5BasicObjectBuilder { 36 37 /** 38 * Adds additional attributes used for complex object model. 39 * @param string &$script The script will be modified in this method. 40 * @see addFKAttributes() 41 * @see addRefFKAttributes() 42 * @see addAlreadyInSaveAttribute() 43 * @see addAlreadyInValidationAttribute() 44 */ 45 protected function addAttributes(&$script) 46 { 47 $table = $this->getTable(); 48 parent::addAttributes($script); 49 50 foreach ($table->getForeignKeys() as $fk) { 51 $this->addFKAttributes($script, $fk); 52 } 53 54 foreach($table->getReferrers() as $refFK) { 55 // if ($refFK->getTable()->getName() != $table->getName()) { 56 $this->addRefFKAttributes($script, $refFK); 57 // } 58 } 59 60 $this->addAlreadyInSaveAttribute($script); 61 $this->addAlreadyInValidationAttribute($script); 62 } 63 64 /** 65 * Specifies the methods that are added as part of the basic OM class. 66 * This can be overridden by subclasses that wish to add more methods. 67 * @param string &$script The script will be modified in this method. 68 * @see PHP5BasicObjectBuilder::addClassBody() 69 */ 70 protected function addClassBody(&$script) 71 { 72 $table = $this->getTable(); 73 parent::addClassBody($script); 74 75 76 $this->addFKMethods($script); 77 $this->addRefFKMethods($script); 78 79 } 80 81 /** 82 * Adds the close of mutator (setter) method for a column. 83 * This method overrides the method from PHP5BasicObjectBuilder in order to 84 * account for updating related objects. 85 * @param string &$script The script will be modified in this method. 86 * @param Column $col The current column. 87 * @see PHP5BasicObjectBuilder::addMutatorClose() 88 */ 89 protected function addMutatorClose(&$script, Column $col) 90 { 91 $table = $this->getTable(); 92 $cfc=$col->getPhpName(); 93 $clo=strtolower($col->getName()); 94 95 if ($col->isForeignKey()) { 96 97 $tblFK = $table->getDatabase()->getTable($col->getRelatedTableName()); 98 $colFK = $tblFK->getColumn($col->getRelatedColumnName()); 99 100 $varName = $this->getFKVarName($col->getForeignKey()); 101 102 $script .= " 103 if (\$this->$varName !== null && \$this->".$varName."->get".$colFK->getPhpName()."() !== \$v) { 104 \$this->$varName = null; 105 } 106 "; 107 } /* if col is foreign key */ 108 109 foreach ($col->getReferrers() as $fk) { 110 111 $tblFK = $this->getDatabase()->getTable($fk->getForeignTableName()); 112 113 if ( $tblFK->getName() != $table->getName() ) { 114 115 $collName = $this->getRefFKCollVarName($fk); 116 117 $tblFK = $table->getDatabase()->getTable($col->getRelatedTableName()); 118 $colFK = $tblFK->getColumn($col->getRelatedColumnName()); 119 120 $script .= " 121 122 // update associated ".$tblFK->getPhpName()." 123 if (\$this->$collName !== null) { 124 foreach(\$this->$collName as \$referrerObject) { 125 \$referrerObject->set".$colFK->getPhpName()."(\$v); 126 } 127 } 128 "; 129 } // if 130 } // foreach 131 132 $script .= " 133 } // set$cfc() 134 "; 135 } // addMutatorClose() 136 137 /** 138 * Adds the methods related to validating, saving and deleting the object. 139 * @param string &$script The script will be modified in this method. 140 */ 141 protected function addManipulationMethods(&$script) 142 { 143 $this->addDelete($script); 144 $this->addSave($script); 145 $this->addDoSave($script); 146 } 147 148 /** 149 * Adds the methods related to validationg the object. 150 * @param string &$script The script will be modified in this method. 151 */ 152 protected function addValidationMethods(&$script) 153 { 154 parent::addValidationMethods($script); 155 $this->addDoValidate($script); 156 } 157 158 /** 159 * Convenience method to get the foreign Table object for an fkey. 160 * @return Table 161 */ 162 protected function getForeignTable(ForeignKey $fk) 163 { 164 return $this->getTable()->getDatabase()->getTable($fk->getForeignTableName()); 165 } 166 167 /** 168 * Gets the PHP method name affix to be used for fkeys for the current table (not referrers to this table). 169 * 170 * The difference between this method and the getRefFKPhpNameAffix() method is that in this method the 171 * classname in the affix is the foreign table classname. 172 * 173 * @param ForeignKey $fk The local FK that we need a name for. 174 * @param boolean $plural Whether the php name should be plural (e.g. initRelatedObjs() vs. addRelatedObj() 175 * @return string 176 */ 177 public function getFKPhpNameAffix(ForeignKey $fk, $plural = false) 178 { 179 $className = $this->getForeignTable($fk)->getPhpName(); 180 return $className . ($plural ? 's' : '') . $this->getRelatedBySuffix($fk); 181 } 182 183 /** 184 * Gets the PHP method name affix to be used for referencing foreign key methods and variable names (e.g. set????(), $coll???). 185 * 186 * The difference between this method and the getFKPhpNameAffix() method is that in this method the 187 * classname in the affix is the classname of the local fkey table. 188 * 189 * @param ForeignKey $fk The referrer FK that we need a name for. 190 * @param boolean $plural Whether the php name should be plural (e.g. initRelatedObjs() vs. addRelatedObj() 191 * @return string 192 */ 193 public function getRefFKPhpNameAffix(ForeignKey $fk, $plural = false) 194 { 195 $className = $fk->getTable()->getPhpName(); 196 return $className . ($plural ? 's' : '') . $this->getRelatedBySuffix($fk); 197 } 198 199 /** 200 * Gets the "RelatedBy*" suffix (if needed) that is attached to method and variable names. 201 * 202 * The related by suffix is based on the local columns of the foreign key. If there is more than 203 * one column in a table that points to the same foreign table, then a 'RelatedByLocalColName' suffix 204 * will be appended. 205 * 206 * @return string 207 */ 208 protected function getRelatedBySuffix(ForeignKey $fk) 209 { 210 $relCol = ""; 211 foreach ($fk->getLocalColumns() as $columnName) { 212 $column = $fk->getTable()->getColumn($columnName); 213 if (!$column) { 214 $e = new Exception("Could not fetch column: $columnName in table " . $fk->getTable()->getName()); 215 print $e; 216 throw $e; 217 } 218 if ($column->isMultipleFK() || $fk->getForeignTableName() == $fk->getTable()->getName()) { 219 // if there are seeral foreign keys that point to the same table 220 // then we need to generate methods like getAuthorRelatedByColName() 221 // instead of just getAuthor(). Currently we are doing the same 222 // for self-referential foreign keys, to avoid confusion. 223 $relCol .= $column->getPhpName(); 224 } 225 } 226 227 if ($relCol != "") { 228 $relCol = "RelatedBy" . $relCol; 229 } 230 231 return $relCol; 232 } 233 234 protected function getFKVarName(ForeignKey $fk) 235 { 236 return 'a' . $this->getFKPhpNameAffix($fk, $plural = false); 237 } 238 239 protected function getRefFKCollVarName(ForeignKey $fk) 240 { 241 return 'coll' . $this->getRefFKPhpNameAffix($fk, $plural = true); 242 } 243 244 protected function getRefFKLastCriteriaVarName(ForeignKey $fk) 245 { 246 return 'last' . $this->getRefFKPhpNameAffix($fk, $plural = false) . 'Criteria'; 247 } 248 249 // ---------------------------------------------------------------- 250 // 251 // F K M E T H O D S 252 // 253 // ---------------------------------------------------------------- 254 255 /** 256 * Adds the methods that get & set objects related by foreign key to the current object. 257 * @param string &$script The script will be modified in this method. 258 */ 259 protected function addFKMethods(&$script) 260 { 261 foreach ($this->getTable()->getForeignKeys() as $fk) { 262 $this->addFKMutator($script, $fk); 263 $this->addFKAccessor($script, $fk); 264 } // foreach fk 265 } 266 267 /** 268 * Adds the class attributes that are needed to store fkey related objects. 269 * @param string &$script The script will be modified in this method. 270 */ 271 protected function addFKAttributes(&$script, ForeignKey $fk) 272 { 273 $className = $this->getForeignTable($fk)->getPhpName(); 274 $varName = $this->getFKVarName($fk); 275 276 $script .= " 277 /** 278 * @var $className 279 */ 280 protected $".$varName."; 281 "; 282 } 283 284 /** 285 * Adds the mutator (setter) method for setting an fkey related object. 286 * @param string &$script The script will be modified in this method. 287 */ 288 protected function addFKMutator(&$script, ForeignKey $fk) 289 { 290 $table = $this->getTable(); 291 $tblFK = $this->getForeignTable($fk); 292 $className = $this->getForeignTable($fk)->getPhpName(); 293 $varName = $this->getFKVarName($fk); 294 295 $script .= " 296 /** 297 * Declares an association between this object and a $className object. 298 * 299 * @param $className \$v 300 * @return void 301 * @throws PropelException 302 */ 303 public function set".$this->getFKPhpNameAffix($fk, $plural = false)."(\$v) 304 { 305 "; 306 foreach ($fk->getLocalColumns() as $columnName) { 307 $column = $table->getColumn($columnName); 308 $lfmap = $fk->getLocalForeignMapping(); 309 $colFKName = $lfmap[$columnName]; 310 $colFK = $tblFK->getColumn($colFKName); 311 $script .= " 312 313 if (\$v === null) { 314 \$this->set".$column->getPhpName()."(".var_export($column->getDefaultValue(), true)."); 315 } else { 316 \$this->set".$column->getPhpName()."(\$v->get".$colFK->getPhpName()."()); 317 } 318 "; 319 320 } /* foreach local col */ 321 322 $script .= " 323 324 \$this->$varName = \$v; 325 } 326 "; 327 } 328 329 /** 330 * Adds the accessor (getter) method for getting an fkey related object. 331 * @param string &$script The script will be modified in this method. 332 */ 333 protected function addFKAccessor(&$script, ForeignKey $fk) 334 { 335 $table = $this->getTable(); 336 337 $className = $this->getForeignTable($fk)->getPhpName(); 338 $varName = $this->getFKVarName($fk); 339 340 $and = ""; 341 $comma = ""; 342 $conditional = ""; 343 $arglist = ""; 344 $argsize = 0; 345 foreach ($fk->getLocalColumns() as $columnName) { 346 $column = $table->getColumn($columnName); 347 $cptype = $column->getPhpNative(); 348 $clo = strtolower($column->getName()); 349 350 // FIXME: is this correct? what about negative numbers? 351 if ($cptype == "integer" || $cptype == "float" || $cptype == "double") { 352 $conditional .= $and . "\$this->". $clo ." > 0"; 353 } elseif($cptype == "string") { 354 $conditional .= $and . "(\$this->" . $clo ." !== \"\" && \$this->".$clo." !== null)"; 355 } else { 356 $conditional .= $and . "\$this->" . $clo ." !== null"; 357 } 358 $arglist .= $comma . "\$this->" . $clo; 359 $and = " && "; 360 $comma = ", "; 361 $argsize = $argsize + 1; 362 } 363 364 $pCollName = $this->getFKPhpNameAffix($fk, $plural = true); 365 366 $fkPeerBuilder = OMBuilder::getNewPeerBuilder($this->getForeignTable($fk)); 367 368 $script .= " 369 370 /** 371 * Get the associated $className object 372 * 373 * @param Connection Optional Connection object. 374 * @return $className The associated $className object. 375 * @throws PropelException 376 */ 377 public function get".$this->getFKPhpNameAffix($fk, $plural = false)."(\$con = null) 378 { 379 // include the related Peer class 380 include_once '".$fkPeerBuilder->getClassFilePath()."'; 381 382 if (\$this->$varName === null && ($conditional)) { 383 "; 384 $script .= " 385 \$this->$varName = ".$fkPeerBuilder->getPeerClassname()."::".$fkPeerBuilder->getRetrieveMethodName()."($arglist, \$con); 386 387 /* The following can be used instead of the line above to 388 guarantee the related object contains a reference 389 to this object, but this level of coupling 390 may be undesirable in many circumstances. 391 As it can lead to a db query with many results that may 392 never be used. 393 \$obj = ".$fkPeerBuilder->getPeerClassname()."::retrieveByPK($arglist, \$con); 394 \$obj->add$pCollName(\$this); 395 */ 396 } 397 return \$this->$varName; 398 } 399 "; 400 401 } // addFKAccessor 402 403 /** 404 * Adds a convenience method for setting a related object by specifying the primary key. 405 * This can be used in conjunction with the getPrimaryKey() for systems where nothing is known 406 * about the actual objects being related. 407 * @param string &$script The script will be modified in this method. 408 */ 409 protected function addFKByKeyMutator(&$script, ForeignKey $fk) 410 { 411 $table = $this->getTable(); 412 413 #$className = $this->getForeignTable($fk)->getPhpName(); 414 $methodAffix = $this->getFKPhpNameAffix($fk); 415 #$varName = $this->getFKVarName($fk); 416 417 $script .= " 418 /** 419 * Provides convenient way to set a relationship based on a 420 * key. e.g. 421 * <code>\$bar->setFooKey(\$foo->getPrimaryKey())</code> 422 *"; 423 if (count($fk->getLocalColumns()) > 1) { 424 $script .= " 425 * Note: It is important that the xml schema used to create this class 426 * maintains consistency in the order of related columns between 427 * ".$table->getName()." and ". $tblFK->getName().". 428 * If for some reason this is impossible, this method should be 429 * overridden in <code>".$table->getPhpName()."</code>."; 430 } 431 $script .= " 432 * @return void 433 * @throws PropelException 434 */ 435 public function set".$methodAffix."Key(\$key) 436 { 437 "; 438 if (count($fk->getLocalColumns()) > 1) { 439 $i = 0; 440 foreach ($fk->getLocalColumns() as $colName) { 441 $col = $table->getColumn($colName); 442 $fktype = $col->getPhpNative(); 443 $script .= " 444 \$this->set".$col->getPhpName()."( ($fktype) \$key[$i] ); 445 "; 446 $i++; 447 } /* foreach */ 448 } else { 449 $lcols = $fk->getLocalColumns(); 450 $colName = $lcols[0]; 451 $col = $table->getColumn($colName); 452 $fktype = $col->getPhpNative(); 453 $script .= " 454 \$this->set".$col->getPhpName()."( ($fktype) \$key); 455 "; 456 } 457 $script .= " 458 } 459 "; 460 } // addFKByKeyMutator() 461 462 /** 463 * Adds the method that fetches fkey-related (referencing) objects but also joins in data from another table. 464 * @param string &$script The script will be modified in this method. 465 */ 466 protected function addRefFKGetJoinMethods(&$script, ForeignKey $refFK) 467 { 468 $table = $this->getTable(); 469 $tblFK = $refFK->getTable(); 470 471 $relCol = $this->getRefFKPhpNameAffix($refFK, $plural=true); 472 $collName = $this->getRefFKCollVarName($refFK); 473 $lastCriteriaName = $this->getRefFKLastCriteriaVarName($refFK); 474 475 $fkPeerBuilder = OMBuilder::getNewPeerBuilder($tblFK); 476 477 $lastTable = ""; 478 foreach ($tblFK->getForeignKeys() as $fk2) { 479 480 // Add join methods if the fk2 table is not this table or 481 // the fk2 table references this table multiple times. 482 483 $doJoinGet = true; 484 485 if ( $fk2->getForeignTableName() == $table->getName() ) { 486 $doJoinGet = false; 487 } 488 489 foreach ($fk2->getLocalColumns() as $columnName) { 490 $column = $tblFK->getColumn($columnName); 491 if ($column->isMultipleFK()) { 492 $doJoinGet = true; 493 } 494 } 495 496 $tblFK2 = $this->getForeignTable($fk2); 497 $doJoinGet = !$tblFK2->isForReferenceOnly(); 498 499 // it doesn't make sense to join in rows from the curent table, since we are fetching 500 // objects related to *this* table (i.e. the joined rows will all be the same row as current object) 501 if ($this->getTable()->getPhpName() == $tblFK2->getPhpName()) { 502 $doJoinGet = false; 503 } 504 505 $relCol2 = $this->getFKPhpNameAffix($fk2, $plural = false); 506 507 if ( $this->getRelatedBySuffix($refFK) != "" && 508 ($this->getRelatedBySuffix($refFK) == $this->getRelatedBySuffix($fk2))) { 509 $doJoinGet = false; 510 } 511 512 if ($doJoinGet) { 513 $script .= " 514 515 /** 516 * If this collection has already been initialized with 517 * an identical criteria, it returns the collection. 518 * Otherwise if this ".$table->getPhpName()." is new, it will return 519 * an empty collection; or if this ".$table->getPhpName()." has previously 520 * been saved, it will retrieve related $relCol from storage. 521 * 522 * This method is protected by default in order to keep the public 523 * api reasonable. You can provide public methods for those you 524 * actually need in ".$table->getPhpName().". 525 */ 526 public function get".$relCol."Join".$relCol2."(\$criteria = null, \$con = null) 527 { 528 // include the Peer class 529 include_once '".$fkPeerBuilder->getClassFilePath()."'; 530 if (\$criteria === null) { 531 \$criteria = new Criteria(); 532 } 533 elseif (\$criteria instanceof Criteria) 534 { 535 \$criteria = clone \$criteria; 536 } 537 538 if (\$this->$collName === null) { 539 if (\$this->isNew()) { 540 \$this->$collName = array(); 541 } else { 542 "; 543 foreach ($refFK->getForeignColumns() as $columnName) { 544 $column = $table->getColumn($columnName); 545 $flMap = $refFK->getForeignLocalMapping(); 546 $colFKName = $flMap[$columnName]; 547 $colFK = $tblFK->getColumn($colFKName); 548 if ($colFK === null) { 549 $e = new Exception("Column $colFKName not found in " . $tblFK->getName()); 550 print $e; 551 throw $e; 552 } 553 $script .= " 554 \$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->get".$column->getPhpName()."()); 555 "; 556 } // end foreach ($fk->getForeignColumns() 557 558 $script .= " 559 \$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelectJoin$relCol2(\$criteria, \$con); 560 } 561 } else { 562 // the following code is to determine if a new query is 563 // called for. If the criteria is the same as the last 564 // one, just return the collection. 565 "; 566 foreach ($refFK->getForeignColumns() as $columnName) { 567 $column = $table->getColumn($columnName); 568 $flMap = $refFK->getForeignLocalMapping(); 569 $colFKName = $flMap[$columnName]; 570 $colFK = $tblFK->getColumn($colFKName); 571 $script .= " 572 \$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->get".$column->getPhpName()."()); 573 "; 574 } /* end foreach ($fk->getForeignColumns() */ 575 576 $script .= " 577 if (!isset(\$this->$lastCriteriaName) || !\$this->".$lastCriteriaName."->equals(\$criteria)) { 578 \$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelectJoin$relCol2(\$criteria, \$con); 579 } 580 } 581 \$this->$lastCriteriaName = \$criteria; 582 583 return \$this->$collName; 584 } 585 "; 586 } /* end if($doJoinGet) */ 587 588 } /* end foreach ($tblFK->getForeignKeys() as $fk2) { */ 589 590 } // function 591 592 593 // ---------------------------------------------------------------- 594 // 595 // R E F E R R E R F K M E T H O D S 596 // 597 // ---------------------------------------------------------------- 598 599 /** 600 * Adds the attributes used to store objects that have referrer fkey relationships to this object. 601 * <code>protected collVarName;</code> 602 * <code>private lastVarNameCriteria = null;</code> 603 * @param string &$script The script will be modified in this method. 604 */ 605 protected function addRefFKAttributes(&$script, ForeignKey $refFK) 606 { 607 $collName = $this->getRefFKCollVarName($refFK); 608 $lastCriteriaName = $this->getRefFKLastCriteriaVarName($refFK); 609 610 $script .= " 611 /** 612 * Collection to store aggregation of $collName. 613 * @var array 614 */ 615 protected $".$collName."; 616 617 /** 618 * The criteria used to select the current contents of $collName. 619 * @var Criteria 620 */ 621 protected \$".$lastCriteriaName." = null; 622 "; 623 } 624 625 /** 626 * Adds the methods for retrieving, initializing, adding objects that are related to this one by foreign keys. 627 * @param string &$script The script will be modified in this method. 628 */ 629 protected function addRefFKMethods(&$script) 630 { 631 foreach($this->getTable()->getReferrers() as $refFK) { 632 // if ( $refFK->getTable()->getName() != $this->getTable()->getName() ) { 633 $this->addRefFKInit($script, $refFK); 634 $this->addRefFKGet($script, $refFK); 635 $this->addRefFKCount($script, $refFK); 636 $this->addRefFKAdd($script, $refFK); 637 $this->addRefFKGetJoinMethods($script, $refFK); 638 // } 639 } 640 } 641 642 /** 643 * Adds the method that initializes the referrer fkey collection. 644 * @param string &$script The script will be modified in this method. 645 */ 646 protected function addRefFKInit(&$script, ForeignKey $refFK) { 647 648 $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true); 649 $collName = $this->getRefFKCollVarName($refFK); 650 651 $script .= " 652 /** 653 * Temporary storage of $collName to save a possible db hit in 654 * the event objects are add to the collection, but the 655 * complete collection is never requested. 656 * @return void 657 */ 658 public function init$relCol() 659 { 660 if (\$this->$collName === null) { 661 \$this->$collName = array(); 662 } 663 } 664 "; 665 } // addRefererInit() 666 667 /** 668 * Adds the method that adds an object into the referrer fkey collection. 669 * @param string &$script The script will be modified in this method. 670 */ 671 protected function addRefFKAdd(&$script, ForeignKey $refFK) 672 { 673 $tblFK = $refFK->getTable(); 674 $className = $refFK->getTable()->getPhpName(); 675 676 $joinedTableObjectBuilder = OMBuilder::getNewObjectBuilder($refFK->getTable()); 677 678 $script .= " 679 /** 680 * Method called to associate a ".$tblFK->getPhpName()." object to this object 681 * through the $className foreign key attribute 682 * 683 * @param $className \$l $className 684 * @return void 685 * @throws PropelException 686 */ 687 public function add".$this->getRefFKPhpNameAffix($refFK, $plural = false)."($className \$l) 688 { 689 \$this->coll".$this->getRefFKPhpNameAffix($refFK, $plural = true)."[] = \$l; 690 \$l->set".$this->getFKPhpNameAffix($refFK, $plural = false)."(\$this); 691 } 692 "; 693 } // addRefererAdd 694 695 /** 696 * Adds the method that returns the size of the referrer fkey collection. 697 * @param string &$script The script will be modified in this method. 698 */ 699 protected function addRefFKCount(&$script, ForeignKey $refFK) 700 { 701 $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true); 702 703 $fkPeerBuilder = OMBuilder::getNewPeerBuilder($refFK->getTable()); 704 705 $script .= " 706 /** 707 * Returns the number of related $relCol. 708 * 709 * @param Criteria \$criteria 710 * @param boolean \$distinct 711 * @param Connection \$con 712 * @throws PropelException 713 */ 714 public function count$relCol(\$criteria = null, \$distinct = false, \$con = null) 715 { 716 // include the Peer class 717 include_once '".$fkPeerBuilder->getClassFilePath()."'; 718 if (\$criteria === null) { 719 \$criteria = new Criteria(); 720 } 721 elseif (\$criteria instanceof Criteria) 722 { 723 \$criteria = clone \$criteria; 724 } 725 "; 726 foreach ($refFK->getForeignColumns() as $columnName) { 727 $column = $this->getTable()->getColumn($columnName); 728 $flmap = $refFK->getForeignLocalMapping(); 729 $colFKName = $flmap[$columnName]; 730 $colFK = $refFK->getTable()->getColumn($colFKName); 731 $script .= " 732 \$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->get".$column->getPhpName()."()); 733 "; 734 } // end foreach ($fk->getForeignColumns() 735 $script .=" 736 return ".$fkPeerBuilder->getPeerClassname()."::doCount(\$criteria, \$distinct, \$con); 737 } 738 "; 739 } // addRefererCount 740 741 /** 742 * Adds the method that returns the referrer fkey collection. 743 * @param string &$script The script will be modified in this method. 744 */ 745 protected function addRefFKGet(&$script, ForeignKey $refFK) 746 { 747 $table = $this->getTable(); 748 $tblFK = $refFK->getTable(); 749 750 $fkPeerBuilder = OMBuilder::getNewPeerBuilder($refFK->getTable()); 751 $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true); 752 753 $collName = $this->getRefFKCollVarName($refFK); 754 $lastCriteriaName = $this->getRefFKLastCriteriaVarName($refFK); 755 756 $script .= " 757 /** 758 * If this collection has already been initialized with 759 * an identical criteria, it returns the collection. 760 * Otherwise if this ".$table->getPhpName()." has previously 761 * been saved, it will retrieve related $relCol from storage. 762 * If this ".$table->getPhpName()." is new, it will return 763 * an empty collection or the current collection, the criteria 764 * is ignored on a new object. 765 * 766 * @param Connection \$con 767 * @param Criteria \$criteria 768 * @throws PropelException 769 */ 770 public function get$relCol(\$criteria = null, \$con = null) 771 { 772 // include the Peer class 773 include_once '".$fkPeerBuilder->getClassFilePath()."'; 774 if (\$criteria === null) { 775 \$criteria = new Criteria(); 776 } 777 elseif (\$criteria instanceof Criteria) 778 { 779 \$criteria = clone \$criteria; 780 } 781 782 if (\$this->$collName === null) { 783 if (\$this->isNew()) { 784 \$this->$collName = array(); 785 } else { 786 "; 787 foreach ($refFK->getLocalColumns() as $colFKName) { 788 // $colFKName is local to the referring table (i.e. foreign to this table) 789 $lfmap = $refFK->getLocalForeignMapping(); 790 $localColumn = $this->getTable()->getColumn($lfmap[$colFKName]); 791 $colFK = $refFK->getTable()->getColumn($colFKName); 792 793 $script .= " 794 \$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->get".$localColumn->getPhpName()."()); 795 "; 796 } // end foreach ($fk->getForeignColumns() 797 798 $script .= " 799 ".$fkPeerBuilder->getPeerClassname()."::addSelectColumns(\$criteria); 800 \$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelect(\$criteria, \$con); 801 } 802 } else { 803 // criteria has no effect for a new object 804 if (!\$this->isNew()) { 805 // the following code is to determine if a new query is 806 // called for. If the criteria is the same as the last 807 // one, just return the collection. 808 "; 809 foreach ($refFK->getLocalColumns() as $colFKName) { 810 // $colFKName is local to the referring table (i.e. foreign to this table) 811 $lfmap = $refFK->getLocalForeignMapping(); 812 $localColumn = $this->getTable()->getColumn($lfmap[$colFKName]); 813 $colFK = $refFK->getTable()->getColumn($colFKName); 814 $script .= " 815 816 \$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->get".$localColumn->getPhpName()."()); 817 "; 818 } // foreach ($fk->getForeignColumns() 819 $script .= " 820 ".$fkPeerBuilder->getPeerClassname()."::addSelectColumns(\$criteria); 821 if (!isset(\$this->$lastCriteriaName) || !\$this->".$lastCriteriaName."->equals(\$criteria)) { 822 \$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelect(\$criteria, \$con); 823 } 824 } 825 } 826 \$this->$lastCriteriaName = \$criteria; 827 return \$this->$collName; 828 } 829 "; 830 } // addRefererGet() 831 832 833 834 // ---------------------------------------------------------------- 835 // 836 // M A N I P U L A T I O N M E T H O D S 837 // 838 // ---------------------------------------------------------------- 839 840 /** 841 * Adds the workhourse doSave() method. 842 * @param string &$script The script will be modified in this method. 843 */ 844 protected function addDoSave(&$script) 845 { 846 $table = $this->getTable(); 847 848 $script .= " 849 /** 850 * Stores the object in the database. 851 * 852 * If the object is new, it inserts it; otherwise an update is performed. 853 * All related objects are also updated in this method. 854 * 855 * @param Connection \$con 856 * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. 857 * @throws PropelException 858 * @see save() 859 */ 860 protected function doSave(\$con) 861 { 862 \$affectedRows = 0; // initialize var to track total num of affected rows 863 if (!\$this->alreadyInSave) { 864 \$this->alreadyInSave = true; 865 "; 866 867 if (count($table->getForeignKeys())) { 868 869 $script .= " 870 871 // We call the save method on the following object(s) if they 872 // were passed to this object by their coresponding set 873 // method. This object relates to these object(s) by a 874 // foreign key reference. 875 "; 876 877 foreach($table->getForeignKeys() as $fk) 878 { 879 $aVarName = $this->getFKVarName($fk); 880 $script .= " 881 if (\$this->$aVarName !== null) { 882 if (\$this->".$aVarName."->isModified()) { 883 \$affectedRows += \$this->".$aVarName."->save(\$con); 884 } 885 \$this->set".$this->getFKPhpNameAffix($fk, $plural = false)."(\$this->$aVarName); 886 } 887 "; 888 } // foreach foreign k 889 } // if (count(foreign keys)) 890 891 $script .= " 892 893 // If this object has been modified, then save it to the database. 894 if (\$this->isModified()"; 895 896 /* 897 FIXME: this doesn't work right now because the BasePeer::doInsert() method 898 expects to be passed a Criteria object that contains columns (which tell BasePeer 899 which table is being updated) 900 if ($table->hasAutoIncrementPrimaryKey()) { 901 $script .= " || \$this->isNew()"; 902 } 903 */ 904 905 $script .= ") { 906 if (\$this->isNew()) { 907 \$pk = ".$this->getPeerClassname()."::doInsert(\$this, \$con); 908 \$affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which 909 // should always be true here (even though technically 910 // BasePeer::doInsert() can insert multiple rows). 911 "; 912 if ($table->getIdMethod() != IDMethod::NO_ID_METHOD) { 913 914 if (count($pks = $table->getPrimaryKey())) { 915 foreach ($pks as $pk) { 916 if ($pk->isAutoIncrement()) { 917 $script .= " 918 \$this->set".$pk->getPhpName()."(\$pk); //[IMV] update autoincrement primary key 919 "; 920 } 921 } 922 } 923 } // if (id method != "none") 924 925 $script .= " 926 \$this->setNew(false); 927 } else { 928 \$affectedRows += ".$this->getPeerClassname()."::doUpdate(\$this, \$con); 929 } 930 \$this->resetModified(); // [HL] After being saved an object is no longer 'modified' 931 } 932 "; 933 934 foreach ($table->getReferrers() as $fk) { 935 $collName = $this->getRefFKCollVarName($fk); 936 //HL: commenting out self-referrential check below 937 // it seems to work as expected and is desireable since we are also enabling the copy()ing of these related rows 938 //if ( $fk->getTable()->getName() != $table->getName() ) { 939 $script .= " 940 if (\$this->$collName !== null) { 941 foreach(\$this->$collName as \$referrerFK) { 942 if (!\$referrerFK->isDeleted()) { 943 \$affectedRows += \$referrerFK->save(\$con); 944 } 945 } 946 } 947 "; 948 //HL: commenting out close of self-referrential check 949 //} /* if tableFK != table */ 950 } /* foreach getReferrers() */ 951 $script .= " 952 \$this->alreadyInSave = false; 953 } 954 return \$affectedRows; 955 } // doSave() 956 "; 957 958 } 959 960 /** 961 * Adds the $alreadyInSave attribute, which prevents attempting to re-save the same object. 962 * @param string &$script The script will be modified in this method. 963 */ 964 protected function addAlreadyInSaveAttribute(&$script) 965 { 966 $script .= " 967 /** 968 * Flag to prevent endless save loop, if this object is referenced 969 * by another object which falls in this transaction. 970 * @var boolean 971 */ 972 protected \$alreadyInSave = false; 973 "; 974 } 975 976 /** 977 * Adds the save() method. 978 * @param string &$script The script will be modified in this method. 979 */ 980 protected function addSave(&$script) 981 { 982 $script .= " 983 /** 984 * Stores the object in the database. If the object is new, 985 * it inserts it; otherwise an update is performed. This method 986 * wraps the doSave() worker method in a transaction. 987 * 988 * @param Connection \$con 989 * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. 990 * @throws PropelException 991 * @see doSave() 992 */ 993 public function save(\$con = null) 994 { 995 if (\$this->isDeleted()) { 996 throw new PropelException(\"You cannot save an object that has been deleted.\"); 997 } 998 999 if (\$con === null) { 1000 \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME); 1001 } 1002 1003 try { 1004 \$con->begin(); 1005 \$affectedRows = \$this->doSave(\$con); 1006 \$con->commit(); 1007 return \$affectedRows; 1008 } catch (PropelException \$e) { 1009 \$con->rollback(); 1010 throw \$e; 1011 } 1012 } 1013 "; 1014 1015 } 1016 1017 /** 1018 * Adds the $alreadyInValidation attribute, which prevents attempting to re-validate the same object. 1019 * @param string &$script The script will be modified in this method. 1020 */ 1021 protected function addAlreadyInValidationAttribute(&$script) 1022 { 1023 $script .= " 1024 /** 1025 * Flag to prevent endless validation loop, if this object is referenced 1026 * by another object which falls in this transaction. 1027 * @var boolean 1028 */ 1029 protected \$alreadyInValidation = false; 1030 "; 1031 } 1032 1033 /** 1034 * Adds the validate() method. 1035 * @param string &$script The script will be modified in this method. 1036 */ 1037 protected function addValidate(&$script) 1038 { 1039 $script .= " 1040 /** 1041 * Validates the objects modified field values and all objects related to this table. 1042 * 1043 * If \$columns is either a column name or an array of column names 1044 * only those columns are validated. 1045 * 1046 * @param mixed \$columns Column name or an array of column names. 1047 * @return boolean Whether all columns pass validation. 1048 * @see doValidate() 1049 * @see getValidationFailures() 1050 */ 1051 public function validate(\$columns = null) 1052 { 1053 \$res = \$this->doValidate(\$columns); 1054 if (\$res === true) { 1055 \$this->validationFailures = array(); 1056 return true; 1057 } else { 1058 \$this->validationFailures = \$res; 1059 return false; 1060 } 1061 } 1062 "; 1063 } // addValidate() 1064 1065 /** 1066 * Adds the workhourse doValidate() method. 1067 * @param string &$script The script will be modified in this method. 1068 */ 1069 protected function addDoValidate(&$script) 1070 { 1071 $table = $this->getTable(); 1072 1073 $script .= " 1074 /** 1075 * This function performs the validation work for complex object models. 1076 * 1077 * In addition to checking the current object, all related objects will 1078 * also be validated. If all pass then <code>true</code> is returned; otherwise 1079 * an aggreagated array of ValidationFailed objects will be returned. 1080 * 1081 * @param array \$columns Array of column names to validate. 1082 * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. 1083 */ 1084 protected function doValidate(\$columns = null) 1085 { 1086 if (!\$this->alreadyInValidation) { 1087 \$this->alreadyInValidation = true; 1088 \$retval = null; 1089 1090 \$failureMap = array(); 1091 "; 1092 if (count($table->getForeignKeys()) != 0) { 1093 $script .= " 1094 1095 // We call the validate method on the following object(s) if they 1096 // were passed to this object by their coresponding set 1097 // method. This object relates to these object(s) by a 1098 // foreign key reference. 1099 "; 1100 foreach($table->getForeignKeys() as $fk) { 1101 $aVarName = $this->getFKVarName($fk); 1102 $script .= " 1103 if (\$this->".$aVarName." !== null) { 1104 if (!\$this->".$aVarName."->validate(\$columns)) { 1105 \$failureMap = array_merge(\$failureMap, \$this->".$aVarName."->getValidationFailures()); 1106 } 1107 } 1108 "; 1109 } /* for() */ 1110 } /* if count(fkeys) */ 1111 1112 $script .= " 1113 1114 if ((\$retval = ".$this->getPeerClassname()."::doValidate(\$this, \$columns)) !== true) { 1115 \$failureMap = array_merge(\$failureMap, \$retval); 1116 } 1117 1118 "; 1119 1120 foreach ($table->getReferrers() as $fk) { 1121 $tblFK = $fk->getTable(); 1122 if ( $tblFK->getName() != $table->getName() ) { 1123 $collName = $this->getRefFKCollVarName($fk); 1124 $script .= " 1125 if (\$this->$collName !== null) { 1126 foreach(\$this->$collName as \$referrerFK) { 1127 if (!\$referrerFK->validate(\$columns)) { 1128 \$failureMap = array_merge(\$failureMap, \$referrerFK->getValidationFailures()); 1129 } 1130 } 1131 } 1132 "; 1133 } /* if tableFK !+ table */ 1134 } /* foreach getReferrers() */ 1135 1136 $script .= " 1137 1138 \$this->alreadyInValidation = false; 1139 } 1140 1141 return (!empty(\$failureMap) ? \$failureMap : true); 1142 } 1143 "; 1144 } // addDoValidate() 1145 1146 /** 1147 * Adds the copy() method, which (in complex OM) includes the $deepCopy param for making copies of related objects. 1148 * @param string &$script The script will be modified in this method. 1149 */ 1150 protected function addCopy(&$script) 1151 { 1152 $this->addCopyInto($script); 1153 1154 $table = $this->getTable(); 1155 1156 $script .= " 1157 /** 1158 * Makes a copy of this object that will be inserted as a new row in table when saved. 1159 * It creates a new object filling in the simple attributes, but skipping any primary 1160 * keys that are defined for the table. 1161 * 1162 * If desired, this method can also make copies of all associated (fkey referrers) 1163 * objects. 1164 * 1165 * @param boolean \$deepCopy Whether to also copy all rows that refer (by fkey) to the current row. 1166 * @return ".$table->getPhpName()." Clone of current object. 1167 * @throws PropelException 1168 */ 1169 public function copy(\$deepCopy = false) 1170 { 1171 // we use get_class(), because this might be a subclass 1172 \$clazz = get_class(\$this); 1173 \$copyObj = new \$clazz(); 1174 \$this->copyInto(\$copyObj, \$deepCopy); 1175 return \$copyObj; 1176 } 1177 "; 1178 } // addCopy() 1179 1180 /** 1181 * Adds the copyInto() method, which takes an object and sets contents to match current object. 1182 * In complex OM this method includes the $deepCopy param for making copies of related objects. 1183 * @param string &$script The script will be modified in this method. 1184 */ 1185 protected function addCopyInto(&$script) 1186 { 1187 $table = $this->getTable(); 1188 1189 $script .= " 1190 /** 1191 * Sets contents of passed object to values from current object. 1192 * 1193 * If desired, this method can also make copies of all associated (fkey referrers) 1194 * objects. 1195 * 1196 * @param object \$copyObj An object of ".$table->getPhpName()." (or compatible) type. 1197 * @param boolean \$deepCopy Whether to also copy all rows that refer (by fkey) to the current row. 1198 * @throws PropelException 1199 */ 1200 public function copyInto(\$copyObj, \$deepCopy = false) 1201 { 1202 "; 1203 1204 $pkcols = array(); 1205 foreach ($table->getColumns() as $pkcol) { 1206 if ($pkcol->isPrimaryKey()) { 1207 $pkcols[] = $pkcol->getName(); 1208 } 1209 } 1210 1211 foreach ($table->getColumns() as $col) { 1212 if (!in_array($col->getName(), $pkcols)) { 1213 $script .= " 1214 \$copyObj->set".$col->getPhpName()."(\$this->".strtolower($col->getName())."); 1215 "; 1216 } 1217 } // foreach 1218 1219 // Avoid useless code by checking to see if there are any referrers 1220 // to this table: 1221 if (count($table->getReferrers()) > 0) { 1222 $script .= " 1223 1224 if (\$deepCopy) { 1225 // important: temporarily setNew(false) because this affects the behavior of 1226 // the getter/setter methods for fkey referrer objects. 1227 \$copyObj->setNew(false); 1228 "; 1229 foreach ($table->getReferrers() as $fk) { 1230 // Continue if $this and $copyObj are the same class and have the same primary key 1231 // to avoid endless loops 1232 $script .= " 1233 foreach(\$this->get".$this->getRefFKPhpNameAffix($fk, true)."() as \$relObj) {"; 1234 if ($table->getName() === $fk->getTableName()) { 1235 $script .= " 1236 if(\$this->getPrimaryKey() === \$relObj->getPrimaryKey()) { 1237 continue; 1238 } 1239 "; 1240 } 1241 $script .= " 1242 \$copyObj->add".$this->getRefFKPhpNameAffix($fk)."(\$relObj->copy(\$deepCopy)); 1243 } 1244 "; 1245 // HL: commenting out close of self-referential check 1246 // } /* if tblFK != table */ 1247 } /* foreach */ 1248 $script .= " 1249 } // if (\$deepCopy) 1250 "; 1251 } /* if (count referrers > 0 ) */ 1252 1253 $script .= " 1254 1255 \$copyObj->setNew(true); 1256 "; 1257 1258 1259 foreach ($table->getColumns() as $col) { 1260 if ($col->isPrimaryKey()) { 1261 $coldefval = $col->getPhpDefaultValue(); 1262 $coldefval = var_export($coldefval, true); 1263 $script .= " 1264 \$copyObj->set".$col->getPhpName() ."($coldefval); // this is a pkey column, so set to default value 1265 "; 1266 } // if col->isPrimaryKey 1267 } // foreach 1268 $script .= " 1269 } 1270 "; 1271 } // addCopyInto() 1272 1273 } // PHP5ComplexObjectBuilder
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |