/** * finds or makes a ProductAttributeType, based on the lower case Name. * * @param ProductAttributeType | int $type * @param String $value * @param Boolean $create * * @return ProductAttributeType */ public static function find_or_make($type, $value, $create = true, $findByID = false) { if ($type instanceof ProductAttributeType) { $type = $type->ID; } $cleanedValue = strtolower($value); if ($findByID) { $intValue = intval($value); $valueObj = ProductAttributeValue::get()->filter(array("ID" => $intValue, "TypeID" => intval($type)))->First(); //debug::log("INT VALUE:" .$intValue."-".$type); } else { $valueObj = ProductAttributeValue::get()->where("(LOWER(\"Code\") = '{$cleanedValue}' OR LOWER(\"Value\") = '{$cleanedValue}') AND TypeID = " . intval($type))->First(); //debug::log("CLEANED VALUE:" .$cleanedValue."-".$type); } if ($valueObj) { return $valueObj; } $valueObj = new ProductAttributeValue(); $valueObj->Code = $cleanedValue; $valueObj->Value = $value; $valueObj->TypeID = $type; if ($create) { $valueObj->write(); } return $valueObj; }
/** * Get all the {@link ProductAttributeValue} for a given attribute type, * based on this product's variations. * * @return DataList */ public function possibleValuesForAttributeType($type) { if (!is_numeric($type)) { $type = $type->ID; } if (!$type) { return null; } return ProductAttributeValue::get()->innerJoin("ProductVariation_AttributeValues", "\"ProductAttributeValue\".\"ID\" = \"ProductVariation_AttributeValues\".\"ProductAttributeValueID\"")->innerJoin("ProductVariation", "\"ProductVariation_AttributeValues\".\"ProductVariationID\" = \"ProductVariation\".\"ID\"")->where("TypeID = {$type} AND \"ProductVariation\".\"ProductID\" = " . $this->owner->ID); }
/** * Get all the {@link ProductAttributeValue} for a given attribute type, * based on this product's variations. * * @return DataList */ public function possibleValuesForAttributeType($type) { if (!is_numeric($type)) { $type = $type->ID; } if (!$type) { return null; } $list = ProductAttributeValue::get()->innerJoin("ProductVariation_AttributeValues", "\"ProductAttributeValue\".\"ID\" = \"ProductVariation_AttributeValues\".\"ProductAttributeValueID\"")->innerJoin("ProductVariation", "\"ProductVariation_AttributeValues\".\"ProductVariationID\" = \"ProductVariation\".\"ID\"")->where("TypeID = {$type} AND \"ProductVariation\".\"ProductID\" = " . $this->owner->ID); if (!Product::config()->allow_zero_price) { $list = $list->where('"ProductVariation"."Price" > 0'); } return $list; }
/** * @param $typeID * @return callable */ protected function getValuesClosure($typeID) { return function () use($typeID) { return ProductAttributeValue::get()->filter('TypeID', $typeID)->map('ID', 'Value')->toArray(); }; }
function cleanup() { $sql = "\r\n\t\t\tSelect \"ProductAttributeTypeID\"\r\n\t\t\tFROM \"Product_VariationAttributes\"\r\n\t\t\tWHERE \"ProductID\" = " . $this->owner->ID; $data = DB::query($sql); $array = $data->keyedColumn(); if (is_array($array) && count($array)) { foreach ($array as $key => $productAttributeTypeID) { //attribute type does not exist. if (!ProductAttributeType::get()->byID($productAttributeTypeID)) { //delete non-existing combinations of Product_VariationAttributes (where the attribute does not exist) //DB::query("DELETE FROM \"Product_VariationAttributes\" WHERE \"ProductAttributeTypeID\" = $productAttributeTypeID"); //non-existing product attribute values. $productAttributeValues = ProductAttributeValue::get()->filter(array("TypeID" => $productAttributeTypeID)); if ($productAttributeValues->count()) { foreach ($productAttributeValues as $productAttributeValue) { $productAttributeValue->delete(); } } } } } }
private function addvariations() { $colourObject = ProductAttributeType::get()->where("\"Name\" = 'Colour'")->First(); if (!$colourObject) { $colourObject = new ProductAttributeType(); $colourObject->Name = "Colour"; $colourObject->Label = "Colour"; $colourObject->IsColour = true; $colourObject->Sort = 100; $colourObject->write(); } if ($colourObject) { $redObject = ProductAttributeValue::get()->where("\"Value\" = 'red'")->First(); if (!$redObject) { $redObject = new ProductAttributeValue(); $redObject->Value = "red"; $redObject->RGBCode = "ff0000"; $redObject->ContrastRGBCode = "BFC1C1"; $redObject->TypeID = $colourObject->ID; $redObject->Sort = 100; $redObject->write(); } $blueObject = ProductAttributeValue::get()->where("\"Value\" = 'blue'")->First(); if (!$blueObject) { $blueObject = new ProductAttributeValue(); $blueObject->Value = "blue"; $blueObject->RGBCode = "0000ff"; $blueObject->ContrastRGBCode = "BFC1C1"; $blueObject->TypeID = $colourObject->ID; $blueObject->Sort = 110; $blueObject->write(); } } else { die("COULD NOT CREATE COLOUR OBJECT"); } $sizeObject = ProductAttributeType::get()->filter("Name", 'Size')->First(); if (!$sizeObject) { $sizeObject = new ProductAttributeType(); $sizeObject->Name = "Size"; $sizeObject->Label = "Size"; $sizeObject->Sort = 110; $sizeObject->write(); } if ($sizeObject) { $smallObject = ProductAttributeValue::get()->where("\"Value\" = 'S'")->First(); if (!$smallObject) { $smallObject = new ProductAttributeValue(); $smallObject->Value = "S"; $smallObject->TypeID = $sizeObject->ID; $smallObject->Sort = 100; $smallObject->write(); } $xtraLargeObject = ProductAttributeValue::get()->where("\"Value\" = 'XL'")->First(); if (!$xtraLargeObject) { $xtraLargeObject = new ProductAttributeValue(); $xtraLargeObject->Value = "XL"; $xtraLargeObject->TypeID = $sizeObject->ID; $xtraLargeObject->Sort = 110; $xtraLargeObject->write(); } } else { die("COULD NOT CREATE SIZE OBJECT"); } $products = Product::get()->where("ClassName = 'Product'")->sort("RAND()")->limit(2); $this->addExamplePages(1, "products with variations (size, colour, etc...)", $products); if ($products->count() && $colourObject && $sizeObject) { $variationCombos = array(array("Size" => $xtraLargeObject, "Colour" => $redObject), array("Size" => $xtraLargeObject, "Colour" => $blueObject), array("Size" => $smallObject, "Colour" => $redObject), array("Size" => $smallObject, "Colour" => $blueObject)); foreach ($products as $product) { $existingAttributeTypes = $product->VariationAttributes(); $existingAttributeTypes->add($sizeObject); $existingAttributeTypes->add($colourObject); $this->addToTitle($product, "with variation", false); $product->Content .= "<p>On this page you can see two example of how you customers can add variations to their products (form / table)... In a real-life shop you would probably choose one or the other.</p>"; $product->write(); $product->Publish('Stage', 'Live'); $product->flushCache(); $descriptionOptions = array("", "Per Month", "", "", "Per Year", "This option has limited warranty"); if (!ProductVariation::get()->where("ProductID = " . $product->ID)->count()) { foreach ($variationCombos as $variationCombo) { $productVariation = new ProductVariation(); $productVariation->ProductID = $product->ID; $productVariation->Price = $product->Price * 2; $productVariation->Description = $descriptionOptions[rand(0, 5)]; $productVariation->ImageID = rand(0, 1) ? 0 : $this->getRandomImageID(); $productVariation->write(); $existingAttributeValues = $productVariation->AttributeValues(); $existingAttributeValues->add($variationCombo["Size"]); $existingAttributeValues->add($variationCombo["Colour"]); DB::alteration_message(" Creating variation for " . $product->Title . " // COLOUR " . $variationCombo["Colour"]->Value . " SIZE " . $variationCombo["Size"]->Value, "created"); } } } } }
/** * * @param Int | ProductAttributeType * * @return DataList of ProductAttributeValues */ function possibleValuesForAttributeType($type) { if ($type instanceof ProductAttributeType) { $typeID = $type->ID; } elseif ($type = ProductAttributeType::get()->byID(intval($type))) { $typeID = $type->ID; } else { return null; } $vals = ProductAttributeValue::get()->where("\"TypeID\" = {$typeID} AND \"ProductVariation\".\"ProductID\" = " . $this->owner->ID . " AND \"ProductVariation\".\"AllowPurchase\" = 1")->sort(array("ProductAttributeValue.Sort" => "ASC"))->innerJoin("ProductVariation_AttributeValues", "\"ProductAttributeValue\".\"ID\" = \"ProductVariation_AttributeValues\".\"ProductAttributeValueID\"")->innerJoin("ProductVariation", "\"ProductVariation_AttributeValues\".\"ProductVariationID\" = \"ProductVariation\".\"ID\""); if ($this->variationFilter) { $vals = $vals->filter(array("ProductVariation.ID" => $this->variationFilter)); } return $vals; }
protected function createVariations() { $this->alterationMessage("================================================ CREATING VARIATIONS ================================================", "show"); foreach ($this->data as $data) { $types = array(); $values = array(); $product = $data["Product"]; $arrayForCreation = array(); $variationFilter = array(); $this->alterationMessage("<h1>Working out variations for " . $product->Title . "</h1>"); //create attribute types for one product $this->alterationMessage("....Creating attribute types"); foreach ($this->Config()->get("attribute_type_field_names") as $fieldKey => $fieldName) { $startMessage = "........Checking field {$fieldName}"; $attributeTypeName = trim($data["Product"]->Title) . "_" . $fieldName; $filterArray = array("Name" => $attributeTypeName); $type = ProductAttributeType::get()->filter($filterArray)->first(); if (!$type) { $this->alterationMessage($startMessage . " ... creating new attribute type: " . $attributeTypeName, "created"); $type = new ProductAttributeType($filterArray); $type->Label = $attributeTypeName; $type->Sort = $fieldKey; } else { $this->alterationMessage($startMessage . " ... \tfound existing attribute type: " . $attributeTypeName); } $this->addMoreAttributeType($type, $fieldName, $product); $type->write(); $types[$fieldName] = $type; $product->VariationAttributes()->add($type); } //go through each variation to make the values $this->alterationMessage("....Creating attribute values"); foreach ($data["VariationRows"] as $key => $row) { //go through each value foreach ($this->Config()->get("attribute_type_field_names") as $fieldName) { if (!isset($row["Data"][$fieldName])) { $this->alterationMessage("ERROR; {$fieldName} not set at all....", "deleted"); continue; } elseif (!trim($row["Data"][$fieldName])) { $this->alterationMessage("skipping {$fieldName} as there are no entries..."); continue; } $startMessage = "........Checking field {$fieldName}"; //create attribute value $attributeValueName = $row["Data"][$fieldName]; $filterArray = array("Code" => $attributeValueName, "TypeID" => $types[$fieldName]->ID); $value = ProductAttributeValue::get()->filter($filterArray)->first(); if (!$value) { $this->alterationMessage($startMessage . "............creating new attribute value: <strong>" . $attributeValueName . "</strong> for " . $types[$fieldName]->Name, "created"); $value = ProductAttributeValue::create($filterArray); $value->Code = $attributeValueName; $value->Value = $attributeValueName; } else { $this->alterationMessage($startMessage . "............found existing attribute value: <strong>" . $attributeValueName . "</strong> for " . $types[$fieldName]->Name); } $this->addMoreAttributeType($value, $types[$fieldName], $product); $value->write(); $values[$fieldName] = $value; //add at arrays for creation... if (!isset($arrayForCreation[$types[$fieldName]->ID])) { $arrayForCreation[$types[$fieldName]->ID] = array(); } $arrayForCreation[$types[$fieldName]->ID][] = $value->ID; if (!isset($variationFilters[$key])) { $variationFilters[$key] = array(); } $variationFilters[$key][$types[$fieldName]->ID] = $value->ID; } } //remove attribute types without values... (i.e. product only has size of colour) foreach ($product->VariationAttributes() as $productTypeToBeDeleted) { if ($productTypeToBeDeleted->Values()->count() == 0) { $this->alterationMessage("....deleting attribute type with no values: " . $productTypeToBeDeleted->Title); $product->VariationAttributes()->remove($productTypeToBeDeleted); } } $this->alterationMessage("....Creating Variations ///"); //$this->alterationMessage("....Creating Variations From: ".print_r(array_walk($arrayForCreation, array($this, 'implodeWalk')))); //generate variations $variationAttributeValuesPerVariation = array(); foreach ($arrayForCreation as $typeID => $variationEntry) { foreach ($variationEntry as $positionOfVariation => $attributeValueID) { $variationAttributeValuesPerVariation[$positionOfVariation][$typeID] = $attributeValueID; } } foreach ($variationAttributeValuesPerVariation as $variationAttributes) { $variation = $product->getVariationByAttributes($variationAttributes); if ($variation instanceof ProductVariation) { $this->alterationMessage(".... Variation " . $variation->FullName . " Already Exists ///"); } else { //2. if not, create variation with attributes $className = $product->getClassNameOfVariations(); $newVariation = new $className(array('ProductID' => $product->ID, 'Price' => $product->Price)); $newVariation->setSaveParentProduct(false); $newVariation->write(); $newVariation->AttributeValues()->addMany($variationAttributes); $this->alterationMessage(".... Variation " . $newVariation->FullName . " created ///", "created"); } } //find variations and add to VariationsRows foreach ($data["VariationRows"] as $key => $row) { $variation = $product->getVariationByAttributes($variationFilters[$key]); if ($variation instanceof ProductVariation) { $this->alterationMessage("........Created variation, " . $variation->getTitle()); $this->data[$product->ID]["VariationRows"][$key]["Variation"] = $variation; } else { $this->alterationMessage("........Could not find variation", "deleted"); } } } $this->alterationMessage("================================================", "show"); }