protected function step()
 {
     $image_model = new shopProductImagesModel();
     $create_thumbnails = waRequest::post('create_thumbnails');
     $chunk_size = 50;
     if ($create_thumbnails) {
         $chunk_size = 10;
     }
     $sizes = wa('shop')->getConfig()->getImageSizes();
     $images = $image_model->getAvailableImages($this->data['offset'], $chunk_size);
     foreach ($images as $i) {
         if ($this->data['product_id'] != $i['product_id']) {
             sleep(0.2);
             $this->data['product_id'] = $i['product_id'];
             $this->data['product_count'] += 1;
         }
         try {
             $path = shopImage::getThumbsPath($i);
             if (!waFiles::delete($path)) {
                 throw new waException(sprintf(_w('Error when delete thumbnails for image %d'), $i['id']));
             }
             if ($create_thumbnails) {
                 shopImage::generateThumbs($i, $sizes);
             }
             $this->data['image_count'] += 1;
             // image count - count of successful progessed images
         } catch (Exception $e) {
             $this->error($e->getMessage());
         }
         $this->data['offset'] += 1;
     }
 }
 public function execute()
 {
     $product_id = $this->get('product_id', true);
     $this->getProduct($product_id);
     $file = waRequest::file('file');
     $image = $file->waImage();
     if ($file->uploaded()) {
         $data = array('product_id' => $product_id, 'upload_datetime' => date('Y-m-d H:i:s'), 'width' => $image->width, 'height' => $image->height, 'size' => $file->size, 'original_filename' => basename($file->name), 'ext' => $file->extension, 'description' => waRequest::post('description'));
         $product_images_model = new shopProductImagesModel();
         $image_id = $data['id'] = $product_images_model->add($data);
         if (!$image_id) {
             throw new waAPIException('server_error', 500);
         }
         /**
          * @var shopConfig $config
          */
         $config = wa('shop')->getConfig();
         $image_path = shopImage::getPath($data);
         if (file_exists($image_path) && !is_writable($image_path) || !file_exists($image_path) && !waFiles::create($image_path)) {
             $product_images_model->deleteById($image_id);
             throw new waAPIException(sprintf("The insufficient file write permissions for the %s folder.", substr($image_path, strlen($config->getRootPath()))));
         }
         $file->moveTo($image_path);
         unset($image);
         shopImage::generateThumbs($data, $config->getImageSizes());
         $method = new shopProductImagesGetInfoMethod();
         $_GET['id'] = $image_id;
         $this->response = $method->getResponse(true);
     } else {
         throw new waAPIException('server_error', $file->error);
     }
 }
 protected function save(waRequestFile $file)
 {
     $product_id = waRequest::post('product_id', null, waRequest::TYPE_INT);
     $product_model = new shopProductModel();
     if (!$product_model->checkRights($product_id)) {
         throw new waException(_w("Access denied"));
     }
     // check image
     if (!($image = $file->waImage())) {
         throw new waException('Incorrect image');
     }
     $image_changed = false;
     /**
      * Extend upload proccess
      * Make extra workup
      * @event image_upload
      */
     $event = wa()->event('image_upload', $image);
     if ($event) {
         foreach ($event as $plugin_id => $result) {
             if ($result) {
                 $image_changed = true;
             }
         }
     }
     if (!$this->model) {
         $this->model = new shopProductImagesModel();
     }
     $data = array('product_id' => $product_id, 'upload_datetime' => date('Y-m-d H:i:s'), 'width' => $image->width, 'height' => $image->height, 'size' => $file->size, 'original_filename' => basename($file->name), 'ext' => $file->extension);
     $image_id = $data['id'] = $this->model->add($data);
     if (!$image_id) {
         throw new waException("Database error");
     }
     /**
      * @var shopConfig $config
      */
     $config = $this->getConfig();
     $image_path = shopImage::getPath($data);
     if (file_exists($image_path) && !is_writable($image_path) || !file_exists($image_path) && !waFiles::create($image_path)) {
         $this->model->deleteById($image_id);
         throw new waException(sprintf("The insufficient file write permissions for the %s folder.", substr($image_path, strlen($config->getRootPath()))));
     }
     if ($image_changed) {
         $image->save($image_path);
         // save original
         $original_file = shopImage::getOriginalPath($data);
         if ($config->getOption('image_save_original') && $original_file) {
             $file->moveTo($original_file);
         }
     } else {
         $file->moveTo($image_path);
     }
     unset($image);
     // free variable
     shopImage::generateThumbs($data, $config->getImageSizes());
     return array('id' => $image_id, 'name' => $file->name, 'type' => $file->type, 'size' => $file->size, 'url_thumb' => shopImage::getUrl($data, $config->getImageSize('thumb')), 'url_crop' => shopImage::getUrl($data, $config->getImageSize('crop')), 'url_crop_small' => shopImage::getUrl($data, $config->getImageSize('crop_small')), 'description' => '');
 }
 public function execute()
 {
     $id = $this->get('id', true);
     $images_model = new shopProductImagesModel();
     $image = $images_model->getById($id);
     if (!$image) {
         throw new waAPIException('invalid_param', 'Product image not found', 404);
     }
     $this->response = $image;
     $size = waRequest::get('size', wa('shop')->getConfig()->getImageSize('thumb'));
     $this->response['url_thumb'] = shopImage::getUrl($image, $size, true);
 }
 public function execute()
 {
     $id = $this->post('id', true);
     $images_model = new shopProductImagesModel();
     $image = $images_model->getById($id);
     if (!$image) {
         throw new waAPIException('invalid_param', 'Product image not found', 404);
     }
     // check product rights
     $this->getProduct($image['product_id']);
     $product_images_model = new shopProductImagesModel();
     if ($product_images_model->delete($id)) {
         $this->response = true;
     } else {
         throw new waAPIException('server_error', 500);
     }
 }
 public function execute()
 {
     $id = waRequest::post('id', 0, waRequest::TYPE_INT);
     if (!$id) {
         throw new waException(_w("Unknown image"));
     }
     $product_images_model = new shopProductImagesModel();
     $image = $product_images_model->getById($id);
     if (!$image) {
         throw new waException(_w("Unknown image"));
     }
     // check rights
     $product_model = new shopProductModel();
     if (!$product_model->checkRights($image['product_id'])) {
         throw new waException(_w("Access denied"));
     }
     $product_images_model->updateById($id, $this->getData());
 }
 public function execute()
 {
     $id = waRequest::get('id', null, waRequest::TYPE_INT);
     if (!$id) {
         throw new waException(_w("Unknown image"));
     }
     $product_images_model = new shopProductImagesModel();
     $image = $product_images_model->getById($id);
     if (!$image) {
         throw new waException(_w("Unknown image"));
     }
     $product_model = new shopProductModel();
     if (!$product_model->checkRights($image['product_id'])) {
         throw new waException(_w("Access denied"));
     }
     if (!$product_images_model->delete($id)) {
         throw new waException(_w("Coudn't delete image"));
     }
     $this->response['id'] = $id;
 }
 public function execute()
 {
     $id = waRequest::get('id', 0, waRequest::TYPE_INT);
     if (!$id) {
         throw new waException(_w("Image not found"), 404);
     }
     $product_images_model = new shopProductImagesModel();
     $image = $product_images_model->getById($id);
     if (!$image) {
         throw new waException(_w("Image not found"), 404);
     }
     if (waRequest::get('original')) {
         $path = shopImage::getOriginalPath($image);
     } else {
         $path = shopImage::getPath($image);
     }
     if (!$path || !file_exists($path)) {
         throw new waException(_w("Image not found"), 404);
     }
     waFiles::readFile($path, "Image_{$image['product_id']}_{$image['id']}.{$image['ext']}", true, true);
 }
 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;
 }
 public function execute()
 {
     $id = waRequest::get('id', null, waRequest::TYPE_INT);
     if (!$id) {
         throw new waException("Unknown image");
     }
     $direction = waRequest::post('direction', 'left', waRequest::TYPE_STRING_TRIM);
     if (!isset($this->angles[$direction])) {
         throw new waException("Can't rotate image");
     }
     $product_images_model = new shopProductImagesModel();
     $image = $product_images_model->getById($id);
     if (!$image) {
         throw new waException("Unknown image");
     }
     // check rights
     $product_model = new shopProductModel();
     if (!$product_model->checkRights($image['product_id'])) {
         throw new waException(_w("Access denied"));
     }
     $image_path = shopImage::getPath($image);
     $paths = array();
     try {
         $result_image_path = preg_replace('/(\\.[^\\.]+)$/', '.result$1', $image_path);
         $backup_image_path = preg_replace('/(\\.[^\\.]+)$/', '.backup$1', $image_path);
         $paths[] = $result_image_path;
         if ($this->rotate($image_path, $result_image_path, $this->angles[$direction])) {
             $count = 0;
             while (!file_exists($result_image_path) && ++$count < 5) {
                 sleep(1);
             }
             if (!file_exists($result_image_path)) {
                 throw new waException(_w("Error while rotate. I/O error"));
             }
             if (!waFiles::move($image_path, $backup_image_path)) {
                 throw new waException(_w("Error while rotate. Operation canceled"));
             }
             $paths[] = $backup_image_path;
             if (!waFiles::move($result_image_path, $image_path)) {
                 if (!waFiles::move($backup_image_path, $image_path)) {
                     throw new waException(_w("Error while rotate. Original file corupted but backuped"));
                 }
                 throw new waException(_w("Error while rotate. Operation canceled"));
             }
             $datetime = date('Y-m-d H:i:s');
             $data = array('edit_datetime' => $datetime, 'width' => $image['height'], 'height' => $image['width']);
             $product_images_model->updateById($id, $data);
             $image = array_merge($image, $data);
             $thumb_dir = shopImage::getThumbsPath($image);
             $back_thumb_dir = preg_replace('@(/$|$)@', '.back$1', $thumb_dir, 1);
             $paths[] = $back_thumb_dir;
             waFiles::delete($back_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"));
             }
             $config = $this->getConfig();
             try {
                 shopImage::generateThumbs($image, $config->getImageSizes());
             } catch (Exception $e) {
                 waLog::log($e->getMessage());
             }
             $this->response = $image;
             $edit_datetime_ts = strtotime($image['edit_datetime']);
             $this->response['url_big'] = shopImage::getUrl($image, $config->getImageSize('big')) . '?' . $edit_datetime_ts;
             $this->response['url_crop'] = shopImage::getUrl($image, $config->getImageSize('crop')) . '?' . $edit_datetime_ts;
         }
         foreach ($paths as $path) {
             waFiles::delete($path);
         }
     } catch (Exception $e) {
         foreach ($paths as $path) {
             waFiles::delete($path);
         }
         throw $e;
     }
 }
 public function cart()
 {
     $this->getResponse()->addHeader("Cache-Control", "no-store, no-cache, must-revalidate");
     $this->getResponse()->addHeader("Expires", date("r"));
     if (waRequest::method() == 'post') {
         $data = wa()->getStorage()->get('shop/checkout', array());
         if ($coupon_code = waRequest::post('coupon_code')) {
             $data['coupon_code'] = $coupon_code;
         } elseif (isset($data['coupon_code'])) {
             unset($data['coupon_code']);
         }
         if (($use = waRequest::post('use_affiliate')) !== null) {
             if ($use) {
                 $data['use_affiliate'] = 1;
             } elseif (isset($data['use_affiliate'])) {
                 unset($data['use_affiliate']);
             }
         }
         if ($coupon_code || $use) {
             wa()->getStorage()->set('shop/checkout', $data);
             wa()->getStorage()->remove('shop/cart');
         }
     }
     $cart_model = new shopCartItemsModel();
     $cart = new shopCart();
     $code = $cart->getCode();
     $errors = array();
     if (waRequest::post('checkout')) {
         $saved_quantity = $cart_model->select('id,quantity')->where("type='product' AND code = s:code", array('code' => $code))->fetchAll('id');
         $quantity = waRequest::post('quantity');
         foreach ($quantity as $id => $q) {
             if ($q != $saved_quantity[$id]) {
                 $cart->setQuantity($id, $q);
             }
         }
         $not_available_items = $cart_model->getNotAvailableProducts($code, !wa()->getSetting('ignore_stock_count'));
         foreach ($not_available_items as $row) {
             if ($row['sku_name']) {
                 $row['name'] .= ' (' . $row['sku_name'] . ')';
             }
             if ($row['available']) {
                 $errors[$row['id']] = sprintf(_w('Only %d pcs of %s are available, and you already have all of them in your shopping cart.'), $row['count'], $row['name']);
             } else {
                 $errors[$row['id']] = _w('Oops! %s is not available for purchase at the moment. Please remove this product from your shopping cart to proceed.');
             }
         }
         if (!$errors) {
             $this->redirect(wa()->getRouteUrl('/frontend/checkout'));
         }
     }
     $items = $cart_model->where('code= ?', $code)->order('parent_id')->fetchAll('id');
     $product_ids = $sku_ids = $service_ids = $type_ids = array();
     foreach ($items as $item) {
         $product_ids[] = $item['product_id'];
         $sku_ids[] = $item['sku_id'];
     }
     $product_ids = array_unique($product_ids);
     $sku_ids = array_unique($sku_ids);
     $product_model = new shopProductModel();
     if (waRequest::param('url_type') == 2) {
         $products = $product_model->getWithCategoryUrl($product_ids);
     } else {
         $products = $product_model->getById($product_ids);
     }
     $sku_model = new shopProductSkusModel();
     $skus = $sku_model->getByField('id', $sku_ids, 'id');
     $image_model = new shopProductImagesModel();
     $delete_items = array();
     foreach ($items as $item_id => &$item) {
         if (!isset($skus[$item['sku_id']])) {
             unset($items[$item_id]);
             $delete_items[] = $item_id;
             continue;
         }
         if ($item['type'] == 'product') {
             $item['product'] = $products[$item['product_id']];
             $sku = $skus[$item['sku_id']];
             if ($sku['image_id'] && $sku['image_id'] != $item['product']['image_id']) {
                 $img = $image_model->getById($sku['image_id']);
                 if ($img) {
                     $item['product']['image_id'] = $sku['image_id'];
                     $item['product']['ext'] = $img['ext'];
                 }
             }
             $item['sku_name'] = $sku['name'];
             $item['sku_code'] = $sku['sku'];
             $item['price'] = $sku['price'];
             $item['compare_price'] = $sku['compare_price'];
             $item['currency'] = $item['product']['currency'];
             $type_ids[] = $item['product']['type_id'];
             if (isset($errors[$item_id])) {
                 $item['error'] = $errors[$item_id];
                 if (strpos($item['error'], '%s') !== false) {
                     $item['error'] = sprintf($item['error'], $item['product']['name'] . ($item['sku_name'] ? ' (' . $item['sku_name'] . ')' : ''));
                 }
             }
         }
     }
     unset($item);
     if ($delete_items) {
         $cart_model->deleteByField(array('code' => $code, 'id' => $delete_items));
     }
     $type_ids = array_unique($type_ids);
     // get available services for all types of products
     $type_services_model = new shopTypeServicesModel();
     $rows = $type_services_model->getByField('type_id', $type_ids, true);
     $type_services = array();
     foreach ($rows as $row) {
         $service_ids[] = $row['service_id'];
         $type_services[$row['type_id']][$row['service_id']] = true;
     }
     // get services for all products
     $product_services_model = new shopProductServicesModel();
     $rows = $product_services_model->getByProducts($product_ids);
     $product_services = $sku_services = array();
     foreach ($rows as $row) {
         if ($row['sku_id'] && !in_array($row['sku_id'], $sku_ids)) {
             continue;
         }
         $service_ids[] = $row['service_id'];
         if (!$row['sku_id']) {
             $product_services[$row['product_id']][$row['service_id']]['variants'][$row['service_variant_id']] = $row;
         }
         if ($row['sku_id']) {
             $sku_services[$row['sku_id']][$row['service_id']]['variants'][$row['service_variant_id']] = $row;
         }
     }
     $service_ids = array_unique($service_ids);
     $service_model = new shopServiceModel();
     $variant_model = new shopServiceVariantsModel();
     $services = $service_model->getByField('id', $service_ids, 'id');
     foreach ($services as &$s) {
         unset($s['id']);
     }
     unset($s);
     $rows = $variant_model->getByField('service_id', $service_ids, true);
     foreach ($rows as $row) {
         $services[$row['service_id']]['variants'][$row['id']] = $row;
         unset($services[$row['service_id']]['variants'][$row['id']]['id']);
     }
     foreach ($items as $item_id => $item) {
         if ($item['type'] == 'product') {
             $p = $item['product'];
             $item_services = array();
             // services from type settings
             if (isset($type_services[$p['type_id']])) {
                 foreach ($type_services[$p['type_id']] as $service_id => &$s) {
                     $item_services[$service_id] = $services[$service_id];
                 }
             }
             // services from product settings
             if (isset($product_services[$item['product_id']])) {
                 foreach ($product_services[$item['product_id']] as $service_id => $s) {
                     if (!isset($s['status']) || $s['status']) {
                         if (!isset($item_services[$service_id])) {
                             $item_services[$service_id] = $services[$service_id];
                         }
                         // update variants
                         foreach ($s['variants'] as $variant_id => $v) {
                             if ($v['status']) {
                                 if ($v['price'] !== null) {
                                     $item_services[$service_id]['variants'][$variant_id]['price'] = $v['price'];
                                 }
                             } else {
                                 unset($item_services[$service_id]['variants'][$variant_id]);
                             }
                         }
                     } elseif (isset($item_services[$service_id])) {
                         // remove disabled service
                         unset($item_services[$service_id]);
                     }
                 }
             }
             // services from sku settings
             if (isset($sku_services[$item['sku_id']])) {
                 foreach ($sku_services[$item['sku_id']] as $service_id => $s) {
                     if (!isset($s['status']) || $s['status']) {
                         // update variants
                         foreach ($s['variants'] as $variant_id => $v) {
                             if ($v['status']) {
                                 if ($v['price'] !== null) {
                                     $item_services[$service_id]['variants'][$variant_id]['price'] = $v['price'];
                                 }
                             } else {
                                 unset($item_services[$service_id]['variants'][$variant_id]);
                             }
                         }
                     } elseif (isset($item_services[$service_id])) {
                         // remove disabled service
                         unset($item_services[$service_id]);
                     }
                 }
             }
             foreach ($item_services as $s_id => &$s) {
                 if (!$s['variants']) {
                     unset($item_services[$s_id]);
                     continue;
                 }
                 if ($s['currency'] == '%') {
                     foreach ($s['variants'] as $v_id => $v) {
                         $s['variants'][$v_id]['price'] = $v['price'] * $item['price'] / 100;
                     }
                     $s['currency'] = $item['currency'];
                 }
                 if (count($s['variants']) == 1) {
                     $v = reset($s['variants']);
                     $s['price'] = $v['price'];
                     unset($s['variants']);
                 }
             }
             unset($s);
             uasort($item_services, array('shopServiceModel', 'sortServices'));
             $items[$item_id]['services'] = $item_services;
         } else {
             $items[$item['parent_id']]['services'][$item['service_id']]['id'] = $item['id'];
             if (isset($item['service_variant_id'])) {
                 $items[$item['parent_id']]['services'][$item['service_id']]['variant_id'] = $item['service_variant_id'];
             }
             unset($items[$item_id]);
         }
     }
     foreach ($items as $item_id => $item) {
         $price = shop_currency($item['price'] * $item['quantity'], $item['currency'], null, false);
         if (isset($item['services'])) {
             foreach ($item['services'] as $s) {
                 if (!empty($s['id'])) {
                     if (isset($s['variants'])) {
                         $price += shop_currency($s['variants'][$s['variant_id']]['price'] * $item['quantity'], $s['currency'], null, false);
                     } else {
                         $price += shop_currency($s['price'] * $item['quantity'], $s['currency'], null, false);
                     }
                 }
             }
         }
         $items[$item_id]['full_price'] = $price;
     }
     $total = $cart->total(false);
     $order = array('total' => $total, 'items' => $items);
     $order['discount'] = $discount = shopDiscounts::calculate($order);
     $order['total'] = $total = $total - $order['discount'];
     $data = wa()->getStorage()->get('shop/checkout');
     $this->view->assign('cart', array('items' => $items, 'total' => $total, 'count' => $cart->count()));
     $this->view->assign('coupon_code', isset($data['coupon_code']) ? $data['coupon_code'] : '');
     if (shopAffiliate::isEnabled()) {
         $affiliate_bonus = 0;
         if ($this->getUser()->isAuth()) {
             $customer_model = new shopCustomerModel();
             $customer = $customer_model->getById($this->getUser()->getId());
             $affiliate_bonus = $customer ? round($customer['affiliate_bonus'], 2) : 0;
         }
         $this->view->assign('affiliate_bonus', $affiliate_bonus);
         $use = !empty($data['use_affiliate']);
         $this->view->assign('use_affiliate', $use);
         if ($use) {
             $discount -= shop_currency(shopAffiliate::convertBonus($order['params']['affiliate_bonus']), $this->getConfig()->getCurrency(true), null, false);
             $this->view->assign('used_affiliate_bonus', $order['params']['affiliate_bonus']);
         }
         $order['currency'] = $this->getConfig()->getCurrency(false);
         $add_affiliate_bonus = shopAffiliate::calculateBonus($order);
         $this->view->assign('add_affiliate_bonus', round($add_affiliate_bonus, 2));
     }
     $this->view->assign('discount', $discount);
     /**
      * @event frontend_cart
      * @return array[string]string $return[%plugin_id%] html output
      */
     $this->view->assign('frontend_cart', wa()->event('frontend_cart'));
     $checkout_flow = new shopCheckoutFlowModel();
     $checkout_flow->add(array('code' => $code, 'step' => 0, 'description' => null));
 }
 /**
  * @param $items
  * @param $sku_ids
  * @param $product_ids
  * @return array
  */
 private function getTypeIds(&$items, $sku_ids, $product_ids)
 {
     $product_model = new shopProductModel();
     $sku_model = new shopProductSkusModel();
     $image_model = new shopProductImagesModel();
     /**
      * @todo: $products = $product_model->getWithCategoryUrl($product_ids);
      * $products = $product_model->getById($product_ids);
      */
     $products = $product_model->getWithCategoryUrl($product_ids);
     $skus = $sku_model->getByField('id', $sku_ids, 'id');
     $type_ids = array();
     foreach ($items as $item_id => &$item) {
         if (!isset($skus[$item['sku_id']])) {
             unset($items[$item_id]);
             continue;
         }
         if ($item['type'] == 'product') {
             $item['product'] = $products[$item['product_id']];
             $sku = $skus[$item['sku_id']];
             if ($sku['image_id'] && $sku['image_id'] != $item['product']['image_id']) {
                 $img = $image_model->getById($sku['image_id']);
                 if ($img) {
                     $item['product']['image_id'] = $sku['image_id'];
                     $item['product']['ext'] = $img['ext'];
                 }
             }
             $item['sku_name'] = $sku['name'];
             $item['sku_code'] = $sku['sku'];
             $item['price'] = $sku['price'];
             $item['currency'] = $item['product']['currency'];
             $type_ids[] = $item['product']['type_id'];
         }
     }
     return array_unique($type_ids);
 }
