       1: <?php
       2:
       3: namespace Thelia\Model\om;
       4:
       5: use \BaseObject;
       6: use \BasePeer;
       7: use \Criteria;
       8: use \DateTime;
       9: use \Exception;
      10: use \PDO;
      11: use \Persistent;
      12: use \Propel;
      13: use \PropelCollection;
      14: use \PropelDateTime;
      15: use \PropelException;
      16: use \PropelObjectCollection;
      17: use \PropelPDO;
      18: use Thelia\Model\Accessory;
      19: use Thelia\Model\AccessoryQuery;
      20: use Thelia\Model\ContentAssoc;
      21: use Thelia\Model\ContentAssocQuery;
      22: use Thelia\Model\Document;
      23: use Thelia\Model\DocumentQuery;
      24: use Thelia\Model\FeatureProd;
      25: use Thelia\Model\FeatureProdQuery;
      26: use Thelia\Model\Image;
      27: use Thelia\Model\ImageQuery;
      28: use Thelia\Model\Product;
      29: use Thelia\Model\ProductCategory;
      30: use Thelia\Model\ProductCategoryQuery;
      31: use Thelia\Model\ProductI18n;
      32: use Thelia\Model\ProductI18nQuery;
      33: use Thelia\Model\ProductPeer;
      34: use Thelia\Model\ProductQuery;
      35: use Thelia\Model\ProductVersion;
      36: use Thelia\Model\ProductVersionPeer;
      37: use Thelia\Model\ProductVersionQuery;
      38: use Thelia\Model\Rewriting;
      39: use Thelia\Model\RewritingQuery;
      40: use Thelia\Model\Stock;
      41: use Thelia\Model\StockQuery;
      42: use Thelia\Model\TaxRule;
      43: use Thelia\Model\TaxRuleQuery;
      44:
      45: /**
      46:  * Base class that represents a row from the 'product' table.
      47:  *
      48:  *
      49:  *
      50:  * @package    propel.generator.Thelia.Model.om
      51:  */
      52: abstract class BaseProduct extends BaseObject implements Persistent
      53: {
      54:     /**
      55:      * Peer class name
      56:      */
      57:     const PEER = 'Thelia\\Model\\ProductPeer';
      58:
      59:     /**
      60:      * The Peer class.
      61:      * Instance provides a convenient way of calling static methods on a class
      62:      * that calling code may not be able to identify.
      63:      * @var        ProductPeer
      64:      */
      65:     protected static $peer;
      66:
      67:     /**
      68:      * The flag var to prevent infinit loop in deep copy
      69:      * @var       boolean
      70:      */
      71:     protected $startCopy = false;
      72:
      73:     /**
      74:      * The value for the id field.
      75:      * @var        int
      76:      */
      77:     protected $id;
      78:
      79:     /**
      80:      * The value for the tax_rule_id field.
      81:      * @var        int
      82:      */
      83:     protected $tax_rule_id;
      84:
      85:     /**
      86:      * The value for the ref field.
      87:      * @var        string
      88:      */
      89:     protected $ref;
      90:
      91:     /**
      92:      * The value for the price field.
      93:      * @var        double
      94:      */
      95:     protected $price;
      96:
      97:     /**
      98:      * The value for the price2 field.
      99:      * @var        double
     100:      */
     101:     protected $price2;
     102:
     103:     /**
     104:      * The value for the ecotax field.
     105:      * @var        double
     106:      */
     107:     protected $ecotax;
     108:
     109:     /**
     110:      * The value for the newness field.
     111:      * Note: this column has a database default value of: 0
     112:      * @var        int
     113:      */
     114:     protected $newness;
     115:
     116:     /**
     117:      * The value for the promo field.
     118:      * Note: this column has a database default value of: 0
     119:      * @var        int
     120:      */
     121:     protected $promo;
     122:
     123:     /**
     124:      * The value for the stock field.
     125:      * Note: this column has a database default value of: 0
     126:      * @var        int
     127:      */
     128:     protected $stock;
     129:
     130:     /**
     131:      * The value for the visible field.
     132:      * Note: this column has a database default value of: 0
     133:      * @var        int
     134:      */
     135:     protected $visible;
     136:
     137:     /**
     138:      * The value for the weight field.
     139:      * @var        double
     140:      */
     141:     protected $weight;
     142:
     143:     /**
     144:      * The value for the position field.
     145:      * @var        int
     146:      */
     147:     protected $position;
     148:
     149:     /**
     150:      * The value for the created_at field.
     151:      * @var        string
     152:      */
     153:     protected $created_at;
     154:
     155:     /**
     156:      * The value for the updated_at field.
     157:      * @var        string
     158:      */
     159:     protected $updated_at;
     160:
     161:     /**
     162:      * The value for the version field.
     163:      * Note: this column has a database default value of: 0
     164:      * @var        int
     165:      */
     166:     protected $version;
     167:
     168:     /**
     169:      * The value for the version_created_at field.
     170:      * @var        string
     171:      */
     172:     protected $version_created_at;
     173:
     174:     /**
     175:      * The value for the version_created_by field.
     176:      * @var        string
     177:      */
     178:     protected $version_created_by;
     179:
     180:     /**
     181:      * @var        TaxRule
     182:      */
     183:     protected $aTaxRule;
     184:
     185:     /**
     186:      * @var        PropelObjectCollection|ProductCategory[] Collection to store aggregation of ProductCategory objects.
     187:      */
     188:     protected $collProductCategorys;
     189:     protected $collProductCategorysPartial;
     190:
     191:     /**
     192:      * @var        PropelObjectCollection|FeatureProd[] Collection to store aggregation of FeatureProd objects.
     193:      */
     194:     protected $collFeatureProds;
     195:     protected $collFeatureProdsPartial;
     196:
     197:     /**
     198:      * @var        PropelObjectCollection|Stock[] Collection to store aggregation of Stock objects.
     199:      */
     200:     protected $collStocks;
     201:     protected $collStocksPartial;
     202:
     203:     /**
     204:      * @var        PropelObjectCollection|ContentAssoc[] Collection to store aggregation of ContentAssoc objects.
     205:      */
     206:     protected $collContentAssocs;
     207:     protected $collContentAssocsPartial;
     208:
     209:     /**
     210:      * @var        PropelObjectCollection|Image[] Collection to store aggregation of Image objects.
     211:      */
     212:     protected $collImages;
     213:     protected $collImagesPartial;
     214:
     215:     /**
     216:      * @var        PropelObjectCollection|Document[] Collection to store aggregation of Document objects.
     217:      */
     218:     protected $collDocuments;
     219:     protected $collDocumentsPartial;
     220:
     221:     /**
     222:      * @var        PropelObjectCollection|Accessory[] Collection to store aggregation of Accessory objects.
     223:      */
     224:     protected $collAccessorysRelatedByProductId;
     225:     protected $collAccessorysRelatedByProductIdPartial;
     226:
     227:     /**
     228:      * @var        PropelObjectCollection|Accessory[] Collection to store aggregation of Accessory objects.
     229:      */
     230:     protected $collAccessorysRelatedByAccessory;
     231:     protected $collAccessorysRelatedByAccessoryPartial;
     232:
     233:     /**
     234:      * @var        PropelObjectCollection|Rewriting[] Collection to store aggregation of Rewriting objects.
     235:      */
     236:     protected $collRewritings;
     237:     protected $collRewritingsPartial;
     238:
     239:     /**
     240:      * @var        PropelObjectCollection|ProductI18n[] Collection to store aggregation of ProductI18n objects.
     241:      */
     242:     protected $collProductI18ns;
     243:     protected $collProductI18nsPartial;
     244:
     245:     /**
     246:      * @var        PropelObjectCollection|ProductVersion[] Collection to store aggregation of ProductVersion objects.
     247:      */
     248:     protected $collProductVersions;
     249:     protected $collProductVersionsPartial;
     250:
     251:     /**
     252:      * Flag to prevent endless save loop, if this object is referenced
     253:      * by another object which falls in this transaction.
     254:      * @var        boolean
     255:      */
     256:     protected $alreadyInSave = false;
     257:
     258:     /**
     259:      * Flag to prevent endless validation loop, if this object is referenced
     260:      * by another object which falls in this transaction.
     261:      * @var        boolean
     262:      */
     263:     protected $alreadyInValidation = false;
     264:
     265:     /**
     266:      * Flag to prevent endless clearAllReferences($deep=true) loop, if this object is referenced
     267:      * @var        boolean
     268:      */
     269:     protected $alreadyInClearAllReferencesDeep = false;
     270:
     271:     // i18n behavior
     272:
     273:     /**
     274:      * Current locale
     275:      * @var        string
     276:      */
     277:     protected $currentLocale = 'en_US';
     278:
     279:     /**
     280:      * Current translation objects
     281:      * @var        array[ProductI18n]
     282:      */
     283:     protected $currentTranslations;
     284:
     285:     // versionable behavior
     286:
     287:
     288:     /**
     289:      * @var bool
     290:      */
     291:     protected $enforceVersion = false;
     292:
     293:     /**
     294:      * An array of objects scheduled for deletion.
     295:      * @var     PropelObjectCollection
     296:      */
     297:     protected $productCategorysScheduledForDeletion = null;
     298:
     299:     /**
     300:      * An array of objects scheduled for deletion.
     301:      * @var     PropelObjectCollection
     302:      */
     303:     protected $featureProdsScheduledForDeletion = null;
     304:
     305:     /**
     306:      * An array of objects scheduled for deletion.
     307:      * @var     PropelObjectCollection
     308:      */
     309:     protected $stocksScheduledForDeletion = null;
     310:
     311:     /**
     312:      * An array of objects scheduled for deletion.
     313:      * @var     PropelObjectCollection
     314:      */
     315:     protected $contentAssocsScheduledForDeletion = null;
     316:
     317:     /**
     318:      * An array of objects scheduled for deletion.
     319:      * @var     PropelObjectCollection
     320:      */
     321:     protected $imagesScheduledForDeletion = null;
     322:
     323:     /**
     324:      * An array of objects scheduled for deletion.
     325:      * @var     PropelObjectCollection
     326:      */
     327:     protected $documentsScheduledForDeletion = null;
     328:
     329:     /**
     330:      * An array of objects scheduled for deletion.
     331:      * @var     PropelObjectCollection
     332:      */
     333:     protected $accessorysRelatedByProductIdScheduledForDeletion = null;
     334:
     335:     /**
     336:      * An array of objects scheduled for deletion.
     337:      * @var     PropelObjectCollection
     338:      */
     339:     protected $accessorysRelatedByAccessoryScheduledForDeletion = null;
     340:
     341:     /**
     342:      * An array of objects scheduled for deletion.
     343:      * @var     PropelObjectCollection
     344:      */
     345:     protected $rewritingsScheduledForDeletion = null;
     346:
     347:     /**
     348:      * An array of objects scheduled for deletion.
     349:      * @var     PropelObjectCollection
     350:      */
     351:     protected $productI18nsScheduledForDeletion = null;
     352:
     353:     /**
     354:      * An array of objects scheduled for deletion.
     355:      * @var     PropelObjectCollection
     356:      */
     357:     protected $productVersionsScheduledForDeletion = null;
     358:
     359:     /**
     360:      * Applies default values to this object.
     361:      * This method should be called from the object's constructor (or
     362:      * equivalent initialization method).
     363:      * @see        __construct()
     364:      */
     365:     public function applyDefaultValues()
     366:     {
     367:         $this->newness = 0;
     368:         $this->promo = 0;
     369:         $this->stock = 0;
     370:         $this->visible = 0;
     371:         $this->version = 0;
     372:     }
     373:
     374:     /**
     375:      * Initializes internal state of BaseProduct object.
     376:      * @see        applyDefaults()
     377:      */
     378:     public function __construct()
     379:     {
     380:         parent::__construct();
     381:         $this->applyDefaultValues();
     382:     }
     383:
     384:     /**
     385:      * Get the [id] column value.
     386:      *
     387:      * @return int
     388:      */
     389:     public function getId()
     390:     {
     391:         return $this->id;
     392:     }
     393:
     394:     /**
     395:      * Get the [tax_rule_id] column value.
     396:      *
     397:      * @return int
     398:      */
     399:     public function getTaxRuleId()
     400:     {
     401:         return $this->tax_rule_id;
     402:     }
     403:
     404:     /**
     405:      * Get the [ref] column value.
     406:      *
     407:      * @return string
     408:      */
     409:     public function getRef()
     410:     {
     411:         return $this->ref;
     412:     }
     413:
     414:     /**
     415:      * Get the [price] column value.
     416:      *
     417:      * @return double
     418:      */
     419:     public function getPrice()
     420:     {
     421:         return $this->price;
     422:     }
     423:
     424:     /**
     425:      * Get the [price2] column value.
     426:      *
     427:      * @return double
     428:      */
     429:     public function getPrice2()
     430:     {
     431:         return $this->price2;
     432:     }
     433:
     434:     /**
     435:      * Get the [ecotax] column value.
     436:      *
     437:      * @return double
     438:      */
     439:     public function getEcotax()
     440:     {
     441:         return $this->ecotax;
     442:     }
     443:
     444:     /**
     445:      * Get the [newness] column value.
     446:      *
     447:      * @return int
     448:      */
     449:     public function getNewness()
     450:     {
     451:         return $this->newness;
     452:     }
     453:
     454:     /**
     455:      * Get the [promo] column value.
     456:      *
     457:      * @return int
     458:      */
     459:     public function getPromo()
     460:     {
     461:         return $this->promo;
     462:     }
     463:
     464:     /**
     465:      * Get the [stock] column value.
     466:      *
     467:      * @return int
     468:      */
     469:     public function getStock()
     470:     {
     471:         return $this->stock;
     472:     }
     473:
     474:     /**
     475:      * Get the [visible] column value.
     476:      *
     477:      * @return int
     478:      */
     479:     public function getVisible()
     480:     {
     481:         return $this->visible;
     482:     }
     483:
     484:     /**
     485:      * Get the [weight] column value.
     486:      *
     487:      * @return double
     488:      */
     489:     public function getWeight()
     490:     {
     491:         return $this->weight;
     492:     }
     493:
     494:     /**
     495:      * Get the [position] column value.
     496:      *
     497:      * @return int
     498:      */
     499:     public function getPosition()
     500:     {
     501:         return $this->position;
     502:     }
     503:
     504:     /**
     505:      * Get the [optionally formatted] temporal [created_at] column value.
     506:      *
     507:      *
     508:      * @param string $format The date/time format string (either date()-style or strftime()-style).
     509:      *               If format is null, then the raw DateTime object will be returned.
     510:      * @return mixed Formatted date/time value as string or DateTime object (if format is null), null if column is null, and 0 if column value is 0000-00-00 00:00:00
     511:      * @throws PropelException - if unable to parse/validate the date/time value.
     512:      */
     513:     public function getCreatedAt($format = 'Y-m-d H:i:s')
     514:     {
     515:         if ($this->created_at === null) {
     516:             return null;
     517:         }
     518:
     519:         if ($this->created_at === '0000-00-00 00:00:00') {
     520:             // while technically this is not a default value of null,
     521:             // this seems to be closest in meaning.
     522:             return null;
     523:         }
     524:
     525:         try {
     526:             $dt = new DateTime($this->created_at);
     527:         } catch (Exception $x) {
     528:             throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->created_at, true), $x);
     529:         }
     530:
     531:         if ($format === null) {
     532:             // Because propel.useDateTimeClass is true, we return a DateTime object.
     533:             return $dt;
     534:         }
     535:
     536:         if (strpos($format, '%') !== false) {
     537:             return strftime($format, $dt->format('U'));
     538:         }
     539:
     540:         return $dt->format($format);
     541:
     542:     }
     543:
     544:     /**
     545:      * Get the [optionally formatted] temporal [updated_at] column value.
     546:      *
     547:      *
     548:      * @param string $format The date/time format string (either date()-style or strftime()-style).
     549:      *               If format is null, then the raw DateTime object will be returned.
     550:      * @return mixed Formatted date/time value as string or DateTime object (if format is null), null if column is null, and 0 if column value is 0000-00-00 00:00:00
     551:      * @throws PropelException - if unable to parse/validate the date/time value.
     552:      */
     553:     public function getUpdatedAt($format = 'Y-m-d H:i:s')
     554:     {
     555:         if ($this->updated_at === null) {
     556:             return null;
     557:         }
     558:
     559:         if ($this->updated_at === '0000-00-00 00:00:00') {
     560:             // while technically this is not a default value of null,
     561:             // this seems to be closest in meaning.
     562:             return null;
     563:         }
     564:
     565:         try {
     566:             $dt = new DateTime($this->updated_at);
     567:         } catch (Exception $x) {
     568:             throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->updated_at, true), $x);
     569:         }
     570:
     571:         if ($format === null) {
     572:             // Because propel.useDateTimeClass is true, we return a DateTime object.
     573:             return $dt;
     574:         }
     575:
     576:         if (strpos($format, '%') !== false) {
     577:             return strftime($format, $dt->format('U'));
     578:         }
     579:
     580:         return $dt->format($format);
     581:
     582:     }
     583:
     584:     /**
     585:      * Get the [version] column value.
     586:      *
     587:      * @return int
     588:      */
     589:     public function getVersion()
     590:     {
     591:         return $this->version;
     592:     }
     593:
     594:     /**
     595:      * Get the [optionally formatted] temporal [version_created_at] column value.
     596:      *
     597:      *
     598:      * @param string $format The date/time format string (either date()-style or strftime()-style).
     599:      *               If format is null, then the raw DateTime object will be returned.
     600:      * @return mixed Formatted date/time value as string or DateTime object (if format is null), null if column is null, and 0 if column value is 0000-00-00 00:00:00
     601:      * @throws PropelException - if unable to parse/validate the date/time value.
     602:      */
     603:     public function getVersionCreatedAt($format = 'Y-m-d H:i:s')
     604:     {
     605:         if ($this->version_created_at === null) {
     606:             return null;
     607:         }
     608:
     609:         if ($this->version_created_at === '0000-00-00 00:00:00') {
     610:             // while technically this is not a default value of null,
     611:             // this seems to be closest in meaning.
     612:             return null;
     613:         }
     614:
     615:         try {
     616:             $dt = new DateTime($this->version_created_at);
     617:         } catch (Exception $x) {
     618:             throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->version_created_at, true), $x);
     619:         }
     620:
     621:         if ($format === null) {
     622:             // Because propel.useDateTimeClass is true, we return a DateTime object.
     623:             return $dt;
     624:         }
     625:
     626:         if (strpos($format, '%') !== false) {
     627:             return strftime($format, $dt->format('U'));
     628:         }
     629:
     630:         return $dt->format($format);
     631:
     632:     }
     633:
     634:     /**
     635:      * Get the [version_created_by] column value.
     636:      *
     637:      * @return string
     638:      */
     639:     public function getVersionCreatedBy()
     640:     {
     641:         return $this->version_created_by;
     642:     }
     643:
     644:     /**
     645:      * Set the value of [id] column.
     646:      *
     647:      * @param int $v new value
     648:      * @return Product The current object (for fluent API support)
     649:      */
     650:     public function setId($v)
     651:     {
     652:         if ($v !== null && is_numeric($v)) {
     653:             $v = (int) $v;
     654:         }
     655:
     656:         if ($this->id !== $v) {
     657:             $this->id = $v;
     658:             $this->modifiedColumns[] = ProductPeer::ID;
     659:         }
     660:
     661:
     662:         return $this;
     663:     } // setId()
     664:
     665:     /**
     666:      * Set the value of [tax_rule_id] column.
     667:      *
     668:      * @param int $v new value
     669:      * @return Product The current object (for fluent API support)
     670:      */
     671:     public function setTaxRuleId($v)
     672:     {
     673:         if ($v !== null && is_numeric($v)) {
     674:             $v = (int) $v;
     675:         }
     676:
     677:         if ($this->tax_rule_id !== $v) {
     678:             $this->tax_rule_id = $v;
     679:             $this->modifiedColumns[] = ProductPeer::TAX_RULE_ID;
     680:         }
     681:
     682:         if ($this->aTaxRule !== null && $this->aTaxRule->getId() !== $v) {
     683:             $this->aTaxRule = null;
     684:         }
     685:
     686:
     687:         return $this;
     688:     } // setTaxRuleId()
     689:
     690:     /**
     691:      * Set the value of [ref] column.
     692:      *
     693:      * @param string $v new value
     694:      * @return Product The current object (for fluent API support)
     695:      */
     696:     public function setRef($v)
     697:     {
     698:         if ($v !== null && is_numeric($v)) {
     699:             $v = (string) $v;
     700:         }
     701:
     702:         if ($this->ref !== $v) {
     703:             $this->ref = $v;
     704:             $this->modifiedColumns[] = ProductPeer::REF;
     705:         }
     706:
     707:
     708:         return $this;
     709:     } // setRef()
     710:
     711:     /**
     712:      * Set the value of [price] column.
     713:      *
     714:      * @param double $v new value
     715:      * @return Product The current object (for fluent API support)
     716:      */
     717:     public function setPrice($v)
     718:     {
     719:         if ($v !== null && is_numeric($v)) {
     720:             $v = (double) $v;
     721:         }
     722:
     723:         if ($this->price !== $v) {
     724:             $this->price = $v;
     725:             $this->modifiedColumns[] = ProductPeer::PRICE;
     726:         }
     727:
     728:
     729:         return $this;
     730:     } // setPrice()
     731:
     732:     /**
     733:      * Set the value of [price2] column.
     734:      *
     735:      * @param double $v new value
     736:      * @return Product The current object (for fluent API support)
     737:      */
     738:     public function setPrice2($v)
     739:     {
     740:         if ($v !== null && is_numeric($v)) {
     741:             $v = (double) $v;
     742:         }
     743:
     744:         if ($this->price2 !== $v) {
     745:             $this->price2 = $v;
     746:             $this->modifiedColumns[] = ProductPeer::PRICE2;
     747:         }
     748:
     749:
     750:         return $this;
     751:     } // setPrice2()
     752:
     753:     /**
     754:      * Set the value of [ecotax] column.
     755:      *
     756:      * @param double $v new value
     757:      * @return Product The current object (for fluent API support)
     758:      */
     759:     public function setEcotax($v)
     760:     {
     761:         if ($v !== null && is_numeric($v)) {
     762:             $v = (double) $v;
     763:         }
     764:
     765:         if ($this->ecotax !== $v) {
     766:             $this->ecotax = $v;
     767:             $this->modifiedColumns[] = ProductPeer::ECOTAX;
     768:         }
     769:
     770:
     771:         return $this;
     772:     } // setEcotax()
     773:
     774:     /**
     775:      * Set the value of [newness] column.
     776:      *
     777:      * @param int $v new value
     778:      * @return Product The current object (for fluent API support)
     779:      */
     780:     public function setNewness($v)
     781:     {
     782:         if ($v !== null && is_numeric($v)) {
     783:             $v = (int) $v;
     784:         }
     785:
     786:         if ($this->newness !== $v) {
     787:             $this->newness = $v;
     788:             $this->modifiedColumns[] = ProductPeer::NEWNESS;
     789:         }
     790:
     791:
     792:         return $this;
     793:     } // setNewness()
     794:
     795:     /**
     796:      * Set the value of [promo] column.
     797:      *
     798:      * @param int $v new value
     799:      * @return Product The current object (for fluent API support)
     800:      */
     801:     public function setPromo($v)
     802:     {
     803:         if ($v !== null && is_numeric($v)) {
     804:             $v = (int) $v;
     805:         }
     806:
     807:         if ($this->promo !== $v) {
     808:             $this->promo = $v;
     809:             $this->modifiedColumns[] = ProductPeer::PROMO;
     810:         }
     811:
     812:
     813:         return $this;
     814:     } // setPromo()
     815:
     816:     /**
     817:      * Set the value of [stock] column.
     818:      *
     819:      * @param int $v new value
     820:      * @return Product The current object (for fluent API support)
     821:      */
     822:     public function setStock($v)
     823:     {
     824:         if ($v !== null && is_numeric($v)) {
     825:             $v = (int) $v;
     826:         }
     827:
     828:         if ($this->stock !== $v) {
     829:             $this->stock = $v;
     830:             $this->modifiedColumns[] = ProductPeer::STOCK;
     831:         }
     832:
     833:
     834:         return $this;
     835:     } // setStock()
     836:
     837:     /**
     838:      * Set the value of [visible] column.
     839:      *
     840:      * @param int $v new value
     841:      * @return Product The current object (for fluent API support)
     842:      */
     843:     public function setVisible($v)
     844:     {
     845:         if ($v !== null && is_numeric($v)) {
     846:             $v = (int) $v;
     847:         }
     848:
     849:         if ($this->visible !== $v) {
     850:             $this->visible = $v;
     851:             $this->modifiedColumns[] = ProductPeer::VISIBLE;
     852:         }
     853:
     854:
     855:         return $this;
     856:     } // setVisible()
     857:
     858:     /**
     859:      * Set the value of [weight] column.
     860:      *
     861:      * @param double $v new value
     862:      * @return Product The current object (for fluent API support)
     863:      */
     864:     public function setWeight($v)
     865:     {
     866:         if ($v !== null && is_numeric($v)) {
     867:             $v = (double) $v;
     868:         }
     869:
     870:         if ($this->weight !== $v) {
     871:             $this->weight = $v;
     872:             $this->modifiedColumns[] = ProductPeer::WEIGHT;
     873:         }
     874:
     875:
     876:         return $this;
     877:     } // setWeight()
     878:
     879:     /**
     880:      * Set the value of [position] column.
     881:      *
     882:      * @param int $v new value
     883:      * @return Product The current object (for fluent API support)
     884:      */
     885:     public function setPosition($v)
     886:     {
     887:         if ($v !== null && is_numeric($v)) {
     888:             $v = (int) $v;
     889:         }
     890:
     891:         if ($this->position !== $v) {
     892:             $this->position = $v;
     893:             $this->modifiedColumns[] = ProductPeer::POSITION;
     894:         }
     895:
     896:
     897:         return $this;
     898:     } // setPosition()
     899:
     900:     /**
     901:      * Sets the value of [created_at] column to a normalized version of the date/time value specified.
     902:      *
     903:      * @param mixed $v string, integer (timestamp), or DateTime value.
     904:      *               Empty strings are treated as null.
     905:      * @return Product The current object (for fluent API support)
     906:      */
     907:     public function setCreatedAt($v)
     908:     {
     909:         $dt = PropelDateTime::newInstance($v, null, 'DateTime');
     910:         if ($this->created_at !== null || $dt !== null) {
     911:             $currentDateAsString = ($this->created_at !== null && $tmpDt = new DateTime($this->created_at)) ? $tmpDt->format('Y-m-d H:i:s') : null;
     912:             $newDateAsString = $dt ? $dt->format('Y-m-d H:i:s') : null;
     913:             if ($currentDateAsString !== $newDateAsString) {
     914:                 $this->created_at = $newDateAsString;
     915:                 $this->modifiedColumns[] = ProductPeer::CREATED_AT;
     916:             }
     917:         } // if either are not null
     918:
     919:
     920:         return $this;
     921:     } // setCreatedAt()
     922:
     923:     /**
     924:      * Sets the value of [updated_at] column to a normalized version of the date/time value specified.
     925:      *
     926:      * @param mixed $v string, integer (timestamp), or DateTime value.
     927:      *               Empty strings are treated as null.
     928:      * @return Product The current object (for fluent API support)
     929:      */
     930:     public function setUpdatedAt($v)
     931:     {
     932:         $dt = PropelDateTime::newInstance($v, null, 'DateTime');
     933:         if ($this->updated_at !== null || $dt !== null) {
     934:             $currentDateAsString = ($this->updated_at !== null && $tmpDt = new DateTime($this->updated_at)) ? $tmpDt->format('Y-m-d H:i:s') : null;
     935:             $newDateAsString = $dt ? $dt->format('Y-m-d H:i:s') : null;
     936:             if ($currentDateAsString !== $newDateAsString) {
     937:                 $this->updated_at = $newDateAsString;
     938:                 $this->modifiedColumns[] = ProductPeer::UPDATED_AT;
     939:             }
     940:         } // if either are not null
     941:
     942:
     943:         return $this;
     944:     } // setUpdatedAt()
     945:
     946:     /**
     947:      * Set the value of [version] column.
     948:      *
     949:      * @param int $v new value
     950:      * @return Product The current object (for fluent API support)
     951:      */
     952:     public function setVersion($v)
     953:     {
     954:         if ($v !== null && is_numeric($v)) {
     955:             $v = (int) $v;
     956:         }
     957:
     958:         if ($this->version !== $v) {
     959:             $this->version = $v;
     960:             $this->modifiedColumns[] = ProductPeer::VERSION;
     961:         }
     962:
     963:
     964:         return $this;
     965:     } // setVersion()
     966:
     967:     /**
     968:      * Sets the value of [version_created_at] column to a normalized version of the date/time value specified.
     969:      *
     970:      * @param mixed $v string, integer (timestamp), or DateTime value.
     971:      *               Empty strings are treated as null.
     972:      * @return Product The current object (for fluent API support)
     973:      */
     974:     public function setVersionCreatedAt($v)
     975:     {
     976:         $dt = PropelDateTime::newInstance($v, null, 'DateTime');
     977:         if ($this->version_created_at !== null || $dt !== null) {
     978:             $currentDateAsString = ($this->version_created_at !== null && $tmpDt = new DateTime($this->version_created_at)) ? $tmpDt->format('Y-m-d H:i:s') : null;
     979:             $newDateAsString = $dt ? $dt->format('Y-m-d H:i:s') : null;
     980:             if ($currentDateAsString !== $newDateAsString) {
     981:                 $this->version_created_at = $newDateAsString;
     982:                 $this->modifiedColumns[] = ProductPeer::VERSION_CREATED_AT;
     983:             }
     984:         } // if either are not null
     985:
     986:
     987:         return $this;
     988:     } // setVersionCreatedAt()
     989:
     990:     /**
     991:      * Set the value of [version_created_by] column.
     992:      *
     993:      * @param string $v new value
     994:      * @return Product The current object (for fluent API support)
     995:      */
     996:     public function setVersionCreatedBy($v)
     997:     {
     998:         if ($v !== null && is_numeric($v)) {
     999:             $v = (string) $v;
    1000:         }
    1001:
    1002:         if ($this->version_created_by !== $v) {
    1003:             $this->version_created_by = $v;
    1004:             $this->modifiedColumns[] = ProductPeer::VERSION_CREATED_BY;
    1005:         }
    1006:
    1007:
    1008:         return $this;
    1009:     } // setVersionCreatedBy()
    1010:
    1011:     /**
    1012:      * Indicates whether the columns in this object are only set to default values.
    1013:      *
    1014:      * This method can be used in conjunction with isModified() to indicate whether an object is both
    1015:      * modified _and_ has some values set which are non-default.
    1016:      *
    1017:      * @return boolean Whether the columns in this object are only been set with default values.
    1018:      */
    1019:     public function hasOnlyDefaultValues()
    1020:     {
    1021:             if ($this->newness !== 0) {
    1022:                 return false;
    1023:             }
    1024:
    1025:             if ($this->promo !== 0) {
    1026:                 return false;
    1027:             }
    1028:
    1029:             if ($this->stock !== 0) {
    1030:                 return false;
    1031:             }
    1032:
    1033:             if ($this->visible !== 0) {
    1034:                 return false;
    1035:             }
    1036:
    1037:             if ($this->version !== 0) {
    1038:                 return false;
    1039:             }
    1040:
    1041:         // otherwise, everything was equal, so return true
    1042:         return true;
    1043:     } // hasOnlyDefaultValues()
    1044:
    1045:     /**
    1046:      * Hydrates (populates) the object variables with values from the database resultset.
    1047:      *
    1048:      * An offset (0-based "start column") is specified so that objects can be hydrated
    1049:      * with a subset of the columns in the resultset rows.  This is needed, for example,
    1050:      * for results of JOIN queries where the resultset row includes columns from two or
    1051:      * more tables.
    1052:      *
    1053:      * @param array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM)
    1054:      * @param int $startcol 0-based offset column which indicates which restultset column to start with.
    1055:      * @param boolean $rehydrate Whether this object is being re-hydrated from the database.
    1056:      * @return int             next starting column
    1057:      * @throws PropelException - Any caught Exception will be rewrapped as a PropelException.
    1058:      */
    1059:     public function hydrate($row, $startcol = 0, $rehydrate = false)
    1060:     {
    1061:         try {
    1062:
    1063:             $this->id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null;
    1064:             $this->tax_rule_id = ($row[$startcol + 1] !== null) ? (int) $row[$startcol + 1] : null;
    1065:             $this->ref = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null;
    1066:             $this->price = ($row[$startcol + 3] !== null) ? (double) $row[$startcol + 3] : null;
    1067:             $this->price2 = ($row[$startcol + 4] !== null) ? (double) $row[$startcol + 4] : null;
    1068:             $this->ecotax = ($row[$startcol + 5] !== null) ? (double) $row[$startcol + 5] : null;
    1069:             $this->newness = ($row[$startcol + 6] !== null) ? (int) $row[$startcol + 6] : null;
    1070:             $this->promo = ($row[$startcol + 7] !== null) ? (int) $row[$startcol + 7] : null;
    1071:             $this->stock = ($row[$startcol + 8] !== null) ? (int) $row[$startcol + 8] : null;
    1072:             $this->visible = ($row[$startcol + 9] !== null) ? (int) $row[$startcol + 9] : null;
    1073:             $this->weight = ($row[$startcol + 10] !== null) ? (double) $row[$startcol + 10] : null;
    1074:             $this->position = ($row[$startcol + 11] !== null) ? (int) $row[$startcol + 11] : null;
    1075:             $this->created_at = ($row[$startcol + 12] !== null) ? (string) $row[$startcol + 12] : null;
    1076:             $this->updated_at = ($row[$startcol + 13] !== null) ? (string) $row[$startcol + 13] : null;
    1077:             $this->version = ($row[$startcol + 14] !== null) ? (int) $row[$startcol + 14] : null;
    1078:             $this->version_created_at = ($row[$startcol + 15] !== null) ? (string) $row[$startcol + 15] : null;
    1079:             $this->version_created_by = ($row[$startcol + 16] !== null) ? (string) $row[$startcol + 16] : null;
    1080:             $this->resetModified();
    1081:
    1082:             $this->setNew(false);
    1083:
    1084:             if ($rehydrate) {
    1085:                 $this->ensureConsistency();
    1086:             }
    1087:             $this->postHydrate($row, $startcol, $rehydrate);
    1088:             return $startcol + 17; // 17 = ProductPeer::NUM_HYDRATE_COLUMNS.
    1089:
    1090:         } catch (Exception $e) {
    1091:             throw new PropelException("Error populating Product object", $e);
    1092:         }
    1093:     }
    1094:
    1095:     /**
    1096:      * Checks and repairs the internal consistency of the object.
    1097:      *
    1098:      * This method is executed after an already-instantiated object is re-hydrated
    1099:      * from the database.  It exists to check any foreign keys to make sure that
    1100:      * the objects related to the current object are correct based on foreign key.
    1101:      *
    1102:      * You can override this method in the stub class, but you should always invoke
    1103:      * the base method from the overridden method (i.e. parent::ensureConsistency()),
    1104:      * in case your model changes.
    1105:      *
    1106:      * @throws PropelException
    1107:      */
    1108:     public function ensureConsistency()
    1109:     {
    1110:
    1111:         if ($this->aTaxRule !== null && $this->tax_rule_id !== $this->aTaxRule->getId()) {
    1112:             $this->aTaxRule = null;
    1113:         }
    1114:     } // ensureConsistency
    1115:
    1116:     /**
    1117:      * Reloads this object from datastore based on primary key and (optionally) resets all associated objects.
    1118:      *
    1119:      * This will only work if the object has been saved and has a valid primary key set.
    1120:      *
    1121:      * @param boolean $deep (optional) Whether to also de-associated any related objects.
    1122:      * @param PropelPDO $con (optional) The PropelPDO connection to use.
    1123:      * @return void
    1124:      * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db
    1125:      */
    1126:     public function reload($deep = false, PropelPDO $con = null)
    1127:     {
    1128:         if ($this->isDeleted()) {
    1129:             throw new PropelException("Cannot reload a deleted object.");
    1130:         }
    1131:
    1132:         if ($this->isNew()) {
    1133:             throw new PropelException("Cannot reload an unsaved object.");
    1134:         }
    1135:
    1136:         if ($con === null) {
    1137:             $con = Propel::getConnection(ProductPeer::DATABASE_NAME, Propel::CONNECTION_READ);
    1138:         }
    1139:
    1140:         // We don't need to alter the object instance pool; we're just modifying this instance
    1141:         // already in the pool.
    1142:
    1143:         $stmt = ProductPeer::doSelectStmt($this->buildPkeyCriteria(), $con);
    1144:         $row = $stmt->fetch(PDO::FETCH_NUM);
    1145:         $stmt->closeCursor();
    1146:         if (!$row) {
    1147:             throw new PropelException('Cannot find matching row in the database to reload object values.');
    1148:         }
    1149:         $this->hydrate($row, 0, true); // rehydrate
    1150:
    1151:         if ($deep) {  // also de-associate any related objects?
    1152:
    1153:             $this->aTaxRule = null;
    1154:             $this->collProductCategorys = null;
    1155:
    1156:             $this->collFeatureProds = null;
    1157:
    1158:             $this->collStocks = null;
    1159:
    1160:             $this->collContentAssocs = null;
    1161:
    1162:             $this->collImages = null;
    1163:
    1164:             $this->collDocuments = null;
    1165:
    1166:             $this->collAccessorysRelatedByProductId = null;
    1167:
    1168:             $this->collAccessorysRelatedByAccessory = null;
    1169:
    1170:             $this->collRewritings = null;
    1171:
    1172:             $this->collProductI18ns = null;
    1173:
    1174:             $this->collProductVersions = null;
    1175:
    1176:         } // if (deep)
    1177:     }
    1178:
    1179:     /**
    1180:      * Removes this object from datastore and sets delete attribute.
    1181:      *
    1182:      * @param PropelPDO $con
    1183:      * @return void
    1184:      * @throws PropelException
    1185:      * @throws Exception
    1186:      * @see        BaseObject::setDeleted()
    1187:      * @see        BaseObject::isDeleted()
    1188:      */
    1189:     public function delete(PropelPDO $con = null)
    1190:     {
    1191:         if ($this->isDeleted()) {
    1192:             throw new PropelException("This object has already been deleted.");
    1193:         }
    1194:
    1195:         if ($con === null) {
    1196:             $con = Propel::getConnection(ProductPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
    1197:         }
    1198:
    1199:         $con->beginTransaction();
    1200:         try {
    1201:             $deleteQuery = ProductQuery::create()
    1202:                 ->filterByPrimaryKey($this->getPrimaryKey());
    1203:             $ret = $this->preDelete($con);
    1204:             if ($ret) {
    1205:                 $deleteQuery->delete($con);
    1206:                 $this->postDelete($con);
    1207:                 $con->commit();
    1208:                 $this->setDeleted(true);
    1209:             } else {
    1210:                 $con->commit();
    1211:             }
    1212:         } catch (Exception $e) {
    1213:             $con->rollBack();
    1214:             throw $e;
    1215:         }
    1216:     }
    1217:
    1218:     /**
    1219:      * Persists this object to the database.
    1220:      *
    1221:      * If the object is new, it inserts it; otherwise an update is performed.
    1222:      * All modified related objects will also be persisted in the doSave()
    1223:      * method.  This method wraps all precipitate database operations in a
    1224:      * single transaction.
    1225:      *
    1226:      * @param PropelPDO $con
    1227:      * @return int             The number of rows affected by this insert/update and any referring fk objects' save() operations.
    1228:      * @throws PropelException
    1229:      * @throws Exception
    1230:      * @see        doSave()
    1231:      */
    1232:     public function save(PropelPDO $con = null)
    1233:     {
    1234:         if ($this->isDeleted()) {
    1235:             throw new PropelException("You cannot save an object that has been deleted.");
    1236:         }
    1237:
    1238:         if ($con === null) {
    1239:             $con = Propel::getConnection(ProductPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
    1240:         }
    1241:
    1242:         $con->beginTransaction();
    1243:         $isInsert = $this->isNew();
    1244:         try {
    1245:             $ret = $this->preSave($con);
    1246:             // versionable behavior
    1247:             if ($this->isVersioningNecessary()) {
    1248:                 $this->setVersion($this->isNew() ? 1 : $this->getLastVersionNumber($con) + 1);
    1249:                 if (!$this->isColumnModified(ProductPeer::VERSION_CREATED_AT)) {
    1250:                     $this->setVersionCreatedAt(time());
    1251:                 }
    1252:                 $createVersion = true; // for postSave hook
    1253:             }
    1254:             if ($isInsert) {
    1255:                 $ret = $ret && $this->preInsert($con);
    1256:                 // timestampable behavior
    1257:                 if (!$this->isColumnModified(ProductPeer::CREATED_AT)) {
    1258:                     $this->setCreatedAt(time());
    1259:                 }
    1260:                 if (!$this->isColumnModified(ProductPeer::UPDATED_AT)) {
    1261:                     $this->setUpdatedAt(time());
    1262:                 }
    1263:             } else {
    1264:                 $ret = $ret && $this->preUpdate($con);
    1265:                 // timestampable behavior
    1266:                 if ($this->isModified() && !$this->isColumnModified(ProductPeer::UPDATED_AT)) {
    1267:                     $this->setUpdatedAt(time());
    1268:                 }
    1269:             }
    1270:             if ($ret) {
    1271:                 $affectedRows = $this->doSave($con);
    1272:                 if ($isInsert) {
    1273:                     $this->postInsert($con);
    1274:                 } else {
    1275:                     $this->postUpdate($con);
    1276:                 }
    1277:                 $this->postSave($con);
    1278:                 // versionable behavior
    1279:                 if (isset($createVersion)) {
    1280:                     $this->addVersion($con);
    1281:                 }
    1282:                 ProductPeer::addInstanceToPool($this);
    1283:             } else {
    1284:                 $affectedRows = 0;
    1285:             }
    1286:             $con->commit();
    1287:
    1288:             return $affectedRows;
    1289:         } catch (Exception $e) {
    1290:             $con->rollBack();
    1291:             throw $e;
    1292:         }
    1293:     }
    1294:
    1295:     /**
    1296:      * Performs the work of inserting or updating the row in the database.
    1297:      *
    1298:      * If the object is new, it inserts it; otherwise an update is performed.
    1299:      * All related objects are also updated in this method.
    1300:      *
    1301:      * @param PropelPDO $con
    1302:      * @return int             The number of rows affected by this insert/update and any referring fk objects' save() operations.
    1303:      * @throws PropelException
    1304:      * @see        save()
    1305:      */
    1306:     protected function doSave(PropelPDO $con)
    1307:     {
    1308:         $affectedRows = 0; // initialize var to track total num of affected rows
    1309:         if (!$this->alreadyInSave) {
    1310:             $this->alreadyInSave = true;
    1311:
    1312:             // We call the save method on the following object(s) if they
    1313:             // were passed to this object by their coresponding set
    1314:             // method.  This object relates to these object(s) by a
    1315:             // foreign key reference.
    1316:
    1317:             if ($this->aTaxRule !== null) {
    1318:                 if ($this->aTaxRule->isModified() || $this->aTaxRule->isNew()) {
    1319:                     $affectedRows += $this->aTaxRule->save($con);
    1320:                 }
    1321:                 $this->setTaxRule($this->aTaxRule);
    1322:             }
    1323:
    1324:             if ($this->isNew() || $this->isModified()) {
    1325:                 // persist changes
    1326:                 if ($this->isNew()) {
    1327:                     $this->doInsert($con);
    1328:                 } else {
    1329:                     $this->doUpdate($con);
    1330:                 }
    1331:                 $affectedRows += 1;
    1332:                 $this->resetModified();
    1333:             }
    1334:
    1335:             if ($this->productCategorysScheduledForDeletion !== null) {
    1336:                 if (!$this->productCategorysScheduledForDeletion->isEmpty()) {
    1337:                     ProductCategoryQuery::create()
    1338:                         ->filterByPrimaryKeys($this->productCategorysScheduledForDeletion->getPrimaryKeys(false))
    1339:                         ->delete($con);
    1340:                     $this->productCategorysScheduledForDeletion = null;
    1341:                 }
    1342:             }
    1343:
    1344:             if ($this->collProductCategorys !== null) {
    1345:                 foreach ($this->collProductCategorys as $referrerFK) {
    1346:                     if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
    1347:                         $affectedRows += $referrerFK->save($con);
    1348:                     }
    1349:                 }
    1350:             }
    1351:
    1352:             if ($this->featureProdsScheduledForDeletion !== null) {
    1353:                 if (!$this->featureProdsScheduledForDeletion->isEmpty()) {
    1354:                     FeatureProdQuery::create()
    1355:                         ->filterByPrimaryKeys($this->featureProdsScheduledForDeletion->getPrimaryKeys(false))
    1356:                         ->delete($con);
    1357:                     $this->featureProdsScheduledForDeletion = null;
    1358:                 }
    1359:             }
    1360:
    1361:             if ($this->collFeatureProds !== null) {
    1362:                 foreach ($this->collFeatureProds as $referrerFK) {
    1363:                     if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
    1364:                         $affectedRows += $referrerFK->save($con);
    1365:                     }
    1366:                 }
    1367:             }
    1368:
    1369:             if ($this->stocksScheduledForDeletion !== null) {
    1370:                 if (!$this->stocksScheduledForDeletion->isEmpty()) {
    1371:                     StockQuery::create()
    1372:                         ->filterByPrimaryKeys($this->stocksScheduledForDeletion->getPrimaryKeys(false))
    1373:                         ->delete($con);
    1374:                     $this->stocksScheduledForDeletion = null;
    1375:                 }
    1376:             }
    1377:
    1378:             if ($this->collStocks !== null) {
    1379:                 foreach ($this->collStocks as $referrerFK) {
    1380:                     if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
    1381:                         $affectedRows += $referrerFK->save($con);
    1382:                     }
    1383:                 }
    1384:             }
    1385:
    1386:             if ($this->contentAssocsScheduledForDeletion !== null) {
    1387:                 if (!$this->contentAssocsScheduledForDeletion->isEmpty()) {
    1388:                     foreach ($this->contentAssocsScheduledForDeletion as $contentAssoc) {
    1389:                         // need to save related object because we set the relation to null
    1390:                         $contentAssoc->save($con);
    1391:                     }
    1392:                     $this->contentAssocsScheduledForDeletion = null;
    1393:                 }
    1394:             }
    1395:
    1396:             if ($this->collContentAssocs !== null) {
    1397:                 foreach ($this->collContentAssocs as $referrerFK) {
    1398:                     if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
    1399:                         $affectedRows += $referrerFK->save($con);
    1400:                     }
    1401:                 }
    1402:             }
    1403:
    1404:             if ($this->imagesScheduledForDeletion !== null) {
    1405:                 if (!$this->imagesScheduledForDeletion->isEmpty()) {
    1406:                     foreach ($this->imagesScheduledForDeletion as $image) {
    1407:                         // need to save related object because we set the relation to null
    1408:                         $image->save($con);
    1409:                     }
    1410:                     $this->imagesScheduledForDeletion = null;
    1411:                 }
    1412:             }
    1413:
    1414:             if ($this->collImages !== null) {
    1415:                 foreach ($this->collImages as $referrerFK) {
    1416:                     if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
    1417:                         $affectedRows += $referrerFK->save($con);
    1418:                     }
    1419:                 }
    1420:             }
    1421:
    1422:             if ($this->documentsScheduledForDeletion !== null) {
    1423:                 if (!$this->documentsScheduledForDeletion->isEmpty()) {
    1424:                     foreach ($this->documentsScheduledForDeletion as $document) {
    1425:                         // need to save related object because we set the relation to null
    1426:                         $document->save($con);
    1427:                     }
    1428:                     $this->documentsScheduledForDeletion = null;
    1429:                 }
    1430:             }
    1431:
    1432:             if ($this->collDocuments !== null) {
    1433:                 foreach ($this->collDocuments as $referrerFK) {
    1434:                     if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
    1435:                         $affectedRows += $referrerFK->save($con);
    1436:                     }
    1437:                 }
    1438:             }
    1439:
    1440:             if ($this->accessorysRelatedByProductIdScheduledForDeletion !== null) {
    1441:                 if (!$this->accessorysRelatedByProductIdScheduledForDeletion->isEmpty()) {
    1442:                     AccessoryQuery::create()
    1443:                         ->filterByPrimaryKeys($this->accessorysRelatedByProductIdScheduledForDeletion->getPrimaryKeys(false))
    1444:                         ->delete($con);
    1445:                     $this->accessorysRelatedByProductIdScheduledForDeletion = null;
    1446:                 }
    1447:             }
    1448:
    1449:             if ($this->collAccessorysRelatedByProductId !== null) {
    1450:                 foreach ($this->collAccessorysRelatedByProductId as $referrerFK) {
    1451:                     if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
    1452:                         $affectedRows += $referrerFK->save($con);
    1453:                     }
    1454:                 }
    1455:             }
    1456:
    1457:             if ($this->accessorysRelatedByAccessoryScheduledForDeletion !== null) {
    1458:                 if (!$this->accessorysRelatedByAccessoryScheduledForDeletion->isEmpty()) {
    1459:                     AccessoryQuery::create()
    1460:                         ->filterByPrimaryKeys($this->accessorysRelatedByAccessoryScheduledForDeletion->getPrimaryKeys(false))
    1461:                         ->delete($con);
    1462:                     $this->accessorysRelatedByAccessoryScheduledForDeletion = null;
    1463:                 }
    1464:             }
    1465:
    1466:             if ($this->collAccessorysRelatedByAccessory !== null) {
    1467:                 foreach ($this->collAccessorysRelatedByAccessory as $referrerFK) {
    1468:                     if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
    1469:                         $affectedRows += $referrerFK->save($con);
    1470:                     }
    1471:                 }
    1472:             }
    1473:
    1474:             if ($this->rewritingsScheduledForDeletion !== null) {
    1475:                 if (!$this->rewritingsScheduledForDeletion->isEmpty()) {
    1476:                     foreach ($this->rewritingsScheduledForDeletion as $rewriting) {
    1477:                         // need to save related object because we set the relation to null
    1478:                         $rewriting->save($con);
    1479:                     }
    1480:                     $this->rewritingsScheduledForDeletion = null;
    1481:                 }
    1482:             }
    1483:
    1484:             if ($this->collRewritings !== null) {
    1485:                 foreach ($this->collRewritings as $referrerFK) {
    1486:                     if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
    1487:                         $affectedRows += $referrerFK->save($con);
    1488:                     }
    1489:                 }
    1490:             }
    1491:
    1492:             if ($this->productI18nsScheduledForDeletion !== null) {
    1493:                 if (!$this->productI18nsScheduledForDeletion->isEmpty()) {
    1494:                     ProductI18nQuery::create()
    1495:                         ->filterByPrimaryKeys($this->productI18nsScheduledForDeletion->getPrimaryKeys(false))
    1496:                         ->delete($con);
    1497:                     $this->productI18nsScheduledForDeletion = null;
    1498:                 }
    1499:             }
    1500:
    1501:             if ($this->collProductI18ns !== null) {
    1502:                 foreach ($this->collProductI18ns as $referrerFK) {
    1503:                     if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
    1504:                         $affectedRows += $referrerFK->save($con);
    1505:                     }
    1506:                 }
    1507:             }
    1508:
    1509:             if ($this->productVersionsScheduledForDeletion !== null) {
    1510:                 if (!$this->productVersionsScheduledForDeletion->isEmpty()) {
    1511:                     ProductVersionQuery::create()
    1512:                         ->filterByPrimaryKeys($this->productVersionsScheduledForDeletion->getPrimaryKeys(false))
    1513:                         ->delete($con);
    1514:                     $this->productVersionsScheduledForDeletion = null;
    1515:                 }
    1516:             }
    1517:
    1518:             if ($this->collProductVersions !== null) {
    1519:                 foreach ($this->collProductVersions as $referrerFK) {
    1520:                     if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) {
    1521:                         $affectedRows += $referrerFK->save($con);
    1522:                     }
    1523:                 }
    1524:             }
    1525:
    1526:             $this->alreadyInSave = false;
    1527:
    1528:         }
    1529:
    1530:         return $affectedRows;
    1531:     } // doSave()
    1532:
    1533:     /**
    1534:      * Insert the row in the database.
    1535:      *
    1536:      * @param PropelPDO $con
    1537:      *
    1538:      * @throws PropelException
    1539:      * @see        doSave()
    1540:      */
    1541:     protected function doInsert(PropelPDO $con)
    1542:     {
    1543:         $modifiedColumns = array();
    1544:         $index = 0;
    1545:
    1546:         $this->modifiedColumns[] = ProductPeer::ID;
    1547:         if (null !== $this->id) {
    1548:             throw new PropelException('Cannot insert a value for auto-increment primary key (' . ProductPeer::ID . ')');
    1549:         }
    1550:
    1551:          // check the columns in natural order for more readable SQL queries
    1552:         if ($this->isColumnModified(ProductPeer::ID)) {
    1553:             $modifiedColumns[':p' . $index++]  = '`id`';
    1554:         }
    1555:         if ($this->isColumnModified(ProductPeer::TAX_RULE_ID)) {
    1556:             $modifiedColumns[':p' . $index++]  = '`tax_rule_id`';
    1557:         }
    1558:         if ($this->isColumnModified(ProductPeer::REF)) {
    1559:             $modifiedColumns[':p' . $index++]  = '`ref`';
    1560:         }
    1561:         if ($this->isColumnModified(ProductPeer::PRICE)) {
    1562:             $modifiedColumns[':p' . $index++]  = '`price`';
    1563:         }
    1564:         if ($this->isColumnModified(ProductPeer::PRICE2)) {
    1565:             $modifiedColumns[':p' . $index++]  = '`price2`';
    1566:         }
    1567:         if ($this->isColumnModified(ProductPeer::ECOTAX)) {
    1568:             $modifiedColumns[':p' . $index++]  = '`ecotax`';
    1569:         }
    1570:         if ($this->isColumnModified(ProductPeer::NEWNESS)) {
    1571:             $modifiedColumns[':p' . $index++]  = '`newness`';
    1572:         }
    1573:         if ($this->isColumnModified(ProductPeer::PROMO)) {
    1574:             $modifiedColumns[':p' . $index++]  = '`promo`';
    1575:         }
    1576:         if ($this->isColumnModified(ProductPeer::STOCK)) {
    1577:             $modifiedColumns[':p' . $index++]  = '`stock`';
    1578:         }
    1579:         if ($this->isColumnModified(ProductPeer::VISIBLE)) {
    1580:             $modifiedColumns[':p' . $index++]  = '`visible`';
    1581:         }
    1582:         if ($this->isColumnModified(ProductPeer::WEIGHT)) {
    1583:             $modifiedColumns[':p' . $index++]  = '`weight`';
    1584:         }
    1585:         if ($this->isColumnModified(ProductPeer::POSITION)) {
    1586:             $modifiedColumns[':p' . $index++]  = '`position`';
    1587:         }
    1588:         if ($this->isColumnModified(ProductPeer::CREATED_AT)) {
    1589:             $modifiedColumns[':p' . $index++]  = '`created_at`';
    1590:         }
    1591:         if ($this->isColumnModified(ProductPeer::UPDATED_AT)) {
    1592:             $modifiedColumns[':p' . $index++]  = '`updated_at`';
    1593:         }
    1594:         if ($this->isColumnModified(ProductPeer::VERSION)) {
    1595:             $modifiedColumns[':p' . $index++]  = '`version`';
    1596:         }
    1597:         if ($this->isColumnModified(ProductPeer::VERSION_CREATED_AT)) {
    1598:             $modifiedColumns[':p' . $index++]  = '`version_created_at`';
    1599:         }
    1600:         if ($this->isColumnModified(ProductPeer::VERSION_CREATED_BY)) {
    1601:             $modifiedColumns[':p' . $index++]  = '`version_created_by`';
    1602:         }
    1603:
    1604:         $sql = sprintf(
    1605:             'INSERT INTO `product` (%s) VALUES (%s)',
    1606:             implode(', ', $modifiedColumns),
    1607:             implode(', ', array_keys($modifiedColumns))
    1608:         );
    1609:
    1610:         try {
    1611:             $stmt = $con->prepare($sql);
    1612:             foreach ($modifiedColumns as $identifier => $columnName) {
    1613:                 switch ($columnName) {
    1614:                     case '`id`':
    1615:                         $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT);
    1616:                         break;
    1617:                     case '`tax_rule_id`':
    1618:                         $stmt->bindValue($identifier, $this->tax_rule_id, PDO::PARAM_INT);
    1619:                         break;
    1620:                     case '`ref`':
    1621:                         $stmt->bindValue($identifier, $this->ref, PDO::PARAM_STR);
    1622:                         break;
    1623:                     case '`price`':
    1624:                         $stmt->bindValue($identifier, $this->price, PDO::PARAM_STR);
    1625:                         break;
    1626:                     case '`price2`':
    1627:                         $stmt->bindValue($identifier, $this->price2, PDO::PARAM_STR);
    1628:                         break;
    1629:                     case '`ecotax`':
    1630:                         $stmt->bindValue($identifier, $this->ecotax, PDO::PARAM_STR);
    1631:                         break;
    1632:                     case '`newness`':
    1633:                         $stmt->bindValue($identifier, $this->newness, PDO::PARAM_INT);
    1634:                         break;
    1635:                     case '`promo`':
    1636:                         $stmt->bindValue($identifier, $this->promo, PDO::PARAM_INT);
    1637:                         break;
    1638:                     case '`stock`':
    1639:                         $stmt->bindValue($identifier, $this->stock, PDO::PARAM_INT);
    1640:                         break;
    1641:                     case '`visible`':
    1642:                         $stmt->bindValue($identifier, $this->visible, PDO::PARAM_INT);
    1643:                         break;
    1644:                     case '`weight`':
    1645:                         $stmt->bindValue($identifier, $this->weight, PDO::PARAM_STR);
    1646:                         break;
    1647:                     case '`position`':
    1648:                         $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT);
    1649:                         break;
    1650:                     case '`created_at`':
    1651:                         $stmt->bindValue($identifier, $this->created_at, PDO::PARAM_STR);
    1652:                         break;
    1653:                     case '`updated_at`':
    1654:                         $stmt->bindValue($identifier, $this->updated_at, PDO::PARAM_STR);
    1655:                         break;
    1656:                     case '`version`':
    1657:                         $stmt->bindValue($identifier, $this->version, PDO::PARAM_INT);
    1658:                         break;
    1659:                     case '`version_created_at`':
    1660:                         $stmt->bindValue($identifier, $this->version_created_at, PDO::PARAM_STR);
    1661:                         break;
    1662:                     case '`version_created_by`':
    1663:                         $stmt->bindValue($identifier, $this->version_created_by, PDO::PARAM_STR);
    1664:                         break;
    1665:                 }
    1666:             }
    1667:             $stmt->execute();
    1668:         } catch (Exception $e) {
    1669:             Propel::log($e->getMessage(), Propel::LOG_ERR);
    1670:             throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), $e);
    1671:         }
    1672:
    1673:         try {
    1674:             $pk = $con->lastInsertId();
    1675:         } catch (Exception $e) {
    1676:             throw new PropelException('Unable to get autoincrement id.', $e);
    1677:         }
    1678:         $this->setId($pk);
    1679:
    1680:         $this->setNew(false);
    1681:     }
    1682:
    1683:     /**
    1684:      * Update the row in the database.
    1685:      *
    1686:      * @param PropelPDO $con
    1687:      *
    1688:      * @see        doSave()
    1689:      */
    1690:     protected function doUpdate(PropelPDO $con)
    1691:     {
    1692:         $selectCriteria = $this->buildPkeyCriteria();
    1693:         $valuesCriteria = $this->buildCriteria();
    1694:         BasePeer::doUpdate($selectCriteria, $valuesCriteria, $con);
    1695:     }
    1696:
    1697:     /**
    1698:      * Array of ValidationFailed objects.
    1699:      * @var        array ValidationFailed[]
    1700:      */
    1701:     protected $validationFailures = array();
    1702:
    1703:     /**
    1704:      * Gets any ValidationFailed objects that resulted from last call to validate().
    1705:      *
    1706:      *
    1707:      * @return array ValidationFailed[]
    1708:      * @see        validate()
    1709:      */
    1710:     public function getValidationFailures()
    1711:     {
    1712:         return $this->validationFailures;
    1713:     }
    1714:
    1715:     /**
    1716:      * Validates the objects modified field values and all objects related to this table.
    1717:      *
    1718:      * If $columns is either a column name or an array of column names
    1719:      * only those columns are validated.
    1720:      *
    1721:      * @param mixed $columns Column name or an array of column names.
    1722:      * @return boolean Whether all columns pass validation.
    1723:      * @see        doValidate()
    1724:      * @see        getValidationFailures()
    1725:      */
    1726:     public function validate($columns = null)
    1727:     {
    1728:         $res = $this->doValidate($columns);
    1729:         if ($res === true) {
    1730:             $this->validationFailures = array();
    1731:
    1732:             return true;
    1733:         }
    1734:
    1735:         $this->validationFailures = $res;
    1736:
    1737:         return false;
    1738:     }
    1739:
    1740:     /**
    1741:      * This function performs the validation work for complex object models.
    1742:      *
    1743:      * In addition to checking the current object, all related objects will
    1744:      * also be validated.  If all pass then <code>true</code> is returned; otherwise
    1745:      * an aggreagated array of ValidationFailed objects will be returned.
    1746:      *
    1747:      * @param array $columns Array of column names to validate.
    1748:      * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise.
    1749:      */
    1750:     protected function doValidate($columns = null)
    1751:     {
    1752:         if (!$this->alreadyInValidation) {
    1753:             $this->alreadyInValidation = true;
    1754:             $retval = null;
    1755:
    1756:             $failureMap = array();
    1757:
    1758:
    1759:             // We call the validate method on the following object(s) if they
    1760:             // were passed to this object by their coresponding set
    1761:             // method.  This object relates to these object(s) by a
    1762:             // foreign key reference.
    1763:
    1764:             if ($this->aTaxRule !== null) {
    1765:                 if (!$this->aTaxRule->validate($columns)) {
    1766:                     $failureMap = array_merge($failureMap, $this->aTaxRule->getValidationFailures());
    1767:                 }
    1768:             }
    1769:
    1770:
    1771:             if (($retval = ProductPeer::doValidate($this, $columns)) !== true) {
    1772:                 $failureMap = array_merge($failureMap, $retval);
    1773:             }
    1774:
    1775:
    1776:                 if ($this->collProductCategorys !== null) {
    1777:                     foreach ($this->collProductCategorys as $referrerFK) {
    1778:                         if (!$referrerFK->validate($columns)) {
    1779:                             $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
    1780:                         }
    1781:                     }
    1782:                 }
    1783:
    1784:                 if ($this->collFeatureProds !== null) {
    1785:                     foreach ($this->collFeatureProds as $referrerFK) {
    1786:                         if (!$referrerFK->validate($columns)) {
    1787:                             $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
    1788:                         }
    1789:                     }
    1790:                 }
    1791:
    1792:                 if ($this->collStocks !== null) {
    1793:                     foreach ($this->collStocks as $referrerFK) {
    1794:                         if (!$referrerFK->validate($columns)) {
    1795:                             $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
    1796:                         }
    1797:                     }
    1798:                 }
    1799:
    1800:                 if ($this->collContentAssocs !== null) {
    1801:                     foreach ($this->collContentAssocs as $referrerFK) {
    1802:                         if (!$referrerFK->validate($columns)) {
    1803:                             $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
    1804:                         }
    1805:                     }
    1806:                 }
    1807:
    1808:                 if ($this->collImages !== null) {
    1809:                     foreach ($this->collImages as $referrerFK) {
    1810:                         if (!$referrerFK->validate($columns)) {
    1811:                             $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
    1812:                         }
    1813:                     }
    1814:                 }
    1815:
    1816:                 if ($this->collDocuments !== null) {
    1817:                     foreach ($this->collDocuments as $referrerFK) {
    1818:                         if (!$referrerFK->validate($columns)) {
    1819:                             $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
    1820:                         }
    1821:                     }
    1822:                 }
    1823:
    1824:                 if ($this->collAccessorysRelatedByProductId !== null) {
    1825:                     foreach ($this->collAccessorysRelatedByProductId as $referrerFK) {
    1826:                         if (!$referrerFK->validate($columns)) {
    1827:                             $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
    1828:                         }
    1829:                     }
    1830:                 }
    1831:
    1832:                 if ($this->collAccessorysRelatedByAccessory !== null) {
    1833:                     foreach ($this->collAccessorysRelatedByAccessory as $referrerFK) {
    1834:                         if (!$referrerFK->validate($columns)) {
    1835:                             $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
    1836:                         }
    1837:                     }
    1838:                 }
    1839:
    1840:                 if ($this->collRewritings !== null) {
    1841:                     foreach ($this->collRewritings as $referrerFK) {
    1842:                         if (!$referrerFK->validate($columns)) {
    1843:                             $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
    1844:                         }
    1845:                     }
    1846:                 }
    1847:
    1848:                 if ($this->collProductI18ns !== null) {
    1849:                     foreach ($this->collProductI18ns as $referrerFK) {
    1850:                         if (!$referrerFK->validate($columns)) {
    1851:                             $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
    1852:                         }
    1853:                     }
    1854:                 }
    1855:
    1856:                 if ($this->collProductVersions !== null) {
    1857:                     foreach ($this->collProductVersions as $referrerFK) {
    1858:                         if (!$referrerFK->validate($columns)) {
    1859:                             $failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
    1860:                         }
    1861:                     }
    1862:                 }
    1863:
    1864:
    1865:             $this->alreadyInValidation = false;
    1866:         }
    1867:
    1868:         return (!empty($failureMap) ? $failureMap : true);
    1869:     }
    1870:
    1871:     /**
    1872:      * Retrieves a field from the object by name passed in as a string.
    1873:      *
    1874:      * @param string $name name
    1875:      * @param string $type The type of fieldname the $name is of:
    1876:      *               one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
    1877:      *               BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM.
    1878:      *               Defaults to BasePeer::TYPE_PHPNAME
    1879:      * @return mixed Value of field.
    1880:      */
    1881:     public function getByName($name, $type = BasePeer::TYPE_PHPNAME)
    1882:     {
    1883:         $pos = ProductPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
    1884:         $field = $this->getByPosition($pos);
    1885:
    1886:         return $field;
    1887:     }
    1888:
    1889:     /**
    1890:      * Retrieves a field from the object by Position as specified in the xml schema.
    1891:      * Zero-based.
    1892:      *
    1893:      * @param int $pos position in xml schema
    1894:      * @return mixed Value of field at $pos
    1895:      */
    1896:     public function getByPosition($pos)
    1897:     {
    1898:         switch ($pos) {
    1899:             case 0:
    1900:                 return $this->getId();
    1901:                 break;
    1902:             case 1:
    1903:                 return $this->getTaxRuleId();
    1904:                 break;
    1905:             case 2:
    1906:                 return $this->getRef();
    1907:                 break;
    1908:             case 3:
    1909:                 return $this->getPrice();
    1910:                 break;
    1911:             case 4:
    1912:                 return $this->getPrice2();
    1913:                 break;
    1914:             case 5:
    1915:                 return $this->getEcotax();
    1916:                 break;
    1917:             case 6:
    1918:                 return $this->getNewness();
    1919:                 break;
    1920:             case 7:
    1921:                 return $this->getPromo();
    1922:                 break;
    1923:             case 8:
    1924:                 return $this->getStock();
    1925:                 break;
    1926:             case 9:
    1927:                 return $this->getVisible();
    1928:                 break;
    1929:             case 10:
    1930:                 return $this->getWeight();
    1931:                 break;
    1932:             case 11:
    1933:                 return $this->getPosition();
    1934:                 break;
    1935:             case 12:
    1936:                 return $this->getCreatedAt();
    1937:                 break;
    1938:             case 13:
    1939:                 return $this->getUpdatedAt();
    1940:                 break;
    1941:             case 14:
    1942:                 return $this->getVersion();
    1943:                 break;
    1944:             case 15:
    1945:                 return $this->getVersionCreatedAt();
    1946:                 break;
    1947:             case 16:
    1948:                 return $this->getVersionCreatedBy();
    1949:                 break;
    1950:             default:
    1951:                 return null;
    1952:                 break;
    1953:         } // switch()
    1954:     }
    1955:
    1956:     /**
    1957:      * Exports the object as an array.
    1958:      *
    1959:      * You can specify the key type of the array by passing one of the class
    1960:      * type constants.
    1961:      *
    1962:      * @param     string  $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME,
    1963:      *                    BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM.
    1964:      *                    Defaults to BasePeer::TYPE_PHPNAME.
    1965:      * @param     boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to true.
    1966:      * @param     array $alreadyDumpedObjects List of objects to skip to avoid recursion
    1967:      * @param     boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE.
    1968:      *
    1969:      * @return array an associative array containing the field names (as keys) and field values
    1970:      */
    1971:     public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false)
    1972:     {
    1973:         if (isset($alreadyDumpedObjects['Product'][$this->getPrimaryKey()])) {
    1974:             return '*RECURSION*';
    1975:         }
    1976:         $alreadyDumpedObjects['Product'][$this->getPrimaryKey()] = true;
    1977:         $keys = ProductPeer::getFieldNames($keyType);
    1978:         $result = array(
    1979:             $keys[0] => $this->getId(),
    1980:             $keys[1] => $this->getTaxRuleId(),
    1981:             $keys[2] => $this->getRef(),
    1982:             $keys[3] => $this->getPrice(),
    1983:             $keys[4] => $this->getPrice2(),
    1984:             $keys[5] => $this->getEcotax(),
    1985:             $keys[6] => $this->getNewness(),
    1986:             $keys[7] => $this->getPromo(),
    1987:             $keys[8] => $this->getStock(),
    1988:             $keys[9] => $this->getVisible(),
    1989:             $keys[10] => $this->getWeight(),
    1990:             $keys[11] => $this->getPosition(),
    1991:             $keys[12] => $this->getCreatedAt(),
    1992:             $keys[13] => $this->getUpdatedAt(),
    1993:             $keys[14] => $this->getVersion(),
    1994:             $keys[15] => $this->getVersionCreatedAt(),
    1995:             $keys[16] => $this->getVersionCreatedBy(),
    1996:         );
    1997:         if ($includeForeignObjects) {
    1998:             if (null !== $this->aTaxRule) {
    1999:                 $result['TaxRule'] = $this->aTaxRule->toArray($keyType, $includeLazyLoadColumns,  $alreadyDumpedObjects, true);
    2000:             }
    2001:             if (null !== $this->collProductCategorys) {
    2002:                 $result['ProductCategorys'] = $this->collProductCategorys->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
    2003:             }
    2004:             if (null !== $this->collFeatureProds) {
    2005:                 $result['FeatureProds'] = $this->collFeatureProds->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
    2006:             }
    2007:             if (null !== $this->collStocks) {
    2008:                 $result['Stocks'] = $this->collStocks->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
    2009:             }
    2010:             if (null !== $this->collContentAssocs) {
    2011:                 $result['ContentAssocs'] = $this->collContentAssocs->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
    2012:             }
    2013:             if (null !== $this->collImages) {
    2014:                 $result['Images'] = $this->collImages->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
    2015:             }
    2016:             if (null !== $this->collDocuments) {
    2017:                 $result['Documents'] = $this->collDocuments->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
    2018:             }
    2019:             if (null !== $this->collAccessorysRelatedByProductId) {
    2020:                 $result['AccessorysRelatedByProductId'] = $this->collAccessorysRelatedByProductId->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
    2021:             }
    2022:             if (null !== $this->collAccessorysRelatedByAccessory) {
    2023:                 $result['AccessorysRelatedByAccessory'] = $this->collAccessorysRelatedByAccessory->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
    2024:             }
    2025:             if (null !== $this->collRewritings) {
    2026:                 $result['Rewritings'] = $this->collRewritings->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
    2027:             }
    2028:             if (null !== $this->collProductI18ns) {
    2029:                 $result['ProductI18ns'] = $this->collProductI18ns->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
    2030:             }
    2031:             if (null !== $this->collProductVersions) {
    2032:                 $result['ProductVersions'] = $this->collProductVersions->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects);
    2033:             }
    2034:         }
    2035:
    2036:         return $result;
    2037:     }
    2038:
    2039:     /**
    2040:      * Sets a field from the object by name passed in as a string.
    2041:      *
    2042:      * @param string $name peer name
    2043:      * @param mixed $value field value
    2044:      * @param string $type The type of fieldname the $name is of:
    2045:      *                     one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
    2046:      *                     BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM.
    2047:      *                     Defaults to BasePeer::TYPE_PHPNAME
    2048:      * @return void
    2049:      */
    2050:     public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME)
    2051:     {
    2052:         $pos = ProductPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
    2053:
    2054:         $this->setByPosition($pos, $value);
    2055:     }
    2056:
    2057:     /**
    2058:      * Sets a field from the object by Position as specified in the xml schema.
    2059:      * Zero-based.
    2060:      *
    2061:      * @param int $pos position in xml schema
    2062:      * @param mixed $value field value
    2063:      * @return void
    2064:      */
    2065:     public function setByPosition($pos, $value)
    2066:     {
    2067:         switch ($pos) {
    2068:             case 0:
    2069:                 $this->setId($value);
    2070:                 break;
    2071:             case 1:
    2072:                 $this->setTaxRuleId($value);
    2073:                 break;
    2074:             case 2:
    2075:                 $this->setRef($value);
    2076:                 break;
    2077:             case 3:
    2078:                 $this->setPrice($value);
    2079:                 break;
    2080:             case 4:
    2081:                 $this->setPrice2($value);
    2082:                 break;
    2083:             case 5:
    2084:                 $this->setEcotax($value);
    2085:                 break;
    2086:             case 6:
    2087:                 $this->setNewness($value);
    2088:                 break;
    2089:             case 7:
    2090:                 $this->setPromo($value);
    2091:                 break;
    2092:             case 8:
    2093:                 $this->setStock($value);
    2094:                 break;
    2095:             case 9:
    2096:                 $this->setVisible($value);
    2097:                 break;
    2098:             case 10:
    2099:                 $this->setWeight($value);
    2100:                 break;
    2101:             case 11:
    2102:                 $this->setPosition($value);
    2103:                 break;
    2104:             case 12:
    2105:                 $this->setCreatedAt($value);
    2106:                 break;
    2107:             case 13:
    2108:                 $this->setUpdatedAt($value);
    2109:                 break;
    2110:             case 14:
    2111:                 $this->setVersion($value);
    2112:                 break;
    2113:             case 15:
    2114:                 $this->setVersionCreatedAt($value);
    2115:                 break;
    2116:             case 16:
    2117:                 $this->setVersionCreatedBy($value);
    2118:                 break;
    2119:         } // switch()
    2120:     }
    2121:
    2122:     /**
    2123:      * Populates the object using an array.
    2124:      *
    2125:      * This is particularly useful when populating an object from one of the
    2126:      * request arrays (e.g. $_POST).  This method goes through the column
    2127:      * names, checking to see whether a matching key exists in populated
    2128:      * array. If so the setByName() method is called for that column.
    2129:      *
    2130:      * You can specify the key type of the array by additionally passing one
    2131:      * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME,
    2132:      * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM.
    2133:      * The default key type is the column's BasePeer::TYPE_PHPNAME
    2134:      *
    2135:      * @param array  $arr     An array to populate the object from.
    2136:      * @param string $keyType The type of keys the array uses.
    2137:      * @return void
    2138:      */
    2139:     public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME)
    2140:     {
    2141:         $keys = ProductPeer::getFieldNames($keyType);
    2142:
    2143:         if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]);
    2144:         if (array_key_exists($keys[1], $arr)) $this->setTaxRuleId($arr[$keys[1]]);
    2145:         if (array_key_exists($keys[2], $arr)) $this->setRef($arr[$keys[2]]);
    2146:         if (array_key_exists($keys[3], $arr)) $this->setPrice($arr[$keys[3]]);
    2147:         if (array_key_exists($keys[4], $arr)) $this->setPrice2($arr[$keys[4]]);
    2148:         if (array_key_exists($keys[5], $arr)) $this->setEcotax($arr[$keys[5]]);
    2149:         if (array_key_exists($keys[6], $arr)) $this->setNewness($arr[$keys[6]]);
    2150:         if (array_key_exists($keys[7], $arr)) $this->setPromo($arr[$keys[7]]);
    2151:         if (array_key_exists($keys[8], $arr)) $this->setStock($arr[$keys[8]]);
    2152:         if (array_key_exists($keys[9], $arr)) $this->setVisible($arr[$keys[9]]);
    2153:         if (array_key_exists($keys[10], $arr)) $this->setWeight($arr[$keys[10]]);
    2154:         if (array_key_exists($keys[11], $arr)) $this->setPosition($arr[$keys[11]]);
    2155:         if (array_key_exists($keys[12], $arr)) $this->setCreatedAt($arr[$keys[12]]);
    2156:         if (array_key_exists($keys[13], $arr)) $this->setUpdatedAt($arr[$keys[13]]);
    2157:         if (array_key_exists($keys[14], $arr)) $this->setVersion($arr[$keys[14]]);
    2158:         if (array_key_exists($keys[15], $arr)) $this->setVersionCreatedAt($arr[$keys[15]]);
    2159:         if (array_key_exists($keys[16], $arr)) $this->setVersionCreatedBy($arr[$keys[16]]);
    2160:     }
    2161:
    2162:     /**
    2163:      * Build a Criteria object containing the values of all modified columns in this object.
    2164:      *
    2165:      * @return Criteria The Criteria object containing all modified values.
    2166:      */
    2167:     public function buildCriteria()
    2168:     {
    2169:         $criteria = new Criteria(ProductPeer::DATABASE_NAME);
    2170:
    2171:         if ($this->isColumnModified(ProductPeer::ID)) $criteria->add(ProductPeer::ID, $this->id);
    2172:         if ($this->isColumnModified(ProductPeer::TAX_RULE_ID)) $criteria->add(ProductPeer::TAX_RULE_ID, $this->tax_rule_id);
    2173:         if ($this->isColumnModified(ProductPeer::REF)) $criteria->add(ProductPeer::REF, $this->ref);
    2174:         if ($this->isColumnModified(ProductPeer::PRICE)) $criteria->add(ProductPeer::PRICE, $this->price);
    2175:         if ($this->isColumnModified(ProductPeer::PRICE2)) $criteria->add(ProductPeer::PRICE2, $this->price2);
    2176:         if ($this->isColumnModified(ProductPeer::ECOTAX)) $criteria->add(ProductPeer::ECOTAX, $this->ecotax);
    2177:         if ($this->isColumnModified(ProductPeer::NEWNESS)) $criteria->add(ProductPeer::NEWNESS, $this->newness);
    2178:         if ($this->isColumnModified(ProductPeer::PROMO)) $criteria->add(ProductPeer::PROMO, $this->promo);
    2179:         if ($this->isColumnModified(ProductPeer::STOCK)) $criteria->add(ProductPeer::STOCK, $this->stock);
    2180:         if ($this->isColumnModified(ProductPeer::VISIBLE)) $criteria->add(ProductPeer::VISIBLE, $this->visible);
    2181:         if ($this->isColumnModified(ProductPeer::WEIGHT)) $criteria->add(ProductPeer::WEIGHT, $this->weight);
    2182:         if ($this->isColumnModified(ProductPeer::POSITION)) $criteria->add(ProductPeer::POSITION, $this->position);
    2183:         if ($this->isColumnModified(ProductPeer::CREATED_AT)) $criteria->add(ProductPeer::CREATED_AT, $this->created_at);
    2184:         if ($this->isColumnModified(ProductPeer::UPDATED_AT)) $criteria->add(ProductPeer::UPDATED_AT, $this->updated_at);
    2185:         if ($this->isColumnModified(ProductPeer::VERSION)) $criteria->add(ProductPeer::VERSION, $this->version);
    2186:         if ($this->isColumnModified(ProductPeer::VERSION_CREATED_AT)) $criteria->add(ProductPeer::VERSION_CREATED_AT, $this->version_created_at);
    2187:         if ($this->isColumnModified(ProductPeer::VERSION_CREATED_BY)) $criteria->add(ProductPeer::VERSION_CREATED_BY, $this->version_created_by);
    2188:
    2189:         return $criteria;
    2190:     }
    2191:
    2192:     /**
    2193:      * Builds a Criteria object containing the primary key for this object.
    2194:      *
    2195:      * Unlike buildCriteria() this method includes the primary key values regardless
    2196:      * of whether or not they have been modified.
    2197:      *
    2198:      * @return Criteria The Criteria object containing value(s) for primary key(s).
    2199:      */
    2200:     public function buildPkeyCriteria()
    2201:     {
    2202:         $criteria = new Criteria(ProductPeer::DATABASE_NAME);
    2203:         $criteria->add(ProductPeer::ID, $this->id);
    2204:
    2205:         return $criteria;
    2206:     }
    2207:
    2208:     /**
    2209:      * Returns the primary key for this object (row).
    2210:      * @return int
    2211:      */
    2212:     public function getPrimaryKey()
    2213:     {
    2214:         return $this->getId();
    2215:     }
    2216:
    2217:     /**
    2218:      * Generic method to set the primary key (id column).
    2219:      *
    2220:      * @param  int $key Primary key.
    2221:      * @return void
    2222:      */
    2223:     public function setPrimaryKey($key)
    2224:     {
    2225:         $this->setId($key);
    2226:     }
    2227:
    2228:     /**
    2229:      * Returns true if the primary key for this object is null.
    2230:      * @return boolean
    2231:      */
    2232:     public function isPrimaryKeyNull()
    2233:     {
    2234:
    2235:         return null === $this->getId();
    2236:     }
    2237:
    2238:     /**
    2239:      * Sets contents of passed object to values from current object.
    2240:      *
    2241:      * If desired, this method can also make copies of all associated (fkey referrers)
    2242:      * objects.
    2243:      *
    2244:      * @param object $copyObj An object of Product (or compatible) type.
    2245:      * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row.
    2246:      * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new.
    2247:      * @throws PropelException
    2248:      */
    2249:     public function copyInto($copyObj, $deepCopy = false, $makeNew = true)
    2250:     {
    2251:         $copyObj->setTaxRuleId($this->getTaxRuleId());
    2252:         $copyObj->setRef($this->getRef());
    2253:         $copyObj->setPrice($this->getPrice());
    2254:         $copyObj->setPrice2($this->getPrice2());
    2255:         $copyObj->setEcotax($this->getEcotax());
    2256:         $copyObj->setNewness($this->getNewness());
    2257:         $copyObj->setPromo($this->getPromo());
    2258:         $copyObj->setStock($this->getStock());
    2259:         $copyObj->setVisible($this->getVisible());
    2260:         $copyObj->setWeight($this->getWeight());
    2261:         $copyObj->setPosition($this->getPosition());
    2262:         $copyObj->setCreatedAt($this->getCreatedAt());
    2263:         $copyObj->setUpdatedAt($this->getUpdatedAt());
    2264:         $copyObj->setVersion($this->getVersion());
    2265:         $copyObj->setVersionCreatedAt($this->getVersionCreatedAt());
    2266:         $copyObj->setVersionCreatedBy($this->getVersionCreatedBy());
    2267:
    2268:         if ($deepCopy && !$this->startCopy) {
    2269:             // important: temporarily setNew(false) because this affects the behavior of
    2270:             // the getter/setter methods for fkey referrer objects.
    2271:             $copyObj->setNew(false);
    2272:             // store object hash to prevent cycle
    2273:             $this->startCopy = true;
    2274:
    2275:             foreach ($this->getProductCategorys() as $relObj) {
    2276:                 if ($relObj !== $this) {  // ensure that we don't try to copy a reference to ourselves
    2277:                     $copyObj->addProductCategory($relObj->copy($deepCopy));
    2278:                 }
    2279:             }
    2280:
    2281:             foreach ($this->getFeatureProds() as $relObj) {
    2282:                 if ($relObj !== $this) {  // ensure that we don't try to copy a reference to ourselves
    2283:                     $copyObj->addFeatureProd($relObj->copy($deepCopy));
    2284:                 }
    2285:             }
    2286:
    2287:             foreach ($this->getStocks() as $relObj) {
    2288:                 if ($relObj !== $this) {  // ensure that we don't try to copy a reference to ourselves
    2289:                     $copyObj->addStock($relObj->copy($deepCopy));
    2290:                 }
    2291:             }
    2292:
    2293:             foreach ($this->getContentAssocs() as $relObj) {
    2294:                 if ($relObj !== $this) {  // ensure that we don't try to copy a reference to ourselves
    2295:                     $copyObj->addContentAssoc($relObj->copy($deepCopy));
    2296:                 }
    2297:             }
    2298:
    2299:             foreach ($this->getImages() as $relObj) {
    2300:                 if ($relObj !== $this) {  // ensure that we don't try to copy a reference to ourselves
    2301:                     $copyObj->addImage($relObj->copy($deepCopy));
    2302:                 }
    2303:             }
    2304:
    2305:             foreach ($this->getDocuments() as $relObj) {
    2306:                 if ($relObj !== $this) {  // ensure that we don't try to copy a reference to ourselves
    2307:                     $copyObj->addDocument($relObj->copy($deepCopy));
    2308:                 }
    2309:             }
    2310:
    2311:             foreach ($this->getAccessorysRelatedByProductId() as $relObj) {
    2312:                 if ($relObj !== $this) {  // ensure that we don't try to copy a reference to ourselves
    2313:                     $copyObj->addAccessoryRelatedByProductId($relObj->copy($deepCopy));
    2314:                 }
    2315:             }
    2316:
    2317:             foreach ($this->getAccessorysRelatedByAccessory() as $relObj) {
    2318:                 if ($relObj !== $this) {  // ensure that we don't try to copy a reference to ourselves
    2319:                     $copyObj->addAccessoryRelatedByAccessory($relObj->copy($deepCopy));
    2320:                 }
    2321:             }
    2322:
    2323:             foreach ($this->getRewritings() as $relObj) {
    2324:                 if ($relObj !== $this) {  // ensure that we don't try to copy a reference to ourselves
    2325:                     $copyObj->addRewriting($relObj->copy($deepCopy));
    2326:                 }
    2327:             }
    2328:
    2329:             foreach ($this->getProductI18ns() as $relObj) {
    2330:                 if ($relObj !== $this) {  // ensure that we don't try to copy a reference to ourselves
    2331:                     $copyObj->addProductI18n($relObj->copy($deepCopy));
    2332:                 }
    2333:             }
    2334:
    2335:             foreach ($this->getProductVersions() as $relObj) {
    2336:                 if ($relObj !== $this) {  // ensure that we don't try to copy a reference to ourselves
    2337:                     $copyObj->addProductVersion($relObj->copy($deepCopy));
    2338:                 }
    2339:             }
    2340:
    2341:             //unflag object copy
    2342:             $this->startCopy = false;
    2343:         } // if ($deepCopy)
    2344:
    2345:         if ($makeNew) {
    2346:             $copyObj->setNew(true);
    2347:             $copyObj->setId(NULL); // this is a auto-increment column, so set to default value
    2348:         }
    2349:     }
    2350:
    2351:     /**
    2352:      * Makes a copy of this object that will be inserted as a new row in table when saved.
    2353:      * It creates a new object filling in the simple attributes, but skipping any primary
    2354:      * keys that are defined for the table.
    2355:      *
    2356:      * If desired, this method can also make copies of all associated (fkey referrers)
    2357:      * objects.
    2358:      *
    2359:      * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row.
    2360:      * @return Product Clone of current object.
    2361:      * @throws PropelException
    2362:      */
    2363:     public function copy($deepCopy = false)
    2364:     {
    2365:         // we use get_class(), because this might be a subclass
    2366:         $clazz = get_class($this);
    2367:         $copyObj = new $clazz();
    2368:         $this->copyInto($copyObj, $deepCopy);
    2369:
    2370:         return $copyObj;
    2371:     }
    2372:
    2373:     /**
    2374:      * Returns a peer instance associated with this om.
    2375:      *
    2376:      * Since Peer classes are not to have any instance attributes, this method returns the
    2377:      * same instance for all member of this class. The method could therefore
    2378:      * be static, but this would prevent one from overriding the behavior.
    2379:      *
    2380:      * @return ProductPeer
    2381:      */
    2382:     public function getPeer()
    2383:     {
    2384:         if (self::$peer === null) {
    2385:             self::$peer = new ProductPeer();
    2386:         }
    2387:
    2388:         return self::$peer;
    2389:     }
    2390:
    2391:     /**
    2392:      * Declares an association between this object and a TaxRule object.
    2393:      *
    2394:      * @param             TaxRule $v
    2395:      * @return Product The current object (for fluent API support)
    2396:      * @throws PropelException
    2397:      */
    2398:     public function setTaxRule(TaxRule $v = null)
    2399:     {
    2400:         if ($v === null) {
    2401:             $this->setTaxRuleId(NULL);
    2402:         } else {
    2403:             $this->setTaxRuleId($v->getId());
    2404:         }
    2405:
    2406:         $this->aTaxRule = $v;
    2407:
    2408:         // Add binding for other direction of this n:n relationship.
    2409:         // If this object has already been added to the TaxRule object, it will not be re-added.
    2410:         if ($v !== null) {
    2411:             $v->addProduct($this);
    2412:         }
    2413:
    2414:
    2415:         return $this;
    2416:     }
    2417:
    2418:
    2419:     /**
    2420:      * Get the associated TaxRule object
    2421:      *
    2422:      * @param PropelPDO $con Optional Connection object.
    2423:      * @param $doQuery Executes a query to get the object if required
    2424:      * @return TaxRule The associated TaxRule object.
    2425:      * @throws PropelException
    2426:      */
    2427:     public function getTaxRule(PropelPDO $con = null, $doQuery = true)
    2428:     {
    2429:         if ($this->aTaxRule === null && ($this->tax_rule_id !== null) && $doQuery) {
    2430:             $this->aTaxRule = TaxRuleQuery::create()->findPk($this->tax_rule_id, $con);
    2431:             /* The following can be used additionally to
    2432:                 guarantee the related object contains a reference
    2433:                 to this object.  This level of coupling may, however, be
    2434:                 undesirable since it could result in an only partially populated collection
    2435:                 in the referenced object.
    2436:                 $this->aTaxRule->addProducts($this);
    2437:              */
    2438:         }
    2439:
    2440:         return $this->aTaxRule;
    2441:     }
    2442:
    2443:
    2444:     /**
    2445:      * Initializes a collection based on the name of a relation.
    2446:      * Avoids crafting an 'init[$relationName]s' method name
    2447:      * that wouldn't work when StandardEnglishPluralizer is used.
    2448:      *
    2449:      * @param string $relationName The name of the relation to initialize
    2450:      * @return void
    2451:      */
    2452:     public function initRelation($relationName)
    2453:     {
    2454:         if ('ProductCategory' == $relationName) {
    2455:             $this->initProductCategorys();
    2456:         }
    2457:         if ('FeatureProd' == $relationName) {
    2458:             $this->initFeatureProds();
    2459:         }
    2460:         if ('Stock' == $relationName) {
    2461:             $this->initStocks();
    2462:         }
    2463:         if ('ContentAssoc' == $relationName) {
    2464:             $this->initContentAssocs();
    2465:         }
    2466:         if ('Image' == $relationName) {
    2467:             $this->initImages();
    2468:         }
    2469:         if ('Document' == $relationName) {
    2470:             $this->initDocuments();
    2471:         }
    2472:         if ('AccessoryRelatedByProductId' == $relationName) {
    2473:             $this->initAccessorysRelatedByProductId();
    2474:         }
    2475:         if ('AccessoryRelatedByAccessory' == $relationName) {
    2476:             $this->initAccessorysRelatedByAccessory();
    2477:         }
    2478:         if ('Rewriting' == $relationName) {
    2479:             $this->initRewritings();
    2480:         }
    2481:         if ('ProductI18n' == $relationName) {
    2482:             $this->initProductI18ns();
    2483:         }
    2484:         if ('ProductVersion' == $relationName) {
    2485:             $this->initProductVersions();
    2486:         }
    2487:     }
    2488:
    2489:     /**
    2490:      * Clears out the collProductCategorys collection
    2491:      *
    2492:      * This does not modify the database; however, it will remove any associated objects, causing
    2493:      * them to be refetched by subsequent calls to accessor method.
    2494:      *
    2495:      * @return Product The current object (for fluent API support)
    2496:      * @see        addProductCategorys()
    2497:      */
    2498:     public function clearProductCategorys()
    2499:     {
    2500:         $this->collProductCategorys = null; // important to set this to null since that means it is uninitialized
    2501:         $this->collProductCategorysPartial = null;
    2502:
    2503:         return $this;
    2504:     }
    2505:
    2506:     /**
    2507:      * reset is the collProductCategorys collection loaded partially
    2508:      *
    2509:      * @return void
    2510:      */
    2511:     public function resetPartialProductCategorys($v = true)
    2512:     {
    2513:         $this->collProductCategorysPartial = $v;
    2514:     }
    2515:
    2516:     /**
    2517:      * Initializes the collProductCategorys collection.
    2518:      *
    2519:      * By default this just sets the collProductCategorys collection to an empty array (like clearcollProductCategorys());
    2520:      * however, you may wish to override this method in your stub class to provide setting appropriate
    2521:      * to your application -- for example, setting the initial array to the values stored in database.
    2522:      *
    2523:      * @param boolean $overrideExisting If set to true, the method call initializes
    2524:      *                                        the collection even if it is not empty
    2525:      *
    2526:      * @return void
    2527:      */
    2528:     public function initProductCategorys($overrideExisting = true)
    2529:     {
    2530:         if (null !== $this->collProductCategorys && !$overrideExisting) {
    2531:             return;
    2532:         }
    2533:         $this->collProductCategorys = new PropelObjectCollection();
    2534:         $this->collProductCategorys->setModel('ProductCategory');
    2535:     }
    2536:
    2537:     /**
    2538:      * Gets an array of ProductCategory objects which contain a foreign key that references this object.
    2539:      *
    2540:      * If the $criteria is not null, it is used to always fetch the results from the database.
    2541:      * Otherwise the results are fetched from the database the first time, then cached.
    2542:      * Next time the same method is called without $criteria, the cached collection is returned.
    2543:      * If this Product is new, it will return
    2544:      * an empty collection or the current collection; the criteria is ignored on a new object.
    2545:      *
    2546:      * @param Criteria $criteria optional Criteria object to narrow the query
    2547:      * @param PropelPDO $con optional connection object
    2548:      * @return PropelObjectCollection|ProductCategory[] List of ProductCategory objects
    2549:      * @throws PropelException
    2550:      */
    2551:     public function getProductCategorys($criteria = null, PropelPDO $con = null)
    2552:     {
    2553:         $partial = $this->collProductCategorysPartial && !$this->isNew();
    2554:         if (null === $this->collProductCategorys || null !== $criteria  || $partial) {
    2555:             if ($this->isNew() && null === $this->collProductCategorys) {
    2556:                 // return empty collection
    2557:                 $this->initProductCategorys();
    2558:             } else {
    2559:                 $collProductCategorys = ProductCategoryQuery::create(null, $criteria)
    2560:                     ->filterByProduct($this)
    2561:                     ->find($con);
    2562:                 if (null !== $criteria) {
    2563:                     if (false !== $this->collProductCategorysPartial && count($collProductCategorys)) {
    2564:                       $this->initProductCategorys(false);
    2565:
    2566:                       foreach($collProductCategorys as $obj) {
    2567:                         if (false == $this->collProductCategorys->contains($obj)) {
    2568:                           $this->collProductCategorys->append($obj);
    2569:                         }
    2570:                       }
    2571:
    2572:                       $this->collProductCategorysPartial = true;
    2573:                     }
    2574:
    2575:                     $collProductCategorys->getInternalIterator()->rewind();
    2576:                     return $collProductCategorys;
    2577:                 }
    2578:
    2579:                 if($partial && $this->collProductCategorys) {
    2580:                     foreach($this->collProductCategorys as $obj) {
    2581:                         if($obj->isNew()) {
    2582:                             $collProductCategorys[] = $obj;
    2583:                         }
    2584:                     }
    2585:                 }
    2586:
    2587:                 $this->collProductCategorys = $collProductCategorys;
    2588:                 $this->collProductCategorysPartial = false;
    2589:             }
    2590:         }
    2591:
    2592:         return $this->collProductCategorys;
    2593:     }
    2594:
    2595:     /**
    2596:      * Sets a collection of ProductCategory objects related by a one-to-many relationship
    2597:      * to the current object.
    2598:      * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
    2599:      * and new objects from the given Propel collection.
    2600:      *
    2601:      * @param PropelCollection $productCategorys A Propel collection.
    2602:      * @param PropelPDO $con Optional connection object
    2603:      * @return Product The current object (for fluent API support)
    2604:      */
    2605:     public function setProductCategorys(PropelCollection $productCategorys, PropelPDO $con = null)
    2606:     {
    2607:         $productCategorysToDelete = $this->getProductCategorys(new Criteria(), $con)->diff($productCategorys);
    2608:
    2609:         $this->productCategorysScheduledForDeletion = unserialize(serialize($productCategorysToDelete));
    2610:
    2611:         foreach ($productCategorysToDelete as $productCategoryRemoved) {
    2612:             $productCategoryRemoved->setProduct(null);
    2613:         }
    2614:
    2615:         $this->collProductCategorys = null;
    2616:         foreach ($productCategorys as $productCategory) {
    2617:             $this->addProductCategory($productCategory);
    2618:         }
    2619:
    2620:         $this->collProductCategorys = $productCategorys;
    2621:         $this->collProductCategorysPartial = false;
    2622:
    2623:         return $this;
    2624:     }
    2625:
    2626:     /**
    2627:      * Returns the number of related ProductCategory objects.
    2628:      *
    2629:      * @param Criteria $criteria
    2630:      * @param boolean $distinct
    2631:      * @param PropelPDO $con
    2632:      * @return int             Count of related ProductCategory objects.
    2633:      * @throws PropelException
    2634:      */
    2635:     public function countProductCategorys(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
    2636:     {
    2637:         $partial = $this->collProductCategorysPartial && !$this->isNew();
    2638:         if (null === $this->collProductCategorys || null !== $criteria || $partial) {
    2639:             if ($this->isNew() && null === $this->collProductCategorys) {
    2640:                 return 0;
    2641:             }
    2642:
    2643:             if($partial && !$criteria) {
    2644:                 return count($this->getProductCategorys());
    2645:             }
    2646:             $query = ProductCategoryQuery::create(null, $criteria);
    2647:             if ($distinct) {
    2648:                 $query->distinct();
    2649:             }
    2650:
    2651:             return $query
    2652:                 ->filterByProduct($this)
    2653:                 ->count($con);
    2654:         }
    2655:
    2656:         return count($this->collProductCategorys);
    2657:     }
    2658:
    2659:     /**
    2660:      * Method called to associate a ProductCategory object to this object
    2661:      * through the ProductCategory foreign key attribute.
    2662:      *
    2663:      * @param    ProductCategory $l ProductCategory
    2664:      * @return Product The current object (for fluent API support)
    2665:      */
    2666:     public function addProductCategory(ProductCategory $l)
    2667:     {
    2668:         if ($this->collProductCategorys === null) {
    2669:             $this->initProductCategorys();
    2670:             $this->collProductCategorysPartial = true;
    2671:         }
    2672:         if (!in_array($l, $this->collProductCategorys->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
    2673:             $this->doAddProductCategory($l);
    2674:         }
    2675:
    2676:         return $this;
    2677:     }
    2678:
    2679:     /**
    2680:      * @param   ProductCategory $productCategory The productCategory object to add.
    2681:      */
    2682:     protected function doAddProductCategory($productCategory)
    2683:     {
    2684:         $this->collProductCategorys[]= $productCategory;
    2685:         $productCategory->setProduct($this);
    2686:     }
    2687:
    2688:     /**
    2689:      * @param   ProductCategory $productCategory The productCategory object to remove.
    2690:      * @return Product The current object (for fluent API support)
    2691:      */
    2692:     public function removeProductCategory($productCategory)
    2693:     {
    2694:         if ($this->getProductCategorys()->contains($productCategory)) {
    2695:             $this->collProductCategorys->remove($this->collProductCategorys->search($productCategory));
    2696:             if (null === $this->productCategorysScheduledForDeletion) {
    2697:                 $this->productCategorysScheduledForDeletion = clone $this->collProductCategorys;
    2698:                 $this->productCategorysScheduledForDeletion->clear();
    2699:             }
    2700:             $this->productCategorysScheduledForDeletion[]= clone $productCategory;
    2701:             $productCategory->setProduct(null);
    2702:         }
    2703:
    2704:         return $this;
    2705:     }
    2706:
    2707:
    2708:     /**
    2709:      * If this collection has already been initialized with
    2710:      * an identical criteria, it returns the collection.
    2711:      * Otherwise if this Product is new, it will return
    2712:      * an empty collection; or if this Product has previously
    2713:      * been saved, it will retrieve related ProductCategorys from storage.
    2714:      *
    2715:      * This method is protected by default in order to keep the public
    2716:      * api reasonable.  You can provide public methods for those you
    2717:      * actually need in Product.
    2718:      *
    2719:      * @param Criteria $criteria optional Criteria object to narrow the query
    2720:      * @param PropelPDO $con optional connection object
    2721:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    2722:      * @return PropelObjectCollection|ProductCategory[] List of ProductCategory objects
    2723:      */
    2724:     public function getProductCategorysJoinCategory($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    2725:     {
    2726:         $query = ProductCategoryQuery::create(null, $criteria);
    2727:         $query->joinWith('Category', $join_behavior);
    2728:
    2729:         return $this->getProductCategorys($query, $con);
    2730:     }
    2731:
    2732:     /**
    2733:      * Clears out the collFeatureProds collection
    2734:      *
    2735:      * This does not modify the database; however, it will remove any associated objects, causing
    2736:      * them to be refetched by subsequent calls to accessor method.
    2737:      *
    2738:      * @return Product The current object (for fluent API support)
    2739:      * @see        addFeatureProds()
    2740:      */
    2741:     public function clearFeatureProds()
    2742:     {
    2743:         $this->collFeatureProds = null; // important to set this to null since that means it is uninitialized
    2744:         $this->collFeatureProdsPartial = null;
    2745:
    2746:         return $this;
    2747:     }
    2748:
    2749:     /**
    2750:      * reset is the collFeatureProds collection loaded partially
    2751:      *
    2752:      * @return void
    2753:      */
    2754:     public function resetPartialFeatureProds($v = true)
    2755:     {
    2756:         $this->collFeatureProdsPartial = $v;
    2757:     }
    2758:
    2759:     /**
    2760:      * Initializes the collFeatureProds collection.
    2761:      *
    2762:      * By default this just sets the collFeatureProds collection to an empty array (like clearcollFeatureProds());
    2763:      * however, you may wish to override this method in your stub class to provide setting appropriate
    2764:      * to your application -- for example, setting the initial array to the values stored in database.
    2765:      *
    2766:      * @param boolean $overrideExisting If set to true, the method call initializes
    2767:      *                                        the collection even if it is not empty
    2768:      *
    2769:      * @return void
    2770:      */
    2771:     public function initFeatureProds($overrideExisting = true)
    2772:     {
    2773:         if (null !== $this->collFeatureProds && !$overrideExisting) {
    2774:             return;
    2775:         }
    2776:         $this->collFeatureProds = new PropelObjectCollection();
    2777:         $this->collFeatureProds->setModel('FeatureProd');
    2778:     }
    2779:
    2780:     /**
    2781:      * Gets an array of FeatureProd objects which contain a foreign key that references this object.
    2782:      *
    2783:      * If the $criteria is not null, it is used to always fetch the results from the database.
    2784:      * Otherwise the results are fetched from the database the first time, then cached.
    2785:      * Next time the same method is called without $criteria, the cached collection is returned.
    2786:      * If this Product is new, it will return
    2787:      * an empty collection or the current collection; the criteria is ignored on a new object.
    2788:      *
    2789:      * @param Criteria $criteria optional Criteria object to narrow the query
    2790:      * @param PropelPDO $con optional connection object
    2791:      * @return PropelObjectCollection|FeatureProd[] List of FeatureProd objects
    2792:      * @throws PropelException
    2793:      */
    2794:     public function getFeatureProds($criteria = null, PropelPDO $con = null)
    2795:     {
    2796:         $partial = $this->collFeatureProdsPartial && !$this->isNew();
    2797:         if (null === $this->collFeatureProds || null !== $criteria  || $partial) {
    2798:             if ($this->isNew() && null === $this->collFeatureProds) {
    2799:                 // return empty collection
    2800:                 $this->initFeatureProds();
    2801:             } else {
    2802:                 $collFeatureProds = FeatureProdQuery::create(null, $criteria)
    2803:                     ->filterByProduct($this)
    2804:                     ->find($con);
    2805:                 if (null !== $criteria) {
    2806:                     if (false !== $this->collFeatureProdsPartial && count($collFeatureProds)) {
    2807:                       $this->initFeatureProds(false);
    2808:
    2809:                       foreach($collFeatureProds as $obj) {
    2810:                         if (false == $this->collFeatureProds->contains($obj)) {
    2811:                           $this->collFeatureProds->append($obj);
    2812:                         }
    2813:                       }
    2814:
    2815:                       $this->collFeatureProdsPartial = true;
    2816:                     }
    2817:
    2818:                     $collFeatureProds->getInternalIterator()->rewind();
    2819:                     return $collFeatureProds;
    2820:                 }
    2821:
    2822:                 if($partial && $this->collFeatureProds) {
    2823:                     foreach($this->collFeatureProds as $obj) {
    2824:                         if($obj->isNew()) {
    2825:                             $collFeatureProds[] = $obj;
    2826:                         }
    2827:                     }
    2828:                 }
    2829:
    2830:                 $this->collFeatureProds = $collFeatureProds;
    2831:                 $this->collFeatureProdsPartial = false;
    2832:             }
    2833:         }
    2834:
    2835:         return $this->collFeatureProds;
    2836:     }
    2837:
    2838:     /**
    2839:      * Sets a collection of FeatureProd objects related by a one-to-many relationship
    2840:      * to the current object.
    2841:      * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
    2842:      * and new objects from the given Propel collection.
    2843:      *
    2844:      * @param PropelCollection $featureProds A Propel collection.
    2845:      * @param PropelPDO $con Optional connection object
    2846:      * @return Product The current object (for fluent API support)
    2847:      */
    2848:     public function setFeatureProds(PropelCollection $featureProds, PropelPDO $con = null)
    2849:     {
    2850:         $featureProdsToDelete = $this->getFeatureProds(new Criteria(), $con)->diff($featureProds);
    2851:
    2852:         $this->featureProdsScheduledForDeletion = unserialize(serialize($featureProdsToDelete));
    2853:
    2854:         foreach ($featureProdsToDelete as $featureProdRemoved) {
    2855:             $featureProdRemoved->setProduct(null);
    2856:         }
    2857:
    2858:         $this->collFeatureProds = null;
    2859:         foreach ($featureProds as $featureProd) {
    2860:             $this->addFeatureProd($featureProd);
    2861:         }
    2862:
    2863:         $this->collFeatureProds = $featureProds;
    2864:         $this->collFeatureProdsPartial = false;
    2865:
    2866:         return $this;
    2867:     }
    2868:
    2869:     /**
    2870:      * Returns the number of related FeatureProd objects.
    2871:      *
    2872:      * @param Criteria $criteria
    2873:      * @param boolean $distinct
    2874:      * @param PropelPDO $con
    2875:      * @return int             Count of related FeatureProd objects.
    2876:      * @throws PropelException
    2877:      */
    2878:     public function countFeatureProds(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
    2879:     {
    2880:         $partial = $this->collFeatureProdsPartial && !$this->isNew();
    2881:         if (null === $this->collFeatureProds || null !== $criteria || $partial) {
    2882:             if ($this->isNew() && null === $this->collFeatureProds) {
    2883:                 return 0;
    2884:             }
    2885:
    2886:             if($partial && !$criteria) {
    2887:                 return count($this->getFeatureProds());
    2888:             }
    2889:             $query = FeatureProdQuery::create(null, $criteria);
    2890:             if ($distinct) {
    2891:                 $query->distinct();
    2892:             }
    2893:
    2894:             return $query
    2895:                 ->filterByProduct($this)
    2896:                 ->count($con);
    2897:         }
    2898:
    2899:         return count($this->collFeatureProds);
    2900:     }
    2901:
    2902:     /**
    2903:      * Method called to associate a FeatureProd object to this object
    2904:      * through the FeatureProd foreign key attribute.
    2905:      *
    2906:      * @param    FeatureProd $l FeatureProd
    2907:      * @return Product The current object (for fluent API support)
    2908:      */
    2909:     public function addFeatureProd(FeatureProd $l)
    2910:     {
    2911:         if ($this->collFeatureProds === null) {
    2912:             $this->initFeatureProds();
    2913:             $this->collFeatureProdsPartial = true;
    2914:         }
    2915:         if (!in_array($l, $this->collFeatureProds->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
    2916:             $this->doAddFeatureProd($l);
    2917:         }
    2918:
    2919:         return $this;
    2920:     }
    2921:
    2922:     /**
    2923:      * @param   FeatureProd $featureProd The featureProd object to add.
    2924:      */
    2925:     protected function doAddFeatureProd($featureProd)
    2926:     {
    2927:         $this->collFeatureProds[]= $featureProd;
    2928:         $featureProd->setProduct($this);
    2929:     }
    2930:
    2931:     /**
    2932:      * @param   FeatureProd $featureProd The featureProd object to remove.
    2933:      * @return Product The current object (for fluent API support)
    2934:      */
    2935:     public function removeFeatureProd($featureProd)
    2936:     {
    2937:         if ($this->getFeatureProds()->contains($featureProd)) {
    2938:             $this->collFeatureProds->remove($this->collFeatureProds->search($featureProd));
    2939:             if (null === $this->featureProdsScheduledForDeletion) {
    2940:                 $this->featureProdsScheduledForDeletion = clone $this->collFeatureProds;
    2941:                 $this->featureProdsScheduledForDeletion->clear();
    2942:             }
    2943:             $this->featureProdsScheduledForDeletion[]= clone $featureProd;
    2944:             $featureProd->setProduct(null);
    2945:         }
    2946:
    2947:         return $this;
    2948:     }
    2949:
    2950:
    2951:     /**
    2952:      * If this collection has already been initialized with
    2953:      * an identical criteria, it returns the collection.
    2954:      * Otherwise if this Product is new, it will return
    2955:      * an empty collection; or if this Product has previously
    2956:      * been saved, it will retrieve related FeatureProds from storage.
    2957:      *
    2958:      * This method is protected by default in order to keep the public
    2959:      * api reasonable.  You can provide public methods for those you
    2960:      * actually need in Product.
    2961:      *
    2962:      * @param Criteria $criteria optional Criteria object to narrow the query
    2963:      * @param PropelPDO $con optional connection object
    2964:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    2965:      * @return PropelObjectCollection|FeatureProd[] List of FeatureProd objects
    2966:      */
    2967:     public function getFeatureProdsJoinFeature($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    2968:     {
    2969:         $query = FeatureProdQuery::create(null, $criteria);
    2970:         $query->joinWith('Feature', $join_behavior);
    2971:
    2972:         return $this->getFeatureProds($query, $con);
    2973:     }
    2974:
    2975:
    2976:     /**
    2977:      * If this collection has already been initialized with
    2978:      * an identical criteria, it returns the collection.
    2979:      * Otherwise if this Product is new, it will return
    2980:      * an empty collection; or if this Product has previously
    2981:      * been saved, it will retrieve related FeatureProds from storage.
    2982:      *
    2983:      * This method is protected by default in order to keep the public
    2984:      * api reasonable.  You can provide public methods for those you
    2985:      * actually need in Product.
    2986:      *
    2987:      * @param Criteria $criteria optional Criteria object to narrow the query
    2988:      * @param PropelPDO $con optional connection object
    2989:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    2990:      * @return PropelObjectCollection|FeatureProd[] List of FeatureProd objects
    2991:      */
    2992:     public function getFeatureProdsJoinFeatureAv($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    2993:     {
    2994:         $query = FeatureProdQuery::create(null, $criteria);
    2995:         $query->joinWith('FeatureAv', $join_behavior);
    2996:
    2997:         return $this->getFeatureProds($query, $con);
    2998:     }
    2999:
    3000:     /**
    3001:      * Clears out the collStocks collection
    3002:      *
    3003:      * This does not modify the database; however, it will remove any associated objects, causing
    3004:      * them to be refetched by subsequent calls to accessor method.
    3005:      *
    3006:      * @return Product The current object (for fluent API support)
    3007:      * @see        addStocks()
    3008:      */
    3009:     public function clearStocks()
    3010:     {
    3011:         $this->collStocks = null; // important to set this to null since that means it is uninitialized
    3012:         $this->collStocksPartial = null;
    3013:
    3014:         return $this;
    3015:     }
    3016:
    3017:     /**
    3018:      * reset is the collStocks collection loaded partially
    3019:      *
    3020:      * @return void
    3021:      */
    3022:     public function resetPartialStocks($v = true)
    3023:     {
    3024:         $this->collStocksPartial = $v;
    3025:     }
    3026:
    3027:     /**
    3028:      * Initializes the collStocks collection.
    3029:      *
    3030:      * By default this just sets the collStocks collection to an empty array (like clearcollStocks());
    3031:      * however, you may wish to override this method in your stub class to provide setting appropriate
    3032:      * to your application -- for example, setting the initial array to the values stored in database.
    3033:      *
    3034:      * @param boolean $overrideExisting If set to true, the method call initializes
    3035:      *                                        the collection even if it is not empty
    3036:      *
    3037:      * @return void
    3038:      */
    3039:     public function initStocks($overrideExisting = true)
    3040:     {
    3041:         if (null !== $this->collStocks && !$overrideExisting) {
    3042:             return;
    3043:         }
    3044:         $this->collStocks = new PropelObjectCollection();
    3045:         $this->collStocks->setModel('Stock');
    3046:     }
    3047:
    3048:     /**
    3049:      * Gets an array of Stock objects which contain a foreign key that references this object.
    3050:      *
    3051:      * If the $criteria is not null, it is used to always fetch the results from the database.
    3052:      * Otherwise the results are fetched from the database the first time, then cached.
    3053:      * Next time the same method is called without $criteria, the cached collection is returned.
    3054:      * If this Product is new, it will return
    3055:      * an empty collection or the current collection; the criteria is ignored on a new object.
    3056:      *
    3057:      * @param Criteria $criteria optional Criteria object to narrow the query
    3058:      * @param PropelPDO $con optional connection object
    3059:      * @return PropelObjectCollection|Stock[] List of Stock objects
    3060:      * @throws PropelException
    3061:      */
    3062:     public function getStocks($criteria = null, PropelPDO $con = null)
    3063:     {
    3064:         $partial = $this->collStocksPartial && !$this->isNew();
    3065:         if (null === $this->collStocks || null !== $criteria  || $partial) {
    3066:             if ($this->isNew() && null === $this->collStocks) {
    3067:                 // return empty collection
    3068:                 $this->initStocks();
    3069:             } else {
    3070:                 $collStocks = StockQuery::create(null, $criteria)
    3071:                     ->filterByProduct($this)
    3072:                     ->find($con);
    3073:                 if (null !== $criteria) {
    3074:                     if (false !== $this->collStocksPartial && count($collStocks)) {
    3075:                       $this->initStocks(false);
    3076:
    3077:                       foreach($collStocks as $obj) {
    3078:                         if (false == $this->collStocks->contains($obj)) {
    3079:                           $this->collStocks->append($obj);
    3080:                         }
    3081:                       }
    3082:
    3083:                       $this->collStocksPartial = true;
    3084:                     }
    3085:
    3086:                     $collStocks->getInternalIterator()->rewind();
    3087:                     return $collStocks;
    3088:                 }
    3089:
    3090:                 if($partial && $this->collStocks) {
    3091:                     foreach($this->collStocks as $obj) {
    3092:                         if($obj->isNew()) {
    3093:                             $collStocks[] = $obj;
    3094:                         }
    3095:                     }
    3096:                 }
    3097:
    3098:                 $this->collStocks = $collStocks;
    3099:                 $this->collStocksPartial = false;
    3100:             }
    3101:         }
    3102:
    3103:         return $this->collStocks;
    3104:     }
    3105:
    3106:     /**
    3107:      * Sets a collection of Stock objects related by a one-to-many relationship
    3108:      * to the current object.
    3109:      * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
    3110:      * and new objects from the given Propel collection.
    3111:      *
    3112:      * @param PropelCollection $stocks A Propel collection.
    3113:      * @param PropelPDO $con Optional connection object
    3114:      * @return Product The current object (for fluent API support)
    3115:      */
    3116:     public function setStocks(PropelCollection $stocks, PropelPDO $con = null)
    3117:     {
    3118:         $stocksToDelete = $this->getStocks(new Criteria(), $con)->diff($stocks);
    3119:
    3120:         $this->stocksScheduledForDeletion = unserialize(serialize($stocksToDelete));
    3121:
    3122:         foreach ($stocksToDelete as $stockRemoved) {
    3123:             $stockRemoved->setProduct(null);
    3124:         }
    3125:
    3126:         $this->collStocks = null;
    3127:         foreach ($stocks as $stock) {
    3128:             $this->addStock($stock);
    3129:         }
    3130:
    3131:         $this->collStocks = $stocks;
    3132:         $this->collStocksPartial = false;
    3133:
    3134:         return $this;
    3135:     }
    3136:
    3137:     /**
    3138:      * Returns the number of related Stock objects.
    3139:      *
    3140:      * @param Criteria $criteria
    3141:      * @param boolean $distinct
    3142:      * @param PropelPDO $con
    3143:      * @return int             Count of related Stock objects.
    3144:      * @throws PropelException
    3145:      */
    3146:     public function countStocks(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
    3147:     {
    3148:         $partial = $this->collStocksPartial && !$this->isNew();
    3149:         if (null === $this->collStocks || null !== $criteria || $partial) {
    3150:             if ($this->isNew() && null === $this->collStocks) {
    3151:                 return 0;
    3152:             }
    3153:
    3154:             if($partial && !$criteria) {
    3155:                 return count($this->getStocks());
    3156:             }
    3157:             $query = StockQuery::create(null, $criteria);
    3158:             if ($distinct) {
    3159:                 $query->distinct();
    3160:             }
    3161:
    3162:             return $query
    3163:                 ->filterByProduct($this)
    3164:                 ->count($con);
    3165:         }
    3166:
    3167:         return count($this->collStocks);
    3168:     }
    3169:
    3170:     /**
    3171:      * Method called to associate a Stock object to this object
    3172:      * through the Stock foreign key attribute.
    3173:      *
    3174:      * @param    Stock $l Stock
    3175:      * @return Product The current object (for fluent API support)
    3176:      */
    3177:     public function addStock(Stock $l)
    3178:     {
    3179:         if ($this->collStocks === null) {
    3180:             $this->initStocks();
    3181:             $this->collStocksPartial = true;
    3182:         }
    3183:         if (!in_array($l, $this->collStocks->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
    3184:             $this->doAddStock($l);
    3185:         }
    3186:
    3187:         return $this;
    3188:     }
    3189:
    3190:     /**
    3191:      * @param   Stock $stock The stock object to add.
    3192:      */
    3193:     protected function doAddStock($stock)
    3194:     {
    3195:         $this->collStocks[]= $stock;
    3196:         $stock->setProduct($this);
    3197:     }
    3198:
    3199:     /**
    3200:      * @param   Stock $stock The stock object to remove.
    3201:      * @return Product The current object (for fluent API support)
    3202:      */
    3203:     public function removeStock($stock)
    3204:     {
    3205:         if ($this->getStocks()->contains($stock)) {
    3206:             $this->collStocks->remove($this->collStocks->search($stock));
    3207:             if (null === $this->stocksScheduledForDeletion) {
    3208:                 $this->stocksScheduledForDeletion = clone $this->collStocks;
    3209:                 $this->stocksScheduledForDeletion->clear();
    3210:             }
    3211:             $this->stocksScheduledForDeletion[]= clone $stock;
    3212:             $stock->setProduct(null);
    3213:         }
    3214:
    3215:         return $this;
    3216:     }
    3217:
    3218:
    3219:     /**
    3220:      * If this collection has already been initialized with
    3221:      * an identical criteria, it returns the collection.
    3222:      * Otherwise if this Product is new, it will return
    3223:      * an empty collection; or if this Product has previously
    3224:      * been saved, it will retrieve related Stocks from storage.
    3225:      *
    3226:      * This method is protected by default in order to keep the public
    3227:      * api reasonable.  You can provide public methods for those you
    3228:      * actually need in Product.
    3229:      *
    3230:      * @param Criteria $criteria optional Criteria object to narrow the query
    3231:      * @param PropelPDO $con optional connection object
    3232:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    3233:      * @return PropelObjectCollection|Stock[] List of Stock objects
    3234:      */
    3235:     public function getStocksJoinCombination($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    3236:     {
    3237:         $query = StockQuery::create(null, $criteria);
    3238:         $query->joinWith('Combination', $join_behavior);
    3239:
    3240:         return $this->getStocks($query, $con);
    3241:     }
    3242:
    3243:     /**
    3244:      * Clears out the collContentAssocs collection
    3245:      *
    3246:      * This does not modify the database; however, it will remove any associated objects, causing
    3247:      * them to be refetched by subsequent calls to accessor method.
    3248:      *
    3249:      * @return Product The current object (for fluent API support)
    3250:      * @see        addContentAssocs()
    3251:      */
    3252:     public function clearContentAssocs()
    3253:     {
    3254:         $this->collContentAssocs = null; // important to set this to null since that means it is uninitialized
    3255:         $this->collContentAssocsPartial = null;
    3256:
    3257:         return $this;
    3258:     }
    3259:
    3260:     /**
    3261:      * reset is the collContentAssocs collection loaded partially
    3262:      *
    3263:      * @return void
    3264:      */
    3265:     public function resetPartialContentAssocs($v = true)
    3266:     {
    3267:         $this->collContentAssocsPartial = $v;
    3268:     }
    3269:
    3270:     /**
    3271:      * Initializes the collContentAssocs collection.
    3272:      *
    3273:      * By default this just sets the collContentAssocs collection to an empty array (like clearcollContentAssocs());
    3274:      * however, you may wish to override this method in your stub class to provide setting appropriate
    3275:      * to your application -- for example, setting the initial array to the values stored in database.
    3276:      *
    3277:      * @param boolean $overrideExisting If set to true, the method call initializes
    3278:      *                                        the collection even if it is not empty
    3279:      *
    3280:      * @return void
    3281:      */
    3282:     public function initContentAssocs($overrideExisting = true)
    3283:     {
    3284:         if (null !== $this->collContentAssocs && !$overrideExisting) {
    3285:             return;
    3286:         }
    3287:         $this->collContentAssocs = new PropelObjectCollection();
    3288:         $this->collContentAssocs->setModel('ContentAssoc');
    3289:     }
    3290:
    3291:     /**
    3292:      * Gets an array of ContentAssoc objects which contain a foreign key that references this object.
    3293:      *
    3294:      * If the $criteria is not null, it is used to always fetch the results from the database.
    3295:      * Otherwise the results are fetched from the database the first time, then cached.
    3296:      * Next time the same method is called without $criteria, the cached collection is returned.
    3297:      * If this Product is new, it will return
    3298:      * an empty collection or the current collection; the criteria is ignored on a new object.
    3299:      *
    3300:      * @param Criteria $criteria optional Criteria object to narrow the query
    3301:      * @param PropelPDO $con optional connection object
    3302:      * @return PropelObjectCollection|ContentAssoc[] List of ContentAssoc objects
    3303:      * @throws PropelException
    3304:      */
    3305:     public function getContentAssocs($criteria = null, PropelPDO $con = null)
    3306:     {
    3307:         $partial = $this->collContentAssocsPartial && !$this->isNew();
    3308:         if (null === $this->collContentAssocs || null !== $criteria  || $partial) {
    3309:             if ($this->isNew() && null === $this->collContentAssocs) {
    3310:                 // return empty collection
    3311:                 $this->initContentAssocs();
    3312:             } else {
    3313:                 $collContentAssocs = ContentAssocQuery::create(null, $criteria)
    3314:                     ->filterByProduct($this)
    3315:                     ->find($con);
    3316:                 if (null !== $criteria) {
    3317:                     if (false !== $this->collContentAssocsPartial && count($collContentAssocs)) {
    3318:                       $this->initContentAssocs(false);
    3319:
    3320:                       foreach($collContentAssocs as $obj) {
    3321:                         if (false == $this->collContentAssocs->contains($obj)) {
    3322:                           $this->collContentAssocs->append($obj);
    3323:                         }
    3324:                       }
    3325:
    3326:                       $this->collContentAssocsPartial = true;
    3327:                     }
    3328:
    3329:                     $collContentAssocs->getInternalIterator()->rewind();
    3330:                     return $collContentAssocs;
    3331:                 }
    3332:
    3333:                 if($partial && $this->collContentAssocs) {
    3334:                     foreach($this->collContentAssocs as $obj) {
    3335:                         if($obj->isNew()) {
    3336:                             $collContentAssocs[] = $obj;
    3337:                         }
    3338:                     }
    3339:                 }
    3340:
    3341:                 $this->collContentAssocs = $collContentAssocs;
    3342:                 $this->collContentAssocsPartial = false;
    3343:             }
    3344:         }
    3345:
    3346:         return $this->collContentAssocs;
    3347:     }
    3348:
    3349:     /**
    3350:      * Sets a collection of ContentAssoc objects related by a one-to-many relationship
    3351:      * to the current object.
    3352:      * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
    3353:      * and new objects from the given Propel collection.
    3354:      *
    3355:      * @param PropelCollection $contentAssocs A Propel collection.
    3356:      * @param PropelPDO $con Optional connection object
    3357:      * @return Product The current object (for fluent API support)
    3358:      */
    3359:     public function setContentAssocs(PropelCollection $contentAssocs, PropelPDO $con = null)
    3360:     {
    3361:         $contentAssocsToDelete = $this->getContentAssocs(new Criteria(), $con)->diff($contentAssocs);
    3362:
    3363:         $this->contentAssocsScheduledForDeletion = unserialize(serialize($contentAssocsToDelete));
    3364:
    3365:         foreach ($contentAssocsToDelete as $contentAssocRemoved) {
    3366:             $contentAssocRemoved->setProduct(null);
    3367:         }
    3368:
    3369:         $this->collContentAssocs = null;
    3370:         foreach ($contentAssocs as $contentAssoc) {
    3371:             $this->addContentAssoc($contentAssoc);
    3372:         }
    3373:
    3374:         $this->collContentAssocs = $contentAssocs;
    3375:         $this->collContentAssocsPartial = false;
    3376:
    3377:         return $this;
    3378:     }
    3379:
    3380:     /**
    3381:      * Returns the number of related ContentAssoc objects.
    3382:      *
    3383:      * @param Criteria $criteria
    3384:      * @param boolean $distinct
    3385:      * @param PropelPDO $con
    3386:      * @return int             Count of related ContentAssoc objects.
    3387:      * @throws PropelException
    3388:      */
    3389:     public function countContentAssocs(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
    3390:     {
    3391:         $partial = $this->collContentAssocsPartial && !$this->isNew();
    3392:         if (null === $this->collContentAssocs || null !== $criteria || $partial) {
    3393:             if ($this->isNew() && null === $this->collContentAssocs) {
    3394:                 return 0;
    3395:             }
    3396:
    3397:             if($partial && !$criteria) {
    3398:                 return count($this->getContentAssocs());
    3399:             }
    3400:             $query = ContentAssocQuery::create(null, $criteria);
    3401:             if ($distinct) {
    3402:                 $query->distinct();
    3403:             }
    3404:
    3405:             return $query
    3406:                 ->filterByProduct($this)
    3407:                 ->count($con);
    3408:         }
    3409:
    3410:         return count($this->collContentAssocs);
    3411:     }
    3412:
    3413:     /**
    3414:      * Method called to associate a ContentAssoc object to this object
    3415:      * through the ContentAssoc foreign key attribute.
    3416:      *
    3417:      * @param    ContentAssoc $l ContentAssoc
    3418:      * @return Product The current object (for fluent API support)
    3419:      */
    3420:     public function addContentAssoc(ContentAssoc $l)
    3421:     {
    3422:         if ($this->collContentAssocs === null) {
    3423:             $this->initContentAssocs();
    3424:             $this->collContentAssocsPartial = true;
    3425:         }
    3426:         if (!in_array($l, $this->collContentAssocs->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
    3427:             $this->doAddContentAssoc($l);
    3428:         }
    3429:
    3430:         return $this;
    3431:     }
    3432:
    3433:     /**
    3434:      * @param   ContentAssoc $contentAssoc The contentAssoc object to add.
    3435:      */
    3436:     protected function doAddContentAssoc($contentAssoc)
    3437:     {
    3438:         $this->collContentAssocs[]= $contentAssoc;
    3439:         $contentAssoc->setProduct($this);
    3440:     }
    3441:
    3442:     /**
    3443:      * @param   ContentAssoc $contentAssoc The contentAssoc object to remove.
    3444:      * @return Product The current object (for fluent API support)
    3445:      */
    3446:     public function removeContentAssoc($contentAssoc)
    3447:     {
    3448:         if ($this->getContentAssocs()->contains($contentAssoc)) {
    3449:             $this->collContentAssocs->remove($this->collContentAssocs->search($contentAssoc));
    3450:             if (null === $this->contentAssocsScheduledForDeletion) {
    3451:                 $this->contentAssocsScheduledForDeletion = clone $this->collContentAssocs;
    3452:                 $this->contentAssocsScheduledForDeletion->clear();
    3453:             }
    3454:             $this->contentAssocsScheduledForDeletion[]= $contentAssoc;
    3455:             $contentAssoc->setProduct(null);
    3456:         }
    3457:
    3458:         return $this;
    3459:     }
    3460:
    3461:
    3462:     /**
    3463:      * If this collection has already been initialized with
    3464:      * an identical criteria, it returns the collection.
    3465:      * Otherwise if this Product is new, it will return
    3466:      * an empty collection; or if this Product has previously
    3467:      * been saved, it will retrieve related ContentAssocs from storage.
    3468:      *
    3469:      * This method is protected by default in order to keep the public
    3470:      * api reasonable.  You can provide public methods for those you
    3471:      * actually need in Product.
    3472:      *
    3473:      * @param Criteria $criteria optional Criteria object to narrow the query
    3474:      * @param PropelPDO $con optional connection object
    3475:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    3476:      * @return PropelObjectCollection|ContentAssoc[] List of ContentAssoc objects
    3477:      */
    3478:     public function getContentAssocsJoinCategory($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    3479:     {
    3480:         $query = ContentAssocQuery::create(null, $criteria);
    3481:         $query->joinWith('Category', $join_behavior);
    3482:
    3483:         return $this->getContentAssocs($query, $con);
    3484:     }
    3485:
    3486:
    3487:     /**
    3488:      * If this collection has already been initialized with
    3489:      * an identical criteria, it returns the collection.
    3490:      * Otherwise if this Product is new, it will return
    3491:      * an empty collection; or if this Product has previously
    3492:      * been saved, it will retrieve related ContentAssocs from storage.
    3493:      *
    3494:      * This method is protected by default in order to keep the public
    3495:      * api reasonable.  You can provide public methods for those you
    3496:      * actually need in Product.
    3497:      *
    3498:      * @param Criteria $criteria optional Criteria object to narrow the query
    3499:      * @param PropelPDO $con optional connection object
    3500:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    3501:      * @return PropelObjectCollection|ContentAssoc[] List of ContentAssoc objects
    3502:      */
    3503:     public function getContentAssocsJoinContent($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    3504:     {
    3505:         $query = ContentAssocQuery::create(null, $criteria);
    3506:         $query->joinWith('Content', $join_behavior);
    3507:
    3508:         return $this->getContentAssocs($query, $con);
    3509:     }
    3510:
    3511:     /**
    3512:      * Clears out the collImages collection
    3513:      *
    3514:      * This does not modify the database; however, it will remove any associated objects, causing
    3515:      * them to be refetched by subsequent calls to accessor method.
    3516:      *
    3517:      * @return Product The current object (for fluent API support)
    3518:      * @see        addImages()
    3519:      */
    3520:     public function clearImages()
    3521:     {
    3522:         $this->collImages = null; // important to set this to null since that means it is uninitialized
    3523:         $this->collImagesPartial = null;
    3524:
    3525:         return $this;
    3526:     }
    3527:
    3528:     /**
    3529:      * reset is the collImages collection loaded partially
    3530:      *
    3531:      * @return void
    3532:      */
    3533:     public function resetPartialImages($v = true)
    3534:     {
    3535:         $this->collImagesPartial = $v;
    3536:     }
    3537:
    3538:     /**
    3539:      * Initializes the collImages collection.
    3540:      *
    3541:      * By default this just sets the collImages collection to an empty array (like clearcollImages());
    3542:      * however, you may wish to override this method in your stub class to provide setting appropriate
    3543:      * to your application -- for example, setting the initial array to the values stored in database.
    3544:      *
    3545:      * @param boolean $overrideExisting If set to true, the method call initializes
    3546:      *                                        the collection even if it is not empty
    3547:      *
    3548:      * @return void
    3549:      */
    3550:     public function initImages($overrideExisting = true)
    3551:     {
    3552:         if (null !== $this->collImages && !$overrideExisting) {
    3553:             return;
    3554:         }
    3555:         $this->collImages = new PropelObjectCollection();
    3556:         $this->collImages->setModel('Image');
    3557:     }
    3558:
    3559:     /**
    3560:      * Gets an array of Image objects which contain a foreign key that references this object.
    3561:      *
    3562:      * If the $criteria is not null, it is used to always fetch the results from the database.
    3563:      * Otherwise the results are fetched from the database the first time, then cached.
    3564:      * Next time the same method is called without $criteria, the cached collection is returned.
    3565:      * If this Product is new, it will return
    3566:      * an empty collection or the current collection; the criteria is ignored on a new object.
    3567:      *
    3568:      * @param Criteria $criteria optional Criteria object to narrow the query
    3569:      * @param PropelPDO $con optional connection object
    3570:      * @return PropelObjectCollection|Image[] List of Image objects
    3571:      * @throws PropelException
    3572:      */
    3573:     public function getImages($criteria = null, PropelPDO $con = null)
    3574:     {
    3575:         $partial = $this->collImagesPartial && !$this->isNew();
    3576:         if (null === $this->collImages || null !== $criteria  || $partial) {
    3577:             if ($this->isNew() && null === $this->collImages) {
    3578:                 // return empty collection
    3579:                 $this->initImages();
    3580:             } else {
    3581:                 $collImages = ImageQuery::create(null, $criteria)
    3582:                     ->filterByProduct($this)
    3583:                     ->find($con);
    3584:                 if (null !== $criteria) {
    3585:                     if (false !== $this->collImagesPartial && count($collImages)) {
    3586:                       $this->initImages(false);
    3587:
    3588:                       foreach($collImages as $obj) {
    3589:                         if (false == $this->collImages->contains($obj)) {
    3590:                           $this->collImages->append($obj);
    3591:                         }
    3592:                       }
    3593:
    3594:                       $this->collImagesPartial = true;
    3595:                     }
    3596:
    3597:                     $collImages->getInternalIterator()->rewind();
    3598:                     return $collImages;
    3599:                 }
    3600:
    3601:                 if($partial && $this->collImages) {
    3602:                     foreach($this->collImages as $obj) {
    3603:                         if($obj->isNew()) {
    3604:                             $collImages[] = $obj;
    3605:                         }
    3606:                     }
    3607:                 }
    3608:
    3609:                 $this->collImages = $collImages;
    3610:                 $this->collImagesPartial = false;
    3611:             }
    3612:         }
    3613:
    3614:         return $this->collImages;
    3615:     }
    3616:
    3617:     /**
    3618:      * Sets a collection of Image objects related by a one-to-many relationship
    3619:      * to the current object.
    3620:      * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
    3621:      * and new objects from the given Propel collection.
    3622:      *
    3623:      * @param PropelCollection $images A Propel collection.
    3624:      * @param PropelPDO $con Optional connection object
    3625:      * @return Product The current object (for fluent API support)
    3626:      */
    3627:     public function setImages(PropelCollection $images, PropelPDO $con = null)
    3628:     {
    3629:         $imagesToDelete = $this->getImages(new Criteria(), $con)->diff($images);
    3630:
    3631:         $this->imagesScheduledForDeletion = unserialize(serialize($imagesToDelete));
    3632:
    3633:         foreach ($imagesToDelete as $imageRemoved) {
    3634:             $imageRemoved->setProduct(null);
    3635:         }
    3636:
    3637:         $this->collImages = null;
    3638:         foreach ($images as $image) {
    3639:             $this->addImage($image);
    3640:         }
    3641:
    3642:         $this->collImages = $images;
    3643:         $this->collImagesPartial = false;
    3644:
    3645:         return $this;
    3646:     }
    3647:
    3648:     /**
    3649:      * Returns the number of related Image objects.
    3650:      *
    3651:      * @param Criteria $criteria
    3652:      * @param boolean $distinct
    3653:      * @param PropelPDO $con
    3654:      * @return int             Count of related Image objects.
    3655:      * @throws PropelException
    3656:      */
    3657:     public function countImages(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
    3658:     {
    3659:         $partial = $this->collImagesPartial && !$this->isNew();
    3660:         if (null === $this->collImages || null !== $criteria || $partial) {
    3661:             if ($this->isNew() && null === $this->collImages) {
    3662:                 return 0;
    3663:             }
    3664:
    3665:             if($partial && !$criteria) {
    3666:                 return count($this->getImages());
    3667:             }
    3668:             $query = ImageQuery::create(null, $criteria);
    3669:             if ($distinct) {
    3670:                 $query->distinct();
    3671:             }
    3672:
    3673:             return $query
    3674:                 ->filterByProduct($this)
    3675:                 ->count($con);
    3676:         }
    3677:
    3678:         return count($this->collImages);
    3679:     }
    3680:
    3681:     /**
    3682:      * Method called to associate a Image object to this object
    3683:      * through the Image foreign key attribute.
    3684:      *
    3685:      * @param    Image $l Image
    3686:      * @return Product The current object (for fluent API support)
    3687:      */
    3688:     public function addImage(Image $l)
    3689:     {
    3690:         if ($this->collImages === null) {
    3691:             $this->initImages();
    3692:             $this->collImagesPartial = true;
    3693:         }
    3694:         if (!in_array($l, $this->collImages->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
    3695:             $this->doAddImage($l);
    3696:         }
    3697:
    3698:         return $this;
    3699:     }
    3700:
    3701:     /**
    3702:      * @param   Image $image The image object to add.
    3703:      */
    3704:     protected function doAddImage($image)
    3705:     {
    3706:         $this->collImages[]= $image;
    3707:         $image->setProduct($this);
    3708:     }
    3709:
    3710:     /**
    3711:      * @param   Image $image The image object to remove.
    3712:      * @return Product The current object (for fluent API support)
    3713:      */
    3714:     public function removeImage($image)
    3715:     {
    3716:         if ($this->getImages()->contains($image)) {
    3717:             $this->collImages->remove($this->collImages->search($image));
    3718:             if (null === $this->imagesScheduledForDeletion) {
    3719:                 $this->imagesScheduledForDeletion = clone $this->collImages;
    3720:                 $this->imagesScheduledForDeletion->clear();
    3721:             }
    3722:             $this->imagesScheduledForDeletion[]= $image;
    3723:             $image->setProduct(null);
    3724:         }
    3725:
    3726:         return $this;
    3727:     }
    3728:
    3729:
    3730:     /**
    3731:      * If this collection has already been initialized with
    3732:      * an identical criteria, it returns the collection.
    3733:      * Otherwise if this Product is new, it will return
    3734:      * an empty collection; or if this Product has previously
    3735:      * been saved, it will retrieve related Images from storage.
    3736:      *
    3737:      * This method is protected by default in order to keep the public
    3738:      * api reasonable.  You can provide public methods for those you
    3739:      * actually need in Product.
    3740:      *
    3741:      * @param Criteria $criteria optional Criteria object to narrow the query
    3742:      * @param PropelPDO $con optional connection object
    3743:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    3744:      * @return PropelObjectCollection|Image[] List of Image objects
    3745:      */
    3746:     public function getImagesJoinCategory($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    3747:     {
    3748:         $query = ImageQuery::create(null, $criteria);
    3749:         $query->joinWith('Category', $join_behavior);
    3750:
    3751:         return $this->getImages($query, $con);
    3752:     }
    3753:
    3754:
    3755:     /**
    3756:      * If this collection has already been initialized with
    3757:      * an identical criteria, it returns the collection.
    3758:      * Otherwise if this Product is new, it will return
    3759:      * an empty collection; or if this Product has previously
    3760:      * been saved, it will retrieve related Images from storage.
    3761:      *
    3762:      * This method is protected by default in order to keep the public
    3763:      * api reasonable.  You can provide public methods for those you
    3764:      * actually need in Product.
    3765:      *
    3766:      * @param Criteria $criteria optional Criteria object to narrow the query
    3767:      * @param PropelPDO $con optional connection object
    3768:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    3769:      * @return PropelObjectCollection|Image[] List of Image objects
    3770:      */
    3771:     public function getImagesJoinContent($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    3772:     {
    3773:         $query = ImageQuery::create(null, $criteria);
    3774:         $query->joinWith('Content', $join_behavior);
    3775:
    3776:         return $this->getImages($query, $con);
    3777:     }
    3778:
    3779:
    3780:     /**
    3781:      * If this collection has already been initialized with
    3782:      * an identical criteria, it returns the collection.
    3783:      * Otherwise if this Product is new, it will return
    3784:      * an empty collection; or if this Product has previously
    3785:      * been saved, it will retrieve related Images from storage.
    3786:      *
    3787:      * This method is protected by default in order to keep the public
    3788:      * api reasonable.  You can provide public methods for those you
    3789:      * actually need in Product.
    3790:      *
    3791:      * @param Criteria $criteria optional Criteria object to narrow the query
    3792:      * @param PropelPDO $con optional connection object
    3793:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    3794:      * @return PropelObjectCollection|Image[] List of Image objects
    3795:      */
    3796:     public function getImagesJoinFolder($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    3797:     {
    3798:         $query = ImageQuery::create(null, $criteria);
    3799:         $query->joinWith('Folder', $join_behavior);
    3800:
    3801:         return $this->getImages($query, $con);
    3802:     }
    3803:
    3804:     /**
    3805:      * Clears out the collDocuments collection
    3806:      *
    3807:      * This does not modify the database; however, it will remove any associated objects, causing
    3808:      * them to be refetched by subsequent calls to accessor method.
    3809:      *
    3810:      * @return Product The current object (for fluent API support)
    3811:      * @see        addDocuments()
    3812:      */
    3813:     public function clearDocuments()
    3814:     {
    3815:         $this->collDocuments = null; // important to set this to null since that means it is uninitialized
    3816:         $this->collDocumentsPartial = null;
    3817:
    3818:         return $this;
    3819:     }
    3820:
    3821:     /**
    3822:      * reset is the collDocuments collection loaded partially
    3823:      *
    3824:      * @return void
    3825:      */
    3826:     public function resetPartialDocuments($v = true)
    3827:     {
    3828:         $this->collDocumentsPartial = $v;
    3829:     }
    3830:
    3831:     /**
    3832:      * Initializes the collDocuments collection.
    3833:      *
    3834:      * By default this just sets the collDocuments collection to an empty array (like clearcollDocuments());
    3835:      * however, you may wish to override this method in your stub class to provide setting appropriate
    3836:      * to your application -- for example, setting the initial array to the values stored in database.
    3837:      *
    3838:      * @param boolean $overrideExisting If set to true, the method call initializes
    3839:      *                                        the collection even if it is not empty
    3840:      *
    3841:      * @return void
    3842:      */
    3843:     public function initDocuments($overrideExisting = true)
    3844:     {
    3845:         if (null !== $this->collDocuments && !$overrideExisting) {
    3846:             return;
    3847:         }
    3848:         $this->collDocuments = new PropelObjectCollection();
    3849:         $this->collDocuments->setModel('Document');
    3850:     }
    3851:
    3852:     /**
    3853:      * Gets an array of Document objects which contain a foreign key that references this object.
    3854:      *
    3855:      * If the $criteria is not null, it is used to always fetch the results from the database.
    3856:      * Otherwise the results are fetched from the database the first time, then cached.
    3857:      * Next time the same method is called without $criteria, the cached collection is returned.
    3858:      * If this Product is new, it will return
    3859:      * an empty collection or the current collection; the criteria is ignored on a new object.
    3860:      *
    3861:      * @param Criteria $criteria optional Criteria object to narrow the query
    3862:      * @param PropelPDO $con optional connection object
    3863:      * @return PropelObjectCollection|Document[] List of Document objects
    3864:      * @throws PropelException
    3865:      */
    3866:     public function getDocuments($criteria = null, PropelPDO $con = null)
    3867:     {
    3868:         $partial = $this->collDocumentsPartial && !$this->isNew();
    3869:         if (null === $this->collDocuments || null !== $criteria  || $partial) {
    3870:             if ($this->isNew() && null === $this->collDocuments) {
    3871:                 // return empty collection
    3872:                 $this->initDocuments();
    3873:             } else {
    3874:                 $collDocuments = DocumentQuery::create(null, $criteria)
    3875:                     ->filterByProduct($this)
    3876:                     ->find($con);
    3877:                 if (null !== $criteria) {
    3878:                     if (false !== $this->collDocumentsPartial && count($collDocuments)) {
    3879:                       $this->initDocuments(false);
    3880:
    3881:                       foreach($collDocuments as $obj) {
    3882:                         if (false == $this->collDocuments->contains($obj)) {
    3883:                           $this->collDocuments->append($obj);
    3884:                         }
    3885:                       }
    3886:
    3887:                       $this->collDocumentsPartial = true;
    3888:                     }
    3889:
    3890:                     $collDocuments->getInternalIterator()->rewind();
    3891:                     return $collDocuments;
    3892:                 }
    3893:
    3894:                 if($partial && $this->collDocuments) {
    3895:                     foreach($this->collDocuments as $obj) {
    3896:                         if($obj->isNew()) {
    3897:                             $collDocuments[] = $obj;
    3898:                         }
    3899:                     }
    3900:                 }
    3901:
    3902:                 $this->collDocuments = $collDocuments;
    3903:                 $this->collDocumentsPartial = false;
    3904:             }
    3905:         }
    3906:
    3907:         return $this->collDocuments;
    3908:     }
    3909:
    3910:     /**
    3911:      * Sets a collection of Document objects related by a one-to-many relationship
    3912:      * to the current object.
    3913:      * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
    3914:      * and new objects from the given Propel collection.
    3915:      *
    3916:      * @param PropelCollection $documents A Propel collection.
    3917:      * @param PropelPDO $con Optional connection object
    3918:      * @return Product The current object (for fluent API support)
    3919:      */
    3920:     public function setDocuments(PropelCollection $documents, PropelPDO $con = null)
    3921:     {
    3922:         $documentsToDelete = $this->getDocuments(new Criteria(), $con)->diff($documents);
    3923:
    3924:         $this->documentsScheduledForDeletion = unserialize(serialize($documentsToDelete));
    3925:
    3926:         foreach ($documentsToDelete as $documentRemoved) {
    3927:             $documentRemoved->setProduct(null);
    3928:         }
    3929:
    3930:         $this->collDocuments = null;
    3931:         foreach ($documents as $document) {
    3932:             $this->addDocument($document);
    3933:         }
    3934:
    3935:         $this->collDocuments = $documents;
    3936:         $this->collDocumentsPartial = false;
    3937:
    3938:         return $this;
    3939:     }
    3940:
    3941:     /**
    3942:      * Returns the number of related Document objects.
    3943:      *
    3944:      * @param Criteria $criteria
    3945:      * @param boolean $distinct
    3946:      * @param PropelPDO $con
    3947:      * @return int             Count of related Document objects.
    3948:      * @throws PropelException
    3949:      */
    3950:     public function countDocuments(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
    3951:     {
    3952:         $partial = $this->collDocumentsPartial && !$this->isNew();
    3953:         if (null === $this->collDocuments || null !== $criteria || $partial) {
    3954:             if ($this->isNew() && null === $this->collDocuments) {
    3955:                 return 0;
    3956:             }
    3957:
    3958:             if($partial && !$criteria) {
    3959:                 return count($this->getDocuments());
    3960:             }
    3961:             $query = DocumentQuery::create(null, $criteria);
    3962:             if ($distinct) {
    3963:                 $query->distinct();
    3964:             }
    3965:
    3966:             return $query
    3967:                 ->filterByProduct($this)
    3968:                 ->count($con);
    3969:         }
    3970:
    3971:         return count($this->collDocuments);
    3972:     }
    3973:
    3974:     /**
    3975:      * Method called to associate a Document object to this object
    3976:      * through the Document foreign key attribute.
    3977:      *
    3978:      * @param    Document $l Document
    3979:      * @return Product The current object (for fluent API support)
    3980:      */
    3981:     public function addDocument(Document $l)
    3982:     {
    3983:         if ($this->collDocuments === null) {
    3984:             $this->initDocuments();
    3985:             $this->collDocumentsPartial = true;
    3986:         }
    3987:         if (!in_array($l, $this->collDocuments->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
    3988:             $this->doAddDocument($l);
    3989:         }
    3990:
    3991:         return $this;
    3992:     }
    3993:
    3994:     /**
    3995:      * @param   Document $document The document object to add.
    3996:      */
    3997:     protected function doAddDocument($document)
    3998:     {
    3999:         $this->collDocuments[]= $document;
    4000:         $document->setProduct($this);
    4001:     }
    4002:
    4003:     /**
    4004:      * @param   Document $document The document object to remove.
    4005:      * @return Product The current object (for fluent API support)
    4006:      */
    4007:     public function removeDocument($document)
    4008:     {
    4009:         if ($this->getDocuments()->contains($document)) {
    4010:             $this->collDocuments->remove($this->collDocuments->search($document));
    4011:             if (null === $this->documentsScheduledForDeletion) {
    4012:                 $this->documentsScheduledForDeletion = clone $this->collDocuments;
    4013:                 $this->documentsScheduledForDeletion->clear();
    4014:             }
    4015:             $this->documentsScheduledForDeletion[]= $document;
    4016:             $document->setProduct(null);
    4017:         }
    4018:
    4019:         return $this;
    4020:     }
    4021:
    4022:
    4023:     /**
    4024:      * If this collection has already been initialized with
    4025:      * an identical criteria, it returns the collection.
    4026:      * Otherwise if this Product is new, it will return
    4027:      * an empty collection; or if this Product has previously
    4028:      * been saved, it will retrieve related Documents from storage.
    4029:      *
    4030:      * This method is protected by default in order to keep the public
    4031:      * api reasonable.  You can provide public methods for those you
    4032:      * actually need in Product.
    4033:      *
    4034:      * @param Criteria $criteria optional Criteria object to narrow the query
    4035:      * @param PropelPDO $con optional connection object
    4036:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    4037:      * @return PropelObjectCollection|Document[] List of Document objects
    4038:      */
    4039:     public function getDocumentsJoinCategory($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    4040:     {
    4041:         $query = DocumentQuery::create(null, $criteria);
    4042:         $query->joinWith('Category', $join_behavior);
    4043:
    4044:         return $this->getDocuments($query, $con);
    4045:     }
    4046:
    4047:
    4048:     /**
    4049:      * If this collection has already been initialized with
    4050:      * an identical criteria, it returns the collection.
    4051:      * Otherwise if this Product is new, it will return
    4052:      * an empty collection; or if this Product has previously
    4053:      * been saved, it will retrieve related Documents from storage.
    4054:      *
    4055:      * This method is protected by default in order to keep the public
    4056:      * api reasonable.  You can provide public methods for those you
    4057:      * actually need in Product.
    4058:      *
    4059:      * @param Criteria $criteria optional Criteria object to narrow the query
    4060:      * @param PropelPDO $con optional connection object
    4061:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    4062:      * @return PropelObjectCollection|Document[] List of Document objects
    4063:      */
    4064:     public function getDocumentsJoinContent($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    4065:     {
    4066:         $query = DocumentQuery::create(null, $criteria);
    4067:         $query->joinWith('Content', $join_behavior);
    4068:
    4069:         return $this->getDocuments($query, $con);
    4070:     }
    4071:
    4072:
    4073:     /**
    4074:      * If this collection has already been initialized with
    4075:      * an identical criteria, it returns the collection.
    4076:      * Otherwise if this Product is new, it will return
    4077:      * an empty collection; or if this Product has previously
    4078:      * been saved, it will retrieve related Documents from storage.
    4079:      *
    4080:      * This method is protected by default in order to keep the public
    4081:      * api reasonable.  You can provide public methods for those you
    4082:      * actually need in Product.
    4083:      *
    4084:      * @param Criteria $criteria optional Criteria object to narrow the query
    4085:      * @param PropelPDO $con optional connection object
    4086:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    4087:      * @return PropelObjectCollection|Document[] List of Document objects
    4088:      */
    4089:     public function getDocumentsJoinFolder($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    4090:     {
    4091:         $query = DocumentQuery::create(null, $criteria);
    4092:         $query->joinWith('Folder', $join_behavior);
    4093:
    4094:         return $this->getDocuments($query, $con);
    4095:     }
    4096:
    4097:     /**
    4098:      * Clears out the collAccessorysRelatedByProductId collection
    4099:      *
    4100:      * This does not modify the database; however, it will remove any associated objects, causing
    4101:      * them to be refetched by subsequent calls to accessor method.
    4102:      *
    4103:      * @return Product The current object (for fluent API support)
    4104:      * @see        addAccessorysRelatedByProductId()
    4105:      */
    4106:     public function clearAccessorysRelatedByProductId()
    4107:     {
    4108:         $this->collAccessorysRelatedByProductId = null; // important to set this to null since that means it is uninitialized
    4109:         $this->collAccessorysRelatedByProductIdPartial = null;
    4110:
    4111:         return $this;
    4112:     }
    4113:
    4114:     /**
    4115:      * reset is the collAccessorysRelatedByProductId collection loaded partially
    4116:      *
    4117:      * @return void
    4118:      */
    4119:     public function resetPartialAccessorysRelatedByProductId($v = true)
    4120:     {
    4121:         $this->collAccessorysRelatedByProductIdPartial = $v;
    4122:     }
    4123:
    4124:     /**
    4125:      * Initializes the collAccessorysRelatedByProductId collection.
    4126:      *
    4127:      * By default this just sets the collAccessorysRelatedByProductId collection to an empty array (like clearcollAccessorysRelatedByProductId());
    4128:      * however, you may wish to override this method in your stub class to provide setting appropriate
    4129:      * to your application -- for example, setting the initial array to the values stored in database.
    4130:      *
    4131:      * @param boolean $overrideExisting If set to true, the method call initializes
    4132:      *                                        the collection even if it is not empty
    4133:      *
    4134:      * @return void
    4135:      */
    4136:     public function initAccessorysRelatedByProductId($overrideExisting = true)
    4137:     {
    4138:         if (null !== $this->collAccessorysRelatedByProductId && !$overrideExisting) {
    4139:             return;
    4140:         }
    4141:         $this->collAccessorysRelatedByProductId = new PropelObjectCollection();
    4142:         $this->collAccessorysRelatedByProductId->setModel('Accessory');
    4143:     }
    4144:
    4145:     /**
    4146:      * Gets an array of Accessory objects which contain a foreign key that references this object.
    4147:      *
    4148:      * If the $criteria is not null, it is used to always fetch the results from the database.
    4149:      * Otherwise the results are fetched from the database the first time, then cached.
    4150:      * Next time the same method is called without $criteria, the cached collection is returned.
    4151:      * If this Product is new, it will return
    4152:      * an empty collection or the current collection; the criteria is ignored on a new object.
    4153:      *
    4154:      * @param Criteria $criteria optional Criteria object to narrow the query
    4155:      * @param PropelPDO $con optional connection object
    4156:      * @return PropelObjectCollection|Accessory[] List of Accessory objects
    4157:      * @throws PropelException
    4158:      */
    4159:     public function getAccessorysRelatedByProductId($criteria = null, PropelPDO $con = null)
    4160:     {
    4161:         $partial = $this->collAccessorysRelatedByProductIdPartial && !$this->isNew();
    4162:         if (null === $this->collAccessorysRelatedByProductId || null !== $criteria  || $partial) {
    4163:             if ($this->isNew() && null === $this->collAccessorysRelatedByProductId) {
    4164:                 // return empty collection
    4165:                 $this->initAccessorysRelatedByProductId();
    4166:             } else {
    4167:                 $collAccessorysRelatedByProductId = AccessoryQuery::create(null, $criteria)
    4168:                     ->filterByProductRelatedByProductId($this)
    4169:                     ->find($con);
    4170:                 if (null !== $criteria) {
    4171:                     if (false !== $this->collAccessorysRelatedByProductIdPartial && count($collAccessorysRelatedByProductId)) {
    4172:                       $this->initAccessorysRelatedByProductId(false);
    4173:
    4174:                       foreach($collAccessorysRelatedByProductId as $obj) {
    4175:                         if (false == $this->collAccessorysRelatedByProductId->contains($obj)) {
    4176:                           $this->collAccessorysRelatedByProductId->append($obj);
    4177:                         }
    4178:                       }
    4179:
    4180:                       $this->collAccessorysRelatedByProductIdPartial = true;
    4181:                     }
    4182:
    4183:                     $collAccessorysRelatedByProductId->getInternalIterator()->rewind();
    4184:                     return $collAccessorysRelatedByProductId;
    4185:                 }
    4186:
    4187:                 if($partial && $this->collAccessorysRelatedByProductId) {
    4188:                     foreach($this->collAccessorysRelatedByProductId as $obj) {
    4189:                         if($obj->isNew()) {
    4190:                             $collAccessorysRelatedByProductId[] = $obj;
    4191:                         }
    4192:                     }
    4193:                 }
    4194:
    4195:                 $this->collAccessorysRelatedByProductId = $collAccessorysRelatedByProductId;
    4196:                 $this->collAccessorysRelatedByProductIdPartial = false;
    4197:             }
    4198:         }
    4199:
    4200:         return $this->collAccessorysRelatedByProductId;
    4201:     }
    4202:
    4203:     /**
    4204:      * Sets a collection of AccessoryRelatedByProductId objects related by a one-to-many relationship
    4205:      * to the current object.
    4206:      * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
    4207:      * and new objects from the given Propel collection.
    4208:      *
    4209:      * @param PropelCollection $accessorysRelatedByProductId A Propel collection.
    4210:      * @param PropelPDO $con Optional connection object
    4211:      * @return Product The current object (for fluent API support)
    4212:      */
    4213:     public function setAccessorysRelatedByProductId(PropelCollection $accessorysRelatedByProductId, PropelPDO $con = null)
    4214:     {
    4215:         $accessorysRelatedByProductIdToDelete = $this->getAccessorysRelatedByProductId(new Criteria(), $con)->diff($accessorysRelatedByProductId);
    4216:
    4217:         $this->accessorysRelatedByProductIdScheduledForDeletion = unserialize(serialize($accessorysRelatedByProductIdToDelete));
    4218:
    4219:         foreach ($accessorysRelatedByProductIdToDelete as $accessoryRelatedByProductIdRemoved) {
    4220:             $accessoryRelatedByProductIdRemoved->setProductRelatedByProductId(null);
    4221:         }
    4222:
    4223:         $this->collAccessorysRelatedByProductId = null;
    4224:         foreach ($accessorysRelatedByProductId as $accessoryRelatedByProductId) {
    4225:             $this->addAccessoryRelatedByProductId($accessoryRelatedByProductId);
    4226:         }
    4227:
    4228:         $this->collAccessorysRelatedByProductId = $accessorysRelatedByProductId;
    4229:         $this->collAccessorysRelatedByProductIdPartial = false;
    4230:
    4231:         return $this;
    4232:     }
    4233:
    4234:     /**
    4235:      * Returns the number of related Accessory objects.
    4236:      *
    4237:      * @param Criteria $criteria
    4238:      * @param boolean $distinct
    4239:      * @param PropelPDO $con
    4240:      * @return int             Count of related Accessory objects.
    4241:      * @throws PropelException
    4242:      */
    4243:     public function countAccessorysRelatedByProductId(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
    4244:     {
    4245:         $partial = $this->collAccessorysRelatedByProductIdPartial && !$this->isNew();
    4246:         if (null === $this->collAccessorysRelatedByProductId || null !== $criteria || $partial) {
    4247:             if ($this->isNew() && null === $this->collAccessorysRelatedByProductId) {
    4248:                 return 0;
    4249:             }
    4250:
    4251:             if($partial && !$criteria) {
    4252:                 return count($this->getAccessorysRelatedByProductId());
    4253:             }
    4254:             $query = AccessoryQuery::create(null, $criteria);
    4255:             if ($distinct) {
    4256:                 $query->distinct();
    4257:             }
    4258:
    4259:             return $query
    4260:                 ->filterByProductRelatedByProductId($this)
    4261:                 ->count($con);
    4262:         }
    4263:
    4264:         return count($this->collAccessorysRelatedByProductId);
    4265:     }
    4266:
    4267:     /**
    4268:      * Method called to associate a Accessory object to this object
    4269:      * through the Accessory foreign key attribute.
    4270:      *
    4271:      * @param    Accessory $l Accessory
    4272:      * @return Product The current object (for fluent API support)
    4273:      */
    4274:     public function addAccessoryRelatedByProductId(Accessory $l)
    4275:     {
    4276:         if ($this->collAccessorysRelatedByProductId === null) {
    4277:             $this->initAccessorysRelatedByProductId();
    4278:             $this->collAccessorysRelatedByProductIdPartial = true;
    4279:         }
    4280:         if (!in_array($l, $this->collAccessorysRelatedByProductId->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
    4281:             $this->doAddAccessoryRelatedByProductId($l);
    4282:         }
    4283:
    4284:         return $this;
    4285:     }
    4286:
    4287:     /**
    4288:      * @param   AccessoryRelatedByProductId $accessoryRelatedByProductId The accessoryRelatedByProductId object to add.
    4289:      */
    4290:     protected function doAddAccessoryRelatedByProductId($accessoryRelatedByProductId)
    4291:     {
    4292:         $this->collAccessorysRelatedByProductId[]= $accessoryRelatedByProductId;
    4293:         $accessoryRelatedByProductId->setProductRelatedByProductId($this);
    4294:     }
    4295:
    4296:     /**
    4297:      * @param   AccessoryRelatedByProductId $accessoryRelatedByProductId The accessoryRelatedByProductId object to remove.
    4298:      * @return Product The current object (for fluent API support)
    4299:      */
    4300:     public function removeAccessoryRelatedByProductId($accessoryRelatedByProductId)
    4301:     {
    4302:         if ($this->getAccessorysRelatedByProductId()->contains($accessoryRelatedByProductId)) {
    4303:             $this->collAccessorysRelatedByProductId->remove($this->collAccessorysRelatedByProductId->search($accessoryRelatedByProductId));
    4304:             if (null === $this->accessorysRelatedByProductIdScheduledForDeletion) {
    4305:                 $this->accessorysRelatedByProductIdScheduledForDeletion = clone $this->collAccessorysRelatedByProductId;
    4306:                 $this->accessorysRelatedByProductIdScheduledForDeletion->clear();
    4307:             }
    4308:             $this->accessorysRelatedByProductIdScheduledForDeletion[]= clone $accessoryRelatedByProductId;
    4309:             $accessoryRelatedByProductId->setProductRelatedByProductId(null);
    4310:         }
    4311:
    4312:         return $this;
    4313:     }
    4314:
    4315:     /**
    4316:      * Clears out the collAccessorysRelatedByAccessory collection
    4317:      *
    4318:      * This does not modify the database; however, it will remove any associated objects, causing
    4319:      * them to be refetched by subsequent calls to accessor method.
    4320:      *
    4321:      * @return Product The current object (for fluent API support)
    4322:      * @see        addAccessorysRelatedByAccessory()
    4323:      */
    4324:     public function clearAccessorysRelatedByAccessory()
    4325:     {
    4326:         $this->collAccessorysRelatedByAccessory = null; // important to set this to null since that means it is uninitialized
    4327:         $this->collAccessorysRelatedByAccessoryPartial = null;
    4328:
    4329:         return $this;
    4330:     }
    4331:
    4332:     /**
    4333:      * reset is the collAccessorysRelatedByAccessory collection loaded partially
    4334:      *
    4335:      * @return void
    4336:      */
    4337:     public function resetPartialAccessorysRelatedByAccessory($v = true)
    4338:     {
    4339:         $this->collAccessorysRelatedByAccessoryPartial = $v;
    4340:     }
    4341:
    4342:     /**
    4343:      * Initializes the collAccessorysRelatedByAccessory collection.
    4344:      *
    4345:      * By default this just sets the collAccessorysRelatedByAccessory collection to an empty array (like clearcollAccessorysRelatedByAccessory());
    4346:      * however, you may wish to override this method in your stub class to provide setting appropriate
    4347:      * to your application -- for example, setting the initial array to the values stored in database.
    4348:      *
    4349:      * @param boolean $overrideExisting If set to true, the method call initializes
    4350:      *                                        the collection even if it is not empty
    4351:      *
    4352:      * @return void
    4353:      */
    4354:     public function initAccessorysRelatedByAccessory($overrideExisting = true)
    4355:     {
    4356:         if (null !== $this->collAccessorysRelatedByAccessory && !$overrideExisting) {
    4357:             return;
    4358:         }
    4359:         $this->collAccessorysRelatedByAccessory = new PropelObjectCollection();
    4360:         $this->collAccessorysRelatedByAccessory->setModel('Accessory');
    4361:     }
    4362:
    4363:     /**
    4364:      * Gets an array of Accessory objects which contain a foreign key that references this object.
    4365:      *
    4366:      * If the $criteria is not null, it is used to always fetch the results from the database.
    4367:      * Otherwise the results are fetched from the database the first time, then cached.
    4368:      * Next time the same method is called without $criteria, the cached collection is returned.
    4369:      * If this Product is new, it will return
    4370:      * an empty collection or the current collection; the criteria is ignored on a new object.
    4371:      *
    4372:      * @param Criteria $criteria optional Criteria object to narrow the query
    4373:      * @param PropelPDO $con optional connection object
    4374:      * @return PropelObjectCollection|Accessory[] List of Accessory objects
    4375:      * @throws PropelException
    4376:      */
    4377:     public function getAccessorysRelatedByAccessory($criteria = null, PropelPDO $con = null)
    4378:     {
    4379:         $partial = $this->collAccessorysRelatedByAccessoryPartial && !$this->isNew();
    4380:         if (null === $this->collAccessorysRelatedByAccessory || null !== $criteria  || $partial) {
    4381:             if ($this->isNew() && null === $this->collAccessorysRelatedByAccessory) {
    4382:                 // return empty collection
    4383:                 $this->initAccessorysRelatedByAccessory();
    4384:             } else {
    4385:                 $collAccessorysRelatedByAccessory = AccessoryQuery::create(null, $criteria)
    4386:                     ->filterByProductRelatedByAccessory($this)
    4387:                     ->find($con);
    4388:                 if (null !== $criteria) {
    4389:                     if (false !== $this->collAccessorysRelatedByAccessoryPartial && count($collAccessorysRelatedByAccessory)) {
    4390:                       $this->initAccessorysRelatedByAccessory(false);
    4391:
    4392:                       foreach($collAccessorysRelatedByAccessory as $obj) {
    4393:                         if (false == $this->collAccessorysRelatedByAccessory->contains($obj)) {
    4394:                           $this->collAccessorysRelatedByAccessory->append($obj);
    4395:                         }
    4396:                       }
    4397:
    4398:                       $this->collAccessorysRelatedByAccessoryPartial = true;
    4399:                     }
    4400:
    4401:                     $collAccessorysRelatedByAccessory->getInternalIterator()->rewind();
    4402:                     return $collAccessorysRelatedByAccessory;
    4403:                 }
    4404:
    4405:                 if($partial && $this->collAccessorysRelatedByAccessory) {
    4406:                     foreach($this->collAccessorysRelatedByAccessory as $obj) {
    4407:                         if($obj->isNew()) {
    4408:                             $collAccessorysRelatedByAccessory[] = $obj;
    4409:                         }
    4410:                     }
    4411:                 }
    4412:
    4413:                 $this->collAccessorysRelatedByAccessory = $collAccessorysRelatedByAccessory;
    4414:                 $this->collAccessorysRelatedByAccessoryPartial = false;
    4415:             }
    4416:         }
    4417:
    4418:         return $this->collAccessorysRelatedByAccessory;
    4419:     }
    4420:
    4421:     /**
    4422:      * Sets a collection of AccessoryRelatedByAccessory objects related by a one-to-many relationship
    4423:      * to the current object.
    4424:      * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
    4425:      * and new objects from the given Propel collection.
    4426:      *
    4427:      * @param PropelCollection $accessorysRelatedByAccessory A Propel collection.
    4428:      * @param PropelPDO $con Optional connection object
    4429:      * @return Product The current object (for fluent API support)
    4430:      */
    4431:     public function setAccessorysRelatedByAccessory(PropelCollection $accessorysRelatedByAccessory, PropelPDO $con = null)
    4432:     {
    4433:         $accessorysRelatedByAccessoryToDelete = $this->getAccessorysRelatedByAccessory(new Criteria(), $con)->diff($accessorysRelatedByAccessory);
    4434:
    4435:         $this->accessorysRelatedByAccessoryScheduledForDeletion = unserialize(serialize($accessorysRelatedByAccessoryToDelete));
    4436:
    4437:         foreach ($accessorysRelatedByAccessoryToDelete as $accessoryRelatedByAccessoryRemoved) {
    4438:             $accessoryRelatedByAccessoryRemoved->setProductRelatedByAccessory(null);
    4439:         }
    4440:
    4441:         $this->collAccessorysRelatedByAccessory = null;
    4442:         foreach ($accessorysRelatedByAccessory as $accessoryRelatedByAccessory) {
    4443:             $this->addAccessoryRelatedByAccessory($accessoryRelatedByAccessory);
    4444:         }
    4445:
    4446:         $this->collAccessorysRelatedByAccessory = $accessorysRelatedByAccessory;
    4447:         $this->collAccessorysRelatedByAccessoryPartial = false;
    4448:
    4449:         return $this;
    4450:     }
    4451:
    4452:     /**
    4453:      * Returns the number of related Accessory objects.
    4454:      *
    4455:      * @param Criteria $criteria
    4456:      * @param boolean $distinct
    4457:      * @param PropelPDO $con
    4458:      * @return int             Count of related Accessory objects.
    4459:      * @throws PropelException
    4460:      */
    4461:     public function countAccessorysRelatedByAccessory(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
    4462:     {
    4463:         $partial = $this->collAccessorysRelatedByAccessoryPartial && !$this->isNew();
    4464:         if (null === $this->collAccessorysRelatedByAccessory || null !== $criteria || $partial) {
    4465:             if ($this->isNew() && null === $this->collAccessorysRelatedByAccessory) {
    4466:                 return 0;
    4467:             }
    4468:
    4469:             if($partial && !$criteria) {
    4470:                 return count($this->getAccessorysRelatedByAccessory());
    4471:             }
    4472:             $query = AccessoryQuery::create(null, $criteria);
    4473:             if ($distinct) {
    4474:                 $query->distinct();
    4475:             }
    4476:
    4477:             return $query
    4478:                 ->filterByProductRelatedByAccessory($this)
    4479:                 ->count($con);
    4480:         }
    4481:
    4482:         return count($this->collAccessorysRelatedByAccessory);
    4483:     }
    4484:
    4485:     /**
    4486:      * Method called to associate a Accessory object to this object
    4487:      * through the Accessory foreign key attribute.
    4488:      *
    4489:      * @param    Accessory $l Accessory
    4490:      * @return Product The current object (for fluent API support)
    4491:      */
    4492:     public function addAccessoryRelatedByAccessory(Accessory $l)
    4493:     {
    4494:         if ($this->collAccessorysRelatedByAccessory === null) {
    4495:             $this->initAccessorysRelatedByAccessory();
    4496:             $this->collAccessorysRelatedByAccessoryPartial = true;
    4497:         }
    4498:         if (!in_array($l, $this->collAccessorysRelatedByAccessory->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
    4499:             $this->doAddAccessoryRelatedByAccessory($l);
    4500:         }
    4501:
    4502:         return $this;
    4503:     }
    4504:
    4505:     /**
    4506:      * @param   AccessoryRelatedByAccessory $accessoryRelatedByAccessory The accessoryRelatedByAccessory object to add.
    4507:      */
    4508:     protected function doAddAccessoryRelatedByAccessory($accessoryRelatedByAccessory)
    4509:     {
    4510:         $this->collAccessorysRelatedByAccessory[]= $accessoryRelatedByAccessory;
    4511:         $accessoryRelatedByAccessory->setProductRelatedByAccessory($this);
    4512:     }
    4513:
    4514:     /**
    4515:      * @param   AccessoryRelatedByAccessory $accessoryRelatedByAccessory The accessoryRelatedByAccessory object to remove.
    4516:      * @return Product The current object (for fluent API support)
    4517:      */
    4518:     public function removeAccessoryRelatedByAccessory($accessoryRelatedByAccessory)
    4519:     {
    4520:         if ($this->getAccessorysRelatedByAccessory()->contains($accessoryRelatedByAccessory)) {
    4521:             $this->collAccessorysRelatedByAccessory->remove($this->collAccessorysRelatedByAccessory->search($accessoryRelatedByAccessory));
    4522:             if (null === $this->accessorysRelatedByAccessoryScheduledForDeletion) {
    4523:                 $this->accessorysRelatedByAccessoryScheduledForDeletion = clone $this->collAccessorysRelatedByAccessory;
    4524:                 $this->accessorysRelatedByAccessoryScheduledForDeletion->clear();
    4525:             }
    4526:             $this->accessorysRelatedByAccessoryScheduledForDeletion[]= clone $accessoryRelatedByAccessory;
    4527:             $accessoryRelatedByAccessory->setProductRelatedByAccessory(null);
    4528:         }
    4529:
    4530:         return $this;
    4531:     }
    4532:
    4533:     /**
    4534:      * Clears out the collRewritings collection
    4535:      *
    4536:      * This does not modify the database; however, it will remove any associated objects, causing
    4537:      * them to be refetched by subsequent calls to accessor method.
    4538:      *
    4539:      * @return Product The current object (for fluent API support)
    4540:      * @see        addRewritings()
    4541:      */
    4542:     public function clearRewritings()
    4543:     {
    4544:         $this->collRewritings = null; // important to set this to null since that means it is uninitialized
    4545:         $this->collRewritingsPartial = null;
    4546:
    4547:         return $this;
    4548:     }
    4549:
    4550:     /**
    4551:      * reset is the collRewritings collection loaded partially
    4552:      *
    4553:      * @return void
    4554:      */
    4555:     public function resetPartialRewritings($v = true)
    4556:     {
    4557:         $this->collRewritingsPartial = $v;
    4558:     }
    4559:
    4560:     /**
    4561:      * Initializes the collRewritings collection.
    4562:      *
    4563:      * By default this just sets the collRewritings collection to an empty array (like clearcollRewritings());
    4564:      * however, you may wish to override this method in your stub class to provide setting appropriate
    4565:      * to your application -- for example, setting the initial array to the values stored in database.
    4566:      *
    4567:      * @param boolean $overrideExisting If set to true, the method call initializes
    4568:      *                                        the collection even if it is not empty
    4569:      *
    4570:      * @return void
    4571:      */
    4572:     public function initRewritings($overrideExisting = true)
    4573:     {
    4574:         if (null !== $this->collRewritings && !$overrideExisting) {
    4575:             return;
    4576:         }
    4577:         $this->collRewritings = new PropelObjectCollection();
    4578:         $this->collRewritings->setModel('Rewriting');
    4579:     }
    4580:
    4581:     /**
    4582:      * Gets an array of Rewriting objects which contain a foreign key that references this object.
    4583:      *
    4584:      * If the $criteria is not null, it is used to always fetch the results from the database.
    4585:      * Otherwise the results are fetched from the database the first time, then cached.
    4586:      * Next time the same method is called without $criteria, the cached collection is returned.
    4587:      * If this Product is new, it will return
    4588:      * an empty collection or the current collection; the criteria is ignored on a new object.
    4589:      *
    4590:      * @param Criteria $criteria optional Criteria object to narrow the query
    4591:      * @param PropelPDO $con optional connection object
    4592:      * @return PropelObjectCollection|Rewriting[] List of Rewriting objects
    4593:      * @throws PropelException
    4594:      */
    4595:     public function getRewritings($criteria = null, PropelPDO $con = null)
    4596:     {
    4597:         $partial = $this->collRewritingsPartial && !$this->isNew();
    4598:         if (null === $this->collRewritings || null !== $criteria  || $partial) {
    4599:             if ($this->isNew() && null === $this->collRewritings) {
    4600:                 // return empty collection
    4601:                 $this->initRewritings();
    4602:             } else {
    4603:                 $collRewritings = RewritingQuery::create(null, $criteria)
    4604:                     ->filterByProduct($this)
    4605:                     ->find($con);
    4606:                 if (null !== $criteria) {
    4607:                     if (false !== $this->collRewritingsPartial && count($collRewritings)) {
    4608:                       $this->initRewritings(false);
    4609:
    4610:                       foreach($collRewritings as $obj) {
    4611:                         if (false == $this->collRewritings->contains($obj)) {
    4612:                           $this->collRewritings->append($obj);
    4613:                         }
    4614:                       }
    4615:
    4616:                       $this->collRewritingsPartial = true;
    4617:                     }
    4618:
    4619:                     $collRewritings->getInternalIterator()->rewind();
    4620:                     return $collRewritings;
    4621:                 }
    4622:
    4623:                 if($partial && $this->collRewritings) {
    4624:                     foreach($this->collRewritings as $obj) {
    4625:                         if($obj->isNew()) {
    4626:                             $collRewritings[] = $obj;
    4627:                         }
    4628:                     }
    4629:                 }
    4630:
    4631:                 $this->collRewritings = $collRewritings;
    4632:                 $this->collRewritingsPartial = false;
    4633:             }
    4634:         }
    4635:
    4636:         return $this->collRewritings;
    4637:     }
    4638:
    4639:     /**
    4640:      * Sets a collection of Rewriting objects related by a one-to-many relationship
    4641:      * to the current object.
    4642:      * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
    4643:      * and new objects from the given Propel collection.
    4644:      *
    4645:      * @param PropelCollection $rewritings A Propel collection.
    4646:      * @param PropelPDO $con Optional connection object
    4647:      * @return Product The current object (for fluent API support)
    4648:      */
    4649:     public function setRewritings(PropelCollection $rewritings, PropelPDO $con = null)
    4650:     {
    4651:         $rewritingsToDelete = $this->getRewritings(new Criteria(), $con)->diff($rewritings);
    4652:
    4653:         $this->rewritingsScheduledForDeletion = unserialize(serialize($rewritingsToDelete));
    4654:
    4655:         foreach ($rewritingsToDelete as $rewritingRemoved) {
    4656:             $rewritingRemoved->setProduct(null);
    4657:         }
    4658:
    4659:         $this->collRewritings = null;
    4660:         foreach ($rewritings as $rewriting) {
    4661:             $this->addRewriting($rewriting);
    4662:         }
    4663:
    4664:         $this->collRewritings = $rewritings;
    4665:         $this->collRewritingsPartial = false;
    4666:
    4667:         return $this;
    4668:     }
    4669:
    4670:     /**
    4671:      * Returns the number of related Rewriting objects.
    4672:      *
    4673:      * @param Criteria $criteria
    4674:      * @param boolean $distinct
    4675:      * @param PropelPDO $con
    4676:      * @return int             Count of related Rewriting objects.
    4677:      * @throws PropelException
    4678:      */
    4679:     public function countRewritings(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
    4680:     {
    4681:         $partial = $this->collRewritingsPartial && !$this->isNew();
    4682:         if (null === $this->collRewritings || null !== $criteria || $partial) {
    4683:             if ($this->isNew() && null === $this->collRewritings) {
    4684:                 return 0;
    4685:             }
    4686:
    4687:             if($partial && !$criteria) {
    4688:                 return count($this->getRewritings());
    4689:             }
    4690:             $query = RewritingQuery::create(null, $criteria);
    4691:             if ($distinct) {
    4692:                 $query->distinct();
    4693:             }
    4694:
    4695:             return $query
    4696:                 ->filterByProduct($this)
    4697:                 ->count($con);
    4698:         }
    4699:
    4700:         return count($this->collRewritings);
    4701:     }
    4702:
    4703:     /**
    4704:      * Method called to associate a Rewriting object to this object
    4705:      * through the Rewriting foreign key attribute.
    4706:      *
    4707:      * @param    Rewriting $l Rewriting
    4708:      * @return Product The current object (for fluent API support)
    4709:      */
    4710:     public function addRewriting(Rewriting $l)
    4711:     {
    4712:         if ($this->collRewritings === null) {
    4713:             $this->initRewritings();
    4714:             $this->collRewritingsPartial = true;
    4715:         }
    4716:         if (!in_array($l, $this->collRewritings->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
    4717:             $this->doAddRewriting($l);
    4718:         }
    4719:
    4720:         return $this;
    4721:     }
    4722:
    4723:     /**
    4724:      * @param   Rewriting $rewriting The rewriting object to add.
    4725:      */
    4726:     protected function doAddRewriting($rewriting)
    4727:     {
    4728:         $this->collRewritings[]= $rewriting;
    4729:         $rewriting->setProduct($this);
    4730:     }
    4731:
    4732:     /**
    4733:      * @param   Rewriting $rewriting The rewriting object to remove.
    4734:      * @return Product The current object (for fluent API support)
    4735:      */
    4736:     public function removeRewriting($rewriting)
    4737:     {
    4738:         if ($this->getRewritings()->contains($rewriting)) {
    4739:             $this->collRewritings->remove($this->collRewritings->search($rewriting));
    4740:             if (null === $this->rewritingsScheduledForDeletion) {
    4741:                 $this->rewritingsScheduledForDeletion = clone $this->collRewritings;
    4742:                 $this->rewritingsScheduledForDeletion->clear();
    4743:             }
    4744:             $this->rewritingsScheduledForDeletion[]= $rewriting;
    4745:             $rewriting->setProduct(null);
    4746:         }
    4747:
    4748:         return $this;
    4749:     }
    4750:
    4751:
    4752:     /**
    4753:      * If this collection has already been initialized with
    4754:      * an identical criteria, it returns the collection.
    4755:      * Otherwise if this Product is new, it will return
    4756:      * an empty collection; or if this Product has previously
    4757:      * been saved, it will retrieve related Rewritings from storage.
    4758:      *
    4759:      * This method is protected by default in order to keep the public
    4760:      * api reasonable.  You can provide public methods for those you
    4761:      * actually need in Product.
    4762:      *
    4763:      * @param Criteria $criteria optional Criteria object to narrow the query
    4764:      * @param PropelPDO $con optional connection object
    4765:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    4766:      * @return PropelObjectCollection|Rewriting[] List of Rewriting objects
    4767:      */
    4768:     public function getRewritingsJoinCategory($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    4769:     {
    4770:         $query = RewritingQuery::create(null, $criteria);
    4771:         $query->joinWith('Category', $join_behavior);
    4772:
    4773:         return $this->getRewritings($query, $con);
    4774:     }
    4775:
    4776:
    4777:     /**
    4778:      * If this collection has already been initialized with
    4779:      * an identical criteria, it returns the collection.
    4780:      * Otherwise if this Product is new, it will return
    4781:      * an empty collection; or if this Product has previously
    4782:      * been saved, it will retrieve related Rewritings from storage.
    4783:      *
    4784:      * This method is protected by default in order to keep the public
    4785:      * api reasonable.  You can provide public methods for those you
    4786:      * actually need in Product.
    4787:      *
    4788:      * @param Criteria $criteria optional Criteria object to narrow the query
    4789:      * @param PropelPDO $con optional connection object
    4790:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    4791:      * @return PropelObjectCollection|Rewriting[] List of Rewriting objects
    4792:      */
    4793:     public function getRewritingsJoinFolder($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    4794:     {
    4795:         $query = RewritingQuery::create(null, $criteria);
    4796:         $query->joinWith('Folder', $join_behavior);
    4797:
    4798:         return $this->getRewritings($query, $con);
    4799:     }
    4800:
    4801:
    4802:     /**
    4803:      * If this collection has already been initialized with
    4804:      * an identical criteria, it returns the collection.
    4805:      * Otherwise if this Product is new, it will return
    4806:      * an empty collection; or if this Product has previously
    4807:      * been saved, it will retrieve related Rewritings from storage.
    4808:      *
    4809:      * This method is protected by default in order to keep the public
    4810:      * api reasonable.  You can provide public methods for those you
    4811:      * actually need in Product.
    4812:      *
    4813:      * @param Criteria $criteria optional Criteria object to narrow the query
    4814:      * @param PropelPDO $con optional connection object
    4815:      * @param string $join_behavior optional join type to use (defaults to Criteria::LEFT_JOIN)
    4816:      * @return PropelObjectCollection|Rewriting[] List of Rewriting objects
    4817:      */
    4818:     public function getRewritingsJoinContent($criteria = null, $con = null, $join_behavior = Criteria::LEFT_JOIN)
    4819:     {
    4820:         $query = RewritingQuery::create(null, $criteria);
    4821:         $query->joinWith('Content', $join_behavior);
    4822:
    4823:         return $this->getRewritings($query, $con);
    4824:     }
    4825:
    4826:     /**
    4827:      * Clears out the collProductI18ns collection
    4828:      *
    4829:      * This does not modify the database; however, it will remove any associated objects, causing
    4830:      * them to be refetched by subsequent calls to accessor method.
    4831:      *
    4832:      * @return Product The current object (for fluent API support)
    4833:      * @see        addProductI18ns()
    4834:      */
    4835:     public function clearProductI18ns()
    4836:     {
    4837:         $this->collProductI18ns = null; // important to set this to null since that means it is uninitialized
    4838:         $this->collProductI18nsPartial = null;
    4839:
    4840:         return $this;
    4841:     }
    4842:
    4843:     /**
    4844:      * reset is the collProductI18ns collection loaded partially
    4845:      *
    4846:      * @return void
    4847:      */
    4848:     public function resetPartialProductI18ns($v = true)
    4849:     {
    4850:         $this->collProductI18nsPartial = $v;
    4851:     }
    4852:
    4853:     /**
    4854:      * Initializes the collProductI18ns collection.
    4855:      *
    4856:      * By default this just sets the collProductI18ns collection to an empty array (like clearcollProductI18ns());
    4857:      * however, you may wish to override this method in your stub class to provide setting appropriate
    4858:      * to your application -- for example, setting the initial array to the values stored in database.
    4859:      *
    4860:      * @param boolean $overrideExisting If set to true, the method call initializes
    4861:      *                                        the collection even if it is not empty
    4862:      *
    4863:      * @return void
    4864:      */
    4865:     public function initProductI18ns($overrideExisting = true)
    4866:     {
    4867:         if (null !== $this->collProductI18ns && !$overrideExisting) {
    4868:             return;
    4869:         }
    4870:         $this->collProductI18ns = new PropelObjectCollection();
    4871:         $this->collProductI18ns->setModel('ProductI18n');
    4872:     }
    4873:
    4874:     /**
    4875:      * Gets an array of ProductI18n objects which contain a foreign key that references this object.
    4876:      *
    4877:      * If the $criteria is not null, it is used to always fetch the results from the database.
    4878:      * Otherwise the results are fetched from the database the first time, then cached.
    4879:      * Next time the same method is called without $criteria, the cached collection is returned.
    4880:      * If this Product is new, it will return
    4881:      * an empty collection or the current collection; the criteria is ignored on a new object.
    4882:      *
    4883:      * @param Criteria $criteria optional Criteria object to narrow the query
    4884:      * @param PropelPDO $con optional connection object
    4885:      * @return PropelObjectCollection|ProductI18n[] List of ProductI18n objects
    4886:      * @throws PropelException
    4887:      */
    4888:     public function getProductI18ns($criteria = null, PropelPDO $con = null)
    4889:     {
    4890:         $partial = $this->collProductI18nsPartial && !$this->isNew();
    4891:         if (null === $this->collProductI18ns || null !== $criteria  || $partial) {
    4892:             if ($this->isNew() && null === $this->collProductI18ns) {
    4893:                 // return empty collection
    4894:                 $this->initProductI18ns();
    4895:             } else {
    4896:                 $collProductI18ns = ProductI18nQuery::create(null, $criteria)
    4897:                     ->filterByProduct($this)
    4898:                     ->find($con);
    4899:                 if (null !== $criteria) {
    4900:                     if (false !== $this->collProductI18nsPartial && count($collProductI18ns)) {
    4901:                       $this->initProductI18ns(false);
    4902:
    4903:                       foreach($collProductI18ns as $obj) {
    4904:                         if (false == $this->collProductI18ns->contains($obj)) {
    4905:                           $this->collProductI18ns->append($obj);
    4906:                         }
    4907:                       }
    4908:
    4909:                       $this->collProductI18nsPartial = true;
    4910:                     }
    4911:
    4912:                     $collProductI18ns->getInternalIterator()->rewind();
    4913:                     return $collProductI18ns;
    4914:                 }
    4915:
    4916:                 if($partial && $this->collProductI18ns) {
    4917:                     foreach($this->collProductI18ns as $obj) {
    4918:                         if($obj->isNew()) {
    4919:                             $collProductI18ns[] = $obj;
    4920:                         }
    4921:                     }
    4922:                 }
    4923:
    4924:                 $this->collProductI18ns = $collProductI18ns;
    4925:                 $this->collProductI18nsPartial = false;
    4926:             }
    4927:         }
    4928:
    4929:         return $this->collProductI18ns;
    4930:     }
    4931:
    4932:     /**
    4933:      * Sets a collection of ProductI18n objects related by a one-to-many relationship
    4934:      * to the current object.
    4935:      * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
    4936:      * and new objects from the given Propel collection.
    4937:      *
    4938:      * @param PropelCollection $productI18ns A Propel collection.
    4939:      * @param PropelPDO $con Optional connection object
    4940:      * @return Product The current object (for fluent API support)
    4941:      */
    4942:     public function setProductI18ns(PropelCollection $productI18ns, PropelPDO $con = null)
    4943:     {
    4944:         $productI18nsToDelete = $this->getProductI18ns(new Criteria(), $con)->diff($productI18ns);
    4945:
    4946:         $this->productI18nsScheduledForDeletion = unserialize(serialize($productI18nsToDelete));
    4947:
    4948:         foreach ($productI18nsToDelete as $productI18nRemoved) {
    4949:             $productI18nRemoved->setProduct(null);
    4950:         }
    4951:
    4952:         $this->collProductI18ns = null;
    4953:         foreach ($productI18ns as $productI18n) {
    4954:             $this->addProductI18n($productI18n);
    4955:         }
    4956:
    4957:         $this->collProductI18ns = $productI18ns;
    4958:         $this->collProductI18nsPartial = false;
    4959:
    4960:         return $this;
    4961:     }
    4962:
    4963:     /**
    4964:      * Returns the number of related ProductI18n objects.
    4965:      *
    4966:      * @param Criteria $criteria
    4967:      * @param boolean $distinct
    4968:      * @param PropelPDO $con
    4969:      * @return int             Count of related ProductI18n objects.
    4970:      * @throws PropelException
    4971:      */
    4972:     public function countProductI18ns(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
    4973:     {
    4974:         $partial = $this->collProductI18nsPartial && !$this->isNew();
    4975:         if (null === $this->collProductI18ns || null !== $criteria || $partial) {
    4976:             if ($this->isNew() && null === $this->collProductI18ns) {
    4977:                 return 0;
    4978:             }
    4979:
    4980:             if($partial && !$criteria) {
    4981:                 return count($this->getProductI18ns());
    4982:             }
    4983:             $query = ProductI18nQuery::create(null, $criteria);
    4984:             if ($distinct) {
    4985:                 $query->distinct();
    4986:             }
    4987:
    4988:             return $query
    4989:                 ->filterByProduct($this)
    4990:                 ->count($con);
    4991:         }
    4992:
    4993:         return count($this->collProductI18ns);
    4994:     }
    4995:
    4996:     /**
    4997:      * Method called to associate a ProductI18n object to this object
    4998:      * through the ProductI18n foreign key attribute.
    4999:      *
    5000:      * @param    ProductI18n $l ProductI18n
    5001:      * @return Product The current object (for fluent API support)
    5002:      */
    5003:     public function addProductI18n(ProductI18n $l)
    5004:     {
    5005:         if ($l && $locale = $l->getLocale()) {
    5006:             $this->setLocale($locale);
    5007:             $this->currentTranslations[$locale] = $l;
    5008:         }
    5009:         if ($this->collProductI18ns === null) {
    5010:             $this->initProductI18ns();
    5011:             $this->collProductI18nsPartial = true;
    5012:         }
    5013:         if (!in_array($l, $this->collProductI18ns->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
    5014:             $this->doAddProductI18n($l);
    5015:         }
    5016:
    5017:         return $this;
    5018:     }
    5019:
    5020:     /**
    5021:      * @param   ProductI18n $productI18n The productI18n object to add.
    5022:      */
    5023:     protected function doAddProductI18n($productI18n)
    5024:     {
    5025:         $this->collProductI18ns[]= $productI18n;
    5026:         $productI18n->setProduct($this);
    5027:     }
    5028:
    5029:     /**
    5030:      * @param   ProductI18n $productI18n The productI18n object to remove.
    5031:      * @return Product The current object (for fluent API support)
    5032:      */
    5033:     public function removeProductI18n($productI18n)
    5034:     {
    5035:         if ($this->getProductI18ns()->contains($productI18n)) {
    5036:             $this->collProductI18ns->remove($this->collProductI18ns->search($productI18n));
    5037:             if (null === $this->productI18nsScheduledForDeletion) {
    5038:                 $this->productI18nsScheduledForDeletion = clone $this->collProductI18ns;
    5039:                 $this->productI18nsScheduledForDeletion->clear();
    5040:             }
    5041:             $this->productI18nsScheduledForDeletion[]= clone $productI18n;
    5042:             $productI18n->setProduct(null);
    5043:         }
    5044:
    5045:         return $this;
    5046:     }
    5047:
    5048:     /**
    5049:      * Clears out the collProductVersions collection
    5050:      *
    5051:      * This does not modify the database; however, it will remove any associated objects, causing
    5052:      * them to be refetched by subsequent calls to accessor method.
    5053:      *
    5054:      * @return Product The current object (for fluent API support)
    5055:      * @see        addProductVersions()
    5056:      */
    5057:     public function clearProductVersions()
    5058:     {
    5059:         $this->collProductVersions = null; // important to set this to null since that means it is uninitialized
    5060:         $this->collProductVersionsPartial = null;
    5061:
    5062:         return $this;
    5063:     }
    5064:
    5065:     /**
    5066:      * reset is the collProductVersions collection loaded partially
    5067:      *
    5068:      * @return void
    5069:      */
    5070:     public function resetPartialProductVersions($v = true)
    5071:     {
    5072:         $this->collProductVersionsPartial = $v;
    5073:     }
    5074:
    5075:     /**
    5076:      * Initializes the collProductVersions collection.
    5077:      *
    5078:      * By default this just sets the collProductVersions collection to an empty array (like clearcollProductVersions());
    5079:      * however, you may wish to override this method in your stub class to provide setting appropriate
    5080:      * to your application -- for example, setting the initial array to the values stored in database.
    5081:      *
    5082:      * @param boolean $overrideExisting If set to true, the method call initializes
    5083:      *                                        the collection even if it is not empty
    5084:      *
    5085:      * @return void
    5086:      */
    5087:     public function initProductVersions($overrideExisting = true)
    5088:     {
    5089:         if (null !== $this->collProductVersions && !$overrideExisting) {
    5090:             return;
    5091:         }
    5092:         $this->collProductVersions = new PropelObjectCollection();
    5093:         $this->collProductVersions->setModel('ProductVersion');
    5094:     }
    5095:
    5096:     /**
    5097:      * Gets an array of ProductVersion objects which contain a foreign key that references this object.
    5098:      *
    5099:      * If the $criteria is not null, it is used to always fetch the results from the database.
    5100:      * Otherwise the results are fetched from the database the first time, then cached.
    5101:      * Next time the same method is called without $criteria, the cached collection is returned.
    5102:      * If this Product is new, it will return
    5103:      * an empty collection or the current collection; the criteria is ignored on a new object.
    5104:      *
    5105:      * @param Criteria $criteria optional Criteria object to narrow the query
    5106:      * @param PropelPDO $con optional connection object
    5107:      * @return PropelObjectCollection|ProductVersion[] List of ProductVersion objects
    5108:      * @throws PropelException
    5109:      */
    5110:     public function getProductVersions($criteria = null, PropelPDO $con = null)
    5111:     {
    5112:         $partial = $this->collProductVersionsPartial && !$this->isNew();
    5113:         if (null === $this->collProductVersions || null !== $criteria  || $partial) {
    5114:             if ($this->isNew() && null === $this->collProductVersions) {
    5115:                 // return empty collection
    5116:                 $this->initProductVersions();
    5117:             } else {
    5118:                 $collProductVersions = ProductVersionQuery::create(null, $criteria)
    5119:                     ->filterByProduct($this)
    5120:                     ->find($con);
    5121:                 if (null !== $criteria) {
    5122:                     if (false !== $this->collProductVersionsPartial && count($collProductVersions)) {
    5123:                       $this->initProductVersions(false);
    5124:
    5125:                       foreach($collProductVersions as $obj) {
    5126:                         if (false == $this->collProductVersions->contains($obj)) {
    5127:                           $this->collProductVersions->append($obj);
    5128:                         }
    5129:                       }
    5130:
    5131:                       $this->collProductVersionsPartial = true;
    5132:                     }
    5133:
    5134:                     $collProductVersions->getInternalIterator()->rewind();
    5135:                     return $collProductVersions;
    5136:                 }
    5137:
    5138:                 if($partial && $this->collProductVersions) {
    5139:                     foreach($this->collProductVersions as $obj) {
    5140:                         if($obj->isNew()) {
    5141:                             $collProductVersions[] = $obj;
    5142:                         }
    5143:                     }
    5144:                 }
    5145:
    5146:                 $this->collProductVersions = $collProductVersions;
    5147:                 $this->collProductVersionsPartial = false;
    5148:             }
    5149:         }
    5150:
    5151:         return $this->collProductVersions;
    5152:     }
    5153:
    5154:     /**
    5155:      * Sets a collection of ProductVersion objects related by a one-to-many relationship
    5156:      * to the current object.
    5157:      * It will also schedule objects for deletion based on a diff between old objects (aka persisted)
    5158:      * and new objects from the given Propel collection.
    5159:      *
    5160:      * @param PropelCollection $productVersions A Propel collection.
    5161:      * @param PropelPDO $con Optional connection object
    5162:      * @return Product The current object (for fluent API support)
    5163:      */
    5164:     public function setProductVersions(PropelCollection $productVersions, PropelPDO $con = null)
    5165:     {
    5166:         $productVersionsToDelete = $this->getProductVersions(new Criteria(), $con)->diff($productVersions);
    5167:
    5168:         $this->productVersionsScheduledForDeletion = unserialize(serialize($productVersionsToDelete));
    5169:
    5170:         foreach ($productVersionsToDelete as $productVersionRemoved) {
    5171:             $productVersionRemoved->setProduct(null);
    5172:         }
    5173:
    5174:         $this->collProductVersions = null;
    5175:         foreach ($productVersions as $productVersion) {
    5176:             $this->addProductVersion($productVersion);
    5177:         }
    5178:
    5179:         $this->collProductVersions = $productVersions;
    5180:         $this->collProductVersionsPartial = false;
    5181:
    5182:         return $this;
    5183:     }
    5184:
    5185:     /**
    5186:      * Returns the number of related ProductVersion objects.
    5187:      *
    5188:      * @param Criteria $criteria
    5189:      * @param boolean $distinct
    5190:      * @param PropelPDO $con
    5191:      * @return int             Count of related ProductVersion objects.
    5192:      * @throws PropelException
    5193:      */
    5194:     public function countProductVersions(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
    5195:     {
    5196:         $partial = $this->collProductVersionsPartial && !$this->isNew();
    5197:         if (null === $this->collProductVersions || null !== $criteria || $partial) {
    5198:             if ($this->isNew() && null === $this->collProductVersions) {
    5199:                 return 0;
    5200:             }
    5201:
    5202:             if($partial && !$criteria) {
    5203:                 return count($this->getProductVersions());
    5204:             }
    5205:             $query = ProductVersionQuery::create(null, $criteria);
    5206:             if ($distinct) {
    5207:                 $query->distinct();
    5208:             }
    5209:
    5210:             return $query
    5211:                 ->filterByProduct($this)
    5212:                 ->count($con);
    5213:         }
    5214:
    5215:         return count($this->collProductVersions);
    5216:     }
    5217:
    5218:     /**
    5219:      * Method called to associate a ProductVersion object to this object
    5220:      * through the ProductVersion foreign key attribute.
    5221:      *
    5222:      * @param    ProductVersion $l ProductVersion
    5223:      * @return Product The current object (for fluent API support)
    5224:      */
    5225:     public function addProductVersion(ProductVersion $l)
    5226:     {
    5227:         if ($this->collProductVersions === null) {
    5228:             $this->initProductVersions();
    5229:             $this->collProductVersionsPartial = true;
    5230:         }
    5231:         if (!in_array($l, $this->collProductVersions->getArrayCopy(), true)) { // only add it if the **same** object is not already associated
    5232:             $this->doAddProductVersion($l);
    5233:         }
    5234:
    5235:         return $this;
    5236:     }
    5237:
    5238:     /**
    5239:      * @param   ProductVersion $productVersion The productVersion object to add.
    5240:      */
    5241:     protected function doAddProductVersion($productVersion)
    5242:     {
    5243:         $this->collProductVersions[]= $productVersion;
    5244:         $productVersion->setProduct($this);
    5245:     }
    5246:
    5247:     /**
    5248:      * @param   ProductVersion $productVersion The productVersion object to remove.
    5249:      * @return Product The current object (for fluent API support)
    5250:      */
    5251:     public function removeProductVersion($productVersion)
    5252:     {
    5253:         if ($this->getProductVersions()->contains($productVersion)) {
    5254:             $this->collProductVersions->remove($this->collProductVersions->search($productVersion));
    5255:             if (null === $this->productVersionsScheduledForDeletion) {
    5256:                 $this->productVersionsScheduledForDeletion = clone $this->collProductVersions;
    5257:                 $this->productVersionsScheduledForDeletion->clear();
    5258:             }
    5259:             $this->productVersionsScheduledForDeletion[]= clone $productVersion;
    5260:             $productVersion->setProduct(null);
    5261:         }
    5262:
    5263:         return $this;
    5264:     }
    5265:
    5266:     /**
    5267:      * Clears the current object and sets all attributes to their default values
    5268:      */
    5269:     public function clear()
    5270:     {
    5271:         $this->id = null;
    5272:         $this->tax_rule_id = null;
    5273:         $this->ref = null;
    5274:         $this->price = null;
    5275:         $this->price2 = null;
    5276:         $this->ecotax = null;
    5277:         $this->newness = null;
    5278:         $this->promo = null;
    5279:         $this->stock = null;
    5280:         $this->visible = null;
    5281:         $this->weight = null;
    5282:         $this->position = null;
    5283:         $this->created_at = null;
    5284:         $this->updated_at = null;
    5285:         $this->version = null;
    5286:         $this->version_created_at = null;
    5287:         $this->version_created_by = null;
    5288:         $this->alreadyInSave = false;
    5289:         $this->alreadyInValidation = false;
    5290:         $this->alreadyInClearAllReferencesDeep = false;
    5291:         $this->clearAllReferences();
    5292:         $this->applyDefaultValues();
    5293:         $this->resetModified();
    5294:         $this->setNew(true);
    5295:         $this->setDeleted(false);
    5296:     }
    5297:
    5298:     /**
    5299:      * Resets all references to other model objects or collections of model objects.
    5300:      *
    5301:      * This method is a user-space workaround for PHP's inability to garbage collect
    5302:      * objects with circular references (even in PHP 5.3). This is currently necessary
    5303:      * when using Propel in certain daemon or large-volumne/high-memory operations.
    5304:      *
    5305:      * @param boolean $deep Whether to also clear the references on all referrer objects.
    5306:      */
    5307:     public function clearAllReferences($deep = false)
    5308:     {
    5309:         if ($deep && !$this->alreadyInClearAllReferencesDeep) {
    5310:             $this->alreadyInClearAllReferencesDeep = true;
    5311:             if ($this->collProductCategorys) {
    5312:                 foreach ($this->collProductCategorys as $o) {
    5313:                     $o->clearAllReferences($deep);
    5314:                 }
    5315:             }
    5316:             if ($this->collFeatureProds) {
    5317:                 foreach ($this->collFeatureProds as $o) {
    5318:                     $o->clearAllReferences($deep);
    5319:                 }
    5320:             }
    5321:             if ($this->collStocks) {
    5322:                 foreach ($this->collStocks as $o) {
    5323:                     $o->clearAllReferences($deep);
    5324:                 }
    5325:             }
    5326:             if ($this->collContentAssocs) {
    5327:                 foreach ($this->collContentAssocs as $o) {
    5328:                     $o->clearAllReferences($deep);
    5329:                 }
    5330:             }
    5331:             if ($this->collImages) {
    5332:                 foreach ($this->collImages as $o) {
    5333:                     $o->clearAllReferences($deep);
    5334:                 }
    5335:             }
    5336:             if ($this->collDocuments) {
    5337:                 foreach ($this->collDocuments as $o) {
    5338:                     $o->clearAllReferences($deep);
    5339:                 }
    5340:             }
    5341:             if ($this->collAccessorysRelatedByProductId) {
    5342:                 foreach ($this->collAccessorysRelatedByProductId as $o) {
    5343:                     $o->clearAllReferences($deep);
    5344:                 }
    5345:             }
    5346:             if ($this->collAccessorysRelatedByAccessory) {
    5347:                 foreach ($this->collAccessorysRelatedByAccessory as $o) {
    5348:                     $o->clearAllReferences($deep);
    5349:                 }
    5350:             }
    5351:             if ($this->collRewritings) {
    5352:                 foreach ($this->collRewritings as $o) {
    5353:                     $o->clearAllReferences($deep);
    5354:                 }
    5355:             }
    5356:             if ($this->collProductI18ns) {
    5357:                 foreach ($this->collProductI18ns as $o) {
    5358:                     $o->clearAllReferences($deep);
    5359:                 }
    5360:             }
    5361:             if ($this->collProductVersions) {
    5362:                 foreach ($this->collProductVersions as $o) {
    5363:                     $o->clearAllReferences($deep);
    5364:                 }
    5365:             }
    5366:             if ($this->aTaxRule instanceof Persistent) {
    5367:               $this->aTaxRule->clearAllReferences($deep);
    5368:             }
    5369:
    5370:             $this->alreadyInClearAllReferencesDeep = false;
    5371:         } // if ($deep)
    5372:
    5373:         // i18n behavior
    5374:         $this->currentLocale = 'en_US';
    5375:         $this->currentTranslations = null;
    5376:
    5377:         if ($this->collProductCategorys instanceof PropelCollection) {
    5378:             $this->collProductCategorys->clearIterator();
    5379:         }
    5380:         $this->collProductCategorys = null;
    5381:         if ($this->collFeatureProds instanceof PropelCollection) {
    5382:             $this->collFeatureProds->clearIterator();
    5383:         }
    5384:         $this->collFeatureProds = null;
    5385:         if ($this->collStocks instanceof PropelCollection) {
    5386:             $this->collStocks->clearIterator();
    5387:         }
    5388:         $this->collStocks = null;
    5389:         if ($this->collContentAssocs instanceof PropelCollection) {
    5390:             $this->collContentAssocs->clearIterator();
    5391:         }
    5392:         $this->collContentAssocs = null;
    5393:         if ($this->collImages instanceof PropelCollection) {
    5394:             $this->collImages->clearIterator();
    5395:         }
    5396:         $this->collImages = null;
    5397:         if ($this->collDocuments instanceof PropelCollection) {
    5398:             $this->collDocuments->clearIterator();
    5399:         }
    5400:         $this->collDocuments = null;
    5401:         if ($this->collAccessorysRelatedByProductId instanceof PropelCollection) {
    5402:             $this->collAccessorysRelatedByProductId->clearIterator();
    5403:         }
    5404:         $this->collAccessorysRelatedByProductId = null;
    5405:         if ($this->collAccessorysRelatedByAccessory instanceof PropelCollection) {
    5406:             $this->collAccessorysRelatedByAccessory->clearIterator();
    5407:         }
    5408:         $this->collAccessorysRelatedByAccessory = null;
    5409:         if ($this->collRewritings instanceof PropelCollection) {
    5410:             $this->collRewritings->clearIterator();
    5411:         }
    5412:         $this->collRewritings = null;
    5413:         if ($this->collProductI18ns instanceof PropelCollection) {
    5414:             $this->collProductI18ns->clearIterator();
    5415:         }
    5416:         $this->collProductI18ns = null;
    5417:         if ($this->collProductVersions instanceof PropelCollection) {
    5418:             $this->collProductVersions->clearIterator();
    5419:         }
    5420:         $this->collProductVersions = null;
    5421:         $this->aTaxRule = null;
    5422:     }
    5423:
    5424:     /**
    5425:      * return the string representation of this object
    5426:      *
    5427:      * @return string
    5428:      */
    5429:     public function __toString()
    5430:     {
    5431:         return (string) $this->exportTo(ProductPeer::DEFAULT_STRING_FORMAT);
    5432:     }
    5433:
    5434:     /**
    5435:      * return true is the object is in saving state
    5436:      *
    5437:      * @return boolean
    5438:      */
    5439:     public function isAlreadyInSave()
    5440:     {
    5441:         return $this->alreadyInSave;
    5442:     }
    5443:
    5444:     // timestampable behavior
    5445:
    5446:     /**
    5447:      * Mark the current object so that the update date doesn't get updated during next save
    5448:      *
    5449:      * @return     Product The current object (for fluent API support)
    5450:      */
    5451:     public function keepUpdateDateUnchanged()
    5452:     {
    5453:         $this->modifiedColumns[] = ProductPeer::UPDATED_AT;
    5454:
    5455:         return $this;
    5456:     }
    5457:
    5458:     // i18n behavior
    5459:
    5460:     /**
    5461:      * Sets the locale for translations
    5462:      *
    5463:      * @param     string $locale Locale to use for the translation, e.g. 'fr_FR'
    5464:      *
    5465:      * @return    Product The current object (for fluent API support)
    5466:      */
    5467:     public function setLocale($locale = 'en_US')
    5468:     {
    5469:         $this->currentLocale = $locale;
    5470:
    5471:         return $this;
    5472:     }
    5473:
    5474:     /**
    5475:      * Gets the locale for translations
    5476:      *
    5477:      * @return    string $locale Locale to use for the translation, e.g. 'fr_FR'
    5478:      */
    5479:     public function getLocale()
    5480:     {
    5481:         return $this->currentLocale;
    5482:     }
    5483:
    5484:     /**
    5485:      * Returns the current translation for a given locale
    5486:      *
    5487:      * @param     string $locale Locale to use for the translation, e.g. 'fr_FR'
    5488:      * @param     PropelPDO $con an optional connection object
    5489:      *
    5490:      * @return ProductI18n */
    5491:     public function getTranslation($locale = 'en_US', PropelPDO $con = null)
    5492:     {
    5493:         if (!isset($this->currentTranslations[$locale])) {
    5494:             if (null !== $this->collProductI18ns) {
    5495:                 foreach ($this->collProductI18ns as $translation) {
    5496:                     if ($translation->getLocale() == $locale) {
    5497:                         $this->currentTranslations[$locale] = $translation;
    5498:
    5499:                         return $translation;
    5500:                     }
    5501:                 }
    5502:             }
    5503:             if ($this->isNew()) {
    5504:                 $translation = new ProductI18n();
    5505:                 $translation->setLocale($locale);
    5506:             } else {
    5507:                 $translation = ProductI18nQuery::create()
    5508:                     ->filterByPrimaryKey(array($this->getPrimaryKey(), $locale))
    5509:                     ->findOneOrCreate($con);
    5510:                 $this->currentTranslations[$locale] = $translation;
    5511:             }
    5512:             $this->addProductI18n($translation);
    5513:         }
    5514:
    5515:         return $this->currentTranslations[$locale];
    5516:     }
    5517:
    5518:     /**
    5519:      * Remove the translation for a given locale
    5520:      *
    5521:      * @param     string $locale Locale to use for the translation, e.g. 'fr_FR'
    5522:      * @param     PropelPDO $con an optional connection object
    5523:      *
    5524:      * @return    Product The current object (for fluent API support)
    5525:      */
    5526:     public function removeTranslation($locale = 'en_US', PropelPDO $con = null)
    5527:     {
    5528:         if (!$this->isNew()) {
    5529:             ProductI18nQuery::create()
    5530:                 ->filterByPrimaryKey(array($this->getPrimaryKey(), $locale))
    5531:                 ->delete($con);
    5532:         }
    5533:         if (isset($this->currentTranslations[$locale])) {
    5534:             unset($this->currentTranslations[$locale]);
    5535:         }
    5536:         foreach ($this->collProductI18ns as $key => $translation) {
    5537:             if ($translation->getLocale() == $locale) {
    5538:                 unset($this->collProductI18ns[$key]);
    5539:                 break;
    5540:             }
    5541:         }
    5542:
    5543:         return $this;
    5544:     }
    5545:
    5546:     /**
    5547:      * Returns the current translation
    5548:      *
    5549:      * @param     PropelPDO $con an optional connection object
    5550:      *
    5551:      * @return ProductI18n */
    5552:     public function getCurrentTranslation(PropelPDO $con = null)
    5553:     {
    5554:         return $this->getTranslation($this->getLocale(), $con);
    5555:     }
    5556:
    5557:
    5558:         /**
    5559:          * Get the [title] column value.
    5560:          *
    5561:          * @return string
    5562:          */
    5563:         public function getTitle()
    5564:         {
    5565:         return $this->getCurrentTranslation()->getTitle();
    5566:     }
    5567:
    5568:
    5569:         /**
    5570:          * Set the value of [title] column.
    5571:          *
    5572:          * @param string $v new value
    5573:          * @return ProductI18n The current object (for fluent API support)
    5574:          */
    5575:         public function setTitle($v)
    5576:         {    $this->getCurrentTranslation()->setTitle($v);
    5577:
    5578:         return $this;
    5579:     }
    5580:
    5581:
    5582:         /**
    5583:          * Get the [description] column value.
    5584:          *
    5585:          * @return string
    5586:          */
    5587:         public function getDescription()
    5588:         {
    5589:         return $this->getCurrentTranslation()->getDescription();
    5590:     }
    5591:
    5592:
    5593:         /**
    5594:          * Set the value of [description] column.
    5595:          *
    5596:          * @param string $v new value
    5597:          * @return ProductI18n The current object (for fluent API support)
    5598:          */
    5599:         public function setDescription($v)
    5600:         {    $this->getCurrentTranslation()->setDescription($v);
    5601:
    5602:         return $this;
    5603:     }
    5604:
    5605:
    5606:         /**
    5607:          * Get the [chapo] column value.
    5608:          *
    5609:          * @return string
    5610:          */
    5611:         public function getChapo()
    5612:         {
    5613:         return $this->getCurrentTranslation()->getChapo();
    5614:     }
    5615:
    5616:
    5617:         /**
    5618:          * Set the value of [chapo] column.
    5619:          *
    5620:          * @param string $v new value
    5621:          * @return ProductI18n The current object (for fluent API support)
    5622:          */
    5623:         public function setChapo($v)
    5624:         {    $this->getCurrentTranslation()->setChapo($v);
    5625:
    5626:         return $this;
    5627:     }
    5628:
    5629:
    5630:         /**
    5631:          * Get the [postscriptum] column value.
    5632:          *
    5633:          * @return string
    5634:          */
    5635:         public function getPostscriptum()
    5636:         {
    5637:         return $this->getCurrentTranslation()->getPostscriptum();
    5638:     }
    5639:
    5640:
    5641:         /**
    5642:          * Set the value of [postscriptum] column.
    5643:          *
    5644:          * @param string $v new value
    5645:          * @return ProductI18n The current object (for fluent API support)
    5646:          */
    5647:         public function setPostscriptum($v)
    5648:         {    $this->getCurrentTranslation()->setPostscriptum($v);
    5649:
    5650:         return $this;
    5651:     }
    5652:
    5653:     // versionable behavior
    5654:
    5655:     /**
    5656:      * Enforce a new Version of this object upon next save.
    5657:      *
    5658:      * @return Product
    5659:      */
    5660:     public function enforceVersioning()
    5661:     {
    5662:         $this->enforceVersion = true;
    5663:
    5664:         return $this;
    5665:     }
    5666:
    5667:     /**
    5668:      * Checks whether the current state must be recorded as a version
    5669:      *
    5670:      * @param PropelPDO $con An optional PropelPDO connection to use.
    5671:      *
    5672:      * @return  boolean
    5673:      */
    5674:     public function isVersioningNecessary($con = null)
    5675:     {
    5676:         if ($this->alreadyInSave) {
    5677:             return false;
    5678:         }
    5679:
    5680:         if ($this->enforceVersion) {
    5681:             return true;
    5682:         }
    5683:
    5684:         if (ProductPeer::isVersioningEnabled() && ($this->isNew() || $this->isModified() || $this->isDeleted())) {
    5685:             return true;
    5686:         }
    5687:
    5688:         return false;
    5689:     }
    5690:
    5691:     /**
    5692:      * Creates a version of the current object and saves it.
    5693:      *
    5694:      * @param   PropelPDO $con the connection to use
    5695:      *
    5696:      * @return  ProductVersion A version object
    5697:      */
    5698:     public function addVersion($con = null)
    5699:     {
    5700:         $this->enforceVersion = false;
    5701:
    5702:         $version = new ProductVersion();
    5703:         $version->setId($this->getId());
    5704:         $version->setTaxRuleId($this->getTaxRuleId());
    5705:         $version->setRef($this->getRef());
    5706:         $version->setPrice($this->getPrice());
    5707:         $version->setPrice2($this->getPrice2());
    5708:         $version->setEcotax($this->getEcotax());
    5709:         $version->setNewness($this->getNewness());
    5710:         $version->setPromo($this->getPromo());
    5711:         $version->setStock($this->getStock());
    5712:         $version->setVisible($this->getVisible());
    5713:         $version->setWeight($this->getWeight());
    5714:         $version->setPosition($this->getPosition());
    5715:         $version->setCreatedAt($this->getCreatedAt());
    5716:         $version->setUpdatedAt($this->getUpdatedAt());
    5717:         $version->setVersion($this->getVersion());
    5718:         $version->setVersionCreatedAt($this->getVersionCreatedAt());
    5719:         $version->setVersionCreatedBy($this->getVersionCreatedBy());
    5720:         $version->setProduct($this);
    5721:         $version->save($con);
    5722:
    5723:         return $version;
    5724:     }
    5725:
    5726:     /**
    5727:      * Sets the properties of the curent object to the value they had at a specific version
    5728:      *
    5729:      * @param   integer $versionNumber The version number to read
    5730:      * @param   PropelPDO $con the connection to use
    5731:      *
    5732:      * @return  Product The current object (for fluent API support)
    5733:      * @throws  PropelException - if no object with the given version can be found.
    5734:      */
    5735:     public function toVersion($versionNumber, $con = null)
    5736:     {
    5737:         $version = $this->getOneVersion($versionNumber, $con);
    5738:         if (!$version) {
    5739:             throw new PropelException(sprintf('No Product object found with version %d', $version));
    5740:         }
    5741:         $this->populateFromVersion($version, $con);
    5742:
    5743:         return $this;
    5744:     }
    5745:
    5746:     /**
    5747:      * Sets the properties of the curent object to the value they had at a specific version
    5748:      *
    5749:      * @param   ProductVersion $version The version object to use
    5750:      * @param   PropelPDO $con the connection to use
    5751:      * @param   array $loadedObjects objects thats been loaded in a chain of populateFromVersion calls on referrer or fk objects.
    5752:      *
    5753:      * @return  Product The current object (for fluent API support)
    5754:      */
    5755:     public function populateFromVersion($version, $con = null, &$loadedObjects = array())
    5756:     {
    5757:
    5758:         $loadedObjects['Product'][$version->getId()][$version->getVersion()] = $this;
    5759:         $this->setId($version->getId());
    5760:         $this->setTaxRuleId($version->getTaxRuleId());
    5761:         $this->setRef($version->getRef());
    5762:         $this->setPrice($version->getPrice());
    5763:         $this->setPrice2($version->getPrice2());
    5764:         $this->setEcotax($version->getEcotax());
    5765:         $this->setNewness($version->getNewness());
    5766:         $this->setPromo($version->getPromo());
    5767:         $this->setStock($version->getStock());
    5768:         $this->setVisible($version->getVisible());
    5769:         $this->setWeight($version->getWeight());
    5770:         $this->setPosition($version->getPosition());
    5771:         $this->setCreatedAt($version->getCreatedAt());
    5772:         $this->setUpdatedAt($version->getUpdatedAt());
    5773:         $this->setVersion($version->getVersion());
    5774:         $this->setVersionCreatedAt($version->getVersionCreatedAt());
    5775:         $this->setVersionCreatedBy($version->getVersionCreatedBy());
    5776:
    5777:         return $this;
    5778:     }
    5779:
    5780:     /**
    5781:      * Gets the latest persisted version number for the current object
    5782:      *
    5783:      * @param   PropelPDO $con the connection to use
    5784:      *
    5785:      * @return  integer
    5786:      */
    5787:     public function getLastVersionNumber($con = null)
    5788:     {
    5789:         $v = ProductVersionQuery::create()
    5790:             ->filterByProduct($this)
    5791:             ->orderByVersion('desc')
    5792:             ->findOne($con);
    5793:         if (!$v) {
    5794:             return 0;
    5795:         }
    5796:
    5797:         return $v->getVersion();
    5798:     }
    5799:
    5800:     /**
    5801:      * Checks whether the current object is the latest one
    5802:      *
    5803:      * @param   PropelPDO $con the connection to use
    5804:      *
    5805:      * @return  boolean
    5806:      */
    5807:     public function isLastVersion($con = null)
    5808:     {
    5809:         return $this->getLastVersionNumber($con) == $this->getVersion();
    5810:     }
    5811:
    5812:     /**
    5813:      * Retrieves a version object for this entity and a version number
    5814:      *
    5815:      * @param   integer $versionNumber The version number to read
    5816:      * @param   PropelPDO $con the connection to use
    5817:      *
    5818:      * @return  ProductVersion A version object
    5819:      */
    5820:     public function getOneVersion($versionNumber, $con = null)
    5821:     {
    5822:         return ProductVersionQuery::create()
    5823:             ->filterByProduct($this)
    5824:             ->filterByVersion($versionNumber)
    5825:             ->findOne($con);
    5826:     }
    5827:
    5828:     /**
    5829:      * Gets all the versions of this object, in incremental order
    5830:      *
    5831:      * @param   PropelPDO $con the connection to use
    5832:      *
    5833:      * @return  PropelObjectCollection A list of ProductVersion objects
    5834:      */
    5835:     public function getAllVersions($con = null)
    5836:     {
    5837:         $criteria = new Criteria();
    5838:         $criteria->addAscendingOrderByColumn(ProductVersionPeer::VERSION);
    5839:
    5840:         return $this->getProductVersions($criteria, $con);
    5841:     }
    5842:
    5843:     /**
    5844:      * Compares the current object with another of its version.
    5845:      * <code>
    5846:      * print_r($book->compareVersion(1));
    5847:      * => array(
    5848:      *   '1' => array('Title' => 'Book title at version 1'),
    5849:      *   '2' => array('Title' => 'Book title at version 2')
    5850:      * );
    5851:      * </code>
    5852:      *
    5853:      * @param   integer   $versionNumber
    5854:      * @param   string    $keys Main key used for the result diff (versions|columns)
    5855:      * @param   PropelPDO $con the connection to use
    5856:      * @param   array     $ignoredColumns  The columns to exclude from the diff.
    5857:      *
    5858:      * @return  array A list of differences
    5859:      */
    5860:     public function compareVersion($versionNumber, $keys = 'columns', $con = null, $ignoredColumns = array())
    5861:     {
    5862:         $fromVersion = $this->toArray();
    5863:         $toVersion = $this->getOneVersion($versionNumber, $con)->toArray();
    5864:
    5865:         return $this->computeDiff($fromVersion, $toVersion, $keys, $ignoredColumns);
    5866:     }
    5867:
    5868:     /**
    5869:      * Compares two versions of the current object.
    5870:      * <code>
    5871:      * print_r($book->compareVersions(1, 2));
    5872:      * => array(
    5873:      *   '1' => array('Title' => 'Book title at version 1'),
    5874:      *   '2' => array('Title' => 'Book title at version 2')
    5875:      * );
    5876:      * </code>
    5877:      *
    5878:      * @param   integer   $fromVersionNumber
    5879:      * @param   integer   $toVersionNumber
    5880:      * @param   string    $keys Main key used for the result diff (versions|columns)
    5881:      * @param   PropelPDO $con the connection to use
    5882:      * @param   array     $ignoredColumns  The columns to exclude from the diff.
    5883:      *
    5884:      * @return  array A list of differences
    5885:      */
    5886:     public function compareVersions($fromVersionNumber, $toVersionNumber, $keys = 'columns', $con = null, $ignoredColumns = array())
    5887:     {
    5888:         $fromVersion = $this->getOneVersion($fromVersionNumber, $con)->toArray();
    5889:         $toVersion = $this->getOneVersion($toVersionNumber, $con)->toArray();
    5890:
    5891:         return $this->computeDiff($fromVersion, $toVersion, $keys, $ignoredColumns);
    5892:     }
    5893:
    5894:     /**
    5895:      * Computes the diff between two versions.
    5896:      * <code>
    5897:      * print_r($this->computeDiff(1, 2));
    5898:      * => array(
    5899:      *   '1' => array('Title' => 'Book title at version 1'),
    5900:      *   '2' => array('Title' => 'Book title at version 2')
    5901:      * );
    5902:      * </code>
    5903:      *
    5904:      * @param   array     $fromVersion     An array representing the original version.
    5905:      * @param   array     $toVersion       An array representing the destination version.
    5906:      * @param   string    $keys            Main key used for the result diff (versions|columns).
    5907:      * @param   array     $ignoredColumns  The columns to exclude from the diff.
    5908:      *
    5909:      * @return  array A list of differences
    5910:      */
    5911:     protected function computeDiff($fromVersion, $toVersion, $keys = 'columns', $ignoredColumns = array())
    5912:     {
    5913:         $fromVersionNumber = $fromVersion['Version'];
    5914:         $toVersionNumber = $toVersion['Version'];
    5915:         $ignoredColumns = array_merge(array(
    5916:             'Version',
    5917:             'VersionCreatedAt',
    5918:             'VersionCreatedBy',
    5919:         ), $ignoredColumns);
    5920:         $diff = array();
    5921:         foreach ($fromVersion as $key => $value) {
    5922:             if (in_array($key, $ignoredColumns)) {
    5923:                 continue;
    5924:             }
    5925:             if ($toVersion[$key] != $value) {
    5926:                 switch ($keys) {
    5927:                     case 'versions':
    5928:                         $diff[$fromVersionNumber][$key] = $value;
    5929:                         $diff[$toVersionNumber][$key] = $toVersion[$key];
    5930:                         break;
    5931:                     default:
    5932:                         $diff[$key] = array(
    5933:                             $fromVersionNumber => $value,
    5934:                             $toVersionNumber => $toVersion[$key],
    5935:                         );
    5936:                         break;
    5937:                 }
    5938:             }
    5939:         }
    5940:
    5941:         return $diff;
    5942:     }
    5943:     /**
    5944:      * retrieve the last $number versions.
    5945:      *
    5946:      * @param integer $number the number of record to return.
    5947:      * @param ProductVersionQuery|Criteria $criteria Additional criteria to filter.
    5948:      * @param PropelPDO $con An optional connection to use.
    5949:      *
    5950:      * @return PropelCollection|ProductVersion[] List of ProductVersion objects
    5951:      */
    5952:     public function getLastVersions($number = 10, $criteria = null, PropelPDO $con = null)
    5953:     {
    5954:         $criteria = ProductVersionQuery::create(null, $criteria);
    5955:         $criteria->addDescendingOrderByColumn(ProductVersionPeer::VERSION);
    5956:         $criteria->limit($number);
    5957:
    5958:         return $this->getProductVersions($criteria, $con);
    5959:     }
    5960: }
    5961: