/** * Build the SQL WHERE clause from the various condition arrays * * @param array $cond The condition array, for example * * array( * 'fieldName1' => $value1, * 'fieldName2 >=' => $value2, * 'fieldName3 => NULL * ) * * @param string $type The condition type "AND" or "OR"; Default is "AND" * * @return string The built condition WHERE clause */ public static function buildCondition($cond = array(), $type = 'AND') { if (!is_array($cond)) { return $cond; } if (empty($cond)) { return ''; } $type = strtoupper($type); $condition = array(); foreach ($cond as $field => $value) { $field = trim($field); $fieldOpr = explode(' ', $field); $field = trim($fieldOpr[0]); if (strpos($field, '__QueryBuilder::condition__') !== false) { $field = substr($field, 0, strpos($field, '__QueryBuilder::condition__')); } $opr = count($fieldOpr) === 2 ? trim($fieldOpr[1]) : '='; # check if any operator is given in the field if (!in_array($opr, self::$operators)) { $opr = '='; } if (is_numeric($field)) { # if the field is array index, # assuming that is a condition built by db_or() or db_and(); $condition[] = '( ' . $value . ' )'; } else { # if the operator is "between", the value must be array # otherwise force to "=" if (in_array($opr, array('between', 'nbetween')) && !is_array($value)) { $opr = '='; } $opr = strtolower($opr); $field = self::quote($field); if (array_key_exists($opr, self::$likes)) { $value = str_replace(':likeValue', db_escapeString($value), self::$likes[$opr]); $condition[] = $field . ' ' . $value; } elseif (is_numeric($value)) { $condition[] = $field . ' ' . $opr . ' ' . db_escapeString($value) . ''; } elseif (is_string($value)) { $condition[] = $field . ' ' . $opr . ' "' . db_escapeString($value) . '"'; } elseif (is_null($value)) { if (in_array($opr, array('!=', '<>'))) { $condition[] = $field . ' IS NOT NULL'; } else { $condition[] = $field . ' IS NULL'; } } elseif (is_array($value) && count($value)) { $list = array(); foreach ($value as $v) { $list[] = is_numeric($v) ? db_escapeString($v) : '"' . db_escapeString($v) . '"'; } if ($opr === 'between') { $condition[] = '( ' . $field . ' BETWEEN ' . current($list) . ' AND ' . end($list) . ' )'; } elseif ($opr === 'nbetween') { $condition[] = '( ' . $field . ' NOT BETWEEN ' . current($list) . ' AND ' . end($list) . ' )'; } elseif ($opr === '!=') { $condition[] = $field . ' NOT IN (' . implode(', ', $list) . ')'; } else { $condition[] = $field . ' IN (' . implode(', ', $list) . ')'; } } else { $condition[] = $field . ' ' . $opr . ' ' . db_escapeString($value); } } } if (count($condition)) { $condition = implode(" {$type} ", $condition); } else { $condition = ''; } return $condition; }
/** * Handy MYSQL update operation * * @param string $table The table name without prefix * @param array $data The array of data field names and values * The first field/value pair will be used as condition if you did not provide the fourth argument * * array( * 'conditionField' => $conditionFieldValue, <=== * 'fieldNameToSlug' => $valueToSlug, <=== if $lc_useDBAutoFields is enabled * 'fieldName1' => $value1, * 'fieldName2' => $value2 * ) * * @param boolean $useSlug TRUE to include the slug field or FALSE to not exclude it * The fourth argument can be provided here if you want to omit this. * @param array|string $condition The condition for the UPDATE query. If you provide this, * the first field of `$data` will not be built for condition * * ### Example * * array( * 'fieldName1' => $value1, * 'fieldName2' => $value2 * ) * * OR * * db_or(array( * 'fieldName1' => $value1, * 'fieldName2' => $value2 * )) * * @return boolean Returns TRUE on success or FALSE on failure */ function db_update($table, $data = array(), $useSlug = true, $condition = null) { if (count($data) == 0) { return; } global $_DB; global $_conn; global $lc_useDBAutoFields; if (func_num_args() === 3 && (gettype($useSlug) === 'string' || is_array($useSlug))) { $condition = $useSlug; $useSlug = true; } $table = ltrim($table, db_prefix()); $table = db_prefix() . $table; # Invoke the hook db_update_[table_name] if any $hook = 'db_update_' . strtolower($table); if (function_exists($hook)) { return call_user_func_array($hook, array($table, $data, $useSlug, $condition)); } # if slug is already provided in the data array, use it if (array_key_exists('slug', $data)) { $slug = db_escapeString($data['slug']); $slug = _slug($slug); $data['slug'] = $slug; session_set('lastInsertSlug', $slug); $useSlug = false; } $fields = array(); $slug = ''; $cond = ''; $notCond = ''; $i = 0; $slugIndex = 1; if ($condition) { $slugIndex = 0; } $dsm = $_DB->schemaManager; foreach ($data as $field => $value) { if ($i === 0 && !$condition) { # $data[0] is for PK condition, but only if $condition is not provided $cond = array($field => db_escapeString($value)); # for PK condition $i++; continue; } if (is_object($dsm) && $dsm->isLoaded()) { $fieldType = $dsm->getFieldType($table, $field); if (is_array($value) && $fieldType == 'array') { $value = serialize($value); } elseif (is_array($value) && $fieldType == 'json') { $jsonValue = json_encode($value); $value = $jsonValue ? $jsonValue : null; } elseif ($fieldType == 'boolean') { $value = $value ? 1 : 0; } } if (is_null($value)) { $fields[] = QueryBuilder::quote($field) . ' = NULL'; } else { $fields[] = QueryBuilder::quote($field) . ' = "' . db_escapeString($value) . '"'; } if ($i === $slugIndex && $useSlug === true) { # $data[1] is slug $slug = db_escapeString($value); } $i++; } # must have condition # this prevents unexpected update happened to all records if ($cond || $condition) { if ($cond && is_array($cond)) { $cond = db_condition($cond); } elseif ($condition && is_array($condition)) { $cond = db_condition($condition); } elseif ($condition && is_string($condition)) { $cond = $condition; } if (empty($cond)) { return false; } $notCond = 'NOT ( ' . $cond . ' )'; if (db_tableHasSlug($table, $useSlug)) { $slug = _slug($slug, $table, $notCond); session_set('lastInsertSlug', $slug); $fields[] = '`slug` = "' . $slug . '"'; } if (db_tableHasTimestamps($table)) { $fields[] = '`updated` = "' . date('Y-m-d H:i:s') . '"'; } $fields = implode(', ', $fields); $sql = 'UPDATE ' . QueryBuilder::quote($table) . ' SET ' . $fields . ' WHERE ' . $cond; return db_query($sql); } else { return false; } }