private function stepImportImage()
 {
     /**
      * @var shopProductImagesModel $model
      */
     static $model;
     if (!is_array($this->data['map'][self::STAGE_IMAGE]) && $this->data['map'][self::STAGE_IMAGE]) {
         $this->data['map'][self::STAGE_IMAGE] = array($this->data['map'][self::STAGE_IMAGE]);
     }
     if ($file = reset($this->data['map'][self::STAGE_IMAGE])) {
         if (!$model) {
             $model = new shopProductImagesModel();
         }
         //TODO store image id & if repeated - skip it
         $target = 'new';
         $u = @parse_url($file);
         $_is_url = false;
         if (!$u || !(isset($u['scheme']) && isset($u['host']) && isset($u['path']))) {
         } elseif (in_array($u['scheme'], array('http', 'https', 'ftp', 'ftps'))) {
             $_is_url = true;
         } else {
             $target = 'skip';
             $file = null;
             $this->error(sprintf('Unsupported file source protocol', $u['scheme']));
         }
         $search = array('product_id' => $this->data['map'][self::STAGE_PRODUCT], 'ext' => pathinfo($file, PATHINFO_EXTENSION));
         try {
             $name = preg_replace('@[^a-zA-Zа-яА-Я0-9\\._\\-]+@', '', basename(urldecode($file)));
             if ($_is_url) {
                 $pattern = sprintf('@/(%d)/images/(\\d+)/\\2\\.(\\d+(x\\d+)?)\\.([^\\.]+)$@', $search['product_id']);
                 if (preg_match($pattern, $file, $matches)) {
                     $image = array('product_id' => $matches[1], 'id' => $matches[2], 'ext' => $matches[5]);
                     if (strpos($file, shopImage::getUrl($image, $matches[3])) !== false && $model->getByField($image)) {
                         #skip local file
                         $target = 'skip';
                         $file = null;
                     }
                 }
                 if ($file) {
                     waFiles::upload($file, $file = wa()->getTempPath('csv/upload/images/' . waLocale::transliterate($name, 'en_US')));
                 }
             } elseif ($file) {
                 $file = $this->data['upload_path'] . $file;
             }
             if ($file && file_exists($file)) {
                 if ($image = waImage::factory($file)) {
                     $search['original_filename'] = $name;
                     $data = array('product_id' => $this->data['map'][self::STAGE_PRODUCT], 'upload_datetime' => date('Y-m-d H:i:s'), 'width' => $image->width, 'height' => $image->height, 'size' => filesize($file), 'original_filename' => $name, 'ext' => pathinfo($file, PATHINFO_EXTENSION));
                     if ($exists = $model->getByField($search)) {
                         $data = array_merge($exists, $data);
                         $thumb_dir = shopImage::getThumbsPath($data);
                         $back_thumb_dir = preg_replace('@(/$|$)@', '.back$1', $thumb_dir, 1);
                         $paths[] = $back_thumb_dir;
                         waFiles::delete($back_thumb_dir);
                         // old backups
                         if (file_exists($thumb_dir)) {
                             if (!(waFiles::move($thumb_dir, $back_thumb_dir) || waFiles::delete($back_thumb_dir)) && !waFiles::delete($thumb_dir)) {
                                 throw new waException(_w("Error while rebuild thumbnails"));
                             }
                         }
                     }
                     $image_changed = false;
                     /**
                      * TODO move it code into product core method
                      */
                     /**
                      * Extend add/update product images
                      * Make extra workup
                      * @event image_upload
                      */
                     $event = wa()->event('image_upload', $image);
                     if ($event) {
                         foreach ($event as $result) {
                             if ($result) {
                                 $image_changed = true;
                                 break;
                             }
                         }
                     }
                     if (empty($data['id'])) {
                         $image_id = $data['id'] = $model->add($data);
                     } else {
                         $image_id = $data['id'];
                         $target = 'update';
                         $model->updateById($image_id, $data);
                     }
                     if (!$image_id) {
                         throw new waException("Database error");
                     }
                     $image_path = shopImage::getPath($data);
                     if (file_exists($image_path) && !is_writable($image_path) || !file_exists($image_path) && !waFiles::create($image_path)) {
                         $model->deleteById($image_id);
                         throw new waException(sprintf("The insufficient file write permissions for the %s folder.", substr($image_path, strlen($this->getConfig()->getRootPath()))));
                     }
                     if ($image_changed) {
                         $image->save($image_path);
                         /**
                          * @var shopConfig $config
                          */
                         $config = $this->getConfig();
                         if ($config->getOption('image_save_original') && ($original_file = shopImage::getOriginalPath($data))) {
                             waFiles::copy($file, $original_file);
                         }
                     } else {
                         waFiles::copy($file, $image_path);
                     }
                     $this->data['processed_count'][self::STAGE_IMAGE][$target]++;
                 } else {
                     $this->error(sprintf('Invalid image file', $file));
                 }
             } elseif ($file) {
                 $this->error(sprintf('File %s not found', $file));
                 $target = 'skip';
                 $this->data['processed_count'][self::STAGE_IMAGE][$target]++;
             } else {
                 $this->data['processed_count'][self::STAGE_IMAGE][$target]++;
             }
         } catch (Exception $e) {
             $this->error($e->getMessage());
             //TODO skip on repeated error
         }
         array_shift($this->data['map'][self::STAGE_IMAGE]);
         ++$this->data['current'][self::STAGE_IMAGE];
         if ($_is_url) {
             waFiles::delete($file);
         }
     }
     return true;
 }