Ejemplo n.º 1
0
 public function execute()
 {
     $search = new shopIndexSearch();
     if (waRequest::param(0)) {
         $search->indexProduct(waRequest::param(0));
     } else {
         $product_model = new shopProductModel();
         $n = $product_model->countAll();
         $limit = 100;
         $i = 0;
         $product_model->exec("TRUNCATE TABLE shop_search_index");
         while ($i < $n) {
             echo $i . "/" . $n . "\n";
             $sql = "SELECT p.*, t.name type_name FROM " . $product_model->getTableName() . " p\n                LEFT JOIN shop_type t ON p.type_id = t.id\n                LIMIT " . $i . ", " . $limit;
             $products = $product_model->query($sql)->fetchAll('id');
             $product_ids = array_keys($products);
             // get skus
             $sql = "SELECT * FROM shop_product_skus WHERE product_id IN (i:id)";
             $data = $product_model->query($sql, array('id' => $product_ids));
             foreach ($data as $row) {
                 $products[$row['product_id']]['skus'][] = $row;
             }
             // get tags
             $sql = "SELECT pt.product_id, t.name FROM shop_product_tags pt\n                JOIN shop_tag t ON pt.tag_id = t.id WHERE pt.product_id IN (i:id)";
             $data = $product_model->query($sql, array('id' => $product_ids));
             foreach ($data as $row) {
                 $products[$row['product_id']]['tags'][] = $row['name'];
             }
             // get features
             $sql = "SELECT pf.product_id, fv.value FROM shop_product_features pf\n                JOIN shop_feature f ON pf.feature_id = f.id AND f.type = 'varchar'\n                JOIN shop_feature_values_varchar fv ON pf.feature_value_id = fv.id WHERE pf.product_id IN (i:id)";
             $data = $product_model->query($sql, array('id' => $product_ids));
             foreach ($data as $row) {
                 $products[$row['product_id']]['features'][] = $row['value'];
             }
             $sql = "SELECT pf.product_id, fv.value FROM shop_product_features pf\n                JOIN shop_feature f ON pf.feature_id = f.id AND f.type = 'double'\n                JOIN shop_feature_values_double fv ON pf.feature_value_id = fv.id WHERE pf.product_id IN (i:id)";
             $data = $product_model->query($sql, array('id' => $product_ids));
             foreach ($data as $row) {
                 $products[$row['product_id']]['features'][] = $row['value'];
             }
             $sql = "SELECT pf.product_id, fv.value FROM shop_product_features pf\n                JOIN shop_feature f ON pf.feature_id = f.id AND f.type = 'text'\n                JOIN shop_feature_values_text fv ON pf.feature_value_id = fv.id WHERE pf.product_id IN (i:id)";
             $data = $product_model->query($sql, array('id' => $product_ids));
             foreach ($data as $row) {
                 $products[$row['product_id']]['features'][] = $row['value'];
             }
             // get skus
             $sql = "SELECT * FROM shop_product_skus WHERE product_id IN (i:id)";
             $data = $product_model->query($sql, array('id' => $product_ids));
             foreach ($data as $row) {
                 $products[$row['product_id']]['skus'][] = $row;
             }
             foreach ($products as $p) {
                 $search->indexProduct($p, false);
             }
             $i += $limit;
         }
     }
 }
 protected function step()
 {
     $limit = 10;
     $products = $this->product_model->select('id')->order('id')->limit("{$this->data['offset']}, {$limit}")->fetchAll();
     foreach ($products as $p) {
         $this->data['offset'] += 1;
         try {
             // DO something with product $p
             $this->search_index->indexProduct($p['id']);
         } catch (Exception $e) {
             $this->error($e->getMessage());
         }
     }
     sleep(1);
 }
