Overview

Namespaces

  • Thelia
    • Action
    • Controller
    • Core
      • Bundle
      • Event
      • EventListener
      • Template
        • BaseParam
    • Exception
    • Log
      • Destination
    • Model
      • map
      • om
    • Routing
      • Matcher
    • Tools
    • Tpex
      • BaseParam
      • Exception
      • Loop
      • Tests

Classes

  • BaseAccessory
  • BaseAccessoryPeer
  • BaseAccessoryQuery
  • BaseAddress
  • BaseAddressPeer
  • BaseAddressQuery
  • BaseAdmin
  • BaseAdminGroup
  • BaseAdminGroupPeer
  • BaseAdminGroupQuery
  • BaseAdminLog
  • BaseAdminLogPeer
  • BaseAdminLogQuery
  • BaseAdminPeer
  • BaseAdminQuery
  • BaseArea
  • BaseAreaPeer
  • BaseAreaQuery
  • BaseAttribute
  • BaseAttributeAv
  • BaseAttributeAvDesc
  • BaseAttributeAvDescPeer
  • BaseAttributeAvDescQuery
  • BaseAttributeAvI18n
  • BaseAttributeAvI18nPeer
  • BaseAttributeAvI18nQuery
  • BaseAttributeAvPeer
  • BaseAttributeAvQuery
  • BaseAttributeCategory
  • BaseAttributeCategoryPeer
  • BaseAttributeCategoryQuery
  • BaseAttributeCombination
  • BaseAttributeCombinationPeer
  • BaseAttributeCombinationQuery
  • BaseAttributeDesc
  • BaseAttributeDescPeer
  • BaseAttributeDescQuery
  • BaseAttributeI18n
  • BaseAttributeI18nPeer
  • BaseAttributeI18nQuery
  • BaseAttributePeer
  • BaseAttributeQuery
  • BaseCategory
  • BaseCategoryDesc
  • BaseCategoryDescPeer
  • BaseCategoryDescQuery
  • BaseCategoryI18n
  • BaseCategoryI18nPeer
  • BaseCategoryI18nQuery
  • BaseCategoryPeer
  • BaseCategoryQuery
  • BaseCategoryVersion
  • BaseCategoryVersionPeer
  • BaseCategoryVersionQuery
  • BaseCombination
  • BaseCombinationPeer
  • BaseCombinationQuery
  • BaseConfig
  • BaseConfigDesc
  • BaseConfigDescPeer
  • BaseConfigDescQuery
  • BaseConfigI18n
  • BaseConfigI18nPeer
  • BaseConfigI18nQuery
  • BaseConfigPeer
  • BaseConfigQuery
  • BaseContent
  • BaseContentAssoc
  • BaseContentAssocPeer
  • BaseContentAssocQuery
  • BaseContentDesc
  • BaseContentDescPeer
  • BaseContentDescQuery
  • BaseContentFolder
  • BaseContentFolderPeer
  • BaseContentFolderQuery
  • BaseContentI18n
  • BaseContentI18nPeer
  • BaseContentI18nQuery
  • BaseContentPeer
  • BaseContentQuery
  • BaseContentVersion
  • BaseContentVersionPeer
  • BaseContentVersionQuery
  • BaseCountry
  • BaseCountryDesc
  • BaseCountryDescPeer
  • BaseCountryDescQuery
  • BaseCountryI18n
  • BaseCountryI18nPeer
  • BaseCountryI18nQuery
  • BaseCountryPeer
  • BaseCountryQuery
  • BaseCoupon
  • BaseCouponOrder
  • BaseCouponOrderPeer
  • BaseCouponOrderQuery
  • BaseCouponPeer
  • BaseCouponQuery
  • BaseCouponRule
  • BaseCouponRulePeer
  • BaseCouponRuleQuery
  • BaseCurrency
  • BaseCurrencyPeer
  • BaseCurrencyQuery
  • BaseCustomer
  • BaseCustomerPeer
  • BaseCustomerQuery
  • BaseCustomerTitle
  • BaseCustomerTitleDesc
  • BaseCustomerTitleDescPeer
  • BaseCustomerTitleDescQuery
  • BaseCustomerTitleI18n
  • BaseCustomerTitleI18nPeer
  • BaseCustomerTitleI18nQuery
  • BaseCustomerTitlePeer
  • BaseCustomerTitleQuery
  • BaseDelivzone
  • BaseDelivzonePeer
  • BaseDelivzoneQuery
  • BaseDocument
  • BaseDocumentDesc
  • BaseDocumentDescPeer
  • BaseDocumentDescQuery
  • BaseDocumentI18n
  • BaseDocumentI18nPeer
  • BaseDocumentI18nQuery
  • BaseDocumentPeer
  • BaseDocumentQuery
  • BaseFeature
  • BaseFeatureAv
  • BaseFeatureAvDesc
  • BaseFeatureAvDescPeer
  • BaseFeatureAvDescQuery
  • BaseFeatureAvI18n
  • BaseFeatureAvI18nPeer
  • BaseFeatureAvI18nQuery
  • BaseFeatureAvPeer
  • BaseFeatureAvQuery
  • BaseFeatureCategory
  • BaseFeatureCategoryPeer
  • BaseFeatureCategoryQuery
  • BaseFeatureDesc
  • BaseFeatureDescPeer
  • BaseFeatureDescQuery
  • BaseFeatureI18n
  • BaseFeatureI18nPeer
  • BaseFeatureI18nQuery
  • BaseFeaturePeer
  • BaseFeatureProd
  • BaseFeatureProdPeer
  • BaseFeatureProdQuery
  • BaseFeatureQuery
  • BaseFolder
  • BaseFolderDesc
  • BaseFolderDescPeer
  • BaseFolderDescQuery
  • BaseFolderI18n
  • BaseFolderI18nPeer
  • BaseFolderI18nQuery
  • BaseFolderPeer
  • BaseFolderQuery
  • BaseFolderVersion
  • BaseFolderVersionPeer
  • BaseFolderVersionQuery
  • BaseGroup
  • BaseGroupDesc
  • BaseGroupDescPeer
  • BaseGroupDescQuery
  • BaseGroupI18n
  • BaseGroupI18nPeer
  • BaseGroupI18nQuery
  • BaseGroupModule
  • BaseGroupModulePeer
  • BaseGroupModuleQuery
  • BaseGroupPeer
  • BaseGroupQuery
  • BaseGroupResource
  • BaseGroupResourcePeer
  • BaseGroupResourceQuery
  • BaseImage
  • BaseImageDesc
  • BaseImageDescPeer
  • BaseImageDescQuery
  • BaseImageI18n
  • BaseImageI18nPeer
  • BaseImageI18nQuery
  • BaseImagePeer
  • BaseImageQuery
  • BaseLang
  • BaseLangPeer
  • BaseLangQuery
  • BaseMessage
  • BaseMessageDesc
  • BaseMessageDescPeer
  • BaseMessageDescQuery
  • BaseMessageI18n
  • BaseMessageI18nPeer
  • BaseMessageI18nQuery
  • BaseMessagePeer
  • BaseMessageQuery
  • BaseMessageVersion
  • BaseMessageVersionPeer
  • BaseMessageVersionQuery
  • BaseModuleDesc
  • BaseModuleDescPeer
  • BaseModuleDescQuery
  • BaseModuleI18n
  • BaseModuleI18nPeer
  • BaseModuleI18nQuery
  • BaseModulePeer
  • BaseOrder
  • BaseOrderAddress
  • BaseOrderAddressPeer
  • BaseOrderAddressQuery
  • BaseOrderFeature
  • BaseOrderFeaturePeer
  • BaseOrderFeatureQuery
  • BaseOrderPeer
  • BaseOrderProduct
  • BaseOrderProductPeer
  • BaseOrderProductQuery
  • BaseOrderQuery
  • BaseOrderStatus
  • BaseOrderStatusDesc
  • BaseOrderStatusDescPeer
  • BaseOrderStatusDescQuery
  • BaseOrderStatusI18n
  • BaseOrderStatusI18nPeer
  • BaseOrderStatusI18nQuery
  • BaseOrderStatusPeer
  • BaseOrderStatusQuery
  • BaseProduct
  • BaseProductCategory
  • BaseProductCategoryPeer
  • BaseProductCategoryQuery
  • BaseProductDesc
  • BaseProductDescPeer
  • BaseProductDescQuery
  • BaseProductI18n
  • BaseProductI18nPeer
  • BaseProductI18nQuery
  • BaseProductPeer
  • BaseProductQuery
  • BaseProductVersion
  • BaseProductVersionPeer
  • BaseProductVersionQuery
  • BaseResource
  • BaseResourceDesc
  • BaseResourceDescPeer
  • BaseResourceDescQuery
  • BaseResourceI18n
  • BaseResourceI18nPeer
  • BaseResourceI18nQuery
  • BaseResourcePeer
  • BaseResourceQuery
  • BaseRewriting
  • BaseRewritingPeer
  • BaseRewritingQuery
  • BaseStock
  • BaseStockPeer
  • BaseStockQuery
  • BaseTax
  • BaseTaxDesc
  • BaseTaxDescPeer
  • BaseTaxDescQuery
  • BaseTaxI18n
  • BaseTaxI18nPeer
  • BaseTaxI18nQuery
  • BaseTaxPeer
  • BaseTaxQuery
  • BaseTaxRule
  • BaseTaxRuleCountry
  • BaseTaxRuleCountryPeer
  • BaseTaxRuleCountryQuery
  • BaseTaxRuleDesc
  • BaseTaxRuleDescPeer
  • BaseTaxRuleDescQuery
  • BaseTaxRuleI18n
  • BaseTaxRuleI18nPeer
  • BaseTaxRuleI18nQuery
  • BaseTaxRulePeer
  • BaseTaxRuleQuery
  • Overview
  • Namespace
  • Class
  • Tree
   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: 
thelia API documentation generated by ApiGen 2.8.0