Exemplo n.º 13
0
 /**
  * Get aggregated data about placing products(skus) in stocks
  *
  * @see getProductStocks
  *
  * @param int|array $product_id
  * @param string $order
  * @return array
  */
 public function getProductStocksByProductId($product_id, $order = 'desc')
 {
     if (!$product_id) {
         return array();
     }
     $product_ids = (array) $product_id;
     $product_ids_str = implode(',', $product_ids);
     $order = $order == 'desc' || $order == 'DESC' ? 'DESC' : 'ASC';
     // necessary models
     $stock_model = new shopStockModel();
     $product_images_model = new shopProductImagesModel();
     // stock ids of items ordered by sort
     $stock_ids = array_keys($stock_model->getAll('id'));
     // get products
     $sql = "\n            SELECT id, name, count, image_id\n            FROM {$this->table}\n            WHERE id IN ( {$product_ids_str} )\n            ORDER BY count {$order}\n        ";
     $data = array();
     $image_ids = array();
     foreach ($this->query($sql) as $item) {
         $data[$item['id']] = array('id' => $item['id'], 'name' => $item['name'], 'url_crop_small' => null, 'count' => $item['count'], 'skus' => array(), 'stocks' => array());
         if ($item['image_id'] != null) {
             $image_ids[] = $item['image_id'];
         }
     }
     if (!$data) {
         return array();
     }
     $product_ids = array_keys($data);
     $product_ids_str = implode(',', $product_ids);
     $images = $product_images_model->getByField('id', $image_ids, 'product_id');
     $size = wa()->getConfig()->getImageSize('crop_small');
     // get for skus number of stocks in which it presents
     $sql = "\n            SELECT sk.id, COUNT(sk.id) num_of_stocks\n            FROM shop_product_skus sk\n            JOIN shop_product_stocks st ON sk.id = st.sku_id\n            WHERE sk.product_id IN ( {$product_ids_str} )\n            GROUP BY sk.id\n        ";
     $num_of_stocks = $this->query($sql)->fetchAll('id', true);
     // get info about skus and stocks
     $sql = "SELECT\n                    sk.product_id,\n                    sk.id AS sku_id,\n                    sk.name AS sku_name,\n                    sk.count,\n\n                    pst.stock_id,\n                    pst.count AS stock_count\n                FROM shop_product_skus sk\n                LEFT JOIN shop_product_stocks pst ON pst.sku_id = sk.id\n                WHERE sk.product_id IN ( {$product_ids_str} )\n                ORDER BY sk.product_id, sk.count {$order}, sk.id";
     $stocks_count = count($stock_ids);
     // temporary aggragating info about stocks
     $sku_stocks = array();
     if ($stocks_count) {
         $sku_stocks = array_fill(0, $stocks_count, array());
     }
     $sku_id = 0;
     $product_id = 0;
     $p_product = null;
     foreach ($this->query($sql) as $item) {
         // another product
         if ($product_id != $item['product_id']) {
             $product_id = $item['product_id'];
             $p_product =& $data[$product_id];
             if (isset($images[$product_id])) {
                 $p_product['url_crop_small'] = shopImage::getUrl($images[$product_id], $size);
             }
         }
         // another sku
         if ($sku_id != $item['sku_id']) {
             $sku_id = $item['sku_id'];
             $p_product['skus'][$sku_id] = array('id' => $sku_id, 'name' => $item['sku_name'], 'count' => $item['count'], 'num_of_stocks' => isset($num_of_stocks[$sku_id]) ? $num_of_stocks[$sku_id] : 0);
         }
         // aggregate info about stocks
         if ($item['stock_id'] !== null) {
             $sku_stocks[$item['stock_id']][$sku_id] = $item['stock_count'];
         }
     }
     // lay out stocks info
     if (!empty($sku_stocks)) {
         foreach ($data as &$product) {
             foreach ($stock_ids as $stock_id) {
                 foreach ($product['skus'] as $sku_id => $sku) {
                     $product['stocks'][$stock_id][$sku_id] = array('id' => $sku_id, 'name' => $sku['name'], 'count' => isset($sku_stocks[$stock_id][$sku_id]) ? $sku_stocks[$stock_id][$sku_id] : null, 'num_of_stocks' => $sku['num_of_stocks']);
                 }
             }
         }
         unset($product);
     }
     return $data;
 }
 public function execute()
 {
     $id = waRequest::post('id', null, waRequest::TYPE_INT);
     if (!$id) {
         throw new waException("Can't restore image");
     }
     $product_images_model = new shopProductImagesModel();
     $image = $product_images_model->getById($id);
     if (!$image) {
         throw new waException("Can't restore image");
     }
     // check rights
     $product_model = new shopProductModel();
     if (!$product_model->checkRights($image['product_id'])) {
         throw new waException(_w("Access denied"));
     }
     $original_image_path = shopImage::getOriginalPath($image);
     if (!wa('shop')->getConfig()->getOption('image_save_original') || !file_exists($original_image_path)) {
         throw new waException("Can't restore image. Original image doesn't exist");
     }
     $image_path = shopImage::getPath($image);
     $paths = array();
     try {
         $backup_image_path = preg_replace('/(\\.[^\\.]+)$/', '.backup$1', $image_path);
         if (!waFiles::move($image_path, $backup_image_path)) {
             throw new waException("Error while restore. Operation canceled");
         }
         $paths[] = $backup_image_path;
         if (!waFiles::move($original_image_path, $image_path)) {
             if (!waFiles::move($backup_image_path, $image_path)) {
                 throw new waException("Error while restore. Current file corupted but backuped");
             }
             throw new waException("Error while restore. Operation canceled");
         }
         $data = $this->getData($image_path);
         $product_images_model->updateById($id, $data);
         $image = array_merge($image, $data);
         $thumb_dir = shopImage::getThumbsPath($image);
         $back_thumb_dir = preg_replace('@(/$|$)@', '.back$1', $thumb_dir, 1);
         $paths[] = $back_thumb_dir;
         waFiles::delete($back_thumb_dir);
         // old backups
         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"));
         }
         /**
          * @var shopConfig $config
          */
         $config = $this->getConfig();
         try {
             shopImage::generateThumbs($image, $config->getImageSizes());
         } catch (Exception $e) {
             waLog::log($e->getMessage());
         }
         $this->response = $image;
         $edit_datetime_ts = strtotime($image['edit_datetime']);
         $this->response['url_big'] = shopImage::getUrl($image, $config->getImageSize('big')) . '?' . $edit_datetime_ts;
         $this->response['url_crop'] = shopImage::getUrl($image, $config->getImageSize('crop')) . '?' . $edit_datetime_ts;
         foreach ($paths as $path) {
             waFiles::delete($path);
         }
     } catch (Exception $e) {
         foreach ($paths as $path) {
             waFiles::delete($path);
         }
         throw $e;
     }
 }
