diff --git a/README.md b/README.md index 9b425d6..5ed44b8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Generate fake test data for Magento -MageFaker is a tool for creating a bunch of bogus customer accounts on a Magento installation using realistic, yet fake, customer data. +MageFaker is a tool for creating a bunch of bogus customer accounts, products and orders on a Magento installation using realistic, yet fake, customer data. ![image](http://up.nicksays.co.uk/image/0240281V1D1e/Screen%20Shot%202012-11-27%20at%2000.12.07.png) @@ -13,6 +13,14 @@ MageFaker is a tool for creating a bunch of bogus customer accounts on a Magento ### Usage -The following command will create 300 fake customer accounts for the Magento installation at `~/Sites/my/magento/root`. +Following command will create 1K fake products, 50K fake customer accounts, 3 fake orders (5 purchase items each) per customer & 20K fake guest orders for the Magento installation at `~/Sites/my/magento/root`. - magefaker --magento ~/Sites/my/magento/root 300 \ No newline at end of file + magefaker --magento ~/Sites/my/magento/root --customers 50000 3 5 --guestorders 20000 --products 1000 + +### Note (Caveat) + +For fake products only 'simple' product-types are supported. Other product types like 'configurable' and 'grouped' aren't supported because of the dependencies between parent and child products. + +For fake orders, assumption is that there are 'simple' products already on Magento. If not run something like the following command first (creates 2 fake 'simple' products): + + magefaker --magento ~/Sites/my/magento/root --products 2 diff --git a/bin/magefaker b/bin/magefaker index 1ddbf15..d0f9660 100755 --- a/bin/magefaker +++ b/bin/magefaker @@ -8,14 +8,27 @@ $opts->option('magento') ->require() ->describedAs('The root directory of your Magento installation'); -$opts->argument() - ->require() +$opts->option('products') + ->describedAs("The number of products you'd like to create"); + +$opts->option('customers') ->describedAs("The number of customers you'd like to create"); +$opts->option('guestorders') + ->describedAs("The number of guest orders you'd like to create"); + $c = new \Colors\Color(); $magento_base_dir = $opts['magento']; -$customer_count = $opts[0]; +$product_count = intval($opts['products']); +$guest_order_count = intval($opts['guestorders']); +$customer_count = intval($opts['customers']); +$order_count = 0; +$purchase_item_count = 0; +if (count($opts->getArgumentValues()) == 2) { + $order_count = intval($opts->getArgumentValues()[0]); + $purchase_item_count = intval($opts->getArgumentValues()[1]); +} $app_file = $magento_base_dir . DIRECTORY_SEPARATOR . "app/Mage.php"; @@ -30,9 +43,11 @@ Mage::app(); class MageFaker { protected $_faker; + protected $_productIds; public function __construct() { $this->_faker = \Faker\Factory::create(); + $this->_productIds = array(); } public function createFakeCustomer() { @@ -81,15 +96,188 @@ class MageFaker { return $address; } + + public function createFakeProduct() { + /** Note: Only 'simple' product-types are supported */ + Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); + $product = Mage::getModel('catalog/product'); + $product->setSku($this->_faker->md5); + $product->setName($this->_faker->sentence); + $product->setDescription($this->_faker->text); + $product->setShortDescription($this->_faker->sentence); + $product->setPrice($this->_faker->randomNumber + rand(0, 99)/10); + $product->setTypeId('simple'); + $product->setAttributeSetId(9); + $product->setCategoryIds(array(Mage::app()->getStore(true)->getRootCategoryId())); + $product->setWeight(1.0); + $product->setTaxClassId(2); // taxable goods + $product->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH); + $product->setStatus(1); // enabled + $product->setStockData(array( + 'is_in_stock' => 1, + 'qty' => $this->_faker->randomDigit + )); + $product->setWebsiteIds(array(Mage::app()->getStore(true)->getWebsite()->getId())); + $product->setCreatedAt(strtotime('now')); + $product->save(); + + array_push($this->_productIds, $product->getId()); + + return $product; + } + + public function createFakeOrder($_customer=null, $_purchase_item_count=0) { + $quote = Mage::getModel('sales/quote')->setStoreId(Mage::app()->getStore('default')->getId()); + if (empty($this->_productIds)) { + // Grab productIds from available items - of product type 'simple' + $visibility = array(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH, + Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG + ); + $products = Mage::getModel('catalog/product')->getResourceCollection() + ->addAttributeToSelect('*') + ->addAttributeToFilter('visibility', $visibility) + ->addAttributeToFilter( + 'status', + array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED) + ) + ->addAttributeToFilter('type_id', array('eq' => 'simple')) // REMOVE for all product types: configurable, grouped, bundle, virtual etc. + ->joinField( + 'is_in_stock', + 'cataloginventory/stock_item', + 'is_in_stock', + 'product_id=entity_id', + '{{table}}.stock_id=1', + 'left' + ) + ->joinField( + 'qty', + 'cataloginventory/stock_item', + 'qty', + 'product_id=entity_id', + '{{table}}.stock_id=1', + 'left' + ) + ->addAttributeToFilter('is_in_stock', array('eq' => 1)) + ->setOrder('created_at', 'desc') + ->setPageSize(100); // limit to only 100 results + + foreach ($products as $prod) { + array_push($this->productsIds, $prod->getId()); + } + } + + for ($k = 0; $k < $_purchase_item_count; $k++) { + $index = array_rand($this->_productIds, 1); // Randomly pick a productId + $product = Mage::getModel('catalog/product')->load($this->_productIds[$index]); // Make sure it's a 'simple' item + $qtyInfo = array('qty' => 1); + $quote->addProduct($product, new Varien_Object($qtyInfo)); + } + + if (!isset($_customer)) { // Checks out as guest + $billingAddress = array( + 'firstname' => $this->_faker->firstName, + 'lastname' => $this->_faker->lastName, + 'company' => $this->_faker->company, + 'email' => $this->_faker->safeEmail, + 'street' => array( + $this->_faker->buildingNumber . ' ' . $this->_faker->streetName, + $this->_faker->secondaryAddress + ), + 'city' => $this->_faker->city, + 'region_id' => '', + 'region' => $this->_faker->city, + 'postcode' => $this->_faker->postcode, + 'country_id' => 'GB', + 'telephone' => $this->_faker->phoneNumber, + 'fax' => $this->_faker->phoneNumber, + 'customer_password' => '', + 'confirm_password' => '', + 'save_in_address_book' => '0', + 'use_for_shipping' => '1', + ); + $quote->getBillingAddress()->addData($billingAddress); + $quote->getShippingAddress()->addData($billingAddress); + + $quote->setCheckoutMethod('guest') + ->setCustomerId(null) + ->setCustomerEmail($quote->getBillingAddress()->getEmail()) + ->setCustomerIsGuest(true) + ->setCustomerGroup(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID); + } else { // Check out as registered customer + $quote->assignCustomer($_customer); + + $customer = Mage::getModel('customer/customer')->load($_customer->getId()); + $billingAddress = $customer->getDefaultBillingAddress(); + $shippingAddress = $customer->getDefaultShippingAddress(); + + $addressForm = Mage::getModel('customer/form'); + $addressForm->setFormCode('customer_address_edit') + ->setEntityType('customer_address'); + + foreach ($addressForm->getAttributes() as $attribute) { + if (isset($shippingAddress[$attribute->getAttributeCode()])) { + $quote->getShippingAddress()->setData($attribute->getAttributeCode(), $shippingAddress[$attribute->getAttributeCode()]); + } + } + + foreach ($addressForm->getAttributes() as $attribute) { + if (isset($billingAddress[$attribute->getAttributeCode()])) { + $quote->getBillingAddress()->setData($attribute->getAttributeCode(), $billingAddress[$attribute->getAttributeCode()]); + } + } + } + + $quote->getShippingAddress()->setCollectShippingRates(true); + $quote->getShippingAddress()->setShippingMethod('flatrate_flatrate'); + $quote->getShippingAddress()->setPaymentMethod('checkmo'); + $quote->getPayment()->importData(array('method' => 'checkmo')); + $quote->collectTotals(); + + $quote->save(); + + $service = Mage::getModel('sales/service_quote', $quote); + $service->submitAll(); + + return $service->getOrder(); + } } $magefaker = new MageFaker(); +// Create fake products +for ($i = 0; $i < $product_count; $i++) { + try { + $product = $magefaker->createFakeProduct(); + if (!isset($product)) throw new Exception("Error Creating Product", 1); + echo $c(sprintf("Introducing product.. %s\n", $product->getName()))->green; + } catch (Exception $e) { + echo $c(sprintf("An error occurred: %s\n", $e->getMessage()))->red; + } +} + +// Create fake customers -- assumption each fake customer has x-orders for ($i = 0; $i < $customer_count; $i++) { try { $customer = $magefaker->createFakeCustomer(); - echo $c(sprintf("Introducing.. %s\n", $customer->getName()))->green; + if (!isset($customer)) throw new Exception("Error Creating Customer", 1); + echo $c(sprintf("Introducing customer.. %s\n", $customer->getName()))->green; + for ($j = 0; $j < $order_count; $j++) { + $order = $magefaker->createFakeOrder($customer, $purchase_item_count); + if (!isset($order)) throw new Exception("Error Creating Order", 1); + echo $c(sprintf("Order .. %s for customer %s\n", $order->getRealOrderId(), $customer->getName()))->green; + } } catch (Exception $e) { echo $c(sprintf("An error occurred: %s\n", $e->getMessage()))->red; } -} \ No newline at end of file +} + +// Create fake guest orders +for ($i = 0; $i < $guest_order_count; $i++) { + try { + $guest_order = $magefaker->createFakeOrder(null, $purchase_item_count); + if (!isset($guest_order)) throw new Exception("Error Creating Guest Order", 1); + echo $c(sprintf("Introducing guest order.. %s\n", $guest_order->getRealOrderId()))->green; + } catch (Exception $e) { + echo $c(sprintf("An error occurred: %s\n", $e->getMessage()))->red; + } +}