Skip to content

Instantly share code, notes, and snippets.

@molotovbliss
Last active February 2, 2022 13:42
Show Gist options
  • Save molotovbliss/857973a27109b6770346 to your computer and use it in GitHub Desktop.
Save molotovbliss/857973a27109b6770346 to your computer and use it in GitHub Desktop.
Shopify to Magento 1.x Simple Products Import via Shopify API
<?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