Skip to content

Commit a396dbf

Browse files
authored
Merge pull request #89 from LaswitchTech/dev
General: Version bumped to v0.0.89
2 parents d1fb173 + 87918a8 commit a396dbf

3 files changed

Lines changed: 185 additions & 50 deletions

File tree

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.0.88
1+
v0.0.89

src/Base/BaseModel.php

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,17 @@ protected function process(array $record): array
352352
return $record;
353353
}
354354

355+
/**
356+
* Add joins to the query
357+
*
358+
* @param object $query
359+
* @return object
360+
*/
361+
protected function joins(object $query): object
362+
{
363+
return $query;
364+
}
365+
355366
/**
356367
* Sanitize the data before inserting or updating
357368
*
@@ -548,15 +559,23 @@ public function fetchAll(array $conditions = [], string $conjunction = 'AND'): a
548559
->table($this->table)
549560
->select('*')
550561
->join('owner', 'users', 'username')
562+
->join('owner.vcard', 'vcards', 'id')
551563
->index($this->primary)
552564
->filter()
553565
->where('id', 9999, '<>');
554566

555-
// Set the Owner
567+
// Verify the Organization
556568
if(array_key_exists('organization',$this->definition)){
557-
$Query->join('organization', 'organizations', 'id')->where('organization', $this->Auth->user()->organization()->id);
569+
if($this->Auth->isAuthenticated()){
570+
$Query->join('organization', 'organizations', 'id')
571+
->join('organization.vcard', 'vcards', 'id')
572+
->where('organization', $this->Auth->user()->organization()->id);
573+
}
558574
}
559575

576+
// Apply Joins
577+
$Query = $this->joins($Query);
578+
560579
// Check if the conditions are empty
561580
if(!empty($conditions)){
562581

@@ -601,7 +620,52 @@ public function fetchAll(array $conditions = [], string $conjunction = 'AND'): a
601620
*/
602621
public function count(array $conditions = [], string $conjunction = 'AND'): int
603622
{
604-
return count($this->fetchAll($conditions, $conjunction));
623+
// Create the Query
624+
$Query = $this->Database->query()
625+
->table($this->table)
626+
->count()
627+
->join('owner', 'users', 'username')
628+
->join('owner.vcard', 'vcards', 'id')
629+
->index($this->primary)
630+
->filter()
631+
->where('id', 9999, '<>');
632+
633+
// Verify the Organization
634+
if(array_key_exists('organization',$this->definition)){
635+
if($this->Auth->isAuthenticated()){
636+
$Query->join('organization', 'organizations', 'id')
637+
->join('organization.vcard', 'vcards', 'id')
638+
->where('organization', $this->Auth->user()->organization()->id);
639+
}
640+
}
641+
642+
// Apply Joins
643+
$Query = $this->joins($Query);
644+
645+
// Check if the conditions are empty
646+
if(!empty($conditions)){
647+
648+
// Add a Filter
649+
$Query->filter();
650+
651+
// Add the Conditions
652+
foreach($conditions as $key => $condition){
653+
654+
// Check if the key exists in the definition
655+
if(!array_key_exists($condition['key'], $this->definition)){
656+
657+
// Remove the key from the data
658+
unset($conditions[$key]);
659+
continue;
660+
}
661+
662+
// Add the condition to the Query
663+
$Query->where($condition["key"], $condition["value"], $condition["operator"], $conjunction);
664+
}
665+
}
666+
667+
// Retrieve the count
668+
return $Query->execute();
605669
}
606670

607671
/**
@@ -617,17 +681,25 @@ public function fetch(int $id): array
617681
->table($this->table)
618682
->select('*')
619683
->join('owner', 'users', 'username')
684+
->join('owner.vcard', 'vcards', 'id')
620685
->filter()
621686
->where('id', 9999, '<>')
622687
->filter()
623688
->where($this->primary, $id)
624689
->limit(1);
625690

626-
// Set the Owner
691+
// Verify the Organization
627692
if(array_key_exists('organization',$this->definition)){
628-
$Query->join('organization', 'organizations', 'id')->where('organization', $this->Auth->user()->organization()->id);
693+
if($this->Auth->isAuthenticated()){
694+
$Query->join('organization', 'organizations', 'id')
695+
->join('organization.vcard', 'vcards', 'id')
696+
->where('organization', $this->Auth->user()->organization()->id);
697+
}
629698
}
630699

700+
// Apply Joins
701+
$Query = $this->joins($Query);
702+
631703
// Retrieve the record
632704
$records = $Query->fetch();
633705

src/Objects/Query.php

Lines changed: 107 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,13 @@ class Query {
125125
*/
126126
private $params = [];
127127

