Last active
February 2, 2022 13:42
-
-
Save molotovbliss/857973a27109b6770346 to your computer and use it in GitHub Desktop.
Shopify to Magento 1.x Simple Products Import via Shopify API
This file contains hidden or 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 | |
/** | |
* Import products from Shopify via Shopify API to Magento simple products | |
* by: [email protected] (http://molotovbliss.com) | |
* USE AT YOUR OWN RISK. | |
* | |
* Requires: Avs_FastSimpleImport https://github.com/avstudnitz/AvS_FastSimpleImport | |
* cURL, simpleXML, Magento | |
*/ | |
ob_implicit_flush(true); | |
require_once('app/Mage.php'); | |
umask(0); | |
ini_set('display_errors', 1); | |
Mage::setIsDeveloperMode(true); | |
Mage::app(); | |
set_time_limit(0); | |
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); | |
//Mage::app()->setCurrentStore(Mage_Core_Model_App::DISTRO_STORE_ID); | |
const GRAMS = 0.00220462; | |
class Client { | |
// Configuration found in Shopify private API creation | |
// http://docs.shopify.com/api/tutorials/creating-a-private-app | |
// Total number of items to be returned from shopify API per request | |
public $limit = 100; | |
private $_config = array( | |
'api_key' => '', | |
'secret' => '', | |
'token' => '', | |
'store_url' => '.myshopify.com' | |
); | |
private $_action = "/admin/"; | |
public $varienIo; | |
public $_varDir = ""; | |
public $_mediaDir = ""; | |
public function __construct() { | |
$this->setExportDir(); | |
$this->setMediaDir(); | |
$this->varienIo = new Varien_Io_File(); | |
Mage::getModel('core/config_options')->createDirIfNotExists($this->_varDir); | |
Mage::getModel('core/config_options')->createDirIfNotExists($this->_varDir); | |
} | |
private function setAction($action) { | |
$this->_action = $action; | |
} | |
public function setExportDir() { | |
$this->_varDir = Mage::getModel('core/config_options')->getVarDir() . DIRECTORY_SEPARATOR . "shopify" . DIRECTORY_SEPARATOR; | |
} | |
public function setMediaDir() { | |
$this->_mediaDir = Mage::getBaseDir('media') . DIRECTORY_SEPARATOR . 'shopify' . DIRECTORY_SEPARATOR; | |
} | |
// build simple URL Request | |
// $action should contain trailing and starting slashes / | |
// example $action = /admin/collects/count.xml | |
public function buildUrlRequest($action, $page = 1, $id = NULL, $fields = NULL) { | |
$url = 'https://' . $this->_config['api_key'] . ':' . $this->_config['token'] . '@' . $this->_config['store_url'] . $action . $id . '.xml'; | |
$url .= '?limit='.$this->limit; | |
$url .= '&page='.$page; | |
$url .= '&fields='.$fields; | |
echo "Requesting: ".$url."<br />"; | |
$filename = str_replace('/', '', $action.'_'.$id.'_'.$this->limit.'_'.$page.'_'.$fields); | |
$this->setAction($filename.".xml"); | |
return $url; | |
} | |
/** | |
* Request | |
* @param str $request | |
* @return xml | |
*/ | |
public function request($request) { | |
$session = curl_init(); | |
curl_setopt($session, CURLOPT_URL, $request); | |
curl_setopt($session, CURLOPT_ENCODING, "UTF-8" ); | |
curl_setopt($session, CURLOPT_HTTPGET, 1); | |
curl_setopt($session, CURLOPT_HEADER, false); | |
curl_setopt($session, CURLOPT_HTTPHEADER, array('Accept: application/xml', 'Content-Type: application/xml;')); | |
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); | |
if(preg_match("/^(https)/",$request)) curl_setopt($session,CURLOPT_SSL_VERIFYPEER,false); | |
$response = curl_exec($session); | |
curl_close($session); | |
$xml = new SimpleXMLElement($response); | |
// save copy of generated xml for processing | |
$xml->asXml($this->_varDir . $this->_action); | |
return $xml; | |
} | |
} | |
// Create new Shopify client | |
$shopifyAPI = new Client; | |
// $customCollections = $shopifyAPI->buildUrlRequest('/admin/custom_collections'); | |
// $customCollectionsData = $shopifyAPI->request($customCollections); | |
// zend_debug::dump($customCollectionsData); | |
// exit; | |
// // Get product detail | |
// //$url = $shopifyAPI->buildUrlRequest('/admin/products/','112090464'); | |
// // Get total number of collections: | |
// $collectscountUrl = $shopifyAPI->buildUrlRequest('/admin/collects/count'); | |
// $collectscount = $shopifyAPI->request($collectscountUrl); | |
// $pages = $collectscount / $shopifyAPI->limit; | |
// $pagesRounded = ceil($pages); | |
// echo $pagesRounded; | |
// zend_debug::dump($collectscount); | |
// //Get collections | |
// $i=1; | |
// while($i <= $pagesRounded) { | |
// $collectsUrl = $shopifyAPI->buildUrlRequest('/admin/collects',$i); | |
// $collects = $shopifyAPI->request($collectsUrl); | |
// foreach($collects as $collect) { | |
// echo $collect->{'product-id'}; | |
// } | |
// zend_debug::dump($collects); | |
// $i++; | |
// } | |
// exit; | |
// get total number of products divide to get offset for pages | |
$productsCountUrl = $shopifyAPI->buildUrlRequest('/admin/products/count'); | |
$productsCount = (int) $shopifyAPI->request($productsCountUrl); | |
$pages = $productsCount / $shopifyAPI->limit; | |
$pagesRounded = ceil($pages); | |
zend_debug::dump($pagesRounded); | |
// Get Products | |
$offset = 1; | |
ob_start(); | |
while($offset <= $pagesRounded) { | |
$productsUrl = $shopifyAPI->buildUrlRequest('/admin/products',$offset); | |
$products = $shopifyAPI->request($productsUrl); | |
foreach($products as $p) { | |
unset($mediaImageSrc); | |
unset($mediaImageName); | |
$mediaImageSrc = array(); | |
$mediaImageName = array(); | |
// TODO: Allow for multiple variants | |
foreach($p->variants as $v) { | |
$sku = (string) $v->variant->{'sku'}; | |
$sku = mb_strimwidth($sku,0,254,'','utf-8'); | |
$weight = (string) $v->variant->{'grams'}; | |
$price = (float) $v->variant->{'price'}; | |
$qty = (int) $v->variant->{'inventory-quantity'}; | |
if($qty == 0) { $is_in_stock = 0; } else { $is_in_stock = 1; } | |
} | |
$bodyHtml = (string) $p->{'body-html'}; | |
$body = trim(strip_tags(str_replace(array("\n", "\t", "\r"), '', $bodyHtml))); | |
$body = mb_strimwidth($body,0,250 ,'...','utf-8'); | |
echo "Importing: ".(string) $p->{'title'}."<br />"; | |
ob_flush(); | |
flush(); | |
$data[] = array( | |
'sku' => $sku, | |
'_type' => 'simple', | |
'_attribute_set' => 'Default', | |
'_product_websites' => 'base', | |
'_store' => 'default', | |
//'_category' => 2, | |
'name' => (string) $p->{'title'}, | |
'price' => $price, | |
//'special_price' => 0.00, | |
'cost' => 0.00, | |
'description' => $bodyHtml, | |
'short_description' => $body, | |
'meta_title' => (string) $p->{'title'}, | |
'meta_description' => $body, | |
'meta_keyword' => (string) $p->{'tags'}, | |
'weight' => GRAMS * $weight, | |
'status' => 1, | |
'visibility' => 4, | |
'tax_class_id' => 2, | |
'qty' => $qty, | |
'is_in_stock' => $is_in_stock, | |
'enable_googlecheckout' => '0', | |
'gift_message_available' => '0', | |
'url_key' => (string) trim($p->{'handle'}), | |
'_media_attribute_id' => 88, | |
'_media_image' => (string) $p->images->image->{'src'}, | |
'_media_lable' => (string) $p->{'title'}, | |
'_media_position' => (int) $p->images->image->{'position'}, | |
'_media_is_disabled' => 0, | |
'image' => (string) "/".parse_url(basename($p->images->image->{'src'}),PHP_URL_PATH), | |
'small_image' => (string) "/".parse_url(basename($p->images->image->{'src'}),PHP_URL_PATH), | |
'thumbnail' => (string) "/".parse_url(basename($p->images->image->{'src'}),PHP_URL_PATH) | |
); | |
$count = 1; | |
foreach($p->images as $image) { | |
foreach($image as $i) { | |
if($count == 1) { $count++; continue; } | |
//$mediaImage[] = $shopifyAPI->download($i->{'src'}, $shopifyAPI->_mediaDir . basename(parse_url($i->{'src'},PHP_URL_PATH))); | |
$mediaImageSrc = (string) $i->{'src'}; | |
//$mediaImageName = (string) basename(parse_url($i->{'src'},PHP_URL_PATH)); | |
$mediaImageName = (string) basename($i->{'src'}); | |
$media = array( | |
'sku' => null, | |
'_store' => 'default', | |
'_media_attribute_id' => 88, | |
'_media_image' => $mediaImageSrc, | |
'_media_lable' => (string) $p->{'title'}, | |
'_media_position' => (int) $i->{'position'}, | |
'_media_is_disabled' => 0, | |
'image' => "/".parse_url($mediaImageName,PHP_URL_PATH), | |
'small_image' => "/".parse_url($mediaImageName,PHP_URL_PATH), | |
'thumbnail' => "/".parse_url($mediaImageName,PHP_URL_PATH) | |
); | |
array_push($data,$media); | |
} | |
$count++; | |
} | |
} | |
//zend_debug::dump($data); | |
//zend_debug::dump($products); | |
$offset++; | |
//exit; | |
} | |
echo "Starting Import..."; | |
ob_end_flush(); | |
try { | |
/** @var $import AvS_FastSimpleImport_Model_Import */ | |
$import = Mage::getModel('fastsimpleimport/import'); | |
$import | |
->setPartialIndexing(true) | |
->setContinueAfterErrors(true) | |
->setBehavior(Mage_ImportExport_Model_Import::BEHAVIOR_APPEND) | |
->processProductImport($data); | |
//->dryrunProductImport($data); | |
} catch (Exception $e) { | |
zend_debug::dump($import->getErrorMessages()); | |
zend_debug::dump($e->getMessage()); | |
} | |
// Hack to set all first images as base,thumbnail,image to default | |
$resource = Mage::getSingleton('core/resource'); | |
$writeConnection = $resource->getConnection('core_write'); | |
$sql = "UPDATE catalog_product_entity_media_gallery AS mg, | |
catalog_product_entity_media_gallery_value AS mgv, | |
catalog_product_entity_varchar AS ev | |
SET ev.value = mg.value | |
WHERE mg.value_id = mgv.value_id | |
AND mg.entity_id = ev.entity_id | |
AND ev.attribute_id IN (85, 86, 87) #<-- Find them in catalog_product_entity_varchar | |
AND mgv.position = 1;"; | |
$writeConnection->query($sql); | |
echo "Import Completed"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment