PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/magmi/plugins/base/itemprocessors/configurables/magmi_configurableprocessor.php

https://bitbucket.org/jit_bec/shopifine
PHP | 366 lines | 307 code | 35 blank | 24 comment | 26 complexity | 5ff2edd8a19d216b0465f6280cfcef41 MD5 | raw file
Possible License(s): LGPL-3.0
  1. <?php
  2. class Magmi_ConfigurableItemProcessor extends Magmi_ItemProcessor
  3. {
  4. private $_configurable_attrs=array();
  5. private $_use_defaultopc=false;
  6. private $_optpriceinfo=array();
  7. private $_currentsimples=array();
  8. public function initialize($params)
  9. {
  10. }
  11. public function getPluginInfo()
  12. {
  13. return array(
  14. "name" => "Configurable Item processor",
  15. "author" => "Dweeves",
  16. "version" => "1.3.7",
  17. "url"=> "http://sourceforge.net/apps/mediawiki/magmi/index.php?title=Configurable_Item_processor"
  18. );
  19. }
  20. public function getConfigurableOptsFromAsId($asid)
  21. {
  22. if(!isset($this->_configurable_attrs[$asid]))
  23. {
  24. $ea=$this->tablename("eav_attribute");
  25. $eea=$this->tablename("eav_entity_attribute");
  26. $eas=$this->tablename("eav_attribute_set");
  27. $eet=$this->tablename("eav_entity_type");
  28. $sql="SELECT ea.attribute_code FROM `$ea` as ea
  29. JOIN $eet as eet ON eet.entity_type_id=ea.entity_type_id AND eet.entity_type_id=?
  30. JOIN $eas as eas ON eas.entity_type_id=eet.entity_type_id AND eas.attribute_set_id=?
  31. JOIN $eea as eea ON eea.attribute_id=ea.attribute_id";
  32. $cond="ea.is_user_defined=1";
  33. if($this->getMagentoVersion()!="1.3.x")
  34. {
  35. $cea=$this->tablename("catalog_eav_attribute");
  36. $sql.=" JOIN $cea as cea ON cea.attribute_id=ea.attribute_id AND cea.is_global=1 AND cea.is_configurable=1";
  37. }
  38. else
  39. {
  40. $cond.=" AND ea.is_global=1 AND ea.is_configurable=1";
  41. }
  42. $sql.=" WHERE $cond
  43. GROUP by ea.attribute_id";
  44. $result=$this->selectAll($sql,array($this->getProductEntityType(),$asid));
  45. foreach($result as $r)
  46. {
  47. $this->_configurable_attrs[$asid][]=$r["attribute_code"];
  48. }
  49. }
  50. return $this->_configurable_attrs[$asid];
  51. }
  52. public function dolink($pid,$cond,$conddata=array())
  53. {
  54. $cpsl=$this->tablename("catalog_product_super_link");
  55. $cpr=$this->tablename("catalog_product_relation");
  56. $cpe=$this->tablename("catalog_product_entity");
  57. $sql="DELETE cpsl.*,cpsr.* FROM $cpsl as cpsl
  58. JOIN $cpr as cpsr ON cpsr.parent_id=cpsl.parent_id
  59. WHERE cpsl.parent_id=?";
  60. $this->delete($sql,array($pid));
  61. //recreate associations
  62. $sql="INSERT INTO $cpsl (`parent_id`,`product_id`) SELECT cpec.entity_id as parent_id,cpes.entity_id as product_id
  63. FROM $cpe as cpec
  64. JOIN $cpe as cpes ON cpes.type_id IN ('simple','virtual') AND cpes.sku $cond
  65. WHERE cpec.entity_id=?";
  66. $this->insert($sql,array_merge($conddata,array($pid)));
  67. $sql="INSERT INTO $cpr (`parent_id`,`child_id`) SELECT cpec.entity_id as parent_id,cpes.entity_id as child_id
  68. FROM $cpe as cpec
  69. JOIN $cpe as cpes ON cpes.type_id IN ('simple','virtual') AND cpes.sku $cond
  70. WHERE cpec.entity_id=?";
  71. $this->insert($sql,array_merge($conddata,array($pid)));
  72. unset($conddata);
  73. }
  74. public function autoLink($pid)
  75. {
  76. $this->dolink($pid,"LIKE CONCAT(cpec.sku,'%')");
  77. }
  78. public function updSimpleVisibility($pid)
  79. {
  80. $vis=$this->getParam("CFGR:updsimplevis",0);
  81. if($vis!=0)
  82. {
  83. $attinfo=$this->getAttrInfo("visibility");
  84. $sql="UPDATE ".$this->tablename("catalog_product_entity_int")." as cpei
  85. JOIN ".$this->tablename("catalog_product_super_link"). " as cpsl ON cpsl.parent_id=?
  86. JOIN ".$this->tablename("catalog_product_entity")." as cpe ON cpe.entity_id=cpsl.product_id
  87. SET cpei.value=?
  88. WHERE cpei.entity_id=cpe.entity_id AND attribute_id=?";
  89. $this->update($sql,array($pid,$vis,$attinfo["attribute_id"]));
  90. }
  91. }
  92. public function fixedLink($pid,$skulist)
  93. {
  94. $this->dolink($pid,"IN (".$this->arr2values($skulist).")",$skulist);
  95. }
  96. public function buildSAPTable($sapdesc)
  97. {
  98. $saptable=array();
  99. $sapentries=explode(",",$sapdesc);
  100. foreach($sapentries as $sapentry)
  101. {
  102. $sapinf=explode("::",$sapentry);
  103. $sapname=$sapinf[0];
  104. $sapdata=$sapinf[1];
  105. $sapdarr=explode(";",$sapdata);
  106. $saptable[$sapname]=$sapdarr;
  107. unset($sapdarr);
  108. }
  109. unset($sapentries);
  110. return $saptable;
  111. }
  112. public function processItemBeforeId(&$item,$params=null)
  113. {
  114. //if item is not configurable, nothing to do
  115. if($item["type"]!=="configurable")
  116. {
  117. return true;
  118. }
  119. if($this->_use_defaultopc || ($item["options_container"]!="container1" && $item["options_container"]!="container2"))
  120. {
  121. $item["options_container"]="container2";
  122. }
  123. //reset option price info
  124. $this->_optpriceinfo=array();
  125. if(isset($item["super_attribute_pricing"]))
  126. {
  127. $this->_optpriceinfo=$this->buildSAPTable($item["super_attribute_pricing"]);
  128. unset($item["super_attribute_pricing"]);
  129. }
  130. return true;
  131. }
  132. public function getMatchMode($item)
  133. {
  134. $matchmode="auto";
  135. if($this->getParam('CFGR:nolink',0))
  136. {
  137. $matchmode="none";
  138. }
  139. else
  140. {
  141. if($this->getParam("CFGR:simplesbeforeconf")==1)
  142. {
  143. $matchmode="cursimples";
  144. }
  145. if(isset($item["simples_skus"]) && trim($item["simples_skus"])!="")
  146. {
  147. $matchmode="fixed";
  148. }
  149. }
  150. return $matchmode;
  151. }
  152. public function processItemAfterId(&$item,$params=null)
  153. {
  154. //if item is not configurable, nothing to do
  155. if($item["type"]!=="configurable")
  156. {
  157. if($this->getParam("CFGR:simplesbeforeconf")==1)
  158. {
  159. $this->_currentsimples[]=$item["sku"];
  160. }
  161. return true;
  162. }
  163. //check for explicit configurable attributes
  164. if(isset($item["configurable_attributes"]))
  165. {
  166. $confopts=explode(",",$item["configurable_attributes"]);
  167. for($i=0;$i<count($confopts);$i++)
  168. {
  169. $confopts[$i]=trim($confopts[$i]);
  170. }
  171. }
  172. //if not found, try to deduce them
  173. else
  174. {
  175. $asconfopts=$this->getConfigurableOptsFromAsId($params["asid"]);
  176. //limit configurable options to ones presents & defined in item
  177. $confopts=array();
  178. foreach($asconfopts as $confopt)
  179. {
  180. if(in_array($confopt,array_keys($item)) && trim($item[$confopt])!="")
  181. {
  182. $confopts[]=$confopt;
  183. }
  184. }
  185. unset($asconfotps);
  186. }
  187. //if no configurable attributes, nothing to do
  188. if(count($confopts)==0)
  189. {
  190. $this->log("No configurable attributes found for configurable sku: ".$item["sku"]." cannot link simples.","warning");
  191. return true;
  192. }
  193. //set product to have options & required
  194. $tname=$this->tablename('catalog_product_entity');
  195. $sql="UPDATE $tname SET has_options=1,required_options=1 WHERE entity_id=?";
  196. $this->update($sql,$params["product_id"]);
  197. //matching mode
  198. //if associated skus
  199. $matchmode=$this->getMatchMode($item);
  200. //check if item has exising options
  201. $pid=$params["product_id"];
  202. $cpsa=$this->tablename("catalog_product_super_attribute");
  203. $cpsal=$this->tablename("catalog_product_super_attribute_label");
  204. //process configurable options
  205. $ins_sa=array();
  206. $data_sa=array();
  207. $ins_sal=array();
  208. $data_sal=array();
  209. $idx=0;
  210. foreach($confopts as $confopt)
  211. {
  212. $attrinfo=$this->getAttrInfo($confopt);
  213. $attrid=$attrinfo["attribute_id"];
  214. $psaid=NULL;
  215. //try to get psaid for attribute
  216. $sql="SELECT product_super_attribute_id as psaid FROM `$cpsa` WHERE product_id=? AND attribute_id=?";
  217. $psaid=$this->selectOne($sql,array($pid,$attrid),"psaid");
  218. //if no entry found, create one
  219. if($psaid==NULL)
  220. {
  221. $sql="INSERT INTO `$cpsa` (`product_id`,`attribute_id`,`position`) VALUES (?,?,?)";
  222. //inserting new options
  223. $psaid=$this->insert($sql,array($pid,$attrid,$idx));
  224. }
  225. //for all stores defined for the item
  226. $sids=$this->getItemStoreIds($item,0);
  227. $data=array();
  228. $ins=array();
  229. foreach($sids as $sid)
  230. {
  231. $data[]=$psaid;
  232. $data[]=$sid;
  233. $data[] = $attrinfo['frontend_label'];
  234. $ins[]="(?,?,1,?)";
  235. }
  236. //insert/update attribute value for association
  237. $sql="INSERT INTO `$cpsal` (`product_super_attribute_id`,`store_id`,`use_default`,`value`) VALUES ".implode(",",$ins).
  238. "ON DUPLICATE KEY UPDATE value=VALUES(`value`)";
  239. $this->insert($sql,$data);
  240. //if we have price info for this attribute
  241. if(isset($this->_optpriceinfo[$confopt]))
  242. {
  243. $cpsap=$this->tablename("catalog_product_super_attribute_pricing");
  244. $wsids=$this->getItemWebsites($item);
  245. //if admin set as store, website force to 0
  246. if(in_array(0,$sids))
  247. {
  248. $wsids=array(0);
  249. }
  250. $data=array();
  251. $ins=array();
  252. foreach($this->_optpriceinfo[$confopt] as $opdef)
  253. {
  254. //if optpriceinfo has no is_percent, force to 0
  255. $opinf=explode(":",$opdef);
  256. $optids=$this->getOptionIds($attrid,0,explode("//",$opinf[0]));
  257. foreach($optids as $optid)
  258. {
  259. //generate price info for each given website
  260. foreach($wsids as $wsid)
  261. {
  262. if(count($opinf)<3)
  263. {
  264. $opinf[]=0;
  265. }
  266. $data[]=$psaid;
  267. $data[]=$optid;
  268. $data[]=$opinf[1];
  269. $data[]=$opinf[2];
  270. $data[]=$wsid;
  271. $ins[]="(?,?,?,?,?)";
  272. }
  273. }
  274. }
  275. $sql="INSERT INTO $cpsap (`product_super_attribute_id`,`value_index`,`pricing_value`,`is_percent`,`website_id`) VALUES ".implode(",",$ins).
  276. " ON DUPLICATE KEY UPDATE pricing_value=VALUES(pricing_value),is_percent=VALUES(is_percent)";
  277. $this->insert($sql,$data);
  278. unset($data);
  279. }
  280. $idx++;
  281. }
  282. unset($confopts);
  283. switch($matchmode)
  284. {
  285. case "none":
  286. break;
  287. case "auto":
  288. //destroy old associations
  289. $this->autoLink($pid);
  290. $this->updSimpleVisibility($pid);
  291. break;
  292. case "cursimples":
  293. $this->fixedLink($pid,$this->_currentsimples);
  294. $this->updSimpleVisibility($pid);
  295. break;
  296. case "fixed":
  297. $sskus=explode(",",$item["simples_skus"]);
  298. trimarray($sskus);
  299. $this->fixedLink($pid,$sskus);
  300. $this->updSimpleVisibility($pid);
  301. unset($item["simples_skus"]);
  302. break;
  303. default:
  304. break;
  305. }
  306. //always clear current simples
  307. if(count($this->_currentsimples)>0)
  308. {
  309. unset($this->_currentsimples);
  310. $this->_currentsimples=array();
  311. }
  312. return true;
  313. }
  314. public function processColumnList(&$cols,$params=null)
  315. {
  316. if(!in_array("options_container",$cols))
  317. {
  318. $cols=array_unique(array_merge($cols,array("options_container")));
  319. $this->_use_defaultopc=true;
  320. $this->log("no options_container set, defaulting to :Block after product info","startup");
  321. }
  322. }
  323. public function getPluginParamNames()
  324. {
  325. return array("CFGR:simplesbeforeconf","CFGR:updsimplevis","CFGR:nolink");
  326. }
  327. static public function getCategory()
  328. {
  329. return "Product Type Import";
  330. }
  331. }