Exemplo n.º 15
0
 /**
  * @param array $options
  * @return shopProduct
  * @throws waException
  */
 public function duplicate($options = array())
 {
     if (!$this->checkRights()) {
         throw new waRightsException('Access denied');
     }
     $data = $this->data;
     $skip = array('id', 'create_datetime', 'id_1c', 'rating', 'rating_count', 'total_sales', 'image_id', 'contact_id', 'ext', 'count', 'sku_count');
     foreach ($skip as $field) {
         if (isset($data[$field])) {
             unset($data[$field]);
         }
     }
     $duplicate = new shopProduct();
     $this->getStorage(null);
     $sku_files = array();
     $sku_images = array();
     $ignore_select = true;
     foreach (self::$data_storages as $key => $i) {
         $raw = $this->getStorage($key)->getData($this);
         switch ($key) {
             case 'features_selectable':
                 $storage_data = array();
                 if (!$ignore_select) {
                     if ($this->sku_type == shopProductModel::SKU_TYPE_SELECTABLE) {
                         if (!is_array($raw)) {
                             $raw = array();
                         }
                         foreach ($raw as $id => $f) {
                             if (!empty($f['selected'])) {
                                 foreach ($f['values'] as $value_id => &$value) {
                                     if (!empty($value['selected'])) {
                                         $value = array('id' => $value_id);
                                     } else {
                                         unset($f['values'][$value_id]);
                                     }
                                 }
                                 $storage_data[$id] = $f;
                             }
                         }
                     }
                 }
                 break;
             case 'skus':
                 $storage_data = array();
                 $i = 0;
                 foreach ($raw as $sku_id => $sku) {
                     if (!empty($sku['virtual']) || $ignore_select) {
                         if ($file_path = shopProductSkusModel::getPath($sku)) {
                             $sku_files[$sku['id']] = array('file_name' => $sku['file_name'], 'file_description' => $sku['file_description'], 'file_size' => $sku['file_size'], 'file_path' => $file_path);
                         }
                         if (!empty($sku['image_id'])) {
                             $sku_images[$sku['id']] = $sku['image_id'];
                         }
                         foreach (array('id', 'id_1c', 'product_id', 'image_id', 'file_name', 'file_size', 'file_description') as $field) {
                             if (isset($sku[$field])) {
                                 unset($sku[$field]);
                             }
                         }
                         $storage_data[--$i] = $sku;
                     }
                 }
                 break;
             case 'tags':
                 $storage_data = array_values($raw);
                 break;
             case 'categories':
                 $storage_data = array_keys($raw);
                 break;
             default:
                 $storage_data = $raw;
                 break;
         }
         $duplicate->{$key} = $storage_data;
     }
     $counter = 0;
     $data['url'] = shopHelper::genUniqueUrl($this->url, $this->model, $counter);
     $data['name'] = $this->name . sprintf('(%d)', $counter ? $counter : 1);
     $duplicate->save($data);
     $product_id = $duplicate->getId();
     $sku_map = array_combine(array_keys($this->skus), array_keys($duplicate->skus));
     $config = wa('shop')->getConfig();
     $image_thumbs_on_demand = $config->getOption('image_thumbs_on_demand');
     /**
      * @var shopConfig $config
      */
     if ($this->pages) {
         $product_pages_model = new shopProductPagesModel();
         foreach ($this->pages as $page) {
             unset($page['id']);
             unset($page['create_time']);
             unset($page['update_datetime']);
             unset($page['create_contact_id']);
             $page['product_id'] = $duplicate->getId();
             $product_pages_model->add($page);
         }
     }
     #duplicate images
     $product_skus_model = new shopProductSkusModel();
     $images_model = new shopProductImagesModel();
     $images = $images_model->getByField('product_id', $this->getId(), $images_model->getTableId());
     $callback = create_function('$a, $b', 'return (max(-1, min(1, $a["sort"] - $b["sort"])));');
     usort($images, $callback);
     foreach ($images as $id => $image) {
         $source_path = shopImage::getPath($image);
         $original_file = shopImage::getOriginalPath($image);
         $image['product_id'] = $duplicate->getId();
         if ($sku_id = array_search($image['id'], $sku_images)) {
             $sku_id = $sku_map[$sku_id];
         }
         unset($image['id']);
         try {
             if ($image['id'] = $images_model->add($image, $id == $this->image_id)) {
                 waFiles::copy($source_path, shopImage::getPath($image));
                 if (file_exists($original_file)) {
                     waFiles::copy($original_file, shopImage::getOriginalPath($image));
                 }
                 if ($sku_id) {
                     $product_skus_model->updateById($sku_id, array('image_id' => $image['id']));
                 }
                 if (!$image_thumbs_on_demand) {
                     shopImage::generateThumbs($image, $config->getImageSizes());
                     //TODO use dummy copy  with rename files
                 }
             }
         } catch (waDbException $ex) {
             //just ignore it
             waLog::log('Error during copy product: ' . $ex->getMessage(), 'shop.log');
         } catch (waException $ex) {
             if (!empty($image['id'])) {
                 $images_model->deleteById($image['id']);
             }
             waLog::log('Error during copy product: ' . $ex->getMessage(), 'shop.log');
         }
     }
     foreach ($sku_files as $sku_id => $data) {
         $source_path = $data['file_path'];
         unset($data['file_path']);
         $sku_id = $sku_map[$sku_id];
         $sku = array_merge($duplicate->skus[$sku_id], $data);
         $product_skus_model->updateById($sku_id, $data);
         $target_path = shopProductSkusModel::getPath($sku);
         try {
             waFiles::copy($source_path, $target_path);
         } catch (waException $ex) {
             $data = array('file_name' => '', 'file_description' => '', 'file_size' => 0);
             $product_skus_model->updateById($sku_id, $data);
             print $ex->getMessage();
         }
     }
     $product_features_model = new shopProductFeaturesModel();
     $skus_features = $product_features_model->getSkuFeatures($this->id);
     $skus_features_data = array();
     foreach ($skus_features as $sku_id => $features) {
         $sku_id = $sku_map[$sku_id];
         foreach ($features as $feature_id => $feature_value_id) {
             $skus_features_data[] = compact('product_id', 'sku_id', 'feature_id', 'feature_value_id');
         }
     }
     if ($skus_features_data) {
         $product_features_model->multipleInsert($skus_features_data);
     }
     if ($this->sku_type == shopProductModel::SKU_TYPE_SELECTABLE) {
         $product_features_selectable_model = new shopProductFeaturesSelectableModel();
         if ($features_selectable = $product_features_selectable_model->getByField('product_id', $this->id, true)) {
             foreach ($features_selectable as &$feature_selectable) {
                 $feature_selectable['product_id'] = $product_id;
             }
             unset($feature_selectable);
             $product_features_selectable_model->multipleInsert($features_selectable);
         }
     }
     $product_services_model = new shopProductServicesModel();
     if ($services = $product_services_model->getByField('product_id', $this->id, true)) {
         foreach ($services as &$service) {
             unset($service['id']);
             $service['product_id'] = $product_id;
             $service['sku_id'] = ifset($sku_map[$service['sku_id']]);
             unset($service);
         }
         $product_services_model->multipleInsert($services);
     }
     $product_related_model = new shopProductRelatedModel();
     if ($related = $product_related_model->getByField('product_id', $this->id, true)) {
         foreach ($related as &$row) {
             $row['product_id'] = $product_id;
         }
         unset($row);
         $product_related_model->multipleInsert($related);
     }
     $params = array('product' => &$this, 'duplicate' => &$duplicate);
     /**
      * @wa-event product_duplicate
      */
     wa()->event('product_duplicate', $params);
     return $duplicate;
 }
