Initial commit
This commit is contained in:
163
app/Core/QueryBuilder.php
Normal file
163
app/Core/QueryBuilder.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
namespace App\Core;
|
||||
|
||||
use PDO;
|
||||
|
||||
class QueryBuilder {
|
||||
protected $pdo;
|
||||
protected $table;
|
||||
protected $where = [];
|
||||
protected $params = [];
|
||||
protected $orderBy = [];
|
||||
protected $limit = null;
|
||||
protected $selects = '*'; // Defaults to everything
|
||||
protected $joins = [];
|
||||
|
||||
public function __construct(PDO $pdo) {
|
||||
$this->pdo = $pdo;
|
||||
}
|
||||
|
||||
public function table($table) {
|
||||
$this->table = $table;
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Notice the new $boolean parameter (defaults to 'AND')
|
||||
public function where($column, $operator, $value = null, $boolean = 'AND') {
|
||||
if ($value === null) {
|
||||
$value = $operator;
|
||||
$operator = '=';
|
||||
}
|
||||
|
||||
$paramName = 'where_' . str_replace('.', '_', $column) . '_' . count($this->params);
|
||||
|
||||
// If this is the first where clause, we don't need 'AND' or 'OR'
|
||||
$prefix = empty($this->where) ? '' : strtoupper($boolean) . ' ';
|
||||
|
||||
$this->where[] = "{$prefix}{$column} {$operator} :{$paramName}";
|
||||
$this->params[$paramName] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// orWhere simply calls where() but passes 'OR'
|
||||
public function orWhere($column, $operator, $value = null) {
|
||||
return $this->where($column, $operator, $value, 'OR');
|
||||
}
|
||||
|
||||
// Sort the results
|
||||
public function orderBy($column, $direction = 'ASC') {
|
||||
$direction = strtoupper($direction) === 'DESC' ? 'DESC' : 'ASC';
|
||||
$this->orderBy[] = "{$column} {$direction}";
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Limit the number of results
|
||||
public function limit(int $limit) {
|
||||
$this->limit = $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Fetch a single record instead of an array of arrays
|
||||
public function first() {
|
||||
$this->limit(1);
|
||||
$result = $this->get();
|
||||
return $result ? $result[0] : null;
|
||||
}
|
||||
|
||||
public function getOld() {
|
||||
$sql = "SELECT * FROM {$this->table}";
|
||||
|
||||
// Changed implode from ' AND ' to ' ' because the prefix handles it now
|
||||
if (!empty($this->where)) {
|
||||
$sql .= " WHERE " . implode(' ', $this->where);
|
||||
}
|
||||
|
||||
if (!empty($this->orderBy)) {
|
||||
$sql .= " ORDER BY " . implode(', ', $this->orderBy);
|
||||
}
|
||||
|
||||
if ($this->limit !== null) {
|
||||
$sql .= " LIMIT {$this->limit}";
|
||||
}
|
||||
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->execute($this->params);
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
public function get() {
|
||||
// Use the new selects property instead of hardcoded '*'
|
||||
$sql = "SELECT {$this->selects} FROM {$this->table}";
|
||||
|
||||
// Add joins immediately after the FROM clause
|
||||
if (!empty($this->joins)) {
|
||||
$sql .= " " . implode(' ', $this->joins);
|
||||
}
|
||||
|
||||
if (!empty($this->where)) {
|
||||
$sql .= " WHERE " . implode(' ', $this->where);
|
||||
}
|
||||
|
||||
if (!empty($this->orderBy)) {
|
||||
$sql .= " ORDER BY " . implode(', ', $this->orderBy);
|
||||
}
|
||||
|
||||
if ($this->limit !== null) {
|
||||
$sql .= " LIMIT {$this->limit}";
|
||||
}
|
||||
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->execute($this->params);
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public function insert(array $data) {
|
||||
$columns = implode(', ', array_keys($data));
|
||||
$placeholders = ':' . implode(', :', array_keys($data));
|
||||
|
||||
$sql = "INSERT INTO {$this->table} ({$columns}) VALUES ({$placeholders})";
|
||||
return $this->pdo->prepare($sql)->execute($data);
|
||||
}
|
||||
|
||||
public function update(array $data) {
|
||||
$fields = "";
|
||||
foreach ($data as $key => $value) {
|
||||
$fields .= "{$key} = :{$key}, ";
|
||||
}
|
||||
$fields = rtrim($fields, ', ');
|
||||
|
||||
$sql = "UPDATE {$this->table} SET {$fields}";
|
||||
if (!empty($this->where)) {
|
||||
$sql .= " WHERE " . implode(' ', $this->where);
|
||||
}
|
||||
|
||||
return $this->pdo->prepare($sql)->execute(array_merge($data, $this->params));
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
$sql = "DELETE FROM {$this->table}";
|
||||
if (!empty($this->where)) {
|
||||
$sql .= " WHERE " . implode(' ', $this->where);
|
||||
}
|
||||
|
||||
return $this->pdo->prepare($sql)->execute($this->params);
|
||||
}
|
||||
// Specify exactly which columns to return
|
||||
public function select($columns) {
|
||||
// Allow passing an array ['id', 'name'] or a raw string 'id, name'
|
||||
$this->selects = is_array($columns) ? implode(', ', $columns) : $columns;
|
||||
return $this;
|
||||
}
|
||||
|
||||
// The main join method
|
||||
public function join($table, $firstColumn, $operator, $secondColumn, $type = 'INNER') {
|
||||
$this->joins[] = "{$type} JOIN {$table} ON {$firstColumn} {$operator} {$secondColumn}";
|
||||
return $this;
|
||||
}
|
||||
|
||||
// A helpful shortcut for LEFT JOINS
|
||||
public function leftJoin($table, $firstColumn, $operator, $secondColumn) {
|
||||
return $this->join($table, $firstColumn, $operator, $secondColumn, 'LEFT');
|
||||
}
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user