/**
  * @throws \Craft\Exception
  * @throws \Exception
  */
 private function defaultProductTypes()
 {
     $productType = new Market_ProductTypeModel();
     $productType->name = 'Plain Shirts';
     $productType->handle = 'plainShirts';
     $productType->hasUrls = true;
     $productType->hasVariants = false;
     $productType->template = 'commerce/products/_product';
     $productType->urlFormat = 'commerce/products/{slug}';
     $fieldLayout = FieldLayoutModel::populateModel(['type' => 'Market_Product']);
     \Craft\craft()->fields->saveLayout($fieldLayout);
     $productType->asa('productFieldLayout')->setFieldLayout($fieldLayout);
     $variantFieldLayout = FieldLayoutModel::populateModel(['type' => 'Market_Variant']);
     \Craft\craft()->fields->saveLayout($variantFieldLayout);
     $productType->asa('variantFieldLayout')->setFieldLayout($variantFieldLayout);
     \Craft\craft()->market_productType->save($productType);
 }
 /**
  * @param Market_ProductTypeModel $productType
  *
  * @return bool
  * @throws Exception
  * @throws \CDbException
  * @throws \Exception
  */
 public function save(Market_ProductTypeModel $productType)
 {
     $urlFormatChanged = false;
     $titleFormatChanged = false;
     if ($productType->id) {
         $productTypeRecord = Market_ProductTypeRecord::model()->findById($productType->id);
         if (!$productTypeRecord) {
             throw new Exception(Craft::t('No product type exists with the ID “{id}”', ['id' => $productType->id]));
         }
         $oldProductType = Market_ProductTypeModel::populateModel($productTypeRecord);
         $isNewProductType = false;
     } else {
         $productTypeRecord = new Market_ProductTypeRecord();
         $isNewProductType = true;
     }
     $productTypeRecord->name = $productType->name;
     $productTypeRecord->handle = $productType->handle;
     $productTypeRecord->hasUrls = $productType->hasUrls;
     $productTypeRecord->hasVariants = $productType->hasVariants;
     $productTypeRecord->template = $productType->template;
     if ($productTypeRecord->titleFormat != $productType->titleFormat) {
         $titleFormatChanged = true;
     }
     $productTypeRecord->titleFormat = $productType->titleFormat ? $productType->titleFormat : "{sku}";
     // Set flag if urlFormat changed so we can update all product elements.
     if ($productTypeRecord->urlFormat != $productType->urlFormat) {
         $urlFormatChanged = true;
     }
     $productTypeRecord->urlFormat = $productType->urlFormat;
     $productTypeRecord->validate();
     $productType->addErrors($productTypeRecord->getErrors());
     if (!$productType->hasErrors()) {
         MarketDbHelper::beginStackedTransaction();
         try {
             // Product Field Layout
             if (!$isNewProductType && $oldProductType->fieldLayoutId) {
                 // Drop the old field layout
                 craft()->fields->deleteLayoutById($oldProductType->fieldLayoutId);
             }
             // Save the new one
             $fieldLayout = $productType->asa('productFieldLayout')->getFieldLayout();
             craft()->fields->saveLayout($fieldLayout);
             $productType->fieldLayoutId = $fieldLayout->id;
             $productTypeRecord->fieldLayoutId = $fieldLayout->id;
             if (!$isNewProductType && $oldProductType->variantFieldLayoutId) {
                 // Drop the old field layout
                 craft()->fields->deleteLayoutById($oldProductType->variantFieldLayoutId);
             }
             // Save the new one
             $variantFieldLayout = $productType->asa('variantFieldLayout')->getFieldLayout();
             craft()->fields->saveLayout($variantFieldLayout);
             $productType->variantFieldLayoutId = $variantFieldLayout->id;
             $productTypeRecord->variantFieldLayoutId = $variantFieldLayout->id;
             // Save it!
             $productTypeRecord->save(false);
             // Now that we have a product type ID, save it on the model
             if (!$productType->id) {
                 $productType->id = $productTypeRecord->id;
             }
             if ($productType->hasVariants) {
                 //Refresh all urls for products of same type if urlFormat changed.
                 if ($titleFormatChanged) {
                     $criteria = craft()->elements->getCriteria('Market_Product');
                     $criteria->typeId = $productType->id;
                     $products = $criteria->find();
                     /** @var Market_ProductModel $product */
                     foreach ($products as $key => $product) {
                         if ($product && $product->getContent()->id) {
                             foreach ($product->getVariants() as $variant) {
                                 craft()->market_variant->save($variant);
                             }
                         }
                     }
                 }
             }
             //Refresh all urls for products of same type if urlFormat changed.
             if ($urlFormatChanged) {
                 $criteria = craft()->elements->getCriteria('Market_Product');
                 $criteria->typeId = $productType->id;
                 $products = $criteria->find();
                 foreach ($products as $key => $product) {
                     if ($product && $product->getContent()->id) {
                         craft()->elements->updateElementSlugAndUri($product, false, false);
                     }
                 }
             }
             MarketDbHelper::commitStackedTransaction();
         } catch (\Exception $e) {
             MarketDbHelper::rollbackStackedTransaction();
             throw $e;
         }
         return true;
     } else {
         return false;
     }
 }