PageRenderTime 54ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/magmi/plugins/extra/itemprocessors/categories/categoryimport.php

https://bitbucket.org/jit_bec/shopifine
PHP | 367 lines | 306 code | 30 blank | 31 comment | 18 complexity | 129ba066e9669d0e7a211d33efc28089 MD5 | raw file
Possible License(s): LGPL-3.0
  1. <?php
  2. class CategoryImporter extends Magmi_ItemProcessor
  3. {
  4. protected $_idcache=array();
  5. protected $_catattr=array();
  6. protected $_cattrinfos=array();
  7. protected $_catroots=array();
  8. protected $_catrootw=array();
  9. protected $_cat_eid=null;
  10. protected $_tsep;
  11. public function initialize($params)
  12. {
  13. $this->initCats();
  14. $this->_cattrinfos=array("varchar"=>array("name"=>array(),"url_key"=>array(),"url_path"=>array()),
  15. "int"=>array("is_active"=>array(),"is_anchor"=>array(),"include_in_menu"=>array()));
  16. foreach($this->_cattrinfos as $catype=>$attrlist)
  17. {
  18. foreach(array_keys($attrlist) as $catatt)
  19. {
  20. $this->_cattrinfos[$catype][$catatt]=$this->getCatAttributeInfos($catatt);
  21. }
  22. }
  23. $this->_tsep=$this->getParam("CAT:treesep","/");
  24. }
  25. public function initCats()
  26. {
  27. // zioigor - 20110426 missing call to tablename method for table_prfix
  28. $t=$this->tablename("catalog_category_entity");
  29. $csg=$this->tablename("core_store_group");
  30. $cs=$this->tablename("core_store");
  31. $ccev=$t."_varchar";
  32. $ea=$this->tablename("eav_attribute");
  33. $result=$this->selectAll("SELECT cs.store_id,csg.website_id,cce.entity_type_id,cce.path,ccev.value as name
  34. FROM $cs as cs
  35. JOIN $csg as csg on csg.group_id=cs.group_id
  36. JOIN $t as cce ON cce.entity_id=csg.root_category_id
  37. JOIN $ea as ea ON ea.attribute_code='name' AND ea.entity_type_id=cce.entity_type_id
  38. JOIN $ccev as ccev ON ccev.attribute_id=ea.attribute_id AND ccev.entity_id=cce.entity_id
  39. ");
  40. foreach($result as $row)
  41. {
  42. $rootinfo=array("path"=>$row["path"],"etid"=>$row["entity_type_id"],"name"=>$row["name"],"rootarr"=>explode("/",$row["path"]));
  43. $this->_catroots[$row["store_id"]]=$rootinfo;
  44. $this->_catrootw[$row["website_id"]][]=$row["store_id"];
  45. if($this->_cat_eid==null)
  46. {
  47. $this->_cat_eid=$row["entity_type_id"];
  48. }
  49. }
  50. }
  51. public function getCatAttributeInfos($attcode)
  52. {
  53. $t=$this->tablename("eav_attribute");
  54. $sql="SELECT * FROM $t WHERE entity_type_id=? AND attribute_code=?";
  55. $info=$this->selectAll($sql,array($this->_cat_eid,$attcode));
  56. return $info[0];
  57. }
  58. public function getCache($cdef,$bp)
  59. {
  60. $ck="$bp::$cdef";
  61. return $this->_idcache[$ck];
  62. }
  63. public function isInCache($cdef,$bp)
  64. {
  65. $ck="$bp::$cdef";
  66. return isset($this->_idcache[$ck]);
  67. }
  68. public function putInCache($cdef,$bp,$idarr)
  69. {
  70. $ck="$bp::$cdef";
  71. $this->_idcache[$ck]=$idarr;
  72. }
  73. public function getPluginInfo()
  74. {
  75. return array(
  76. "name" => "On the fly category creator/importer",
  77. "author" => "Dweeves",
  78. "version" => "0.1.7",
  79. "url" => "http://sourceforge.net/apps/mediawiki/magmi/index.php?title=On_the_fly_category_creator/importer"
  80. );
  81. }
  82. public function getExistingCategory($parentpath,$cattr)
  83. {
  84. $cet=$this->tablename("catalog_category_entity");
  85. $cetv=$this->tablename("catalog_category_entity_varchar");
  86. $parentid=array_pop($parentpath);
  87. $sql="SELECT cet.entity_id FROM $cet as cet
  88. JOIN $cetv as cetv ON cetv.entity_id=cet.entity_id AND cetv.attribute_id=? AND cetv.value=?
  89. WHERE cet.parent_id=? ";
  90. $catid=$this->selectone($sql,array($this->_cattrinfos["varchar"]["name"]["attribute_id"],$cattr["name"],$parentid),"entity_id");
  91. return $catid;
  92. }
  93. public function getCategoryId($parentpath,$cattrs)
  94. {
  95. //get exisiting cat id
  96. $catid=$this->getExistingCategory($parentpath,$cattrs);
  97. //if found , return it
  98. if($catid!=null)
  99. {
  100. return $catid;
  101. }
  102. //otherwise, get new category values from parent & siblings
  103. $cet=$this->tablename("catalog_category_entity");
  104. $path=implode("/",$parentpath);
  105. $parentid=array_pop($parentpath);
  106. //get child info using parent data
  107. $sql="SELECT cce.entity_type_id,cce.attribute_set_id,cce.level+1 as level,COALESCE(MAX(eac.position),0)+1 as position
  108. FROM $cet as cce
  109. LEFT JOIN $cet as eac ON eac.parent_id=cce.entity_id
  110. WHERE cce.entity_id=?
  111. GROUP BY eac.parent_id";
  112. $info=$this->selectAll($sql,$parentid);
  113. $info=$info[0];
  114. //insert new category
  115. $sql="INSERT INTO $cet (entity_type_id,attribute_set_id,parent_id,position,level,path,children_count) VALUES (?,?,?,?,?,?,?)";
  116. //insert empty path until we get category id
  117. $data=array($info["entity_type_id"],$info["attribute_set_id"],$parentid,$info["position"],$info["level"],"",0);
  118. //insert in db,get cat id
  119. $catid=$this->insert($sql,$data);
  120. unset($data);
  121. //set category path with inserted category id
  122. $sql="UPDATE $cet SET path=?,created_at=NOW(),updated_at=NOW() WHERE entity_id=?";
  123. $data=array("$path/$catid",$catid);
  124. $this->update($sql,$data);
  125. unset($data);
  126. //set category attributes
  127. foreach($this->_cattrinfos as $tp=>$attinfo)
  128. {
  129. $inserts=array();
  130. $data=array();
  131. $tb=$this->tablename("catalog_category_entity_$tp");
  132. foreach($attinfo as $attrcode=>$attdata)
  133. {
  134. if(isset($attdata["attribute_id"]))
  135. {
  136. $inserts[]="(?,?,?,?,?)";
  137. $data[]=$info["entity_type_id"];
  138. $data[]=$attdata["attribute_id"];
  139. $data[]=0;//store id 0 for categories
  140. $data[]=$catid;
  141. $data[]=$cattrs[$attrcode];
  142. }
  143. }
  144. $sql="INSERT INTO $tb (entity_type_id,attribute_id,store_id,entity_id,value) VALUES ".implode(",",$inserts).
  145. " ON DUPLICATE KEY UPDATE value=VALUES(`value`)";
  146. $this->insert($sql,$data);
  147. unset($data);
  148. unset($inserts);
  149. }
  150. return $catid;
  151. }
  152. public function extractCatAttrs(&$catdef)
  153. {
  154. $cdefs=explode($this->_tsep,$catdef);
  155. $odefs=array();
  156. $clist=array();
  157. foreach($cdefs as $cdef)
  158. {
  159. $attrs=array();
  160. $parts=explode("::",$cdef);
  161. $cp=count($parts);
  162. $cname=trim($parts[0]);
  163. $odefs[]=$cname;
  164. $attrs=array("name"=>$cname,"is_active"=>($cp>1)?$parts[1]:1,
  165. "is_anchor"=>($cp>2)?$parts[2]:1,
  166. "include_in_menu"=>$cp>3?$parts[3]:1,
  167. "url_key"=>Slugger::slug($cname),
  168. "url_path"=>Slugger::slug(implode("/",$odefs),true).$this->getParam("CAT:urlending",".html"));
  169. $clist[]=$attrs;
  170. }
  171. $catdef=implode($this->_tsep,$odefs);
  172. return $clist;
  173. }
  174. public function getCategoryIdsFromDef($catdef,$basepath)
  175. {
  176. //if full def is in cache, use it
  177. if($this->isInCache($catdef,$basepath))
  178. {
  179. $catids=$this->getCache($catdef,$basepath);
  180. }
  181. else
  182. {
  183. //category ids
  184. $catids=array();
  185. $lastcached=array();
  186. //get cat tree branches names
  187. $catparts=explode($this->_tsep,$catdef);
  188. //path as array , basepath is always "/" separated
  189. $basearr=explode("/",$basepath);
  190. //for each cat tree branch
  191. $pdef=array();
  192. foreach($catparts as $catpart)
  193. {
  194. //add it to the current tree level
  195. $pdef[]=$catpart;
  196. $ptest=implode($this->_tsep,$pdef);
  197. //test for tree level in cache
  198. if($this->isInCache($ptest,$basepath))
  199. {
  200. //if yes , set current known cat ids to corresponding cached branch
  201. $catids=$this->getCache($ptest,$basepath);
  202. //store last cached branch
  203. $lastcached=$pdef;
  204. }
  205. else
  206. //no more tree info in cache,stop further retrieval, we need to create missing levels
  207. {
  208. break;
  209. }
  210. }
  211. //add store tree root to category path
  212. $curpath=array_merge($basearr,$catids);
  213. //get categories attributes
  214. $catattributes=$this->extractCatAttrs($catdef);
  215. //iterate on missing levels.
  216. for($i=count($catids);$i<count($catparts);$i++)
  217. {
  218. //retrieve category id (by creating it if needed from categories attributes)
  219. $catid=$this->getCategoryId($curpath,$catattributes[$i]);
  220. //add newly created level to item category ids
  221. $catids[]=$catid;
  222. //add newly created level to current paths
  223. $curpath[]=$catid;
  224. //cache newly created levels
  225. $lastcached[]=$catparts[$i];
  226. $this->putInCache(implode($this->_tsep,$lastcached),$basepath,$catids);
  227. }
  228. }
  229. return $catids;
  230. }
  231. public function processColumnList(&$cols,$params)
  232. {
  233. $cols[]="category_ids";
  234. $cols=array_unique($cols);
  235. return true;
  236. }
  237. public function getStoreRootPaths(&$item)
  238. {
  239. $rootpaths=array();
  240. $sids=$this->getItemStoreIds($item,2);
  241. $trimroot="";
  242. //remove admin from store ids (no category root on it)
  243. if($sids[0]==0)
  244. {
  245. array_shift($sids);
  246. }
  247. //only admin store set,use websites store roots
  248. if(count($sids)==0)
  249. {
  250. $wsids=$this->getItemWebsites($item);
  251. foreach($wsids as $wsid)
  252. {
  253. $sids=array_merge($sids,$this->_catrootw[$wsid]);
  254. }
  255. }
  256. foreach($sids as $sid)
  257. {
  258. $srp=$this->_catroots[$sid];
  259. $cmatch=true;
  260. //If using explicit root assignment , identify which root it is
  261. if(preg_match("|^\[(.*)?\].*$|",$item["categories"],$matches))
  262. {
  263. $cmatch=(trim($matches[1])==$srp["name"]);
  264. if($cmatch)
  265. {
  266. $trimroot=$matches[1];
  267. }
  268. }
  269. if($cmatch)
  270. {
  271. $rootpaths[$srp["path"]]=$srp["rootarr"];
  272. }
  273. }
  274. if($trimroot!="")
  275. {
  276. $item["categories"]=substr($item["categories"],strlen($trimroot)+2+strlen($this->_tsep));
  277. }
  278. return $rootpaths;
  279. }
  280. public function processItemAfterId(&$item,$params=null)
  281. {
  282. if(isset($item["categories"]))
  283. {
  284. $rootpaths=$this->getStoreRootPaths($item);
  285. if(count($rootpaths)==0)
  286. {
  287. if(preg_match("|^\[(.*)?\].*$|",$item["categories"],$matches))
  288. {
  289. $this->log("Cannot find site root with name : ".$matches[1],"error");
  290. return false;
  291. }
  292. }
  293. $catlist=explode(";;",$item["categories"]);
  294. $catids=array();
  295. foreach($catlist as $catdef)
  296. {
  297. if($catdef!="")
  298. {
  299. $root=$this->getParam("CAT:baseroot","");
  300. if($root!="")
  301. {
  302. $catdef=$root.$this->_tsep.$catdef;
  303. }
  304. foreach(array_keys($rootpaths) as $rp)
  305. {
  306. $cdef=$this->getCategoryIdsFromDef($catdef,$rp);
  307. if($this->getParam("CAT:lastonly",0)==1)
  308. {
  309. $cdef=array($cdef[count($cdef)-1]);
  310. }
  311. $catids=array_unique(array_merge($catids,$cdef));
  312. }
  313. }
  314. }
  315. $item["category_ids"]=implode(",",$catids);
  316. }
  317. return true;
  318. }
  319. public function getPluginParamNames()
  320. {
  321. return array('CAT:baseroot','CAT:lastonly','CAT:urlending','CAT:treesep');
  322. }
  323. public function afterImport()
  324. {
  325. //automatically update all children_count for catalog categories
  326. $cce=$this->tablename("catalog_category_entity");
  327. $sql="UPDATE $cce as cce
  328. LEFT JOIN
  329. (SELECT s1.entity_id as cid, COALESCE( COUNT( s2.entity_id ) , 0 ) AS cnt
  330. FROM $cce AS s1
  331. LEFT JOIN $cce AS s2 ON s2.parent_id = s1.entity_id
  332. GROUP BY s1.entity_id) as sq ON sq.cid=cce.entity_id
  333. SET cce.children_count=sq.cnt";
  334. $this->update($sql);
  335. return true;
  336. }
  337. }