PageRenderTime 66ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/magmi/plugins/extra/itemprocessors/imageprocessor/imageitattributeemprocessor.php

https://gitlab.com/myurd/magmi-git
PHP | 631 lines | 488 code | 55 blank | 88 comment | 100 complexity | 8d1186e5193bf053b4bb1cd26813f2eb MD5 | raw file
  1. <?php
  2. class ImageAttributeItemProcessor extends Magmi_ItemProcessor
  3. {
  4. protected $forcename = null;
  5. protected $magdir = null;
  6. protected $imgsourcedirs = array();
  7. protected $errattrs = array();
  8. protected $_errorimgs = array();
  9. protected $_lastimage = "";
  10. protected $_handled_attributes = array();
  11. protected $_img_baseattrs = array("image","small_image","thumbnail");
  12. protected $_active = false;
  13. protected $_newitem;
  14. protected $_mdh;
  15. protected $_remoteroot = "";
  16. protected $debug;
  17. public function initialize($params)
  18. {
  19. // declare current class as attribute handler
  20. $this->registerAttributeHandler($this, array("frontend_input:(media_image|gallery)"));
  21. $this->magdir = Magmi_Config::getInstance()->getMagentoDir();
  22. $this->_mdh = MagentoDirHandlerFactory::getInstance()->getHandler($this->magdir);
  23. $this->_mdh->setRemoteGetterId("image");
  24. // remote root
  25. if ($this->getParam("IMG:remoteroot", "")) {
  26. if ($this->getParam("IMG:remoteauth", false) == true) {
  27. $this->_mdh->setRemoteCredentials($this->getParam("IMG:remoteuser"), $this->getParam("IMG:remotepass"));
  28. }
  29. $this->_remoteroot = $this->getParam("IMG:remoteroot");
  30. }
  31. $this->forcename = $this->getParam("IMG:renaming");
  32. foreach ($params as $k => $v) {
  33. if (preg_match_all("/^IMG_ERR:(.*)$/", $k, $m)) {
  34. $this->errattrs[$m[1][0]] = $params[$k];
  35. }
  36. }
  37. $this->debug = $this->getParam("IMG:debug", 0);
  38. }
  39. public function getPluginInfo()
  40. {
  41. return array("name"=>"Image attributes processor","author"=>"Dweeves, Tommy Goode","version"=>"1.0.33a",
  42. "url"=>$this->pluginDocUrl("Image_attributes_processor"));
  43. }
  44. public function isErrorImage($img)
  45. {
  46. return isset($this->_errorimgs[$img]);
  47. }
  48. public function cachesort($v1, $v2)
  49. {
  50. return $v2 - $v1;
  51. }
  52. public function setErrorImg($img)
  53. {
  54. $mxerrcache = $this->getParam("IMG:maxerrorcache", 100);
  55. // remove limit => 10%
  56. $removelimit = intval($mxerrcache / 10);
  57. if (count($this->_errorimgs) > $mxerrcache) {
  58. uasort($this->_errorimgs, array($this, "cachesort"));
  59. array_splice($this->_errorimgs, $removelimit, count($this->_errorimgs));
  60. }
  61. $this->_errorimgs[$img] = microtime(true);
  62. }
  63. // Image removal feature
  64. public function handleRemoveImages($pid, &$item, $ivalue)
  65. {
  66. $gal_attinfo = $this->getAttrInfo("media_gallery");
  67. $t = $this->tablename('catalog_product_entity_media_gallery');
  68. $tv = $this->tablename('catalog_product_entity_media_gallery_value');
  69. $rimgs = explode(";", $ivalue);
  70. $rivals = array();
  71. foreach ($rimgs as $rimg) {
  72. $rivals[] = '/' . implode('/', array($rimg[0], $rimg[1], $rimg));
  73. }
  74. $sql = "DELETE $t.* FROM $t
  75. WHERE $t.entity_id=? AND $t.attribute_id=? AND $t.value IN (" . $this->arr2values($rivals) . ")";
  76. $this->delete($sql, array_merge(array($pid, $gal_attinfo["attribute_id"]), $rivals));
  77. }
  78. public function handleGalleryTypeAttribute($pid, &$item, $storeid, $attrcode, $attrdesc, $ivalue)
  79. {
  80. // do nothing if empty
  81. if ($ivalue == "") {
  82. return false;
  83. }
  84. // use ";" as image separator
  85. $images = explode(";", $ivalue);
  86. $imageindex = 0;
  87. // for each image
  88. foreach ($images as $imagefile) {
  89. // trim image file in case of spaced split
  90. $imagefile = trim($imagefile);
  91. // handle exclude flag explicitely
  92. $exclude = $this->getExclude($imagefile, false);
  93. $infolist = explode("::", $imagefile);
  94. $label = null;
  95. if (count($infolist) > 1) {
  96. $label = $infolist[1];
  97. $imagefile = $infolist[0];
  98. }
  99. unset($infolist);
  100. $extra=array("store"=>$storeid,"attr_code"=>$attrcode,"imageindex"=>$imageindex == 0 ? "" : $imageindex);
  101. // copy it from source dir to product media dir
  102. $imagefile = $this->copyImageFile($imagefile, $item, $extra);
  103. unset($extra);
  104. if ($imagefile !== false) {
  105. // add to gallery
  106. $targetsids = $this->getStoreIdsForStoreScope($item["store"]);
  107. $vid = $this->addImageToGallery($pid, $storeid, $attrdesc, $imagefile, $targetsids, $label, $exclude);
  108. }
  109. $imageindex++;
  110. }
  111. unset($images);
  112. // we don't want to insert after that
  113. $ovalue = false;
  114. return $ovalue;
  115. }
  116. public function removeImageFromGallery($pid, $storeid, $attrdesc)
  117. {
  118. $t = $this->tablename('catalog_product_entity_media_gallery');
  119. $tv = $this->tablename('catalog_product_entity_media_gallery_value');
  120. $sql = "DELETE $tv.* FROM $tv
  121. JOIN $t ON $t.value_id=$tv.value_id AND $t.entity_id=? AND $t.attribute_id=?
  122. WHERE $tv.store_id=?";
  123. $this->delete($sql, array($pid, $attrdesc["attribute_id"], $storeid));
  124. }
  125. public function getExclude(&$val, $default = true)
  126. {
  127. $exclude = $default;
  128. if ($val[0] == "+" || $val[0] == "-") {
  129. $exclude = $val[0] == "-";
  130. $val = substr($val, 1);
  131. }
  132. return $exclude;
  133. }
  134. public function findImageFile($ivalue)
  135. {
  136. // do no try to find remote image
  137. if (is_remote_path($ivalue)) {
  138. return $ivalue;
  139. }
  140. // if existing, return it directly
  141. if (realpath($ivalue)) {
  142. return $ivalue;
  143. }
  144. // ok , so it's a relative path
  145. $imgfile = false;
  146. $scandirs = explode(";", $this->getParam("IMG:sourcedir"));
  147. $cscandirs = count($scandirs);
  148. // iterate on image sourcedirs, trying to resolve file name based on input value and current source dir
  149. for ($i = 0; $i < $cscandirs && $imgfile === false; $i++) {
  150. $sd = $scandirs[$i];
  151. // scandir is relative, use mdh
  152. if ($sd[0] != "/") {
  153. $sd = $this->_mdh->getMagentoDir() . "/" . $sd;
  154. }
  155. $imgfile = abspath($ivalue, $sd, true);
  156. }
  157. return $imgfile;
  158. }
  159. public function handleImageTypeAttribute($pid, &$item, $storeid, $attrcode, $attrdesc, $ivalue)
  160. {
  161. // remove attribute value if empty
  162. if ($ivalue == "" || $ivalue == "__NULL__") {
  163. $this->removeImageFromGallery($pid, $storeid, $attrdesc);
  164. return "__MAGMI_DELETE__";
  165. }
  166. // add support for explicit exclude
  167. $exclude = $this->getExclude($ivalue, true);
  168. $imagefile = trim($ivalue);
  169. // else copy image file
  170. $imagefile = $this->copyImageFile($imagefile, $item, array("store"=>$storeid, "attr_code"=>$attrcode));
  171. $ovalue = $imagefile;
  172. // add to gallery as excluded
  173. if ($imagefile !== false) {
  174. $label = null;
  175. if (isset($item[$attrcode . "_label"])) {
  176. $label = $item[$attrcode . "_label"];
  177. }
  178. $targetsids = $this->getStoreIdsForStoreScope($item["store"]);
  179. $vid = $this->addImageToGallery($pid, $storeid, $attrdesc, $imagefile, $targetsids, $label, $exclude,
  180. $attrdesc["attribute_id"]);
  181. }
  182. return $ovalue;
  183. }
  184. public function handleVarcharAttribute($pid, &$item, $storeid, $attrcode, $attrdesc, $ivalue)
  185. {
  186. // trimming
  187. $ivalue = trim($ivalue);
  188. if ($ivalue=="") {
  189. return $ivalue;
  190. }
  191. // if it's a gallery
  192. switch ($attrdesc["frontend_input"]) {
  193. case "gallery":
  194. $ovalue = $this->handleGalleryTypeAttribute($pid, $item, $storeid, $attrcode, $attrdesc, $ivalue);
  195. break;
  196. case "media_image":
  197. $ovalue = $this->handleImageTypeAttribute($pid, $item, $storeid, $attrcode, $attrdesc, $ivalue);
  198. break;
  199. default:
  200. $ovalue = "__MAGMI_UNHANDLED__";
  201. }
  202. return $ovalue;
  203. }
  204. /**
  205. * imageInGallery
  206. *
  207. * @param int $pid
  208. * : product id to test image existence in gallery
  209. * @param string $imgname
  210. * : image file name (relative to /products/media in magento dir)
  211. * @return bool : if image is already present in gallery for a given product id
  212. */
  213. public function getImageId($pid, $attid, $imgname, $refid = null, $store_id = 0)
  214. {
  215. $t = $this->tablename('catalog_product_entity_media_gallery');
  216. $sql = "SELECT $t.value_id FROM $t ";
  217. if ($refid != null) {
  218. $vc = $this->tablename('catalog_product_entity_varchar');
  219. $sql .= " JOIN $vc ON $t.entity_id=$vc.entity_id AND $t.value=$vc.value AND $vc.attribute_id=?
  220. WHERE $t.entity_id=? AND $vc.store_id=?";
  221. $imgid = $this->selectone($sql, array($refid, $pid, $store_id), 'value_id');
  222. } else {
  223. $sql .= " WHERE value=? AND entity_id=? AND attribute_id=?";
  224. $imgid = $this->selectone($sql, array($imgname, $pid, $attid), 'value_id');
  225. }
  226. if ($imgid == null) {
  227. // insert image in media_gallery
  228. $sql = "INSERT INTO $t
  229. (attribute_id,entity_id,value)
  230. VALUES
  231. (?,?,?)";
  232. $imgid = $this->insert($sql, array($attid, $pid, $imgname));
  233. } else {
  234. $sql = "UPDATE $t
  235. SET value=?
  236. WHERE value_id=?";
  237. $this->update($sql, array($imgname, $imgid));
  238. }
  239. return $imgid;
  240. }
  241. /**
  242. * reset product gallery
  243. *
  244. * @param int $pid
  245. * : product id
  246. */
  247. public function resetGallery($pid, $storeid, $attid)
  248. {
  249. $tgv = $this->tablename('catalog_product_entity_media_gallery_value');
  250. $tg = $this->tablename('catalog_product_entity_media_gallery');
  251. $sql = "DELETE emgv,emg FROM `$tgv` as emgv
  252. JOIN `$tg` AS emg ON emgv.value_id = emg.value_id AND emgv.store_id=?
  253. WHERE emg.entity_id=? AND emg.attribute_id=?";
  254. $this->delete($sql, array($storeid, $pid, $attid));
  255. }
  256. /**
  257. * adds an image to product image gallery only if not already exists
  258. *
  259. * @param int $pid
  260. * : product id to test image existence in gallery
  261. * @param array $attrdesc
  262. * : product attribute description
  263. * @param string $imgname
  264. * : image file name (relative to /products/media in magento dir)
  265. */
  266. public function addImageToGallery($pid, $storeid, $attrdesc, $imgname, $targetsids, $imglabel = null, $excluded = false,
  267. $refid = null)
  268. {
  269. $gal_attinfo = $this->getAttrInfo("media_gallery");
  270. $tg = $this->tablename('catalog_product_entity_media_gallery');
  271. $tgv = $this->tablename('catalog_product_entity_media_gallery_value');
  272. $vid = $this->getImageId($pid, $gal_attinfo["attribute_id"], $imgname, $refid, $storeid);
  273. if ($vid != null) {
  274. // et maximum current position in the product gallery
  275. $sql = "SELECT MAX( position ) as maxpos
  276. FROM $tgv AS emgv
  277. JOIN $tg AS emg ON emg.value_id = emgv.value_id AND emg.entity_id = ?
  278. WHERE emgv.store_id=?
  279. GROUP BY emg.entity_id";
  280. $pos = $this->selectone($sql, array($pid, $storeid), 'maxpos');
  281. $pos = ($pos == null ? 0 : $pos + 1);
  282. // nsert new value (ingnore duplicates)
  283. $vinserts = array();
  284. $data = array();
  285. foreach ($targetsids as $tsid) {
  286. $vinserts[] = "(?,?,?,?," . ($imglabel == null ? "NULL" : "?") . ")";
  287. $data = array_merge($data, array($vid, $tsid, $pos, $excluded ? 1 : 0));
  288. if ($imglabel != null) {
  289. $data[] = $imglabel;
  290. }
  291. }
  292. if (count($data) > 0) {
  293. $sql = "INSERT INTO $tgv
  294. (value_id,store_id,position,disabled,label)
  295. VALUES " . implode(",", $vinserts) . "
  296. ON DUPLICATE KEY UPDATE label=VALUES(`label`),disabled=VALUES(`disabled`)";
  297. $this->insert($sql, $data);
  298. }
  299. unset($vinserts);
  300. unset($data);
  301. }
  302. }
  303. public function parsename($info, $item, $extra)
  304. {
  305. $info = $this->parseCalculatedValue($info, $item, $extra);
  306. return $info;
  307. }
  308. public function getPluginParams($params)
  309. {
  310. $pp = array();
  311. foreach ($params as $k => $v) {
  312. if (preg_match("/^IMG(_ERR)?:.*$/", $k)) {
  313. $pp[$k] = $v;
  314. }
  315. }
  316. return $pp;
  317. }
  318. public function fillErrorAttributes(&$item)
  319. {
  320. foreach ($this->errattrs as $k => $v) {
  321. $this->addExtraAttribute($k);
  322. $item[$k] = $v;
  323. }
  324. }
  325. public function getImagenameComponents($fname, $formula, $extra)
  326. {
  327. $matches = array();
  328. $xname = $fname;
  329. if (preg_match("|re::(.*)::(.*)|", $formula, $matches)) {
  330. $rep = $matches[2];
  331. $xname = preg_replace("|" . $matches[1] . "|", $rep, $xname);
  332. $extra['parsed'] = true;
  333. }
  334. $xname = basename($xname);
  335. $m = preg_match("/(.*)\.(jpg|png|gif)$/i", $xname, $matches);
  336. if ($m) {
  337. $extra["imagename"] = $xname;
  338. $extra["imagename.ext"] = $matches[2];
  339. $extra["imagename.noext"] = $matches[1];
  340. } else {
  341. $uid = uniqid("img", true);
  342. $extra = array_merge($extra, array("imagename"=>"$uid.jpg", "imagename.ext"=>"jpg", "imagename.noext"=>$uid));
  343. }
  344. return $extra;
  345. }
  346. public function getTargetName($fname, $item, $extra)
  347. {
  348. $cname = basename($fname);
  349. if (isset($this->forcename) && $this->forcename != "") {
  350. $extra = $this->getImagenameComponents($fname, $this->forcename, $extra);
  351. $pname = (isset($extra['parsed']) ? $extra['imagename'] : $this->forcename);
  352. $cname = $this->parsename($pname, $item, $extra);
  353. }
  354. $cname = strtolower(preg_replace("/%[0-9|A-F][0-9|A-F]/", "_", rawurlencode($cname)));
  355. return $cname;
  356. }
  357. public function saveImage($imgfile, $target)
  358. {
  359. $result = $this->_mdh->copy($imgfile, $target);
  360. return $result;
  361. }
  362. /**
  363. * copy image file from source directory to
  364. * product media directory
  365. *
  366. * @param $imgfile :
  367. * name of image file name in source directory
  368. * @return : name of image file name relative to magento catalog media dir,including leading
  369. * directories made of first char & second char of image file name.
  370. */
  371. public function copyImageFile($imgfile, &$item, $extra)
  372. {
  373. if ($imgfile == "__NULL__" || $imgfile == null) {
  374. return false;
  375. }
  376. // check for source image in error
  377. if ($this->isErrorImage($imgfile)) {
  378. if ($this->_newitem) {
  379. $this->fillErrorAttributes($item);
  380. }
  381. ;
  382. return false;
  383. }
  384. //handle remote root per image
  385. if (!is_remote_path($imgfile)) {
  386. if ($this->_remoteroot != "") {
  387. $imgfile = $this->_remoteroot . str_replace("//", "/", "/$imgfile");
  388. }
  389. }
  390. //handle amazon specific
  391. if (is_remote_path($imgfile)) {
  392. // Amazon images patch , remove SLXXXX part
  393. if (preg_match('|amazon\..*?/images/I|', $imgfile)) {
  394. $pattern = '/\bSL[0-9]+\./i';
  395. $imgfile = preg_replace($pattern, '', $imgfile);
  396. }
  397. }
  398. $source = $this->findImageFile($imgfile);
  399. if ($source == false) {
  400. $this->log("$imgfile cannot be found in images path", "warning");
  401. // last image in error,add it to error cache
  402. $this->setErrorImg($imgfile);
  403. return false;
  404. }
  405. $imgfile = $source;
  406. $checkexist = ($this->getParam("IMG:existingonly") == "yes");
  407. $curlh = false;
  408. $bimgfile = $this->getTargetName($imgfile, $item, $extra);
  409. // source file exists
  410. $i1 = $bimgfile[0];
  411. $i2 = $bimgfile[1];
  412. // magento image value (relative to media catalog)
  413. $impath = "/$i1/$i2/$bimgfile";
  414. // target directory;
  415. $l2d = "media/catalog/product/$i1/$i2";
  416. // test for existence
  417. $targetpath = "$l2d/$bimgfile";
  418. /* test for same image (without problem) */
  419. if ($impath == $this->_lastimage) {
  420. return $impath;
  421. }
  422. /* test if imagefile comes from export */
  423. if (!$this->_mdh->file_exists($targetpath) || $this->getParam("IMG:writemode") == "override") {
  424. // if we already had problems with this target,assume we'll get others.
  425. if ($this->isErrorImage($impath)) {
  426. return false;
  427. }
  428. /* try to recursively create target dir */
  429. if (!$this->_mdh->file_exists($l2d)) {
  430. $tst = $this->_mdh->mkdir($l2d, Magmi_Config::getInstance()->getDirMask(), true);
  431. if (!$tst) {
  432. // if we had problem creating target directory,add target to error cache
  433. $errors = $this->_mdh->getLastError();
  434. $this->log("error creating $l2d: {$errors["type"]},{$errors["message"]}", "warning");
  435. unset($errors);
  436. $this->setErrorImg($impath);
  437. return false;
  438. }
  439. }
  440. if (!$this->saveImage($imgfile, $targetpath)) {
  441. $errors = $this->_mdh->getLastError();
  442. $this->fillErrorAttributes($item);
  443. $this->log("error copying $l2d/$bimgfile : {$errors["type"]},{$errors["message"]}", "warning");
  444. unset($errors);
  445. $this->setErrorImg($impath);
  446. return false;
  447. } else {
  448. @$this->_mdh->chmod("$l2d/$bimgfile", Magmi_Config::getInstance()->getFileMask());
  449. if ($this->getParam("IMG:storeindb", "no") == "yes") {
  450. /* create target dirs if they don't exist */
  451. $dir_table = $this->tablename('core_directory_storage');
  452. // get "catalog/product" path ID
  453. $sql = "SELECT directory_id from $dir_table where name='product' and path='catalog'";
  454. $parent_id = $this->selectone($sql, null, 'directory_id');
  455. // check if i1 dir exists
  456. $i1_dir = "catalog/product/$i1";
  457. $sql = "SELECT directory_id FROM $dir_table WHERE name=? and parent_id=?";
  458. $i1_dir_id = $this->selectone($sql, array($i1, $parent_id), 'directory_id');
  459. // insert if it doesn't exist
  460. if ($i1_dir_id == null) {
  461. $sql = "INSERT INTO $dir_table (name, path, upload_time, parent_id)
  462. VALUES (?, 'catalog/product', NOW(), ?);";
  463. $i1_dir_id = $this->insert($sql, array($i1, $parent_id));
  464. }
  465. // check if i2 dir exists
  466. $i2_dir = "$i1_dir/$i2";
  467. $sql = "SELECT directory_id FROM $dir_table WHERE name=? and parent_id=?";
  468. $i2_dir_id = $this->selectone($sql, array($i2, $i1_dir_id), 'directory_id');
  469. // insert second level if it doesn't exist
  470. if ($i2_dir_id == null) {
  471. $sql = "INSERT INTO $dir_table (name, path, upload_time, parent_id)
  472. VALUES (?, ?, NOW(), ?);";
  473. $i2_dir_id = $this->insert($sql, array($i2, $i1_dir, $i1_dir_id));
  474. }
  475. /* insert the image */
  476. $media_table = $this->tablename('core_file_storage');
  477. $sql = "SELECT file_id FROM $media_table WHERE filename=? and directory_id=?";
  478. $existing_file_id = $this->selectone($sql, array($bimgfile, $i2_dir_id), 'file_id');
  479. if ($existing_file_id == null || $this->getParam("IMG:writemode") == "override") {
  480. $image_path = $this->magdir . '/' . $targetpath;
  481. $image_content = file_get_contents($image_path);
  482. $sql = "INSERT INTO $media_table (content, upload_time, filename, directory_id, directory)
  483. VALUES (?, NOW(), ?, ?, ?)
  484. ON DUPLICATE KEY UPDATE content=VALUES(content), upload_time=VALUES(upload_time);";
  485. $file_id = $this->insert($sql, array($image_content, $bimgfile, $i2_dir_id, $i2_dir));
  486. }
  487. }
  488. }
  489. }
  490. $this->_lastimage = $impath;
  491. /* return image file name relative to media dir (with leading / ) */
  492. return $impath;
  493. }
  494. public function updateLabel($attrdesc, $pid, $sids, $label)
  495. {
  496. $tg = $this->tablename('catalog_product_entity_media_gallery');
  497. $tgv = $this->tablename('catalog_product_entity_media_gallery_value');
  498. $vc = $this->tablename('catalog_product_entity_varchar');
  499. $sql = "UPDATE $tgv as emgv
  500. JOIN $tg as emg ON emg.value_id=emgv.value_id AND emg.entity_id=?
  501. JOIN $vc as ev ON ev.entity_id=emg.entity_id AND ev.value=emg.value and ev.attribute_id=?
  502. SET label=?
  503. WHERE emgv.store_id IN (" . implode(",", $sids) . ")";
  504. $this->update($sql, array($pid, $attrdesc["attribute_id"], $label));
  505. }
  506. public function processItemAfterId(&$item, $params = null)
  507. {
  508. if (!$this->_active) {
  509. return true;
  510. }
  511. $this->_newitem = $params["new"];
  512. $pid = $params["product_id"];
  513. foreach ($this->_img_baseattrs as $attrcode) {
  514. // if only image/small_image/thumbnail label is present (ie: no image field)
  515. if (isset($item[$attrcode . "_label"]) && !isset($item[$attrcode])) {
  516. // force label update
  517. $attrdesc = $this->getAttrInfo($attrcode);
  518. $this->updateLabel($attrdesc, $pid, $this->getItemStoreIds($item, $attrdesc["is_global"]),
  519. $item[$attrcode . "_label"]);
  520. unset($attrdesc);
  521. }
  522. }
  523. // Reset media_gallery
  524. $galreset = !(isset($item["media_gallery_reset"])) || $item["media_gallery_reset"] == 1;
  525. $forcereset = (isset($item["media_gallery_reset"])) && $item["media_gallery_reset"] == 1;
  526. if ((isset($item["media_gallery"]) && $galreset) || $forcereset) {
  527. $gattrdesc = $this->getAttrInfo("media_gallery");
  528. $sids = $this->getItemStoreIds($item, $gattrdesc["is_global"]);
  529. foreach ($sids as $sid) {
  530. $this->resetGallery($pid, $sid, $gattrdesc["attribute_id"]);
  531. }
  532. }
  533. if (isset($item["image_remove"])) {
  534. $this->handleRemoveImages($pid, $item, $item["image_remove"]);
  535. }
  536. return true;
  537. }
  538. public function processColumnList(&$cols, $params = null)
  539. {
  540. // automatically add modified attributes if not found in datasource
  541. // automatically add media_gallery for attributes to handle
  542. $imgattrs = array_intersect(array_merge($this->_img_baseattrs, array('media_gallery', 'image_remove')), $cols);
  543. if (count($imgattrs) > 0) {
  544. $this->_active = true;
  545. $cols = array_unique(array_merge(array_keys($this->errattrs), $cols, $imgattrs));
  546. } else {
  547. $this->log("no image attributes found in datasource, disabling image processor", "startup");
  548. }
  549. return true;
  550. }
  551. // Cleanup gallery from removed images if no more image values are present in any store
  552. public function endImport()
  553. {
  554. if (!$this->_active) {
  555. return;
  556. }
  557. $attids = array();
  558. foreach ($this->_img_baseattrs as $attrcode) {
  559. $inf = $this->getAttrInfo($attrcode);
  560. if (count($inf) > 0) {
  561. $attids[] = $inf["attribute_id"];
  562. }
  563. }
  564. if (count($attids) > 0) {
  565. $tg = $this->tablename('catalog_product_entity_media_gallery');
  566. $tgv = $this->tablename('catalog_product_entity_media_gallery_value');
  567. $sql = "DELETE emg.* FROM $tg as emg
  568. LEFT JOIN (SELECT emg.value_id,count(emgv.value_id) as cnt FROM $tgv as emgv JOIN $tg as emg ON emg.value_id=emgv.value_id GROUP BY emg.value_id ) as t1 ON t1.value_id=emg.value_id
  569. WHERE attribute_id IN (" . implode(",", $attids) . ") AND t1.cnt IS NULL";
  570. $this->delete($sql);
  571. } else {
  572. $this->log("Unexpected problem in image attributes retrieval", "warning");
  573. }
  574. unset($attids);
  575. }
  576. }