/**
  * 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();
 }
示例#6
0
 /**
  * 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;
 }