128+
/**
129+
* Count distinct flag
130+
*
131+
* @var bool
132+
*/
133+
private $countDistinct = false;
134+
128135
/**
129136
* Constructor
130137
*
@@ -143,6 +150,31 @@ public function __toString()
143150
return $this->buildQuery();
144151
}
145152

153+
/**
154+
* FROM clause
155+
*
156+
* @param string $table
157+
* @return self
158+
*/
159+
public function table(string $table): self
160+
{
161+
$this->table = $table;
162+
return $this;
163+
}
164+
165+
/**
166+
* INSERT query
167+
*
168+
* @param array $data
169+
* @return self
170+
*/
171+
public function insert(array $data): self
172+
{
173+
$this->type = 'insert';
174+
$this->values = $data;
175+
return $this;
176+
}
177+
146178
/**
147179
* SELECT query
148180
*
@@ -157,14 +189,41 @@ public function select(string $fields = '*'): self
157189
}
158190

159191
/**
160-
* FROM clause
192+
* COUNT query
161193
*
162-
* @param string $table
194+
* @param string $column
195+
* @param bool $distinct
163196
* @return self
164197
*/
165-
public function table(string $table): self
198+
public function count(string $column = '*', bool $distinct = false): self
166199
{
167-
$this->table = $table;
200+
$this->type = 'count';
201+
$this->fields = $column;
202+
$this->countDistinct = $distinct;
203+
return $this;
204+
}
205+
206+
/**
207+
* UPDATE query
208+
*
209+
* @param array $data
210+
* @return self
211+
*/
212+
public function update(array $data): self
213+
{
214+
$this->type = 'update';
215+
$this->values = $data;
216+
return $this;
217+
}
218+
219+
/**
220+
* DELETE query
221+
*
222+
* @return self
223+
*/
224+
public function delete(): self
225+
{
226+
$this->type = 'delete';
168227
return $this;
169228
}
170229

@@ -285,43 +344,6 @@ public function limit(int $limit): self
285344
return $this;
286345
}
287346

288-
/**
289-
* INSERT query
290-
*
291-
* @param array $data
292-
* @return self
293-
*/
294-
public function insert(array $data): self
295-
{
296-
$this->type = 'insert';
297-
$this->values = $data;
298-
return $this;
299-
}
300-
301-
/**
302-
* UPDATE query
303-
*
304-
* @param array $data
305-
* @return self
306-
*/
307-
public function update(array $data): self
308-
{
309-
$this->type = 'update';
310-
$this->values = $data;
311-
return $this;
312-
}
313-
314-
/**
315-
* DELETE query
316-
*
317-
* @return self
318-
*/
319-
public function delete(): self
320-
{
321-
$this->type = 'delete';
322-
return $this;
323-
}
324-
325347
/**
326348
* Execute the query and return the result
327349
*
@@ -334,15 +356,20 @@ public function delete(): self
334356
public function result()
335357
{
336358
$sql = $this->buildQuery();
337-
$result = $this->connector->prepare($sql, $this->params);
359+
$statement = $this->connector->prepare($sql, $this->params);
338360
if ($this->type === 'select') {
339-
$result = $result->get_result();
361+
$result = $statement->get_result();
340362
$rows = [];
341363
while ($row = $result->fetch_assoc()) {
342364
$rows[] = $row;
343365
}
344366
return $this->buildRows($rows);
345367
}
368+
if ($this->type === 'count') {
369+
$result = $statement->get_result();
370+
$row = $result->fetch_assoc();
371+
return (int) ($row['t__count'] ?? 0);
372+
}
346373
return $this->connector->affectedRows();
347374
}
348375

@@ -376,6 +403,30 @@ public function fetch()
376403
return $this->result();
377404
}
378405

406+
/**
407+
* Resolve column specification
408+
*
409+
* @param string $spec
410+
* @return string
411+
*/
412+
private function resolveColumn(string $spec): string
413+
{
414+
if ($spec === '*') return '*';
415+
416+
if (strpos($spec, '.') === false) {
417+
return "t.`{$spec}`";
418+
}
419+
420+
$parts = explode('.', $spec);
421+
if ($parts[0] === 't' && count($parts) === 2) {
422+
return "t.`{$parts[1]}`";
423+
}
424+
425+
$column = array_pop($parts);
426+
$alias = 'j__' . implode('__', $parts);
427+
return "`{$alias}`.`{$column}`";
428+
}
429+
379430
/**
380431
* Build the rows array
381432
*
@@ -452,6 +503,18 @@ private function buildQuery(): string
452503
}
453504
return $sql;
454505

506+
case 'count':
507+
$col = $this->resolveColumn($this->fields);
508+
$countExpr = ($this->countDistinct && $col !== '*') ? "DISTINCT {$col}" : $col;
509+
$sql = "SELECT COUNT({$countExpr}) AS `t__count` FROM `{$this->table}` AS t";
510+
if (!empty($this->join)) {
511+
$sql .= ' ' . $this->buildJoin();
512+
}
513+
if (!empty($this->where)) {
514+
$sql .= ' WHERE ' . $this->buildWhere();
515+
}
516+
return $sql;
517+
455518
case 'insert':
456519
$columns = array_keys($this->values);
457520
foreach ($columns as $key => $column) {
@@ -548,7 +611,7 @@ private function buildWhere(): string
548611
$clauses = [];
549612
foreach ($where['clauses'] as $i => $condition) {
550613
$conjunction = $condition['conjunction'];
551-
if ($this->type === 'select') {
614+
if (in_array($this->type, ['select','count'], true)) {
552615
$spec = $condition['column'];
553616
if (strpos($spec, '.') === false) {
554617
$col = "t.`{$spec}`";

0 commit comments

Comments
 (0)