ay( $keyName, array( '_price', '_sale_price' ), true ) ) ? '' : ' AND m.meta_value <> ""'; $query = "{$insert} val_dec ) SELECT post_id, {$selectType} {$keyId}, CAST( REPLACE( meta_value, ',', '.') AS DECIMAL(19,4)) {$from} {$whereMeta} {$addWhere}"; break; case 2: $query = "{$insert} val_int ) SELECT post_id, {$selectType} {$keyId}, CAST( meta_value AS SIGNED ) {$from} {$whereMeta}"; break; case 3: $query = "{$insert} val_int, val_dec ) SELECT post_id, {$selectType} {$keyId}, ROUND( CAST(meta_value AS DECIMAL(19,4))), CAST( meta_value AS DECIMAL( 19,4 ) ) {$from} {$whereMeta}"; break; case 7: case 8: case 9: //$query = $insert . 'meta_dec) SELECT post_id,' . $keyId . ',CAST(meta_value AS DECIMAL(19,4)) ' . $from . $whereMeta; $valsModel->selectMetaValues($keyId); $offset = 0; if (!$isKnownKeyList) { $this->dropIndexes(); } $valsModel->dropIndexes(); $limitQuery = 'SELECT post_id, ' . $selectType . ' meta_value' . $from . $whereMeta . ' ORDER BY meta_id LIMIT '; do { $data = DbWpf::get($limitQuery . $offset . ',' . $limit); if (false === $data) { $this->pushError(DbWpf::getError()); return false; } $j = 0; $lastData = count($data) - 1; $insertValues = ''; foreach ($data as $k => $values) { $valuesArr = ( 7 == $keyType ? $values['meta_value'] : @unserialize($values['meta_value']) ); if (is_array($valuesArr)) { $j++; if (9 == $keyType) { $insValues = $this->saveMetaList($keyId, $values['post_id'], $values['is_var'] , $valuesArr); } else { $insValues = $this->saveMetaArray($keyName, $keyId, $values['post_id'], $values['is_var'], $valuesArr); } if (false === $insValues) { return false; } if (!empty($insValues)) { $insertValues .= $insValues; } } if ($j >= 10 || $k >= $lastData) { if (!empty($insertValues)) { if (!DbWpf::query($insert . ' val_id) VALUES ' . substr($insertValues, 0, -1))) { $this->pushError(DbWpf::getError()); return false; } } $insertValues = ''; $j = 0; } } $offset += $limit; } while ( !empty($data) && ( $maxCountProducts >= $offset ) && ( count($data) >= $limit ) ); $status = 1; if (!$isKnownKeyList) { $this->addIndexes(); } $valsModel->addIndexes(); break; default: $status = 10; break; } if (!empty($query)) { if (DbWpf::query($query)) { $status = 1; } else { $this->pushError(DbWpf::getError()); $this->pushError($query); return false; } } } if ($isAllProducts && !$keysModel->updateKeyData($keyId, array('status' => $status))) { $this->pushError($keysModel->getErrors()); return false; } } if ($isLike) { $keysModel->updateKeyData($parent, array('status' => 1)); } } set_time_limit(300); if (!$this->addIndexes()) { return false; } if (!$this->addCompatibilities($productId, $tempTable)) { return false; } if (!empty($keyRecalc)) { $attrKey = $keysModel->getKeyData('_product_attributes'); $keys = $this->keysArray; $parentKey = $keysModel->getKeyData('attribute_%'); if (!empty($attrKey) && in_array($attrKey['id'], $keyRecalc) && !empty($parentKey)) { $attrKeyId = $attrKey['id']; $parentKeyId = $parentKey['id']; $attributes = DbWpf::get('SELECT key3, id, value FROM @__meta_values WHERE key_id=' . $attrKeyId . " AND key2='is_variation' AND key4=''"); $attrIds = array(); $varIds = array(); foreach ($attributes as $k => $data) { $key = $data['key3']; $id = $data['id']; $attrIds[$key][] = $id; if (1 == $data['value']) { $varIds[$key] = $id; } } foreach ($attrIds as $key => $ids) { set_time_limit(300); $keyName = 'attribute_' . $key; $keyData = $keysModel->getKeyData($keyName, false); if (empty($keyData)) { $keyId = $keysModel->saveKeyData(array_merge($parentKey, array('meta_key' => $keyName, 'meta_like' => 0, 'parent' => $parentKeyId, 'status' => 0))); } else { $keyId = $keyData['id']; } $isNew = false; $valId = $valsModel->getMetaValueId($keyId, '', $keys); if (empty($valId)) { $valsModel->resetMetaValues(); $valId = $valsModel->insertValueId($keyId, $keys, ''); $isNew = true; } if (empty($valId)) { $this->pushError($valsModel->getErrors()); return false; } if (isset($varIds[$key])) { $query = 'DELETE d FROM @__meta_data as d' . ' INNER JOIN ' . ( $tempTable ? $tempTable : ' `#__posts` ' ) . ' as p ON (p.id=d.product_id)' . ' INNER JOIN `#__posts` as pp ON (pp.id=p.post_parent)' . ' LEFT JOIN @__meta_data as mp ON (mp.product_id=pp.id AND mp.key_id=' . $attrKeyId . ' AND mp.val_id=' . $varIds[$key] . ')' . $where . " AND p.post_type='product_variation' AND d.key_id=" . $keyId . ' AND d.is_var=1 AND ISNULL(mp.id)'; } else { $query = 'DELETE d FROM @__meta_data as d' . ' INNER JOIN ' . ( $tempTable ? $tempTable : ' `#__posts` ' ) . ' as p ON (p.id=d.product_id)' . $where . " AND p.post_type='product_variation' AND d.key_id=" . $keyId . ' AND d.is_var=1'; } if (!DbWpf::query($query)) { $this->pushError(DbWpf::getError()); return false; } $query = $insert . 'val_id) SELECT p.id,1,' . $keyId . ',' . $valId . ' FROM ' . ( $tempTable ? $tempTable : ' `#__posts` ' ) . ' as p' . ' INNER JOIN `#__posts` as pp ON (pp.id=p.post_parent)' . ' INNER JOIN @__meta_data as mp ON (mp.product_id=pp.id AND mp.key_id=' . $attrKeyId . ' AND mp.val_id IN (' . implode(',', $ids) . '))' . ' LEFT JOIN @__meta_data as m ON (m.product_id=p.id AND m.key_id=' . $keyId . ')' . $where . " AND p.post_type='product_variation' AND ISNULL(m.id)"; if (DbWpf::query($query)) { if ($isNew && !$keysModel->updateKeyData($keyId, array('status' => 1))) { $this->pushError($keysModel->getErrors()); return false; } } else { $this->pushError(DbWpf::getError()); return false; } } } set_time_limit(300); if (!$valsModel->recalcValuesCount($isAllKeys ? array() : $keyRecalc)) { $this->pushError($valsModel->getErrors()); return false; } } if ($fullRecalc) { $optimizeTables = array( 'meta_data', 'meta_values', 'meta_values_bk' ); foreach ( $optimizeTables as $table ) { DbWpf::query( 'OPTIMIZE TABLE `@__' . $table . '`' ); } $optModel->save('start_indexing', 1); } return true; } public function saveMetaArray( $keyName, $keyId, $productId, $isVar, $data ) { $func = 'saveMetaArray' . $keyName; if (method_exists($this, $func )) { return $this->$func($keyId, $productId, $isVar, $data ); } $insert = ''; $queryValue = '(' . $productId . ',' . $isVar . ',' . $keyId . ','; $keys = $this->keysArray; $valsModel = $this->valsModel; foreach ($data as $k2 => $v2) { $keys['key2'] = $this->getCutKeyValue($k2); if (is_array($v2)) { foreach ($v2 as $k3 => $v3) { $keys['key3'] = $this->getCutKeyValue($k3); if (is_array($v3)) { foreach ($v3 as $k4 => $v4) { $keys['key4'] = $this->getCutKeyValue($k4); $id = $valsModel->insertValueId($keyId, $keys, is_array($v4) ? $this->getCutTextValue(json_encode($v4), false) : $this->getCutTextValue($v4)); if ($id) { $insert .= $queryValue . $id . '),'; } } } else { $id = $valsModel->insertValueId($keyId, $keys, $this->getCutTextValue($v3)); if ($id) { $insert .= $queryValue . $id . '),'; } } } } else { $id = $valsModel->insertValueId($keyId, $keys, $this->getCutTextValue($v2)); if ($id) { $insert .= $queryValue . $id . '),'; } } } return $insert; } public function saveMetaList( $keyId, $productId, $isVar, $data ) { $insert = ''; $queryValue = '(' . $productId . ',' . $isVar . ',' . $keyId . ','; $keys = $this->keysArray; $valsModel = $this->valsModel; foreach ($data as $k => $v) { $id = $valsModel->insertValueId($keyId, $keys, is_array($v) ? $this->getCutTextValue(json_encode($v), false) : $this->getCutTextValue($v)); if ($id) { $insert .= $queryValue . $id . '),'; } } return $insert; } public function saveMetaArray_product_attributes( $keyId, $productId, $isVar, $data ) { $insert = ''; $queryValue = '(' . $productId . ',' . $isVar . ',' . $keyId . ','; $keys = $this->keysArray; $valsModel = $this->valsModel; foreach ($data as $k2 => $v2) { $keys['key3'] = $this->getCutKeyValue($k2); $keys['key2'] = 'is_variation'; $id = $valsModel->insertValueId($keyId, $keys, ( isset($v2['is_variation']) && '1' == $v2['is_variation'] ? 1 : 0 )); if ($id) { $insert .= $queryValue . $id . '),'; } else { $this->pushError($valsModel->getErrors()); return false; } if (is_array($v2) && isset($v2['is_taxonomy']) && ( '1' != $v2['is_taxonomy'] ) && !empty($v2['value'])) { //$keys['key2'] = $this->getCutKeyValue($k2); $values = explode('|', $v2['value']); $keys['key2'] = 'local'; foreach ($values as $value) { $value = trim($value); if (!empty($value)) { $id = $valsModel->insertValueId($keyId, $keys, $this->getCutTextValue($value)); if ($id) { $insert .= $queryValue . $id . '),'; } else { $this->pushError($valsModel->getErrors()); return false; } } } } } return $insert; } public function getCutTextValue( $str, $cut = true ) { if ($this->existMB) { if (mb_strlen($str) > $this->maxTextLength) { return $cut ? mb_substr($str, 0, $this->maxTextLength) : ''; } } else { if (strlen($str) > $this->maxTextLength) { return $cut ? substr($str, 0, $this->maxTextLength) : ''; } } return $str; } public function getCutKeyValue( $str, $cut = true ) { if ($this->existMB) { if (mb_strlen($str) > $this->maxKeyLength) { return $cut ? mb_substr($str, 0, $this->maxKeyLength) : ''; } } else { if (strlen($str) > $this->maxKeyLength) { return $cut ? substr($str, 0, $this->maxKeyLength) : ''; } } return $str; } public function saveMeta_wpf_product_type( $productId, $keyData, $tempTable ) { $keyId = $keyData['id']; $keys = array(); for ($k = $this->maxKeySize; $k >= 2; $k--) { $keys['key' . $k] = ''; } $values = array_flip($this->valsModel->getKeyValueIds($keyId, $keys, true)); $avariable = array('variable', 'single', 'variation'); foreach ($avariable as $value) { if (!isset($values[$value])) { $keys['key_id'] = $keyId; $keys['value'] = $value; $values[$value] = $this->valsModel->insert($keys); if (!$values[$value]) { return false; } } } $query = 'INSERT INTO @__meta_data (product_id, is_var, key_id, val_id)' . ' SELECT DISTINCT p.id, ' . ( $tempTable ? 'p.is_var,' : "IF(p.post_type='product_variation',1,0) as is_var," ) . $keyId . ',' . ' CASE WHEN p.post_parent>0 THEN ' . $values['variation'] . " WHEN EXISTS(SELECT 1 FROM `#__posts` as pa WHERE pa.post_parent=p.ID AND pa.post_type='product_variation' LIMIT 1) THEN " . $values['variable'] . ' ELSE ' . $values['single'] . ' END' . ' FROM ' . ( $tempTable ? $tempTable : ' `#__posts` ' ) . ' as p' . ' WHERE ' . ( $tempTable ? '1=1' : " p.post_type IN ('product','product_variation') AND p.post_status IN('publish', 'private')" ) . ( empty($productId) ? '' : ' AND p.id=' . $productId ); if (!DbWpf::query($query)) { $this->pushError(DbWpf::getError()); return false; } return true; } public function optimizeMetaTables() { $optimizeTables = array( 'meta_data', 'meta_values', 'meta_values_bk' ); foreach ( $optimizeTables as $table ) { if (!DbWpf::query('OPTIMIZE TABLE `@__' . $table . '`')) { $this->pushError(DbWpf::getError()); return false; } } return true; } public function addCompatibilities( $productId, $tempTable ) { if (class_exists( 'WC_Measurement_Price_Calculator' )) { $keysModel = FrameWpf::_()->getModule('meta')->getModel('meta_keys'); $keyData = $keysModel->getKeyData('_price', false); $keyPrice = empty($keyData) ? false : $keyData['id']; $keyData = $keysModel->getKeyData('_sale_price', false); $keySalePrice = empty($keyData) ? false : $keyData['id']; if (!$keyPrice || !$keySalePrice) { return true; } $isOne = false; if ($tempTable) { $ids = DbWpf::get( 'SELECT id FROM ' . $tempTable, 'col'); } else { $product = wc_get_product($productId); if (!$product) { return true; } $ids = array($productId); if ($product->get_type() == 'variable') { $ids = array_merge($ids, $product->get_children()); } else { $isOne = true; } } if (empty($ids)) { return true; } $query = 'UPDATE @__meta_data SET val_dec='; $whPrice = ' WHERE key_id=' . $keyPrice . ' AND product_id='; $whSalePrice = ' WHERE key_id=' . $keySalePrice . ' AND product_id='; foreach ($ids as $id) { if (!$isOne) { $product = wc_get_product( $id ); if (!$product) { return true; } } $price = ''; $salePrice = ''; $settings = new \WC_Price_Calculator_Settings( $product ); // user-defined calculator with pricing rules enabled (nothing needs to be changed for user-defined calculators with no pricing rules) if ( $settings->pricing_rules_enabled() ) { $price = $settings->get_pricing_rules_maximum_price(); $salePrice = $settings->pricing_rules_is_on_sale() ? $settings->get_pricing_rules_maximum_sale_price() : ''; // quantity calculator with per unit pricing } elseif ( $settings->is_quantity_calculator_enabled() && \WC_Price_Calculator_Product::pricing_per_unit_enabled( $product ) ) { $measurement = null; // for variable products we must synchronize price levels to our per unit price if ( $product->is_type( 'variable' ) ) { // synchronize to the price per unit pricing \WC_Price_Calculator_Product::variable_product_sync( $product, $settings ); // save the original price and remove the filter that we're currently within, to avoid an infinite loop $price = $product->get_variation_price( 'min' ); $salePrice = $product->get_variation_sale_price( 'min' ); // restore the original values \WC_Price_Calculator_Product::variable_product_unsync( $product ); // all other product types } else { $measurement = \WC_Price_Calculator_Product::get_product_measurement( $product, $settings ); if ( $measurement ) { $measurement->set_unit( $settings->get_pricing_unit() ); $measurementValue = $measurement ? $measurement->get_value() : null; if ( $measurement && $measurementValue ) { // convert to price per unit $price = floatval($product->get_price( 'edit' )) / $measurementValue; $salePrice = floatval($product->get_sale_price( 'edit' )) / $measurementValue; } } } } if (!empty($price)) { $q = $query . round($price, 4) . $whPrice . $id; if (!DbWpf::query($q)) { $this->pushError(DbWpf::getError()); $this->pushError($q); return false; } } if (!empty($salePrice)) { $q = $query . round($salePrice, 4) . $whSalePrice . $id; if (!DbWpf::query($q)) { $this->pushError(DbWpf::getError()); $this->pushError($q); return false; } } } } return true; } public function hasEmojis( $string ) { $emojis_regex = '/[\x{1F600}-\x{1F64F}\x{2700}-\x{27BF}\x{1F680}-\x{1F6FF}\x{24C2}-\x{1F251}\x{1F30D}-\x{1F567}\x{1F900}-\x{1F9FF}\x{1F300}-\x{1F5FF}\x{1FA70}-\x{1FAF6}]/u'; preg_match($emojis_regex, $string, $matches); return ( empty($matches) ? false : true ); } }