public function execute() { $product_id = (int) waRequest::get('id'); $product = new shopProduct($product_id); $type_model = new shopTypeModel(); $type = $type_model->getById($product['type_id']); if ($product['cross_selling'] === null) { $product['cross_selling'] = $type['cross_selling'] ? 1 : 0; } if ($product['upselling'] === null) { $product['upselling'] = $type['upselling']; } // if manually if ($product['cross_selling'] == 2 || $product['upselling'] == 2) { $related_model = new shopProductRelatedModel(); $related = $related_model->getAllRelated($product_id); } else { $related = array(); } if ($type['upselling']) { $type_upselling_model = new shopTypeUpsellingModel(); $data = $type_upselling_model->getByType($type['id']); $type['upselling_html'] = shopSettingsRecommendationsAction::getConditionHTML($data); } if ($type['cross_selling'] && substr($type['cross_selling'], 0, 9) == 'category/') { $category_model = new shopCategoryModel(); $type['category'] = $category_model->getById(substr($type['cross_selling'], 9)); } $this->view->assign(array('type' => $type, 'product' => $product, 'related' => $related)); }
public function execute() { $setting = waRequest::get('setting'); $this->type_id = waRequest::post('type_id'); $this->type_model = new shopTypeModel(); $this->type = $this->type_model->getById($this->type_id); if (!$this->type) { throw new waException("Type not found"); } if ($setting == 'cross-selling') { $this->saveCrossSelling(); } elseif ($setting == 'upselling') { $this->saveUpSelling(); } else { throw new waException("Unknown setting"); } }
public function execute() { $id = $this->get('id', true); $type_model = new shopTypeModel(); $type = $type_model->getById($id); if ($type) { $this->response = $type; } else { throw new waAPIException('invalid_param', 'Type not found', 404); } }
/** * Collections /type/1 * * @param int $id - type_id * @param bool $auto_title */ protected function typePrepare($id, $auto_title = true) { $type_model = new shopTypeModel(); $type = $type_model->getById($id); if (!$type) { $this->where[] = '0'; return; } $this->info = $type; if ($auto_title) { $this->addTitle($type['name']); } $this->where[] = "p.type_id = " . (int) $id; }
/** * Returns information on product's type. * * @return array|null Product type info array, or null if product has no type */ public function getType() { $model = new shopTypeModel(); return $this->type_id ? $model->getById($this->type_id) : null; }
/** * @param string $field * @param mixed $value * @param array $info * @param array $data * @param null $sku_data * @return mixed|string */ private function format($field, $value, $info = array(), $data = array(), $sku_data = null) { /** * @todo cpa field */ /** * <yml_catalog> * <shop> * <currencies> * <categories> * <local_delivery_cost> * <offers> * <picture> * <description> и <name> * <delivery>, <pickup> и <store> * <adult> * <barcode> * <cpa> TODO * <rec> * <param> (name,unit,value) * <vendor> */ static $currency_model; static $size; switch ($field) { case 'group_id': if ($value === 'auto') { if (!empty($data['market_category'])) { $value = $this->plugin()->isGroupedCategory($data['market_category']) ? $data['id'] : null; } else { $info['format'] = false; } } break; case 'market_category': //it's product constant field //TODO verify it break; case 'name': if (!empty($sku_data['name']) && !empty($data['name']) && $sku_data['name'] != $data['name']) { $value = sprintf('%s (%s)', $value, $sku_data['name']); } $value = preg_replace('/<br\\/?\\s*>/', "\n", $value); $value = preg_replace("/[\r\n]+/", "\n", $value); $value = strip_tags($value); $value = trim($value); if (mb_strlen($value) > 255) { $value = mb_substr($value, 0, 252) . '...'; } break; case 'description': $value = preg_replace('/<br\\/?\\s*>/', "\n", $value); $value = preg_replace("/[\r\n]+/", "\n", $value); $value = strip_tags($value); $value = trim($value); if (mb_strlen($value) > 512) { $value = mb_substr($value, 0, 509) . '...'; } break; case 'barcode': //может содержать несколько элементов $value = preg_replace('@\\D+@', '', $value); if (!in_array(strlen($value), array(8, 12, 13))) { $value = null; } break; case 'sales_notes': $value = trim($value); if (mb_strlen($value) > 50) { $value = mb_substr($value, 0, 50); } break; case 'typePrefix': $model = new shopTypeModel(); if ($type = $model->getById($value)) { $value = $type['name']; } break; case 'url': //max 512 $value = preg_replace_callback('@([^\\[\\]a-zA-Z\\d_/-\\?=%&,\\.]+)@i', array(__CLASS__, 'rawurlencode'), $value); if ($this->data['utm']) { $value .= (strpos($value, '?') ? '&' : '?') . $this->data['utm']; } $value = 'http://' . ifempty($this->data['base_url'], 'localhost') . $value; break; case 'oldprice': if (empty($value) || empty($this->data['export']['compare_price'])) { $value = null; break; } case 'price': if (!$currency_model) { $currency_model = new shopCurrencyModel(); } if ($sku_data) { if (!in_array($data['currency'], $this->data['currency'])) { $value = $currency_model->convert($value, $data['currency'], $this->data['primary_currency']); $data['currency'] = $this->data['primary_currency']; } } else { if (!in_array($data['currency'], $this->data['currency'])) { #value in default currency if ($this->data['default_currency'] != $this->data['primary_currency']) { $value = $currency_model->convert($value, $this->data['default_currency'], $this->data['primary_currency']); } $data['currency'] = $this->data['primary_currency']; } elseif ($this->data['default_currency'] != $data['currency']) { $value = $currency_model->convert($value, $this->data['default_currency'], $data['currency']); } } break; case 'currencyId': if (!in_array($value, $this->data['currency'])) { $value = $this->data['primary_currency']; } break; case 'rate': if (!in_array($value, array('CB', 'CBRF', 'NBU', 'NBK'))) { $info['format'] = '%0.4f'; } break; case 'available': if (!empty($sku_data) && isset($sku_data['available']) && empty($sku_data['available'])) { $value = 'false'; } if (is_object($value)) { switch (get_class($value)) { case 'shopBooleanValue': /** * @var $value shopBooleanValue */ $value = $value->value ? 'true' : 'false'; break; } } $value = ($value <= 0 || $value === 'false' || empty($value)) && $value !== null && $value !== 'true' ? 'false' : 'true'; break; case 'store': case 'pickup': case 'delivery': case 'adult ': if (is_object($value)) { switch (get_class($value)) { case 'shopBooleanValue': /** * @var $value shopBooleanValue */ $value = $value->value ? 'true' : 'false'; break; } } $value = empty($value) || $value === 'false' ? 'false' : 'true'; break; case 'picture': //max 512 $values = array(); $limit = 10; if (!empty($sku_data['image_id'])) { $value = array(ifempty($value[$sku_data['image_id']])); } while (is_array($value) && ($image = array_shift($value)) && $limit--) { if (!$size) { $shop_config = wa('shop')->getConfig(); /** * @var $shop_config shopConfig */ $size = $shop_config->getImageSize('big'); } $values[] = 'http://' . ifempty($this->data['base_url'], 'localhost') . shopImage::getUrl($image, $size); } $value = $values; break; case 'page_extent': $value = max(1, intval($value)); break; case 'seller_warranty': case 'manufacturer_warranty': case 'expiry': /** * ISO 8601, например: P1Y2M10DT2H30M */ $pattern = '@P((\\d+S)?(\\d+M)(\\d+D)?)?(T(\\d+H)?(\\d+M)(\\d+S)?)?@'; $class = is_object($value) ? get_class($value) : false; switch ($class) { case 'shopBooleanValue': /** * @var $value shopBooleanValue */ $value = $value->value ? 'true' : 'false'; break; case 'shopDimensionValue': /** * @var $value shopDimensionValue */ $value = $value->convert('s', false); /** * @var $value int */ if (empty($value)) { $value = 'false'; } else { $value = $this->formatCustom($value, 'ISO8601'); } break; default: $value = (string) $value; if (empty($value) || $value == 'false') { $value = 'false'; } elseif (preg_match('@^\\d+$@', trim($value))) { $value = $this->formatCustom(intval($value) * 3600 * 24, 'ISO8601'); } elseif (!preg_match($pattern, $value)) { $value = 'true'; } break; } break; case 'year': if (empty($value)) { $value = null; } break; case 'ISBN': /** * @todo verify format * Код книги, если их несколько, то указываются через запятую. * Форматы ISBN и SBN проверяются на корректность. Валидация кодов происходит не только по длине, * также проверяется контрольная цифра (check-digit) – последняя цифра кода должна согласовываться * с остальными цифрами по определенной формуле. При разбиении ISBN на части при помощи дефиса * (например, 978-5-94878-004-7) код проверяется на соответствие дополнительным требованиям к * количеству цифр в каждой из частей. * Необязательный элемент. **/ break; case 'recording_length': /** * Время звучания задается в формате mm.ss (минуты.секунды). **/ if (is_object($value)) { switch (get_class($value)) { case 'shopDimensionValue': /** * @var $value shopDimensionValue */ $value = $value->convert('s', false); break; default: $value = (int) $value; break; } } $value = sprintf('%02d.%02d', floor($value / 60), $value % 60); break; case 'weight': /** * Элемент предназначен для указания веса товара. Вес указывается в килограммах с учетом упаковки. * Формат элемента: положительное число с точностью 0.001, разделитель целой и дробной части — точка. * При указании более высокой точности значение автоматически округляется следующим способом: * — если 4-ый знак после разделителя меньше 5, то 3-й знак сохраняется, а все последующие обнуляются; * — если 4-ый знак после разделителя больше или равен 5, то 3-й знак увеличивается на единицу, а все последующие обнуляются. **/ if (is_object($value)) { switch (get_class($value)) { case 'shopDimensionValue': /** * @var $value shopDimensionValue */ if ($value->type == 'weight') { $value = $value->convert('kg', '%0.3f'); } break; default: $value = floatval($value); break; } } else { $value = floatval($value); } break; case 'dimensions': /** * * Элемент предназначен для указания габаритов товара (длина, ширина, высота) в упаковке. Размеры указываются в сантиметрах. * Формат элемента: три положительных числа с точностью 0.001, разделитель целой и дробной части — точка. Числа должны быть разделены символом «/» без пробелов. * При указании более высокой точности значение автоматически округляется следующим способом: * — если 4-ый знак после разделителя меньше 5, то 3-й знак сохраняется, а все последующие обнуляются; * — если 4-ый знак после разделителя больше или равен 5, то 3-й знак увеличивается на единицу, а все последующие обнуляются. **/ /** * @todo use cm * */ $parsed_value = array(); $class = is_object($value) ? get_class($value) : false; switch ($class) { case 'shopCompositeValue': /** * @var $value shopCompositeValue */ for ($i = 0; $i < 3; $i++) { $value_item = $value[$i]; $class_item = is_object($value_item) ? get_class($value_item) : false; switch ($class_item) { case 'shopDimensionValue': /** * @var $value_item shopDimensionValue */ if ($value_item->type == '3d.length') { $parsed_value[] = $value_item->convert('cm', '%0.4f'); } else { $parsed_value[] = sprintf('%0.4f', (string) $value_item); } break; default: $parsed_value[] = sprintf('%0.4f', (string) $value_item); break; } } break; default: $parsed_value = array_map('floatval', explode(':', preg_replace('@[^\\d\\.,]+@', ':', $value), 3)); break; } foreach ($parsed_value as &$p) { $p = str_replace(',', '.', sprintf('%0.4f', $p)); unset($p); } $value = implode('/', $parsed_value); break; case 'age': /** * @todo * unit="year": 0, 6, 12, 16, 18 * unit="month": 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 */ if (is_object($value)) { switch (get_class($value)) { case 'shopDimensionValue': /** * @var $value shopDimensionValue */ if ($value->type == 'time') { $value = $value->convert('month', false); } break; default: $value = intval($value); break; } } else { /** * @var $value shopDimensionValue */ if (preg_match('@^(year|month)s?:(\\d+)$@', trim($value), $matches)) { $value = array('unit' => $matches[1], 'value' => intval($matches[2])); } else { $value = intval($value); } } if (!is_array($value)) { if ($value > 12) { $value = array('unit' => 'year', 'value' => floor($value / 12)); } else { $value = array('unit' => 'month', 'value' => intval($value)); } } break; case 'country_of_origin': /** * @todo * @see http://partner.market.yandex.ru/pages/help/Countries.pdf */ break; case 'local_delivery_cost': if ($value !== '') { $value = max(0, floatval($value)); } break; case 'days': $value = max(1, intval($value)); break; case 'dataTour': /** * @todo * Даты заездов. * Необязательный элемент. Элемент <offer> может содержать несколько элементов <dataTour>. **/ break; case 'hotel_stars': /** * @todo * Звезды отеля. * Необязательный элемент. **/ break; case 'room': /** * @todo * Тип комнаты (SNG, DBL, ...). * Необязательный элемент. **/ break; case 'meal': /** * @todo * Тип питания (All, HB, ...). * Необязательный элемент. **/ break; case 'date': /** * @todo * Дата и время сеанса. Указываются в формате ISO 8601: YYYY-MM-DDThh:mm. **/ break; case 'hall': /** * @todo * max 512 * Ссылка на изображение с планом зала. **/ //plan - property break; case 'param': $unit = null; $name = ifset($info['source_name'], ''); if ($value instanceof shopDimensionValue) { $unit = $value->unit_name; $value = $value->format('%s'); } elseif (is_array($value)) { $_value = reset($value); if ($_value instanceof shopDimensionValue) { $unit = $_value->unit_name; $values = array(); foreach ($value as $_value) { /** * @var shopDimensionValue $_value */ $values[] = $_value->convert($unit, '%s'); } $value = implode(', ', $values); } else { if (preg_match('@^(.+)\\s*\\(([^\\)]+)\\)\\s*$@', $name, $matches)) { //feature name based unit $unit = $matches[2]; $name = $matches[1]; } $value = implode(', ', $value); } } elseif (preg_match('@^(.+)\\s*\\(([^\\)]+)\\)\\s*$@', $name, $matches)) { //feature name based unit $unit = $matches[2]; $name = $matches[1]; } $value = trim((string) $value); if (in_array($value, array(null, false, ''), true)) { $value = null; } else { $value = array('name' => $name, 'unit' => $unit, 'value' => trim((string) $value)); } break; } $format = ifempty($info['format'], '%s'); if (is_array($value)) { /** * @var $value array */ reset($value); if (key($value) == 0) { foreach ($value as &$item) { $item = str_replace(' ', ' ', $item); $item = str_replace('&', '&', $item); $item = $this->sprintf($format, $item); } unset($item); } if (!in_array($field, array('email', 'picture', 'dataTour', 'additional', 'barcode', 'param', 'related_offer'))) { $value = implode(', ', $value); } } elseif ($value !== null) { /** * @var $value string */ $value = str_replace(' ', ' ', $value); $value = str_replace('&', '&', $value); $value = $this->sprintf($format, $value); } return $value; }
/** * @param $data * @param array $features строка 1 строка 2 * @return string */ public static function getConditionHTML($data, $features = array()) { $result = array(); foreach ($data as $row) { if (empty($row['cond'])) { continue; } if (!empty($row['feature_id'])) { if ($features) { $html = $features[$row['feature_id']]['name']; } else { $html = $row['feature_name']; } } else { if ($row['feature'] == 'price') { $html = _w('Price'); } elseif ($row['feature'] == 'tag') { $html = _w('Tags'); } elseif ($row['feature'] == 'type_id') { $html = _w('Type'); } else { continue; } } $html .= ' '; switch ($row['cond']) { case 'between': $v = explode(',', $row['value']); $html .= '<span class="s-plus-minus">' . ($v[1] > 0 ? '+' : '') . $v[1] . '%<br>' . ($v[0] > 0 ? '+' : '') . $v[0] . '%</span>'; break; case 'contain': $html .= $row['cond'] . ' "' . $row['value'] . '"'; break; case 'same': $html .= _w('matches base product value'); break; case 'notsame': $html .= _w('differs from base product value'); break; case 'all': case 'any': case 'is': if ($row['cond'] == 'any') { $html .= _w('any of selected values (OR)'); } elseif ($row['cond'] == 'all') { $html .= _w('all of selected values (AND)'); } else { $html .= _w($row['cond']); } $html .= ' '; if ($row['feature'] == 'type_id') { $type_model = new shopTypeModel(); $type = $type_model->getById($row['value']); $html .= $type['name']; } else { $feature_values_model = shopFeatureModel::getValuesModel($features ? $features[$row['feature_id']]['type'] : $row['feature_type']); if (strpos($row['value'], ',') !== false) { $value_ids = explode(',', $row['value']); $values = $feature_values_model->getById($value_ids); foreach ($values as &$v) { $v = $v['value']; } unset($v); $html .= implode(', ', $values); } else { $v = $feature_values_model->getById($row['value']); $html .= $v['value']; } } break; } $result[] = $html; } return implode('; ', $result); }