Ejemplo n.º 3
0
 /**
  * @return shopSearchWordModel
  */
 protected function getWordModel()
 {
     if (!self::$word_model) {
         self::$word_model = new shopSearchWordModel();
     }
     return self::$word_model;
 }
 protected function searchPrepare($query, $auto_title = true)
 {
     $query = urldecode($query);
     $i = $offset = 0;
     $query_parts = array();
     while (($j = strpos($query, '&', $offset)) !== false) {
         // escaped &
         if ($query[$j - 1] != '\\') {
             $query_parts[] = str_replace('\\&', '&', substr($query, $i, $j - $i));
             $i = $j + 1;
         }
         $offset = $j + 1;
     }
     $query_parts[] = str_replace('\\&', '&', substr($query, $i));
     $model = $this->getModel();
     $title = array();
     foreach ($query_parts as $part) {
         if (!($part = trim($part))) {
             continue;
         }
         $parts = preg_split("/(\\\$=|\\^=|\\*=|==|!=|>=|<=|=|>|<)/uis", $part, 2, PREG_SPLIT_DELIM_CAPTURE);
         if ($parts) {
             if ($parts[0] == 'category_id') {
                 if ($parts[1] == '==' && $parts[2] == 'null') {
                     $this->where[] = 'p.category_id IS NULL';
                     $title[] = 'without category';
                 } else {
                     $this->addJoin('shop_category_products', null, ':table.category_id' . $this->getExpression($parts[1], $parts[2]));
                     $title[] = "category_id " . $parts[1] . $parts[2];
                 }
             } elseif ($parts[0] == 'query') {
                 $search = new shopIndexSearch();
                 $word_ids = $search->getWordIds($parts[2], true);
                 if ($word_ids) {
                     $this->joins[] = array('table' => 'shop_search_index', 'alias' => 'si');
                     $this->where[] = 'si.word_id IN (' . implode(",", $word_ids) . ')';
                     if (count($word_ids) > 1) {
                         $this->fields[] = "SUM(si.weight) AS weight";
                         $this->order_by = 'weight DESC';
                         $this->group_by = 'p.id';
                     } else {
                         $this->fields[] = "si.weight";
                         $this->order_by = 'si.weight DESC';
                     }
                 } elseif ($parts[2]) {
                     $this->where[] = '0';
                 }
                 $this->prepared = true;
                 // if not found try find by name
                 if (!$this->count()) {
                     $this->count = null;
                     $this->joins = $this->where = $this->having = $this->fields = array();
                     if ($this->is_frontend) {
                         if ($this->filtered) {
                             $this->filtered = false;
                         }
                         $this->frontendConditions();
                     }
                     $this->order_by = 'p.create_datetime DESC';
                     $this->group_by = null;
                     $q = $model->escape($parts[2], 'like');
                     $this->addJoin('shop_product_skus', null, "(p.name LIKE '%" . $q . "%' OR :table.name LIKE '%" . $q . "%' OR :table.sku LIKE '%" . $q . "%')");
                     $this->group_by = 'p.id';
                     return;
                 } elseif ($word_ids) {
                     $result = $this->getProducts('*', 0, 1);
                     $p = array_shift($result);
                     $w = str_replace(',', '.', 0.3 * $p['weight']);
                     if (count($word_ids) > 1) {
                         $this->having[] = 'SUM(si.weight) >= ' . $w;
                     } else {
                         $this->where[] = 'weight >= ' . $w;
                     }
                     $this->count = null;
                 }
                 $title[] = $parts[0] . $parts[1] . $parts[2];
             } elseif ($parts[0] == 'tag') {
                 $tag_model = $this->getModel('tag');
                 if (strpos($parts[2], '||') !== false) {
                     $tags = explode('||', $parts[2]);
                     $tag_ids = $tag_model->getIds($tags);
                 } else {
                     $sql = "SELECT id FROM " . $tag_model->getTableName() . " WHERE name" . $this->getExpression($parts[1], $parts[2]);
                     $tag_ids = $tag_model->query($sql)->fetchAll(null, true);
                 }
                 if ($tag_ids) {
                     $this->addJoin('shop_product_tags', null, ":table.tag_id IN ('" . implode("', '", $tag_ids) . "')");
                 } else {
                     $this->where[] = "0";
                 }
             } elseif ($model->fieldExists($parts[0])) {
                 $title[] = $parts[0] . $parts[1] . $parts[2];
                 $this->where[] = 'p.' . $parts[0] . $this->getExpression($parts[1], $parts[2]);
             } elseif ($parts[1] == '=') {
                 $code = $parts[0];
                 $is_value_id = false;
                 if (substr($code, -9) == '.value_id') {
                     $code = substr($code, 0, -9);
                     $is_value_id = true;
                 }
                 $feature_model = $this->getModel('feature');
                 $f = $feature_model->getByCode($code);
                 if ($f) {
                     if ($is_value_id) {
                         $value_id = $parts[2];
                     } else {
                         $values_model = $feature_model->getValuesModel($f['type']);
                         $value_id = $values_model->getValueId($f['id'], $parts[2]);
                     }
                     $this->addJoin('shop_product_features', null, ':table.feature_id = ' . $f['id'] . ' AND :table.feature_value_id = ' . (int) $value_id);
                     $this->group_by = 'p.id';
                 }
             }
         }
     }
     if ($title) {
         $title = implode(', ', $title);
         // Strip slashes from search title.
         $bs = '\\\\';
         $title = preg_replace("~{$bs}(_|%|&|{$bs})~", '\\1', $title);
     }
     if ($auto_title) {
         $this->addTitle($title, ' ');
     }
 }
