Skip to content

Instantly share code, notes, and snippets.

@prodigitalson
Last active August 29, 2015 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save prodigitalson/2cbd9e1787a1db388cee to your computer and use it in GitHub Desktop.
Save prodigitalson/2cbd9e1787a1db388cee to your computer and use it in GitHub Desktop.
Simple Initial Box importer
<?php
function underscore($input)
{
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
$ret = $matches[0];
foreach ($ret as &$match) {
$match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
}
return implode('_', $ret);
}
class Product {
protected $data = array();
protected static $fields = array(
'ship_length',
'ship_width',
'ship_height',
'sku',
);
public function __construct(array $data = null)
{
}
public function __get($name)
{
return $this->data[$name];
}
public function getVolume()
{
$volume = $this->data['ship_length'] * $this->data['ship_width'] * $this->data['ship_height'];
return $volume;
}
public function __set($name, $value)
{
$this->data[$name] = $value;
}
public function __call($method, $args)
{
if (strpos('get', $method) === 0) {
$property = $underscore(substr($method, 2));
if (array_key_exists($property, $this->data))
{
return $this->data['property'];
}
}
}
public static function getFields()
{
return self::$fields;
}
}
class Box
{
protected $data = array();
public function __construct(array $data = null)
{
if ($data !== null) {
$this->data = $data;
}
}
public function __get($name)
{
return $this->data[$name];
}
public function __set($name, $value)
{
$this->data[$name] = $value;
}
public function getData()
{
return $this->data;
}
public function __call($method, $args)
{
if (strpos('get', $method) === 0) {
$property = $underscore(substr($method, 2));
if (array_key_exists($property, $this->data))
{
return $this->data['property'];
}
}
}
public function canContain($product)
{
$volume = $product->getVolume();
if ($volume <= $this->data['volume'] && $volume != 0) {
return floor($this->data['volume']/$volume);
} else {
return false;
}
}
}
class Flatbox extends Box {
static protected $boxTypes = array(
'1' => 'Priority Mail Small Flat Rate Box',
'2' => 'Priority Mail Medium Flat Rate Box',
'3' => 'Priority Mail Large Flat Rate Box',
'5' => 'Priority Mail Padded Flat Rate Envelope',
'6' => 'Priority Mail Small Flat Rate Envelope',
'7' => 'Priority Mail Legal Flat Rate Envelope',
'8' => 'Priority Mail Flat Rate Envelope',
);
public static function getBoxTypes() {
return self::$boxTypes;
}
}
abstract class ProductShippingBoxUpdater
{
protected $db;
protected $products = null;
protected $boxes = null;
protected $isDryRun = true;
protected $boxTableName = null;
public function __construct(PDO $db, $log = false, $dryrun = true)
{
$this->db = $db;
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if (!$this->db instanceof PDO) {
throw new Exception('WTF!');
}
if ($log !== false) {
$this->initLogger($log);
}
$this->isDryRun = $dryrun;
}
public function execute()
{
foreach($this->getProducts() as $product)
{
$this->addBoxRules($product);
}
}
public function initLogger($path)
{
}
public function getDatabase()
{
return $this->db;
}
public function setBoxTableName($name)
{
$this->boxTableName = $name;
}
public function getBoxTableName()
{
return $this->boxTableName;
}
public function getProducts()
{
if (null === $this->products)
{
$stmt = $this->getDatabase()
->prepare(sprintf('SELECT %s FROM catalog_product_flat_5', implode(',', Product::getFields())));
$stmt->execute();
$this->products = $stmt->fetchAll(PDO::FETCH_CLASS, 'Product');
}
return $this->products;
}
public function addBoxRules($product)
{
$rules = $this->buildBoxRules($product);
//print "Rules for {$product->sku}:\n" . var_export($rules, true) . "\n";
if (!empty($rules))
{
$fields = array_keys($this->getDefaultRule());
$placeholders = array_map(function ($f) { return ':' . $f; }, $fields);
$sql = sprintf('INSERT INTO %s (%s) VALUES(%s)', $this->getBoxTableName(), implode(',', $fields), implode(',',$placeholders));
$stmt = $this->getDatabase()
->prepare($sql);
if ($this->isDryRun === false)
{
$this->getDatabase()->beginTransaction();
}
try
{
foreach ($rules as $rule) {
$p = array_keys($rule);
$v = array_values($rule);
array_walk($p, function (&$f) { $f = ':' . $f; });
$params = array_combine($p, $v);
if ($this->isDryRun === false) {
$stmt->execute($params);
} else {
print "To execute: " .strtr($sql, $params) . "\n";
}
}
if ($this->isDryRun === false)
{
$this->getDatabase()->commit();
}
} catch (Exception $ex) {
if ($this->isDryRun === false)
{
$this->getDatabase()->rollBack();
}
print "To execute: " .strtr($sql, $params) . "\n";
throw $ex;
}
}
}
protected function buildBoxRules($product)
{
$rules = array();
$allowedBoxes = array();
foreach($this->getBoxes() as $box)
{
$max = $box->canContain($product);
if ( $max !== false) {
$rule = $this->getDefaultRule();
$rule['sku'] = $product->sku;
$rule['box_id'] = $box->boxmenu_id;
$rule['max_box'] = $max;
if (!empty($allowedBoxes)) {
$lastBox = end($allowedBoxes);
//$rule['min_qty'] = $lastBox->canContain($product)+1;
}
$allowedBoxes[$box->title] = $box;
$rules[$box->title] = $rule;
}
}
return $rules;
}
protected function getDefaultRule()
{
return array(
'sku' => null,
'box_id' => null,
'length' => -1,
'width' => -1,
'height' => -1,
'max_box' => -1,
'min_qty' => 0,
'max_qty' => -1
);
}
}
class USPSUpdater extends ProductShippingBoxUpdater
{
protected $boxTableName = 'shipusa_flatboxes';
public function getBoxes()
{
if (null === $this->boxes) {
$types = array_keys(Flatbox::getBoxTypes());
$placeholders = array_fill(0, count($types), '?');
$stmt = $this->getDatabase()
->prepare(sprintf('SELECT * FROM boxmenu b WHERE b.box_type IN (%s) ORDER BY b.volume ASC', implode(',', $placeholders)));
$stmt->execute($types);
$this->boxes = $stmt->fetchAll(PDO::FETCH_CLASS, 'Flatbox');
}
return $this->boxes;
}
}
class CustomUpdater extends ProductShippingBoxUpdater
{
protected $boxTableName = 'shipusa_singleboxes';
public function getBoxes()
{
if (null === $this->boxes) {
$stmt = $this->getDatabase()
->prepare('SELECT * FROM boxmenu b WHERE b.box_type = ? ORDER BY b.volume ASC');
$stmt->execute(array(4));
$this->boxes = $stmt->fetchAll(PDO::FETCH_CLASS, 'Box');
}
return $this->boxes;
}
}
$config = realpath(dirname(__FILE__) . '/../magento/app/etc/local.xml');
if (!$config) {
throw new Exception('Could not load magento config.');
} else {
$conf = new SimpleXMLElement($config, LIBXML_NOCDATA, true);
$conn = $conf->global->resources->default_setup->connection;
$dsn = sprintf('mysql:host=%s;dbname=%s', $conn->host, $conn->dbname);
$user = (string) $conn->username;
$pass = (string) $conn->password;
$db = new PDO($dsn, $user, $pass);
if (!$db instanceof PDO) {
throw new Exception('Could not create database connection!');
exit;
}
}
$fedex = new CustomUpdater($db, false, false);
print "Executing Custom Box Updater for FedEx... \n";
$fedex->execute();
print "Done.\n\n";
$usps = new USPSUpdater($db, false, false);
print "Executing Custom Box Updater for FedEx \n";
$usps->execute();
print "Done\n\n";
print "Box update complete.\n\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment