/** * Pass an array of attribute ids to query for the appropriate variation. * * @param array $attributes * * @return NULL */ public function getVariationByAttributes(array $attributes) { if (!is_array($attributes)) { return null; } $keyattributes = array_keys($attributes); $id = $keyattributes[0]; $variations = ProductVariation::get()->filter("ProductID", $this->owner->ID); foreach ($attributes as $typeid => $valueid) { if (!is_numeric($typeid) || !is_numeric($valueid)) { return null; } //ids MUST be numeric $alias = "A{$typeid}"; $variations = $variations->innerJoin("ProductVariation_AttributeValues", "\"ProductVariation\".\"ID\" = \"{$alias}\".\"ProductVariationID\"", $alias)->where("\"{$alias}\".\"ProductAttributeValueID\" = {$valueid}"); } if ($variation = $variations->First()) { return $variation; } return false; }
/** * Conditions for whether a product can be purchased: * - global allow purchase is enabled * - product AllowPurchase field is true * - if variations, then one of them needs to be purchasable * - if not variations, selling price must be above 0 * * Other conditions may be added by decorating with the canPurcahse function * * @param Member $member * @param int $quantity * * @throws ShopBuyableException * * @return boolean */ public function canPurchase($member = null, $quantity = 1) { $global = self::config()->global_allow_purchase; if (!$global || !$this->AllowPurchase) { return false; } $allowpurchase = false; $extension = self::has_extension("ProductVariationsExtension"); if ($extension && ProductVariation::get()->filter("ProductID", $this->ID)->first()) { foreach ($this->Variations() as $variation) { try { if ($variation->canPurchase($member, $quantity)) { $allowpurchase = true; break; } } catch (ShopBuyableException $e) { } } // if not allowed to buy after any variations then raise the last // exception again if (!$allowpurchase && isset($e)) { throw $e; return false; } } else { if ($this->sellingPrice() > 0 || self::config()->allow_zero_price) { $allowpurchase = true; } } // Standard mechanism for accepting permission changes from decorators $extended = $this->extendedCan('canPurchase', $member, $quantity); if ($allowpurchase && $extended !== null) { $allowpurchase = $extended; } return $allowpurchase; }
function run($request) { $productVariationArrayID = array(); if (empty($_GET["silent"])) { $this->verbose = true; } else { $this->verbose = intval($_GET["silent"]) == 1 ? false : true; } if (empty($_GET["productid"])) { $productID = 0; } elseif ($_GET["productid"] == 'all') { $productID = -1; } else { $productID = intval($_GET["productid"]); } if (empty($_GET["live"])) { $live = false; } else { $live = intval($_GET["live"]) == 1 ? true : false; } if ($live) { if ($this->verbose) { DB::alteration_message("this is a live task", "deleted"); } } else { if ($this->verbose) { DB::alteration_message("this is a test only. If you add a live=1 get variable then you can make it for real ;-)", "created"); } } if ($productID == -1) { $products = Product::get(); } else { $products = null; $product = Product::get()->byID($productID); if ($product) { $products = new ArrayList(); $products->push($product); } } if ($products && $products->count()) { foreach ($products as $product) { $productID = $product->ID; if ($products->count()) { if ($this->verbose) { DB::alteration_message("Deleting variations for " . $product->Title, "deleted"); } $variations = ProductVariation::get()->filter(array("ProductID" => $productID))->limit(100); if ($variations->count()) { if ($this->verbose) { DB::alteration_message("PRE DELETE COUNT: " . $variations->count()); } foreach ($variations as $variation) { if ($this->verbose) { DB::alteration_message(" Deleting Variation: " . $variation->Title(), "deleted"); } if ($live) { $variation->delete(); } $productVariationArrayID[$variation->ID] = $variation->ID; } $variations = ProductVariation::get()->filter(array("ProductID" => $productID))->limit(100); if ($live) { if ($variations->count()) { if ($this->verbose) { DB::alteration_message("POST DELETE COUNT: " . $variations->count()); } } else { if ($this->verbose) { DB::alteration_message("All variations have been deleted: ", "created"); } } } else { if ($this->verbose) { DB::alteration_message("This was a test only", "created"); } } } else { if ($this->verbose) { DB::alteration_message("There are no variations to delete", "created"); } } if ($this->verbose) { DB::alteration_message("Starting cleanup", "created"); } if ($live) { $sql = "\r\n\t\t\t\t\t\t\t\t\tDELETE\r\n\t\t\t\t\t\t\t\t\tFROM \"Product_VariationAttributes\"\r\n\t\t\t\t\t\t\t\t\tWHERE \"ProductID\" = " . $productID; if ($this->verbose) { DB::alteration_message("<pre>RUNNING<br />" . $sql . "</pre>"); } DB::query($sql); $sql = "\r\n\t\t\t\t\t\t\t\t\tDELETE \"ProductVariation_AttributeValues\"\r\n\t\t\t\t\t\t\t\t\tFROM \"ProductVariation_AttributeValues\"\r\n\t\t\t\t\t\t\t\t\t\tLEFT JOIN \"ProductVariation\"\r\n\t\t\t\t\t\t\t\t\t\t\tON \"ProductVariation_AttributeValues\".\"ProductVariationID\" = \"ProductVariation\".\"ID\"\r\n\t\t\t\t\t\t\t\t\tWHERE \"ProductVariation\".\"ID\" IS NULL"; if ($this->verbose) { DB::alteration_message("<pre>RUNNING<br />" . $sql . "</pre>"); } DB::query($sql); } else { $sql = "\r\n\t\t\t\t\t\t\t\t\tSELECT COUNT(Product_VariationAttributes.ID)\r\n\t\t\t\t\t\t\t\t\tFROM \"Product_VariationAttributes\"\r\n\t\t\t\t\t\t\t\t\tWHERE \"ProductID\" = " . $productID; if ($this->verbose) { DB::alteration_message("<pre>RUNNING<br />" . $sql . "</pre>"); } $result = DB::query($sql); if ($this->verbose) { DB::alteration_message("Would have deleted " . $result->value() . " rows"); } $sql = "\r\n\t\t\t\t\t\t\t\t\tSELECT COUNT (\"ProductVariation_AttributeValues\".\"ID\")\r\n\t\t\t\t\t\t\t\t\tFROM \"ProductVariation_AttributeValues\"\r\n\t\t\t\t\t\t\t\t\t\tLEFT JOIN \"ProductVariation\"\r\n\t\t\t\t\t\t\t\t\t\t\tON \"ProductVariation_AttributeValues\".\"ProductVariationID\" = \"ProductVariation\".\"ID\"\r\n\t\t\t\t\t\t\t\t\tWHERE\r\n\t\t\t\t\t\t\t\t\t\t\"ProductVariation\".\"ID\" IS NULL OR\r\n\t\t\t\t\t\t\t\t\t\t\"ProductVariation\".\"ID\" IN(" . implode(",", $productVariationArrayID) . ") "; if ($this->verbose) { DB::alteration_message("<pre>RUNNING<br />" . $sql . "</pre>"); } $result = DB::query($sql); if ($this->verbose) { DB::alteration_message("Would have deleted " . $result->value() . " rows"); } } } } } else { if ($this->verbose) { DB::alteration_message("Product does not exist. You can set the product by adding it productid=XXX as a GET variable. You can also add <i>all</i> to delete ALL product Variations.", "deleted"); } } DB::alteration_message("Completed", "created"); }
/** * finds similar ("siblings") variations where one * attribute value is NOT the same. * * @return DataList */ public function MostLikeMe() { $idArray = array(); foreach ($this->AttributeValues() as $excludeValue) { unset($getAnyArray); $getAnyArray = array(); foreach ($this->AttributeValues() as $innerValue) { if ($excludeValue->ID != $innerValue->ID) { $getAnyArray[$innerValue->ID] = $innerValue->ID; } //find a product variation that has the getAnyArray Values $items = ProductVariation::get()->innerJoin("ProductVariation_AttributeValues", "\"ProductVariation\".\"ID\" = \"ProductVariationID\" ")->filter(array("ProductAttributeValueID" => $getAnyArray, "ProductID" => $this->ProductID))->exclude(array("ID" => $this->ID)); $idArray += $items->map("ID", "ID")->toArray(); } } return ProductVariation::get()->filter(array("ID" => $idArray)); }
public function variationRow(&$obj, $val, $record) { $obj->write(); //make sure product is in DB //TODO: or find existing variation $variation = ProductVariation::get()->filter("InternalItemID", '$val')->first(); if (!$variation) { $variation = new ProductVariation(); $variation->InternalItemID = $val; $variation->ProductID = $obj->ID; //link to product $variation->write(); } $varcols = array('->processVariation', '->processVariation1', '->processVariation2', '->processVariation3', '->processVariation4', '->processVariation5', '->processVariation6'); foreach ($varcols as $col) { if (isset($record[$col])) { $parts = explode(":", $record[$col]); if (count($parts) == 2) { $attributetype = trim($parts[0]); $attributevalues = explode(",", $parts[1]); //get rid of empty values foreach ($attributevalues as $key => $value) { if (!$value || trim($value) == "") { unset($attributevalues[$key]); } } if (count($attributevalues) == 1) { $attributetype = ProductAttributeType::find_or_make($attributetype); foreach ($attributevalues as $key => $value) { $val = trim($value); if ($val != "" && $val != null) { $attributevalues[$key] = $val; //remove outside spaces from values } } $attributetype->addValues($attributevalues); //create and add values to attribute type $obj->VariationAttributeTypes()->add($attributetype); //add variation attribute type to product //TODO: if existing variation, then remove current values //record vairation attribute values (variation1, 2 etc) foreach ($attributetype->convertArrayToValues($attributevalues) as $value) { $variation->AttributeValues()->add($value); break; } } } } } //copy db values into variation (InternalItemID, Price, Stock, etc) ...there will be unknowns from extensions. $dbfields = $variation->db(); foreach ($record as $field => $value) { if (isset($dbfields[$field])) { $variation->{$field} = $value; } } $variation->write(); }
/** * Conditions for whether a product can be purchased: * - global allow purchase is enabled * - product AllowPurchase field is true * - if variations, then one of them needs to be purchasable * - if not variations, selling price must be above 0 * * Other conditions may be added by decorating with the canPurchase function * * @param Member $member * @param int $quantity * * @return boolean */ public function canPurchase($member = null, $quantity = 1) { $global = self::config()->global_allow_purchase; if (!$global || !$this->AllowPurchase) { return false; } $allowpurchase = false; $extension = self::has_extension("ProductVariationsExtension"); if ($extension && ProductVariation::get()->filter("ProductID", $this->ID)->first()) { foreach ($this->Variations() as $variation) { if ($variation->canPurchase($member, $quantity)) { $allowpurchase = true; break; } } } else { $allowpurchase = $this->sellingPrice() > 0 || self::config()->allow_zero_price; } // Standard mechanism for accepting permission changes from decorators $permissions = $this->extend('canPurchase', $member, $quantity); $permissions[] = $allowpurchase; return min($permissions); }
private function addspecialprice() { $task = new EcommerceTaskCreateMemberGroups(); $task->run(false); $customerGroup = EcommerceRole::get_customer_group(); if (!$customerGroup) { die("could not create customer group"); } $group = new Group(); $group->Title = "Discount Customers"; $group->Code = "discountcustomers"; $group->ParentID = $customerGroup->ID; $group->write(); $member = new Member(); $member->FirstName = 'Bob'; $member->Surname = 'Jones'; $member->Email = '*****@*****.**'; $member->Password = '******'; $member->write(); $member->Groups()->add($group); $products = Product::get()->where("ClassName = 'Product'")->sort("RAND()")->limit(2); $this->addExamplePages(4, "Special price for particular customers", $products); $i = 0; foreach ($products as $product) { $i++; $complexObjectPrice = new ComplexPriceObject(); if ($i == 1) { $complexObjectPrice->Price = $product->Price - 1.5; } elseif ($i == 2) { $complexObjectPrice->Percentage = 10; $complexObjectPrice->Reduction = 2.5; } else { $complexObjectPrice->Price = $product->Price - 1.5; $complexObjectPrice->Percentage = 10; $complexObjectPrice->Reduction = 2.5; } $complexObjectPrice->From = date("Y-m-d h:n:s", strtotime("now")); $complexObjectPrice->Until = date("Y-m-d h:n:s", strtotime("next year")); $complexObjectPrice->ProductID = $product->ID; $complexObjectPrice->write(); $complexObjectPrice->Groups()->add($group); $product->Content = "<p><a href=\"Security/login/?BackURL=" . $product->Link() . "\">Login</a> as bob@silverstripe-ecommerce.com, password: test123 to get a special price. You can then <a href=\"Security/logout/?BackURL=" . $product->Link() . "\">log out</a> again to see the original price.</p>"; $this->addToTitle($product, "member price", true); } $variations = ProductVariation::get()->where("ClassName = 'ProductVariation'")->sort("RAND()")->limit(2); $i = 0; foreach ($variations as $variation) { $i++; $complexObjectPrice = new ComplexPriceObject(); if ($i == 1) { $complexObjectPrice->Price = $product->Price - 1.5; } elseif ($i == 2) { $complexObjectPrice->Percentage = 10; $complexObjectPrice->Reduction = 2.5; } else { $complexObjectPrice->Price = $product->Price - 1.5; $complexObjectPrice->Percentage = 10; $complexObjectPrice->Reduction = 2.5; } $complexObjectPrice->Price = $variation->Price - 1.5; $complexObjectPrice->From = date("Y-m-d h:n:s", strtotime("now")); $complexObjectPrice->Until = date("Y-m-d h:n:s", strtotime("next year")); $complexObjectPrice->ProductVariationID = $variation->ID; $complexObjectPrice->write(); $complexObjectPrice->Groups()->add($group); $product = $variation->Product(); $this->addExamplePages(4, "Special price for particular customers for product variations {$i}", $product); $product->Content = "<p><a href=\"Security/login/?BackURL=" . $product->Link() . "\">Login</a> as bob@jones.com, password: test123 to get a special price</p>"; $this->addToTitle($product, "member price", true); } }
function resaveAllPRoductsVariations_210() { $explanation = "\r\n\t\t\t<h1>210. Resave All Product Variations to update the FullName and FullSiteTreeSort Field</h1>\r\n\t\t\t<p>Saves all the product variations on the site. You may need to run this task several times.</p>\r\n\t\t"; if ($this->retrieveInfoOnly) { return $explanation; } else { echo $explanation; } $count = 0; if (class_exists("ProductVariation")) { ProductVariation::get()->where("\"FullName\" = '' OR \"FullName\" IS NULL")->sort("ID", "ASC")->limit($this->limit, $this->start); if ($variations->count()) { foreach ($variations as $variation) { $count++; $variation->write(); $this->DBAlterationMessageNow("Saving Variation " . $variation->getTitle()); } return $this->start + $this->limit; } else { $this->DBAlterationMessageNow("No product variations to update."); } } else { $this->DBAlterationMessageNow("There are not ProductVariations in this project"); } return 0; }
/** * returns the matching variation if any * @param array $attributes formatted as (TypeID => ValueID, TypeID => ValueID) * * @return ProductVariation | NULL */ function getVariationByAttributes(array $attributes) { if (!is_array($attributes) || !count($attributes)) { user_error("attributes must be provided as an array of numeric keys and values IDs...", E_USER_NOTICE); return null; } $variations = ProductVariation::get()->filter(array("ProductID" => $this->owner->ID)); $keyattributes = array_keys($attributes); $id = $keyattributes[0]; foreach ($attributes as $typeid => $valueid) { if (!is_numeric($typeid) || !is_numeric($valueid)) { user_error("key and value ID must be numeric", E_USER_NOTICE); return null; } $alias = "A{$typeid}"; $variations = $variations->where("\"{$alias}\".\"ProductAttributeValueID\" = {$valueid}")->innerJoin("ProductVariation_AttributeValues", "\"ProductVariation\".\"ID\" = \"{$alias}\".\"ProductVariationID\"", $alias); } if ($variation = $variations->First()) { return $variation; } return null; }