PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.0.1
Booking for Appointments and Events Calendar – Amelia v2.0.1
2.4.5 2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / src / Infrastructure / DB / WPDB / Statement.php
ameliabooking / src / Infrastructure / DB / WPDB Last commit date
Connection.php 6 months ago Statement.php 6 months ago
Statement.php
144 lines
1 <?php
2
3 namespace AmeliaBooking\Infrastructure\DB\WPDB;
4
5 use wpdb;
6
7 class Statement
8 {
9 /** @var wpdb */
10 private $wpdb;
11
12 /** @var string */
13 private $statement;
14
15 /** @var array */
16 private $bindings = [];
17
18 /** @var int */
19 private $fetchIndex = 0;
20
21 /** @var array|null Cached result set for fetch operations */
22 private $results = null;
23
24 /** @var int */
25 private $affectedRows = 0;
26
27 /**
28 * @param wpdb $wpdb
29 * @param string $statement
30 */
31 public function __construct($wpdb, $statement)
32 {
33 $this->wpdb = $wpdb;
34 $this->statement = $statement;
35 }
36
37 /**
38 * @param int|string $parameter
39 * @param mixed $variable
40 */
41 public function bindValue($parameter, $variable)
42 {
43 $this->bindings[$parameter] = $variable;
44 }
45
46 /**
47 * @param int|string $parameter
48 * @param mixed $variable
49 */
50 public function bindParam($parameter, $variable)
51 {
52 $this->bindValue($parameter, $variable);
53 }
54
55 /**
56 * Execute the statement.
57 * Accepts optional params array (e.g. [':id' => 5]).
58 * Repositories previously called execute($params); this now works.
59 *
60 * @param array $params
61 * @return bool
62 */
63 public function execute(array $params = [])
64 {
65 // Merge passed params into bindings (allows both bindParam + execute($params))
66 if ($params) {
67 foreach ($params as $key => $value) {
68 $this->bindings[$key] = $value;
69 }
70 }
71
72 $query = $this->statement;
73
74 if ($this->bindings) {
75 // Sort bindings by key length, descending, to avoid replacing ":p1" with value of ":p10"
76 uksort($this->bindings, function ($a, $b) {
77 return strlen($b) - strlen($a);
78 });
79
80 foreach ($this->bindings as $placeholder => $value) {
81 $replacement = 'NULL';
82
83 if ($value !== null) {
84 $format = is_int($value) || is_bool($value) ? '%d' : (is_float($value) ? '%f' : '%s');
85 $replacement = $this->wpdb->prepare($format, $value);
86 }
87
88 $query = str_replace($placeholder, $replacement, $query);
89 }
90 }
91
92 $this->fetchIndex = 0; // reset pointer for subsequent fetch() calls
93
94 // Execute using query() - this handles all query types (SELECT, INSERT, UPDATE, etc.)
95 // It populates $wpdb->last_result (for rows) and returns the count
96 $result = $this->wpdb->query($query);
97
98 if ($result === false) {
99 $this->results = [];
100 $this->affectedRows = 0;
101 return false;
102 }
103
104 // Capture affected rows immediately so it's stable even if other WP queries run later
105 $this->affectedRows = (int) $result;
106
107 // If the query produced results (SELECT, SHOW, etc.), wpdb stores them in last_result as objects
108 // Convert objects to arrays to match PDO::FETCH_ASSOC behavior
109 $this->results = array_map(function ($row) {
110 return (array) $row;
111 }, $this->wpdb->last_result ?? []);
112
113 return true;
114 }
115
116 /**
117 * @return array
118 */
119 public function fetchAll()
120 {
121 return $this->results ?: [];
122 }
123
124 /**
125 * @return array|false
126 */
127 public function fetch()
128 {
129 if ($this->results && isset($this->results[$this->fetchIndex])) {
130 return $this->results[$this->fetchIndex++];
131 }
132
133 return false;
134 }
135
136 /**
137 * @return int
138 */
139 public function rowCount()
140 {
141 return $this->affectedRows;
142 }
143 }
144