Ejemplo n.º 5
0
 /**
  * Saves product data to database.
  *
  * @param array $data
  * @return bool Whether saved successfully
  */
 public function save($data = array(), $validate = true, &$errors = array())
 {
     $result = false;
     $id = $this->getId();
     $search = new shopIndexSearch();
     foreach ($data as $name => $value) {
         // name have to be not empty
         if ($name == 'name' && !$value) {
             $value = _w('New product');
         }
         // url have to be not empty
         if ($name == 'url' && !$value && $id) {
             $value = $id;
         }
         $this->__set($name, $value);
     }
     if ($this->is_dirty) {
         $product = array();
         $id_changed = !empty($this->is_dirty['id']);
         foreach ($this->is_dirty as $field => $v) {
             if ($this->model->fieldExists($field)) {
                 $product[$field] = $this->data[$field];
                 unset($this->is_dirty[$field]);
             }
         }
         if ($id && !$id_changed) {
             if (!isset($product['edit_datetime'])) {
                 $product['edit_datetime'] = date('Y-m-d H:i:s');
             }
             if (isset($product['type_id'])) {
                 $this->model->updateType($id, $product['type_id']);
                 unset($product['type_id']);
             }
             if ($this->model->updateById($id, $product)) {
                 $this->saveData($errors);
                 $search->onUpdate($id);
                 $this->is_dirty = array();
                 $result = true;
             }
         } else {
             if (!isset($product['contact_id'])) {
                 $product['contact_id'] = wa()->getUser()->getId();
             }
             if (!isset($product['create_datetime'])) {
                 $product['create_datetime'] = date('Y-m-d H:i:s');
             }
             if (!isset($product['currency'])) {
                 $product['currency'] = wa('shop')->getConfig()->getCurrency();
             }
             if ($id = $this->model->insert($product)) {
                 $this->data['id'] = $id;
                 // update empty url by ID
                 if (empty($product['url'])) {
                     $this->data['url'] = $id;
                     $this->model->updateById($id, array('url' => $this->data['url']));
                 }
                 $this->saveData();
                 $search->onAdd($id);
                 $this->is_dirty = array();
                 if (!empty($this->data['type_id'])) {
                     $type_model = new shopTypeModel();
                     // increment on +1
                     $type_model->incCounters(array($this->data['type_id'] => 1));
                 }
                 $result = true;
             }
         }
     } else {
         $result = true;
     }
     $params = array('data' => $this->getData(), 'instance' => &$this);
     /**
      * Plugin hook for handling product entry saving event
      * @event product_save
      *
      * @param array [string]mixed $params
      * @param array [string][string]mixed $params['data'] raw product data fields (see shop_product table description and related storages)
      * @param array [string][string]int $data['data']['id'] product ID
      * @param array [string]shopProduct $params['instance'] current shopProduct entry instance (avoid recursion)
      * @return void
      */
     wa()->event('product_save', $params);
     return $result;
 }