Skip to content

Instantly share code, notes, and snippets.

@St0iK
Created September 21, 2015 11:56
Show Gist options
  • Save St0iK/c566afab0ec71a53fc7b to your computer and use it in GitHub Desktop.
Save St0iK/c566afab0ec71a53fc7b to your computer and use it in GitHub Desktop.
<?php
class Creode_Nothimport_Model_Converter extends Mage_Core_Model_Abstract
{
/** Defintion Data */
private $_definitionConfigurableSku;
private $_definitionProductAttributes;
private $_definitionCustomOptions;
private $_definitionAdditionalProducts;
private $_definitionSwapProducts;
private $_definitionRibbonOptions;
/** My1stYears product data */
private $_my1styearsProductId;
private $_my1styearsProduct;
private $_my1styearsProductCustomOptions;
/** NOTH Data */
private $_nothItemOptions;
/** buyInfo Arrays */
private $_buyInfo = array();
private $_buyInfoAdditional = array();
private $_buyInfoGiftWrap = array();
private $_buyInfoSwap = array();
/** Logger **/
private $_loggerActive = FALSE;
private $_loggerPrintArrays = FALSE;
/** FLAGS */
private $_giftWrapOptionFound = FALSE;
private $_swapProductFound = FALSE;
private $_additionalProductFound = FALSE;
/** Helpers */
private $_productAttributesMatched = array();
private $_customOptionsMatchedCounter = 0;
/** Gift Wrap Options */
private $_ribbon_title;
private $_gift_box_title;
private $_gift_box_sku;
private $_ribbon_sku;
public function __construct($loggerActive = FALSE, $loggerPrintArrays = FALSE)
{
$this->_loggerActive = $loggerActive;
$this->_loggerPrintArrays = $loggerPrintArrays;
}
/**
* Custom construct method
* Initialize member variables
* @param Array $nothOrderItemDetails [data from API]
*/
private function bootstrap(Array $nothOrderItemDetails, $definition){
// Clear values
$this->clear();
$this->logger(" ");
$this->logger("=================== Start =======================");
$this->logger($nothOrderItemDetails);
// Get Definition data from DB
$this->_definitionConfigurableSku = $definition->getConfigurableSku();
$this->_definitionProductAttributes = unserialize($definition->getProductAttributes());
$this->_definitionCustomOptions = unserialize($definition->getCustomOptions());
$this->_definitionAdditionalProducts = unserialize($definition->getAdditionalProducts());
$this->_definitionSwapProducts = unserialize($definition->getSwapProducts());
$this->_definitionRibbonOptions = unserialize($definition->getRibbon()); // TODO: Fix me
// Load Magento product details
$this->_my1styearsProductId = Mage::getModel('catalog/product')->getIdBySku( $this->_definitionConfigurableSku );
$this->_my1styearsProduct = Mage::getModel("catalog/product")->load($this->_my1styearsProductId);
// Product's Custom Options
$this->_my1styearsProductCustomOptions = $this->_my1styearsProduct->getOptions();
// Gift Wrap Options
// $this->_ribbon_sku = Mage::getStoreConfig('sales/ribbon/ribbon_sku');
// $this->_gift_box_sku = Mage::getStoreConfig('sales/ribbon/giftbox_sku');
$this->_gift_box_sku = "gift_box_noth";
$this->_ribbon_sku = "ribbon_noth";
$this->_ribbon_title = Mage::getStoreConfig('sales/ribbon/ribbon_title');
$this->_gift_box_title = Mage::getStoreConfig('sales/ribbon/giftbox_title');
$this->_nothItemOptions = $nothOrderItemDetails['options'];
$this->_buyInfo['qty'] = $nothOrderItemDetails['quantity'];
}
/**
* @param array $nothOrderItemDetails
* @return array|bool
*/
public function run(Array $nothOrderItemDetails){
// Load Definition for this Product
// $definition = Mage::getModel('nothimport/definition')->load($nothOrderItemDetails['noth_product_id'], 'product_id');
$definition = Mage::getModel('nothimport/definition')->load($nothOrderItemDetails['noth_product_sku'],'configurable_sku');
if(!$definition->getId())
{
$this->logger("No Definition was found: 'noth_product_id'",$nothOrderItemDetails['noth_product_id']);
return "def_not_found";
}
// Initialize member variables
$this->bootstrap($nothOrderItemDetails, $definition);
$this->checkSwapProducts($this->_definitionSwapProducts);
if (!$this->_swapProductFound)
{
// Loop Order Item Options
foreach ($this->_nothItemOptions as $item)
{
// Check for CustomOptions
$this->checkForCustomOptions($this->_definitionCustomOptions, $item['name'], $item['value']);
if ($this->_my1styearsProduct->isConfigurable())
{
// Check for Product Attributes
$this->checkOptionInProductAttributes($this->_definitionProductAttributes, $item['name'], $item['value']);
}
}
}
// Check for Ribbon
$this->checkForRibbon($this->_definitionRibbonOptions);
// Check for Additional Products
$this->checkAdditionalProducts($this->_definitionAdditionalProducts);
// Check if we have a configurable product & set the product_id to child product id
if ($this->_my1styearsProduct->isConfigurable())
{
$this->logger("Magento Product matched is 'Configurable'");
$this->getChildProductId();
}
// Check Matched Custom Options and add any missing
$this->logger("Matched Custom Options Count:: ".$this->_customOptionsMatchedCounter);
if($this->_customOptionsMatchedCounter){
$this->setDefaultValuesForCustomOptions();
}
return $this->buildReturnArray();
}
/**
* Build the final return array
* @return array Final Array
*/
private function buildReturnArray()
{
// Check if Product is a Bundle
// and add missing products to the array
if($this->_my1styearsProduct->getTypeId() === 'bundle')
{
$bundled_items = array();
$optionCollection = $this->_my1styearsProduct->getTypeInstance()->getOptionsCollection();
$selectionCollection = $this->_my1styearsProduct->getTypeInstance()->getSelectionsCollection($this->_my1styearsProduct->getTypeInstance()->getOptionsIds());
$options = $optionCollection->appendSelections($selectionCollection);
foreach($options as $option) {
$_selections = $option->getSelections();
foreach($_selections as $selection) {
$bundled_items[$option->getOptionId()] = $selection->getSelectionId();
}
}
$params = array('bundle_option' => $bundled_items,'qty' => 1,'product'=>$this->_my1styearsProduct->getId());
$this->_buyInfo['bundle_option'] = $bundled_items;
$this->_buyInfo['qty'] = 1;
$this->_buyInfo['product'] = $this->_my1styearsProduct->getId();
}
$this->logger("Started building return array");
// We have a Swap
if (!empty($this->_buyInfoSwap) && $this->_swapProductFound)
{
$returnArray[] = $this->_buyInfoSwap; // Add Swap product to the return array
}
else
{
// Add original product to the return array
$returnArray[] = array('id' => $this->_my1styearsProductId, 'buy_request' => $this->_buyInfo);
}
if (!empty($this->_buyInfoAdditional) && $this->_additionalProductFound)
{
$returnArray[] = $this->_buyInfoAdditional; // Add additional product info
}
if ($this->_giftWrapOptionFound)
{
$returnArray = array_merge($returnArray, $this->_buyInfoGiftWrap);
}
if($this->_loggerPrintArrays)
{
$this->logger($returnArray);
}
$this->logger("=================== End =======================");
return $returnArray;
}
private function checkOptionInProductAttributes($productAttributes, $name, $value){
$this->logger("** Checking Option: $name in 'Product Attributes' **");
if(is_null($productAttributes['title'])){
$noth_helper = Mage::helper('nothimport/data');
$this->_definitionConfigurableSku();
$noth_helper->report('501', 'Definition for product'.$this->_definitionConfigurableSku());
}
$trimmedTitlesArray = array_map("trim", $productAttributes['title']);
$key = array_search(trim($name), $trimmedTitlesArray);
if ($key !== false){ $type = $productAttributes['type'][$key]; }
if($type === "options"){
foreach ($productAttributes['lookup_value'][$key] as $index => $prValue) {
if($prValue === $value) {
$this->_productAttributesMatched[$productAttributes['code'][$key]] = $productAttributes['match_value'][$key][$index];
}
}
}else if($type === "fixed_value"){
return $productAttributes['code'][$key];
}
}
/**
* Checks option's 'name' & 'value'
* @param $customOptions
* @param $name
* @param $value
* @internal param $ [String] $name Option name from NOTH
* @internal param $ [String] $value Option value from NOTH
*/
private function checkForCustomOptions($customOptions, $name, $value){
$this->logger("** Checking Option:$name in 'Custom Options' **");
// Trimming values
$trimmedTitlesArray = array_map("trim", $customOptions['title']);
$key = array_search(trim($name), $trimmedTitlesArray);
if ($key !== false){
$type = $customOptions['type'][$key];
$customOptionId = $this->getCustomOptionIDbyCode($this->_my1styearsProductCustomOptions, $customOptions['code'][$key]);
if($type === "options"){
$matchedOptionId = $this->mactchValueWithMultipleCustomOptionValue($this->_my1styearsProductCustomOptions, $customOptionId, $value);
$this->buildArrayItem($customOptionId, $matchedOptionId);
}else if($type === "fixed_value"){
$this->buildArrayItem($customOptionId, $value);
}
}
}
/**
* Matches the value from the Option with the value of the Custom Option
* @return Int the id of the selected Option
*/
private function mactchValueWithMultipleCustomOptionValue($productCustomOptions, $customOptionId, $value){
// Loop product's custom options
foreach ($productCustomOptions as $customOptionKey => $customOptionValue)
{
// Loop Option Values
foreach ($customOptionValue->getValues() as $oVal)
{
if($oVal->getTitle() == $value) return $oVal->getId();
}
}
}
/**
* Returns the Custom Option ID
* @param String $customOptionTitle Custom Option Title
* @return Int Custom Option ID
*/
private function getCustomOptionIDbyCode($productCustomOptions, $customOptionTitle){
// Loop all the product's custom options
foreach ($productCustomOptions as $customOptionKey => $customOptionValue)
{
// If we have a match for the 'code', return the id
if($customOptionValue->getCode() === $customOptionTitle)
{
return $customOptionValue->getId();
}
}
}
/**
* Build array item
* @param [sting] $key array key
* @param [type] $value array value
*/
private function buildArrayItem($key,$value){
$this->_customOptionsMatchedCounter++;
$this->logger("buildArrayItem $key",$value);
if(!empty($key) && !empty($value)){
$this->_buyInfo['options'][$key] = $value;
}
}
/**
* Replace 'Original product_id' of Configurable with selected 'Child' product Id based on attributes selected
*/
private function getChildProductId(){
$childProducts = Mage::getModel('catalog/product_type_configurable')->getUsedProducts(null, $this->_my1styearsProduct);
foreach($childProducts as $child) {
$found = FALSE;
foreach ($this->_productAttributesMatched as $key => $value) {
if( trim($child->getAttributeText($key)) === trim($value) ) {
$found = TRUE;
break;
}else{
$found = FALSE;
}
}
if($found){
$this->logger("Replacing 'original' product_id with child product_id (we have attributes matched)");
$this->_my1styearsProductId = $child->getId();
}else{
$this->logger("We could not match the attributes");
$this->_definitionFound = FALSE;
}
}
}
/**
* Checks if we have 'Additional Product' & Build Array that will be returned
* @param array $additionalProducts additional product info from db
*/
private function checkAdditionalProducts($additionalProducts){
$this->logger("** Checking Options for Additional Products **");
$this->logger($additionalProducts);
foreach ($this->_nothItemOptions as $item) {
if(trim($additionalProducts['upsell_title']) === trim($item['name']) && trim($item['value']) === trim($additionalProducts['upsell_active_value'])){
$this->_additionalProductFound = TRUE;
}
}
if($this->_additionalProductFound){
$this->logger("Additional product detected".$additionalProducts['upsell_title']);
$attributeDetected = $this->checkForAttributeMode($additionalProducts);
$this->_buyInfoAdditional['id'] = $this->additionalProductId($attributeDetected,$additionalProducts['upsell_sku']);
if(empty($this->_buyInfoAdditional['id'])){
$this->logger("No product found for this SKU",$additionalProducts['upsell_sku']);
}
$this->_buyInfoAdditional['buy_request']['qty'] = 1;
$additionalProduct = Mage::getModel("catalog/product")->load($this->_buyInfoAdditional['id']);
$additionalProductCustomOptions = $additionalProduct->getOptions();
// Check all options for a match on the additional product
foreach ($this->_nothItemOptions as $item)
{
$key = array_search(trim($item['name']), $additionalProducts['upsell_options']['title']);
if ($key !== false)
{
$type = $additionalProducts['upsell_options']['type'][$key];
$mode = $additionalProducts['upsell_options']['mode'][$key];
$customOptionId = $this->getCustomOptionIDbyCode($additionalProductCustomOptions,$additionalProducts['upsell_options']['code'][$key]);
if ($type === "options" && $mode == "custom_option")
{
$matchedOptionId = $this->mactchValueWithMultipleCustomOptionValue($additionalProductCustomOptions, $customOptionId, $item['value']);
$this->_buyInfoAdditional['buy_request']['options'][$customOptionId] = $matchedOptionId;
}
else if ($type === "fixed_value" && $mode == "custom_option")
{
$this->_buyInfoAdditional['buy_request']['options'][$customOptionId] = $item['value'];
}
}
}
}else{
$this->logger("No additional product found");
}
}
/**
* Check for Swap Product
* @param array $definitionSwapData Swap product info from db
* @return bool TRUE/FALSE
*/
private function checkSwapProducts($definitionSwapData){
$this->logger("** Checking for Swap Products **");
$this->logger($definitionSwapData);
// Loop NOTH item options
foreach ($this->_nothItemOptions as $item)
{
if(trim($definitionSwapData['swap_title']) === trim($item['name'])
&& trim($item['value']) === trim($definitionSwapData['swap_active_value']))
{
$this->_swapProductFound = TRUE;
$this->buildBuyInfoForSwap($definitionSwapData);
$this->logger("Swap product detected");
return TRUE; // quit loop, no reason to continue
}
}
$this->logger("No Swap Product Detected");
return FALSE;
}
/**
* Build Array for Swap product that will be returned
* @param array $definitionSwapData Swap product info from db
* @return bool|array buyInfoSwap
*/
private function buildBuyInfoForSwap($definitionSwapData)
{
$this->logger("Started building array for Swap Prodct");
if($definitionSwapData['swap_mode'] == "multi")
{
foreach ($this->_nothItemOptions as $item)
{
$key = array_search(trim($item['value']), $definitionSwapData['swaps_multi']['lookup_value']);
if ($key !== false)
{
$swap_sku_for_switch = $definitionSwapData['swaps_multi']['match_value'][$key];
//echo "swap_sku_for_switch".$swap_sku_for_switch;
break;
}
}
}else
{
$swap_sku_for_switch = $definitionSwapData['swap_sku'];
}
$this->_buyInfoSwap['id'] = Mage::getModel('catalog/product')->getIdBySku( $swap_sku_for_switch );
if(empty($this->_buyInfoSwap['id']))
{
//TODO: Critical error
$this->logger("Critical No product was found with this SKU", $definitionSwapData['swap_sku']);
return FALSE; // quit method
}
$swapProduct = Mage::getModel("catalog/product")->load($this->_buyInfoSwap['id']);
$swapProductCustomOptions = $swapProduct->getOptions();
// Build the buyInfoSwap Array
$this->populateSwapArray($definitionSwapData, $swapProductCustomOptions);
}
private function populateSwapArray($definitionSwapData, $swapProductCustomOptions)
{
$this->_buyInfoSwap['buy_request']['qty'] = 1;
// Loop NOTH item options
foreach ($this->_nothItemOptions as $item)
{
$key = array_search(trim($item['name']), $definitionSwapData['swap_options']['title']);
if ($key !== false)
{
$type = $definitionSwapData['swap_options']['type'][$key];
$customOptionId = $this->getCustomOptionIDbyCode($swapProductCustomOptions,$definitionSwapData['swap_options']['code'][$key]);
if($type === "options")
{
$matchedOptionId = $this->mactchValueWithMultipleCustomOptionValue($swapProductCustomOptions, $customOptionId, $item['value']);
$this->_buyInfoSwap['buy_request']['options'][$customOptionId] = $matchedOptionId;
}else if($type === "fixed_value")
{
$this->_buyInfoSwap['buy_request']['options'][$customOptionId] = $item['value'];
}
}
}
}
/**
* Checks if we have 'Ribbon' & Build Array that will be returned
*
* @param $ribbonData
*/
private function checkForRibbon($ribbonData){
$this->logger("** Checking Options for Ribbon **");
$this->logger($ribbonData);
$this->logger($this->_ribbon_title);
foreach ($this->_nothItemOptions as $item)
{
if ( trim(strtolower($item['name'])) == trim(strtolower($this->_ribbon_title)) && $ribbonData['ribbon_active'] == "on")
{
$this->logger("Adding Ribbon");
$this->_giftWrapOptionFound = TRUE;
$this->addRibbonAndGiftBox($ribbonData,"ribbon");
}
if ( trim($item['name']) == "Gift wrap options" && trim($item['value']) == "Gift box" && $ribbonData['gift_box_active'] == "on")
{
$this->logger("Adding Ribbon");
$this->_giftWrapOptionFound = TRUE;
$this->addRibbonAndGiftBox($ribbonData,"giftbox");
}
}
}
//89.151.77.8,89.151.77.9,94.143.253.178,92.27.206.145
private function checkForAttributeMode($additionalProducts)
{
foreach ($additionalProducts['upsell_options']['mode'] as $m)
{
if($m == "attribute")
{
$this->logger("WE HAVE AN ATTRIBUTE");
return TRUE;
}
}
$this->logger("NO ATTRIBUTE FOUND");
return FALSE;
}
// TODO: Log and check what is going on!
private function additionalProductId($attributeDetected,$upsell_sku)
{
$this->logger("additionalProductId function called");
if ( !$attributeDetected )
{
$this->logger("No attribute was detected");
return Mage::getModel('catalog/product')->getIdBySku( $upsell_sku);
}
// Loop order item Options
foreach ($this->_nothItemOptions as $item)
{
$key = array_search(trim($item['name']), $this->_definitionAdditionalProducts['upsell_options']['title']);
if ($key !== false)
{
$type = $this->_definitionAdditionalProducts['upsell_options']['type'][$key];
$mode = $this->_definitionAdditionalProducts['upsell_options']['mode'][$key];
}
// If it is an 'attribute'
if ($type === "options" && $mode === "attribute")
{
// Loop all its values and search for a match with the Option
foreach ($this->_definitionAdditionalProducts['upsell_options']['lookup_value'][$key] as $index => $prValue)
{
// For all the matches found build an array
if($prValue === $item['value'])
{
$additionalAttributeMatched[$this->_definitionAdditionalProducts['upsell_options']['code'][$key]] = $this->_definitionAdditionalProducts['upsell_options']['match_value'][$key][$index];
}
}
}
}
// Load additional product from the SKU
$_catalog = Mage::getModel('catalog/product');
$_product = Mage::getModel('catalog/product')->load($_catalog->getIdBySku($upsell_sku));
$childProducts = Mage::getModel('catalog/product_type_configurable')->getUsedProducts(null, $_product);
// Loop all its Child Products
// TODO : ADD AN EXTRA CHECK FOR EMPTY
foreach($childProducts as $child)
{
$found = FALSE;
foreach ($additionalAttributeMatched as $key => $value)
{
// All items of the array should be matched for this to work
if($child->getAttributeText($key) === $value)
{
$found = TRUE;
}
else
{
$found = FALSE;
}
}
if($found)
{
$this->logger("We have your new ID BOSS!");
return $child->getId();
}else
{
$this->logger("No id was found boss, check wazzup plz");
}
}
}
private function setDefaultValuesForCustomOptions()
{
$productOptions = $this->_my1styearsProduct->getOptions();
$defaultTitle = '';
foreach ($productOptions as $option)
{
$optionValues = $option->getValues();
// Check if we have a custom optins that is not on 'Custom Options'
if ( !array_key_exists($option->getOptionId(), $this->_buyInfo['options'] ) &&
($option->getType() == "colour" || $option->getType() == "dropdown" || $option->getType() == "font") )
{
// Get the first value
foreach ($optionValues as $optionValue) {
$defaultTitle = $optionValue['default_title'];
$matchedOptionId = $this->mactchValueWithMultipleCustomOptionValue($this->_my1styearsProductCustomOptions, $option->getOptionId(), $defaultTitle);
break;
}
if(!empty($matchedOptionId))
{
$this->buildArrayItem($option->getOptionId(),$matchedOptionId );
}
}
}
}
/**
* Logging functionality, Write to custom log file
*
* @param string $title message
* @param vale $value variable
*/
private function logger($title, $value = NULL){
if($this->_loggerActive){
if(is_array($title) && $this->_loggerPrintArrays){
Mage::log($title, null, 'nothimport-converter.log', false);
}else{
if($value){
Mage::log($title.": ".$value, null, 'nothimport-converter.log', false);
}else{
if(!is_array($title)){
Mage::log($title, null, 'nothimport-converter.log', false);
}
}
}
}
}
private function clear()
{
$this->_additionalProductFound = FALSE;
$this->$_swapProductFound = FALSE;
$this->$_additionalProductFound = FALSE;
$this->_productAttributesMatched = array();
$this->_giftWrapOptionFound = FALSE;
$this->_buyInfo = array();
$this->_buyInfoAdditional = array();
$this->_buyInfoGiftWrap = array();
$this->_buyInfoSwap = array();
}
private function addRibbonAndGiftBox($ribbonData,$type)
{
if($type == "ribbon"){
$this->addRibbon($ribbonData);
}
if($type == "giftbox"){
$this->addGiftBox($ribbonData);
}
}
private function addGiftBox($ribbonData)
{
// Build array and append it
$giftBoxArray = array();
$giftBoxArray['id'] = Mage::getModel('catalog/product')->getIdBySku( $this->_gift_box_sku );
$giftBoxArray['buy_request']['qty'] = 1;
$this->_buyInfoGiftWrap[] = $giftBoxArray;
}
private function addRibbon($ribbonData)
{
// Build array and append it
$ribbonArray = array();
$ribbonArray['id'] = Mage::getModel('catalog/product')->getIdBySku( $this->_ribbon_sku );
$ribbonArray['buy_request']['qty'] = 1;
// Add Custom Options
$ribbonArray['id'] = Mage::getModel('catalog/product')->getIdBySku( $this->_ribbon_sku );
$ribbonArray['buy_request']['qty'] = 1;
$ribbonProduct = Mage::getModel("catalog/product")->load($ribbonArray['id']);
$ribbonProductCustomOptions = $ribbonProduct->getOptions();
// Check all options for a match on the additional product
foreach ($this->_nothItemOptions as $item)
{
$key = array_search(trim($item['name']), $ribbonData['ribbon_options']['title']);
if ($key !== false)
{
$this->logger("Mesa eisai");
$type = $ribbonData['ribbon_options']['type'][$key];
$customOptionId = $this->getCustomOptionIDbyCode($ribbonProductCustomOptions,$ribbonData['ribbon_options']['code'][$key]);
if($type === "options")
{
$matchedOptionId = $this->mactchValueWithMultipleCustomOptionValue($ribbonProductCustomOptions, $customOptionId, $item['value']);
$ribbonArray['buy_request']['options'][$customOptionId] = $matchedOptionId;
}
else if($type === "fixed_value")
{
$ribbonArray['buy_request']['options'][$customOptionId] = $item['value'];
}
}
}
$this->logger($ribbonArray);
$this->_buyInfoGiftWrap[] = $ribbonArray;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment