Created
January 16, 2017 05:27
-
-
Save Acen/9658e59d6f12c652639345c6328c77e9 to your computer and use it in GitHub Desktop.
Convergence Codi -> BigCommerce with Laravel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Core; | |
use \Exception; | |
use Carbon\Carbon; | |
use League\Csv\Reader; | |
use Illuminate\Support\Collection; | |
use Illuminate\Support\Facades\Cache; | |
use Illuminate\Support\Facades\Storage; | |
use Bigcommerce\Api\Client as BigCommerceClient; | |
class CategoryMatcher | |
{ | |
// Codi/Infusion | |
private $level0; // Root Categories | |
private $level1; // Sub Categories | |
private $level2; // Product Groups | |
// BigCommerce Categories | |
private $bigcommerce_categories; | |
/* | |
* @var bool $force | |
* | |
* @return void | |
*/ | |
function __construct($force = false) | |
{ | |
if(!$force) { | |
$this->level0 = $this->getCodiCategories(0); | |
$this->level1 = $this->getCodiCategories(1); | |
$this->level2 = $this->getCodiCategories(2); | |
$this->bigcommerce_categories = $this->getBigCommerceCategories(); | |
}else{ | |
$this->level0 = $this->getCodiCategories(0, true); | |
$this->level1 = $this->getCodiCategories(1, true); | |
$this->level2 = $this->getCodiCategories(2, true); | |
$this->bigcommerce_categories = $this->getBigCommerceCategories(true); | |
} | |
} | |
/** | |
* Get BigCommerce Category IDs from Category Names. | |
* | |
* @var object $product | |
* | |
* @return array|bool | |
* @throws Exception | |
*/ | |
public function getCategoryIDs($product = null) | |
{ | |
if($product != null && isset($product)){ | |
$category_names = $this->getCategoryNames($product); | |
$category_ids = array(); | |
if($category_names && is_array($category_names)){ | |
foreach($category_names as $category_name){ | |
$bigcommerce_categories = $this->executeSearch($this->bigcommerce_categories, $category_name); | |
if($bigcommerce_categories) { | |
$category_ids[] = $bigcommerce_categories; | |
} | |
} | |
return $category_ids; | |
} | |
}else{ | |
throw new Exception( | |
"Bad request. Please specify Infusion/Codi product.", | |
500 | |
); | |
} | |
} | |
/** | |
* Get BigCommerce Category Names for Infusion/Codi Product. | |
* | |
* @var object $product | |
* | |
* @return array|bool | |
* @throws Exception | |
*/ | |
public function getCategoryNames($product = null) | |
{ | |
if($product != null && isset($product)){ | |
if(isset($product->categories)){ | |
$categories = explode(',', $product->categories); | |
$this->trim_spaces($categories); | |
foreach($categories as $key => $category){ | |
$category_name = $this->getCategoryName($category); | |
if($category_name){ | |
$category_names[] = $category_name; | |
} | |
} | |
$this->trim_spaces($category_names); | |
return $category_names; | |
}else{ | |
return false; | |
} | |
}else{ | |
throw new Exception( | |
"Bad request. Please specify Infusion/Codi product.", | |
500 | |
); | |
} | |
} | |
/** | |
* Get categories that exist in BigCommerce, but not Codi. | |
* | |
* @var Integer $mode | |
* | |
* @return array|bool | |
* @throws \Exception | |
*/ | |
public function getMissingCategories($mode = 0) | |
{ | |
switch($mode){ | |
case 0: | |
$source = $this->bigcommerce_categories; | |
$target = $this->mergeCodiCategories(); | |
$key = 'description'; | |
break; | |
case 1: | |
$source = $this->mergeCodiCategories(); | |
$target = $this->bigcommerce_categories; | |
break; | |
default: | |
throw new \Exception( | |
"Bad request.\r\n0 = Show missing from Codi.\r\n1 = Show missing from BigCommerce.", | |
400 | |
); | |
} | |
$results = array(); | |
foreach($source as $item){ | |
if(isset($key)) { | |
$search_results = $this->executeSearch($target, $item, $key); | |
if(!$search_results){ | |
$results[] = $item; | |
} | |
}else{ | |
$search_results = $this->executeSearch($target, $item['description']); | |
if(!$search_results){ | |
$results[] = $item['description']; | |
} | |
} | |
} | |
return $results; | |
} | |
private function mergeCodiCategories() | |
{ | |
$codi_categories = collect($this->level0); | |
$codi_categories = $codi_categories->merge($this->level1->toArray()); | |
$codi_categories = $codi_categories->merge($this->level2->toArray()); | |
return $codi_categories; | |
} | |
/** | |
* Get BigCommerce Category Name from 'categorycode'. | |
* | |
* @var string | |
* | |
* @return string|bool | |
*/ | |
private function getCategoryName($category) | |
{ | |
$search_level2 = $this->executeSearch($this->level2, $category, 'categorycode'); | |
if($search_level2){ | |
return $this->level2[$search_level2]['description']; | |
}else{ | |
$search_level1 = $this->executeSearch($this->level1, $category, 'categorycode'); | |
if($search_level1){ | |
return $this->level1[$search_level1]['description']; | |
}else{ | |
$search_level0 = $this->executeSearch($this->level0, $category, 'categorycode'); | |
if($search_level0){ | |
return $this->level0[$search_level0]['description']; | |
}else{ | |
return false; | |
} | |
} | |
} | |
} | |
/** | |
* Execute search on collection. | |
* | |
* @var Collection $haystack | |
* @var string $needle | |
* @var string $key | |
* | |
* @return string | |
*/ | |
public function executeSearch(Collection $haystack, $needle, $key = null) | |
{ | |
if($key){ | |
$search_query = $haystack->search(function($item) use ($needle, $key){ | |
return $item[$key] == $needle; | |
}); | |
}else{ | |
$search_query = $haystack->search(function($item) use ($needle){ | |
return $item == $needle; | |
}); | |
} | |
return $search_query; | |
} | |
/** | |
* Return data from CSVs. | |
* | |
* @var integer $level | |
* | |
* @return array | |
*/ | |
private function loadFromCSVs($level) | |
{ | |
$reader = Reader::createFromString( | |
Storage::disk('local') | |
->get('categories/level' . ($level + 1) . '.csv')); | |
$categories = iterator_to_array($reader->fetchAssoc(0)); | |
$this->trim_spaces($categories); | |
Cache::forever('level' . $level, $categories); | |
return $categories; | |
} | |
/** | |
* Gets Codi/Infusion Categories. | |
* | |
* @var int $level | |
* @var bool $force | |
* | |
* @return Collection | |
* @throws Exception | |
*/ | |
private function getCodiCategories($level = false, $force = false) | |
{ | |
if($level !== false){ | |
if($force){ | |
return collect($this->loadFromCSVs($level)); | |
}else{ | |
if(Cache::has('level' . $level)){ | |
return collect(Cache::get('level' . $level)); | |
}else { | |
return collect($this->loadFromCSVs($level)); | |
} | |
} | |
}else{ | |
throw new Exception( | |
"Bad request. Please specify a valid level. [0, 1, 2].", | |
503 | |
); | |
} | |
} | |
/** | |
* Gets BigCommerce Categories. | |
* | |
* @return Collection | |
*/ | |
private function getBigCommerceCategories($force = false) | |
{ | |
if($force){ | |
return collect($this->fetchBigCommerceCategories()); | |
}else{ | |
if(Cache::has('bigcommerce_categories')) { | |
return collect(Cache::get('bigcommerce_categories')); | |
}else { | |
return collect($this->fetchBigCommerceCategories()); | |
} | |
} | |
} | |
/** | |
* Fetches BigCommerce Categories from API. | |
* | |
* @return array | |
*/ | |
private function fetchBigCommerceCategories() | |
{ | |
BigCommerceClient::configure(array( | |
'store_url' => getenv('BIGCOMMERCE_STORE_URL'), | |
'username' => getenv('BIGCOMMERCE_USERNAME'), | |
'api_key' => getenv('BIGCOMMERCE_TOKEN') | |
)); | |
$response = BigCommerceClient::getCategories(['limit' => 250]); | |
$formatted_response = array(); | |
foreach($response as $fields){ | |
$formatted_response[] = $fields->fields; | |
} | |
$categories = array(); | |
foreach($formatted_response as $category){ | |
$categories[$category->id] = $category->name; | |
} | |
$this->trim_spaces($categories); | |
Cache::put( | |
'bigcommerce_categories', | |
$categories, | |
Carbon::now()->addHour() | |
); | |
return $categories; | |
} | |
/** | |
* Trims array values, removes empty values. | |
* | |
* @var &array | |
* | |
*/ | |
private function trim_spaces(&$array){ | |
if(is_array($array)) { | |
foreach ($array as $key => &$value) { | |
is_array($value) ? $this->trim_spaces($value) : $value = trim($value); | |
if (empty($value)) { | |
unset($array[$key]); | |
} else { | |
unset($value); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment