| 1 |
<?php |
| 2 |
|
| 3 |
namespace FluentCart\App\Models\BatchQuery; |
| 4 |
|
| 5 |
use FluentCart\Framework\Database\Orm\Model; |
| 6 |
|
| 7 |
class Batch implements BatchInterface |
| 8 |
{ |
| 9 |
|
| 10 |
protected $db; |
| 11 |
|
| 12 |
public function __construct() |
| 13 |
{ |
| 14 |
global $wpdb; |
| 15 |
$this->db = $wpdb; |
| 16 |
} |
| 17 |
|
| 18 |
public function update(Model $table, array $values, ?string $index = null, bool $raw = false) |
| 19 |
{ |
| 20 |
$final = []; |
| 21 |
$ids = []; |
| 22 |
|
| 23 |
if (!count($values)) { |
| 24 |
return false; |
| 25 |
} |
| 26 |
|
| 27 |
if (!isset($index) || empty($index)) { |
| 28 |
$index = $table->getKeyName(); |
| 29 |
} |
| 30 |
|
| 31 |
$driver = $table->getConnection()->getName(); |
| 32 |
foreach ($values as $key => $val) { |
| 33 |
$ids[] = $val[$index]; |
| 34 |
|
| 35 |
if ($table->usesTimestamps()) { |
| 36 |
$updatedAtColumn = $table->getUpdatedAtColumn(); |
| 37 |
|
| 38 |
if (!isset($val[$updatedAtColumn])) { |
| 39 |
$val[$updatedAtColumn] = gmdate($table->getDateFormat()); |
| 40 |
} |
| 41 |
} |
| 42 |
|
| 43 |
foreach (array_keys($val) as $field) { |
| 44 |
if ($field !== $index) { |
| 45 |
// If increment / decrement |
| 46 |
if (gettype($val[$field]) == 'array') { |
| 47 |
|
| 48 |
$isMathOperator = true; |
| 49 |
// If array has two values |
| 50 |
if (!array_key_exists(0, $val[$field]) || !array_key_exists(1, $val[$field])) { |
| 51 |
$isMathOperator = false; |
| 52 |
|
| 53 |
} |
| 54 |
|
| 55 |
if($isMathOperator){ |
| 56 |
// Check first value |
| 57 |
if (gettype($val[$field][0]) != 'string' || !in_array($val[$field][0], ['+', '-', '*', '/', '%'])) { |
| 58 |
throw new \TypeError('First value in Increment/Decrement array needs to be a string and a math operator (+, -, *, /, %)'); |
| 59 |
} |
| 60 |
// Check second value |
| 61 |
if (!is_numeric($val[$field][1])) { |
| 62 |
throw new \TypeError('Second value in Increment/Decrement array needs to be numeric'); |
| 63 |
} |
| 64 |
// Increment / decrement |
| 65 |
if (Common::disableBacktick($driver)) { |
| 66 |
$value = $field . $val[$field][0] . $val[$field][1]; |
| 67 |
} else { |
| 68 |
$value = '`' . $field . '`' . $val[$field][0] . $val[$field][1]; |
| 69 |
} |
| 70 |
} |
| 71 |
else{ |
| 72 |
$value = "'" . json_encode($val[$field]) . "'"; |
| 73 |
} |
| 74 |
|
| 75 |
} else { |
| 76 |
// Only update |
| 77 |
$finalField = $raw ? Common::mysqlEscape($val[$field]) : "'" . Common::mysqlEscape($val[$field]) . "'"; |
| 78 |
$value = (is_null($val[$field]) ? 'NULL' : $finalField); |
| 79 |
} |
| 80 |
|
| 81 |
if (Common::disableBacktick($driver)) |
| 82 |
$final[$field][] = 'WHEN ' . $index . ' = \'' . $val[$index] . '\' THEN ' . $value . ' '; |
| 83 |
else |
| 84 |
$final[$field][] = 'WHEN `' . $index . '` = \'' . $val[$index] . '\' THEN ' . $value . ' '; |
| 85 |
} |
| 86 |
} |
| 87 |
} |
| 88 |
|
| 89 |
if (Common::disableBacktick($driver)) { |
| 90 |
|
| 91 |
$cases = ''; |
| 92 |
foreach ($final as $k => $v) { |
| 93 |
$cases .= '"' . $k . '" = (CASE ' . implode("\n", $v) . "\n" |
| 94 |
. 'ELSE "' . $k . '" END), '; |
| 95 |
} |
| 96 |
|
| 97 |
$query = "UPDATE \"" . $this->getFullTableName($table) . '" SET ' . substr($cases, 0, -2) . " WHERE \"$index\" IN('" . implode("','", $ids) . "');"; |
| 98 |
|
| 99 |
} else { |
| 100 |
|
| 101 |
$cases = ''; |
| 102 |
foreach ($final as $k => $v) { |
| 103 |
$cases .= '`' . $k . '` = (CASE ' . implode("\n", $v) . "\n" |
| 104 |
. 'ELSE `' . $k . '` END), '; |
| 105 |
} |
| 106 |
|
| 107 |
$query = "UPDATE `" . $this->getFullTableName($table) . "` SET " . substr($cases, 0, -2) . " WHERE `$index` IN(" . '"' . implode('","', $ids) . '"' . ");"; |
| 108 |
|
| 109 |
} |
| 110 |
|
| 111 |
return $this->db->query($query); |
| 112 |
|
| 113 |
} |
| 114 |
|
| 115 |
/** |
| 116 |
* Update multiple rows |
| 117 |
* @param Model $table |
| 118 |
* @param array $values |
| 119 |
* @param string $index |
| 120 |
* @param string|null $index2 |
| 121 |
* @param bool $raw |
| 122 |
* @return bool|int |
| 123 |
* |
| 124 |
* @desc |
| 125 |
* Example |
| 126 |
* $table = 'users'; |
| 127 |
* $value = [ |
| 128 |
* [ |
| 129 |
* 'id' => 1, |
| 130 |
* 'status' => 'active', |
| 131 |
* 'nickname' => 'Mohammad' |
| 132 |
* ] , |
| 133 |
* [ |
| 134 |
* 'id' => 5, |
| 135 |
* 'status' => 'deactive', |
| 136 |
* 'nickname' => 'Ghanbari' |
| 137 |
* ] , |
| 138 |
* ]; |
| 139 |
* $index = 'id'; |
| 140 |
* $index2 = 'user_id'; |
| 141 |
* |
| 142 |
*/ |
| 143 |
public function updateWithTwoIndex(Model $table, array $values, ?string $index = null, ?string $index2 = null, bool $raw = false) |
| 144 |
{ |
| 145 |
$final = []; |
| 146 |
$ids = []; |
| 147 |
$driver = $table->getConnection()->getDriverName(); |
| 148 |
|
| 149 |
if (!count($values)) { |
| 150 |
return false; |
| 151 |
} |
| 152 |
|
| 153 |
if (!isset($index) || empty($index)) { |
| 154 |
$index = $table->getKeyName(); |
| 155 |
} |
| 156 |
|
| 157 |
foreach ($values as $key => $val) { |
| 158 |
$ids[] = $val[$index]; |
| 159 |
$ids2[] = $val[$index2]; |
| 160 |
foreach (array_keys($val) as $field) { |
| 161 |
if ($field !== $index || $field !== $index2) { |
| 162 |
$finalField = $raw ? Common::mysqlEscape($val[$field]) : "'" . Common::mysqlEscape($val[$field]) . "'"; |
| 163 |
$value = (is_null($val[$field]) ? 'NULL' : $finalField); |
| 164 |
|
| 165 |
if (Common::disableBacktick($driver)) { |
| 166 |
$final[$field][] = 'WHEN (' . $index . ' = \'' . Common::mysqlEscape($val[$index]) . '\' AND ' . $index2 . ' = \'' . $val[$index2] . '\') THEN ' . $value . ' '; |
| 167 |
} else { |
| 168 |
$final[$field][] = 'WHEN (`' . $index . '` = "' . Common::mysqlEscape($val[$index]) . '" AND `' . $index2 . '` = "' . $val[$index2] . '") THEN ' . $value . ' '; |
| 169 |
} |
| 170 |
} |
| 171 |
} |
| 172 |
} |
| 173 |
|
| 174 |
|
| 175 |
if (Common::disableBacktick($driver)) { |
| 176 |
$cases = ''; |
| 177 |
foreach ($final as $k => $v) { |
| 178 |
$cases .= '"' . $k . '" = (CASE ' . implode("\n", $v) . "\n" |
| 179 |
. 'ELSE "' . $k . '" END), '; |
| 180 |
} |
| 181 |
|
| 182 |
$query = "UPDATE \"" . $this->getFullTableName($table) . '" SET ' . substr($cases, 0, -2) . " WHERE \"$index\" IN('" . implode("','", $ids) . "') AND \"$index2\" IN('" . implode("','", $ids2) . "');"; |
| 183 |
} else { |
| 184 |
$cases = ''; |
| 185 |
foreach ($final as $k => $v) { |
| 186 |
$cases .= '`' . $k . '` = (CASE ' . implode("\n", $v) . "\n" |
| 187 |
. 'ELSE `' . $k . '` END), '; |
| 188 |
} |
| 189 |
$query = "UPDATE `" . $this->getFullTableName($table) . "` SET " . substr($cases, 0, -2) . " WHERE `$index` IN(" . '"' . implode('","', $ids) . '")' . " AND `$index2` IN(" . '"' . implode('","', $ids2) . '"' . " );"; |
| 190 |
} |
| 191 |
return $this->db->query($query); |
| 192 |
} |
| 193 |
|
| 194 |
/** |
| 195 |
* Get the full table name. |
| 196 |
* |
| 197 |
* @param Model $model |
| 198 |
* @return string |
| 199 |
*/ |
| 200 |
private function getFullTableName(Model $model): string |
| 201 |
{ |
| 202 |
return $this->db->prefix . $model->getTable(); |
| 203 |
} |
| 204 |
} |
| 205 |
|