File "meta.php"
Full Path: /home/vantageo/public_html/cache/cache/.wp-cli/wp-content/plugins/woo-product-filter/modules/meta/models/meta.php
File size: 28.43 KB
MIME-type: text/x-php
Charset: utf-8
<?php
class MetaModelWpf extends ModelWpf {
private $maxTextLength = 150;
private $maxKeyLength = 32;
public $maxKeySize = 4;
private $valsModel = array();
private $keysArray = array();
private $existMB = false;
public $metaVarSuf = '#wpfvar#';
public $startLockLimit = 20;
public function __construct() {
$this->existMB = function_exists('mb_substr');
$this->_setTbl('meta_data');
$this->setIndexes(array(
'product_key' => 'INDEX `product_key` (`product_id`, `key_id`)',
'key_id' => 'INDEX `key_id` (`key_id`)',
'key_dec' => 'INDEX `key_dec` (`val_dec`, `key_id`)',
'key_int' => 'INDEX `key_int` (`val_int`, `key_id`)',
'val_id' => 'INDEX `val_id` (`val_id`)'
));
}
private function setKeys() {
$this->keysArray = array();
$len = $this->maxKeySize;
for ($k = 2; $k <= $len; $k++) {
$this->keysArray['key' . $k] = '';
}
}
public function recalcMetaValues( $productId = 0, $params = array() ) {
$result = $this->doRecalcMetaValues($productId, $params);
if (!$result && FrameWpf::_()->getModule('options')->getModel()->get('logging') == 1) {
$logger = wc_get_logger();
if ($logger) {
$logger->warning(UtilsWpf::jsonEncode($this->getErrors()), array('source' => 'wpf-meta-indexing'));
}
}
return $result;
}
public function doRecalcMetaValues( $productId, $params ) {
if (!empty($productId) && !is_numeric($productId)) {
return false;
}
$isAllProducts = empty($productId);
$isAllKeys = empty($params);
$fullRecalc = $isAllProducts && $isAllKeys;
$keysModel = FrameWpf::_()->getModule('meta')->getModel('meta_keys');
$optModel = FrameWpf::_()->getModule('options')->getModel();
if ($fullRecalc && $optModel->get('start_indexing') == 2) {
if (microtime(true) - $optModel->getChanged('start_indexing') > $this->startLockLimit * 60) {
$optModel->save('start_indexing', 1);
} else {
$this->pushError('Wait. The calculation is already running ...');
return false;
}
}
if ($fullRecalc || $optModel->get('start_indexing') != 1) {
if (!$keysModel->controlFiltersMetaKeys(true)) {
$this->pushError($keysModel->getErrors());
return false;
}
//$optModel->save('start_indexing', 1);
/*if (!$keysModel->resetLockedKeys()) {
$this->pushError($keysModel->getErrors());
return false;
}*/
}
if ($fullRecalc) {
$optModel->save('start_indexing', 2);
}
if ($isAllKeys) {
$params['parent'] = 0;
}
$keys = $keysModel->getKeysForRecalc($params);
if (count($keys) == 0) {
return true;
}
$this->addIndexes();
$whereProduct = '';
if (!$isAllProducts) {
$product = wc_get_product($productId);
if (!$product) {
return false;
}
$ids = $product->get_type() == 'variable' ? $product->get_children() : array();
$ids[] = $productId;
$productList = ( count($ids) > 1 ? ' IN (' . implode(',', $ids) . ')' : '=' . $productId );
$whereProduct = 'product_id' . $productList;
}
$isKnownKeyList = true;
$whereKeys = $whereProduct;
if (!$isAllKeys) {
$list = '';
foreach ($keys as $key) {
$list .= $key['id'] . ',';
if (!empty($key['meta_like'])) {
$isKnownKeyList = false;
}
}
if (!empty($list)) {
$whereKeys .= ( $isAllProducts ? '' : ' AND ' ) . ' key_id IN (' . substr($list, 0, -1) . ')';
}
}
if ($isKnownKeyList) {
if ($isAllProducts) {
$this->dropIndexes();
}
if (!$this->delete($whereKeys)) {
return false;
}
}
$valsModel = FrameWpf::_()->getModule('meta')->getModel('meta_values');
$this->valsModel = $valsModel;
$from = ' FROM `#__postmeta` as m INNER JOIN `#__posts` as p ON (p.id=m.post_id)';
$where = " WHERE p.post_type IN ('product', 'product_variation') AND p.post_status IN('publish','private')" . ( $isAllProducts ? '' : ' AND p.id' . $productList );
$tempTable = false;
$maxCntTemp = 0;
if ($isAllProducts) {
$tempTable = FrameWpf::_()->getModule('woofilters')->createTemporaryTable('wpf_meta_calc', "SELECT id, post_parent, post_type, IF(p.post_type='product_variation',1,0) as is_var, 0 as for_ins FROM `#__posts` as p" . $where);
$from = ' FROM `#__postmeta` as m FORCE INDEX (meta_key) INNER JOIN ' . $tempTable . ' as p ON (p.id=m.post_id)';
$where = ' WHERE 1=1';
$maxCntTemp = DbWpf::get( 'SELECT count(*) FROM ' . $tempTable, 'one');
}
$insert = 'INSERT INTO `@__meta_data` (product_id, is_var, key_id, ';
$maxKeySize = $this->maxKeySize;
$maxTextLength = $this->maxTextLength;
$this->setKeys();
$keyRecalc = array();
$limit = 1000;
$maxCountProducts = DbWpf::get('SELECT count(*) FROM `#__posts` as p ' . $where, 'one');
if (false === $maxCountProducts) {
$this->pushError(DbWpf::getError());
return false;
}
$maxCountProducts += 100;
DbWpf::query('SET session wait_timeout=600');
foreach ($keys as $key) {
$keyName = $key['meta_key'];
$isLike = !empty($key['meta_like']);
$parent = $key['id'];
if ($isLike) {
$keysData = DbWpf::get('SELECT DISTINCT meta_key' . ( $isAllProducts ? ' FROM `#__postmeta` as m FORCE INDEX (meta_key) WHERE ' : $from . $where . ' AND ' ) . " m.meta_key LIKE '" . $keyName . "'", 'col');
if (false === $keysData) {
$this->pushError(DbWpf::getError());
return false;
}
if (empty($keysData) && $isAllProducts) {
if (!$keysModel->updateKeyData($key['id'], array('status' => 5))) {
$this->pushError($keysModel->getErrors());
return false;
};
continue;
}
} else {
$keysData = array($keyName);
}
foreach ($keysData as $keyName) {
set_time_limit(300);
if ($this->hasEmojis($keyName)) {
continue;
}
$keyName = str_replace("'", '', $keyName);
$keyData = $keysModel->getKeyData($keyName, true);
if ($isLike) {
if (empty($keyData)) {
$id = $keysModel->saveKeyData(array_merge($key, array('meta_key' => $keyName, 'meta_like' => 0, 'parent' => $key['id'], 'status' => 0)));
if ($id) {
$keyData['id'] = $id;
} else {
$this->pushError($keysModel->getErrors());
return false;
}
}
}
if (empty($keyData)) {
continue;
}
$keyId = $keyData['id'];
$status = empty($keyData['status']) ? 0 : $keyData['status'];
$needLock = $isAllProducts;
$needRecalc = false;
if (2 == $status) {
if ($keysModel->isOldLock($keyData['lock_duration'])) {
if (!$isAllProducts) {
$needRecalc = true;
}
} else {
continue;
}
}
//$keyMode = $key['meta_mode'];
$keyType = DispatcherWpf::applyFilters('getMetaFieldType', $key['meta_type'], $keyName);
if (false === $keyType) {
continue;
}
if ($keyType != $key['meta_type'] && $isAllProducts) {
$needRecalc = true;
}
if ($needRecalc || $needLock) {
if (!$keysModel->updateKeyData($keyId, array('meta_type' => $keyType, 'status' => $needLock ? 2 : 0))) { // set new lock
$this->pushError($keysModel->getErrors());
return false;
}
}
if (!$isKnownKeyList && !$this->delete('key_id=' . $keyId . ( $isAllProducts ? '' : ' AND ' . $whereProduct ))) {
return false;
}
$isMetaVar = strpos($keyName, $this->metaVarSuf) != false;
$keyNameVar = str_replace($this->metaVarSuf, '', $keyName);
if (empty($keyData['taxonomy'])) {
if (!DbWpf::query("UPDATE @__meta_keys SET taxonomy='" . $keyNameVar . "' WHERE id=" . $keyId)) {
return false;
}
}
$calculated = false;
$func = 'saveMeta' . $keyName;
if (method_exists($this, $func )) {
if ($this->$func($productId, $keyData, $tempTable)) {
$calculated = true;
$status = 1;
} else {
return false;
}
}
if (!$calculated) {
$query = '';
$whereMeta = $where . " AND m.meta_key='" . $keyName . "'";
if ($isMetaVar) {
$keyDataVar = $keysModel->getKeyData($keyNameVar, true);
if (empty($keyDataVar)) {
continue;
}
} else {
$keyRecalc[] = $keyId;
}
$selectType = ( $tempTable ? 'p.is_var,' : "IF(p.post_type='product_variation',1,0) as is_var," );
switch ($keyType) {
case 0:
$join = ' JOIN @__meta_values as v ON (v.key_id=' . ( $isMetaVar ? $keyDataVar['id'] : $keyId ) . ' AND v.value=' . ( $isMetaVar || !$isAllProducts ? 'CAST(meta_value AS CHAR(' . $maxTextLength . '))' : 'm.meta_value' );
for ($k = 2; $k <= $maxKeySize; $k++) {
$join .= ' AND v.key' . $k . "=''";
}
$join .= ')';
if ($isMetaVar) {
$query = $insert . 'val_id) SELECT DISTINCT post_parent,0,' . $keyId . ',v.id' . $from . ' INNER ' . $join . $where . " AND m.meta_key='" . $keyNameVar . "' AND p.post_type='product_variation'";
} else {
set_time_limit(300);
DbWpf::query('SET session wait_timeout=600');
if ($isAllProducts) {
$query = 'SELECT m.meta_id as id, m.post_id, ' . $selectType . ' CAST(meta_value AS CHAR(' . $maxTextLength . ')) as meta_value' .
$from . $whereMeta . ( strpos($keyName, 'attribute_') === 0 ? '' : " AND m.meta_value!=''" );
$tempTableAttr = FrameWpf::_()->getModule('woofilters')->createTemporaryTable('wpf_meta_calc_attr', $query);
$query = 'INSERT IGNORE INTO @__meta_values (key_id, value)' .
' SELECT DISTINCT ' . $keyId . ',m.meta_value' .
' FROM ' . $tempTableAttr . ' m LEFT ' . $join .
' WHERE ISNULL(v.id)';
} else {
$query = 'INSERT IGNORE INTO @__meta_values (key_id, value)' .
' SELECT DISTINCT ' . $keyId . ',CAST(meta_value AS CHAR(' . $maxTextLength . '))' .
$from . ' LEFT ' . $join .
$whereMeta . ' AND ISNULL(v.id)' . ( strpos($keyName, 'attribute_') === 0 ? '' : " AND m.meta_value!=''" );
}
if (DbWpf::query($query)) {
if ($isAllProducts) {
$query = $insert . 'val_id) SELECT post_id, is_var, ' . $keyId . ',v.id FROM ' . $tempTableAttr . ' as m INNER ' . $join;
} else {
$query = $insert . 'val_id) SELECT post_id,' . $selectType . $keyId . ',v.id' . $from . ' INNER ' . $join . $whereMeta;
}
/*if ($isAllProducts && $maxCntTemp > 8000) {
$cntValues = DbWpf::get( 'SELECT count(*) FROM `@__meta_values` WHERE key_id=' . $keyId, 'one');
if ($cntValues > 50) {
if ($cntValues < 5000 || $maxCntTemp < 25000) {
$q = 'UPDATE ' . $tempTable . ' SET for_ins=0';
if (!DbWpf::query($q)) {
$this->pushError(DbWpf::getError());
$this->pushError($q);
return false;
}
$bulkLimit = 5000;
$ins = 0;
do {
set_time_limit(300);
$cnt = DbWpf::query('UPDATE ' . $tempTable . ' SET for_ins=1 WHERE for_ins=0 LIMIT ' . $bulkLimit, true);
if (0 == $cnt) {
break;
}
$ins += $cnt;
DbWpf::query('SET session wait_timeout=600');
$q = $query . ' AND p.for_ins=1';
if (!DbWpf::query($q)) {
$this->pushError(DbWpf::getError());
$this->pushError($q);
return false;
}
if (!DbWpf::query('UPDATE ' . $tempTable . ' SET for_ins=2 WHERE for_ins=1')) {
$this->pushError(DbWpf::getError());
$this->pushError($q);
return false;
}
} while ( $maxCntTemp >= $ins );
}
$status = 1;
$query = '';
}
}*/
} else {
$this->pushError(DbWpf::getError());
return false;
}
}
break;
case 1:
$addWhere = ( in_array( $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 );
}
}