Exemplo n.º 16
0
 /**
  * Returns HTML code of product image badge.
  *
  * @param array $image Image data array containing elements 'badge_type' and, optionally, 'badge_code' (for custom badges).
  * @return string
  */
 public static function getImageBadgeHtml($image)
 {
     if (!isset($image['badge_type'])) {
         return '';
     }
     if (shopProductImagesModel::isCustomBadgeType($image['badge_type'])) {
         return isset($image['badge_code']) ? $image['badge_code'] : '';
     }
     return shopProductImagesModel::getBadgeCode($image['badge_type']);
 }
 private function workupProducts(&$products = array(), $escape)
 {
     // Names of fields that must be converted to float values
     $float = array('min_price', 'max_price', 'total_sales', 'base_price_selectable', 'rating', 'price', 'compare_price');
     foreach ($products as &$p) {
         foreach ($float as $field) {
             if (isset($p[$field])) {
                 $p[$field] = (double) $p[$field];
             }
         }
         if ($this->is_frontend && $p['compare_price'] && $p['compare_price'] <= $p['price']) {
             $p['compare_price'] = 0;
         }
         // escape
         if ($escape) {
             $p['name'] = htmlspecialchars($p['name']);
             $p['url'] = htmlspecialchars($p['url']);
         }
     }
     unset($p);
     if (!empty($this->options['params'])) {
         $product_params_model = new shopProductParamsModel();
         $rows = $product_params_model->getByField('product_id', array_keys($products), true);
         foreach ($rows as $row) {
             $products[$row['product_id']]['params'][$row['name']] = $row['value'];
         }
     }
     if ($this->post_fields) {
         $ids = array_keys($products);
         foreach ($this->post_fields as $table => $fields) {
             if ($table == '_internal') {
                 if ($this->is_frontend && waRequest::param('url_type') == 2) {
                     $cat_ids = array();
                     foreach ($products as &$p) {
                         if (!empty($p['category_id'])) {
                             $cat_ids[] = $p['category_id'];
                         }
                     }
                     $cat_ids = array_unique($cat_ids);
                     if ($cat_ids) {
                         $categories = $this->getModel('category')->getById($cat_ids);
                         foreach ($products as &$p) {
                             if (!empty($p['category_id'])) {
                                 $p['category_url'] = $categories[$p['category_id']]['full_url'];
                             }
                         }
                     }
                 }
                 foreach ($fields as $i => $f) {
                     if ($f == 'images' || $f == 'image') {
                         if ($f == 'images') {
                             $product_images_model = new shopProductImagesModel();
                             $product_images = $product_images_model->getImages($ids, 'thumb', 'product_id');
                             foreach ($product_images as $product_id => $images) {
                                 $products[$product_id]['images'] = $images;
                             }
                         } elseif ($f == 'image') {
                             $thumb_size = wa('shop')->getConfig()->getImageSize('thumb');
                             $big_size = wa('shop')->getConfig()->getImageSize('big');
                             foreach ($products as &$p) {
                                 if ($p['image_id']) {
                                     $tmp = array('id' => $p['image_id'], 'product_id' => $p['id'], 'ext' => $p['ext']);
                                     $p['image']['thumb_url'] = shopImage::getUrl($tmp, $thumb_size, isset($this->options['absolute']) ? $this->options['absolute'] : false);
                                     $p['image']['big_url'] = shopImage::getUrl($tmp, $big_size, isset($this->options['absolute']) ? $this->options['absolute'] : false);
                                 }
                             }
                         }
                     } elseif ($f == 'frontend_url') {
                         foreach ($products as &$p) {
                             $route_params = array('product_url' => $p['url']);
                             if (isset($p['category_url'])) {
                                 $route_params['category_url'] = $p['category_url'];
                             } elseif (isset($this->info['hash']) && $this->info['hash'] == 'category') {
                                 if (isset($this->info['subcategories']) && $this->info['id'] != $p['category_id']) {
                                     if (isset($this->info['subcategories'][$p['category_id']])) {
                                         $route_params['category_url'] = $this->info['subcategories'][$p['category_id']]['full_url'];
                                     }
                                 } else {
                                     $route_params['category_url'] = $this->info['full_url'];
                                 }
                             }
                             $p['frontend_url'] = wa()->getRouteUrl('shop/frontend/product', $route_params);
                         }
                         unset($p);
                     }
                 }
             }
         }
     }
 }
Exemplo n.º 18
0
 public function images($product_ids, $size = array(), $absolute = false)
 {
     if (!$product_ids) {
         return array();
     }
     $product_ids = array_map('intval', (array) $product_ids);
     $product_images_model = new shopProductImagesModel();
     return $product_images_model->getImages($product_ids, $size, 'product_id', $absolute);
 }