PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / 6.0.13
Kirki – Freeform Page Builder, Website Builder & Customizer v6.0.13
6.1.1 6.1.0 6.0.14 6.0.13 6.0.12 6.0.11 6.0.10 6.0.9 6.0.8 6.0.7 6.0.6 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0.19 4.0.20 4.0.21 4.0.22 4.0.23 4.0.24 4.1 4.2.0 5.0.0 5.1.0 5.1.1 5.2.0 5.2.1 5.2.2 5.2.3 6.0.0 trunk 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.1.0 3.1.1 3.1.2
kirki / libraries / framework / Database / Concerns / ExecuteQueries.php
kirki / libraries / framework / Database / Concerns Last commit date
ExecuteQueries.php 3 weeks ago GuardAttributes.php 3 weeks ago HasAttributes.php 3 weeks ago HasDictionary.php 3 weeks ago HasRelationships.php 3 weeks ago HasTimestamps.php 3 weeks ago RelationshipQueries.php 3 weeks ago
ExecuteQueries.php
315 lines
1 <?php
2
3 /**
4 * Execute queries and return the results.
5 * This trait provides methods for executing queries and returning the results.
6 * It is used to execute queries and return the results in a consistent manner.
7 *
8 * @package Framework
9 * @subpackage Database\Concerns
10 * @since 1.0.0
11 */
12 namespace Kirki\Framework\Database\Concerns;
13
14 \defined('ABSPATH') || exit;
15 use Closure;
16 use Kirki\Framework\Collections\Collection;
17 use Kirki\Framework\Database\Query\QueryBuilder;
18 use InvalidArgumentException;
19 use RuntimeException;
20 use function Kirki\Framework\collection;
21 trait ExecuteQueries
22 {
23 /**
24 * Chunk the results of the query into a set of smaller collections.
25 *
26 * @param int $count The number of items to include in each chunk
27 * @param Closure $callback The callback to execute for each chunk
28 *
29 * @return bool True if the callback returns true for all chunks, false otherwise
30 *
31 * @since 1.0.0
32 */
33 public function chunk(int $count, Closure $callback) : bool
34 {
35 $this->enforce_order_by_primary_key();
36 $skip = $this->get_offset();
37 $remaining = $this->get_limit();
38 $page = 1;
39 do {
40 $offset = ($page - 1) * $count + \intval($skip);
41 $limit = \is_null($remaining) ? $count : \min($count, $remaining);
42 if ($limit === 0) {
43 break;
44 }
45 $results = $this->offset($offset)->limit($limit)->get();
46 $result_count = $results->count();
47 if ($result_count === 0) {
48 break;
49 }
50 if (!\is_null($remaining)) {
51 $remaining = \max($remaining - $result_count, 0);
52 }
53 if ($callback($results, $page) === \false) {
54 return \false;
55 }
56 unset($results);
57 $page++;
58 } while ($count === $result_count);
59 return \true;
60 }
61 /**
62 * Chunk the results of the query into a set of smaller collections and map the results using a callback.
63 *
64 * @param Closure $callback The callback to execute for each chunk
65 * @param int $count The number of items to include in each chunk
66 *
67 * @return Collection A new collection of mapped results
68 *
69 * @since 1.0.0
70 */
71 public function chunk_map(Closure $callback, $count = 1000)
72 {
73 $collection = collection();
74 $this->chunk($count, function ($results) use($callback, $collection) {
75 $results->each(function ($result) use($callback, $collection) {
76 $collection->push($callback($result));
77 });
78 });
79 return $collection;
80 }
81 /**
82 * Iterate over the results of the query and execute a callback for each result.
83 *
84 * @param Closure $callback The callback to execute for each result
85 * @param int $count The number of items to include in each chunk
86 *
87 * @return bool True if the callback returns true for all results, false otherwise
88 *
89 * @since 1.0.0
90 */
91 public function each(Closure $callback, int $count = 1000)
92 {
93 return $this->chunk($count, function ($results) use($callback) {
94 foreach ($results as $key => $result) {
95 if ($callback($result, $key) === \false) {
96 return \false;
97 }
98 }
99 });
100 }
101 /**
102 * Chunk the results of the query into a set of smaller collections by the given column in ascending order.
103 *
104 * @param int $count The number of items to include in each chunk
105 * @param Closure $callback The callback to execute for each chunk
106 * @param string $column The column to chunk by
107 * @param string $alias The alias of the column
108 *
109 * @return bool True if the callback returns true for all chunks, false otherwise
110 *
111 * @since 1.0.0
112 */
113 public function chunk_by_id(int $count, Closure $callback, $column = null, $alias = null)
114 {
115 return $this->ordered_chunk_by_id($count, $callback, $column, $alias);
116 }
117 /**
118 * Chunk the results of the query into a set of smaller collections by the given column in descending order.
119 *
120 * @param int $count The number of items to include in each chunk
121 * @param Closure $callback The callback to execute for each chunk
122 * @param string $column The column to chunk by
123 * @param string $alias The alias of the column
124 *
125 * @return bool True if the callback returns true for all chunks, false otherwise
126 *
127 * @since 1.0.0
128 */
129 public function chunk_by_id_desc(int $count, Closure $callback, $column = null, $alias = null)
130 {
131 return $this->ordered_chunk_by_id($count, $callback, $column, $alias, \true);
132 }
133 /**
134 * Chunk the results of the query into a set of smaller collections by the given column in the given order.
135 *
136 * @param int $count The number of items to include in each chunk
137 * @param Closure $callback The callback to execute for each chunk
138 * @param string $column The column to chunk by
139 * @param string $alias The alias of the column
140 * @param bool $descending The order to chunk by
141 *
142 * @return bool True if the callback returns true for all chunks, false otherwise
143 *
144 * @throws \RuntimeException
145 *
146 * @since 1.0.0
147 */
148 public function ordered_chunk_by_id(int $count, Closure $callback, $column = null, $alias = null, $descending = \false)
149 {
150 $column ??= $this->default_key_name();
151 $alias ??= $column;
152 $last_id = null;
153 $skip = $this->get_offset();
154 $remaining = $this->get_limit();
155 $page = 1;
156 do {
157 /**
158 * The cloned query builder instance.
159 *
160 * @var QueryBuilder $clone
161 */
162 $clone = clone $this;
163 if ($skip && $page > 1) {
164 $clone->offset(0);
165 }
166 $limit = \is_null($remaining) ? $count : \min($count, $remaining);
167 if ($limit === 0) {
168 break;
169 }
170 if ($descending) {
171 $results = $clone->for_page_before_id($count, $last_id, $column)->get();
172 } else {
173 $results = $clone->for_page_after_id($count, $last_id, $column)->get();
174 }
175 $result_count = $results->count();
176 if ($result_count === 0) {
177 break;
178 }
179 if (!\is_null($remaining)) {
180 $remaining = \max($remaining - $result_count, 0);
181 }
182 if ($callback($results, $page) === \false) {
183 return \false;
184 }
185 $last_result = $results->last();
186 $last_id = \is_null($last_result) ? null : $last_result[$alias];
187 if (\is_null($last_id)) {
188 throw new RuntimeException('No more results found');
189 }
190 unset($results);
191 $page++;
192 } while ($count === $result_count);
193 return \true;
194 }
195 /**
196 * Lazily iterate over the results of the query.
197 *
198 * @param int $chunk_size The number of items to include in each chunk
199 *
200 * @return \Generator
201 *
202 * @throws \InvalidArgumentException
203 *
204 * @since 1.0.0
205 */
206 public function lazy($chunk_size = 1000)
207 {
208 if ($chunk_size < 1) {
209 throw new InvalidArgumentException('Chunk size should be at least 1');
210 }
211 $this->enforce_order_by_primary_key();
212 $page = 1;
213 while (\true) {
214 $results = $this->for_page($page++, $chunk_size)->get();
215 foreach ($results as $result) {
216 (yield $result);
217 }
218 if ($results->count() < $chunk_size) {
219 return;
220 }
221 }
222 }
223 /**
224 * Lazily iterate over the results of the query by the given column in ascending order.
225 *
226 * @param int $chunk_size The number of items to include in each chunk
227 * @param string $column The column to iterate by
228 * @param string $alias The alias of the column
229 *
230 * @return \Generator
231 *
232 * @since 1.0.0
233 */
234 public function lazy_by_id($chunk_size = 1000, $column = null, $alias = null)
235 {
236 return $this->ordered_lazy_by_id($chunk_size, $column, $alias);
237 }
238 /**
239 * Lazily iterate over the results of the query by the given column in descending order.
240 *
241 * @param int $chunk_size The number of items to include in each chunk
242 * @param string $column The column to iterate by
243 * @param string $alias The alias of the column
244 *
245 * @return \Generator
246 *
247 * @since 1.0.0
248 */
249 public function lazy_by_id_desc($chunk_size = 1000, $column = null, $alias = null)
250 {
251 return $this->ordered_lazy_by_id($chunk_size, $column, $alias, \true);
252 }
253 /**
254 * Lazily iterate over the results of the query by the given column in the given order.
255 *
256 * @param int $chunk_size The number of items to include in each chunk
257 * @param string $column The column to iterate by
258 * @param string $alias The alias of the column
259 * @param bool $descending The order to iterate by
260 *
261 * @return \Generator
262 *
263 * @throws \InvalidArgumentException
264 * @throws \RuntimeException
265 *
266 * @since 1.0.0
267 */
268 public function ordered_lazy_by_id($chunk_size = 1000, $column = null, $alias = null, $descending = \false)
269 {
270 if ($chunk_size < 1) {
271 throw new InvalidArgumentException('Chunk size should be at least 1');
272 }
273 $column ??= $this->default_key_name();
274 $alias ??= $column;
275 $last_id = null;
276 while (\true) {
277 /**
278 * The cloned query builder instance.
279 *
280 * @var QueryBuilder $clone
281 */
282 $clone = clone $this;
283 if ($descending) {
284 $results = $clone->for_page_before_id($chunk_size, $last_id, $column)->get();
285 } else {
286 $results = $clone->for_page_after_id($chunk_size, $last_id, $column)->get();
287 }
288 foreach ($results as $result) {
289 (yield $result);
290 }
291 if ($results->count() < $chunk_size) {
292 return;
293 }
294 $last_id = $results->last()[$alias];
295 if (\is_null($last_id)) {
296 throw new RuntimeException('The lazy_by_id operation was aborted.');
297 }
298 }
299 }
300 /**
301 * Call the given Closure with the given value.
302 *
303 * @param mixed $callback The callback to invoke.
304 *
305 * @return $this
306 *
307 * @since 1.0.0
308 */
309 public function tap($callback)
310 {
311 $callback($this);
312 return $this;
313 }
314 }
315