Skip to content

Commit

Permalink
bug fix for model find method
Browse files Browse the repository at this point in the history
  • Loading branch information
donwilson committed Oct 13, 2023
1 parent 505e962 commit 0938066
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 28 deletions.
14 changes: 4 additions & 10 deletions src/Magnetar/Database/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,6 @@ protected function buildQueryAndParams(): array {
/**
* Build the query and fetch the results
* @return array
*
* @todo split off into a separate QueryBuilder, implement fetch() and fetchOne() using adapter
*/
public function fetch(): array {
[$query, $params] = $this->buildQueryAndParams();
Expand All @@ -393,11 +391,9 @@ public function fetch(): array {

/**
* Build the query and fetch a single row
* @return array
*
* @todo split off into a separate QueryBuilder, implement fetch() and fetchOne() using adapter
* @return array|false
*/
public function fetchOne(): array {
public function fetchOne(): array|false {
[$query, $params] = $this->buildQueryAndParams();

// reset query builder (to prevent accidental reuse)
Expand All @@ -410,11 +406,9 @@ public function fetchOne(): array {
/**
* Build the query and fetch a column as a simple array
* @param string|int $column_key The column to use as the array key for the results. If empty, fetches the first column
* @return array
*
* @todo split off into a separate QueryBuilder, implement fetch() and fetchOne() and fetchCol() using adapter
* @return array|false
*/
public function fetchCol(string|int $column_key=0): array {
public function fetchCol(string|int $column_key=0): array|false {
[$query, $params] = $this->buildQueryAndParams();

// reset query builder (to prevent accidental reuse)
Expand Down
13 changes: 13 additions & 0 deletions src/Magnetar/Model/Exceptions/ModelException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);

namespace Magnetar\Model\Exceptions;

use Exception;

/**
* Exception thrown when a model error occurs
*/
class ModelException extends Exception {

}
13 changes: 13 additions & 0 deletions src/Magnetar/Model/Exceptions/ModelNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);

namespace Magnetar\Model\Exceptions;

use Exception;

/**
* Exception thrown when a model could not be found by the specified identifer
*/
class ModelNotFoundException extends Exception {

}
15 changes: 11 additions & 4 deletions src/Magnetar/Model/HasLookupTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,30 @@
namespace Magnetar\Model;

use Magnetar\Helpers\Facades\DB;
use Magnetar\Model\Exceptions\ModelNotFoundException;

/**
* Model trait for lookup functions
*/
trait HasLookupTrait {
/**
* Find a model by ID
* @param int $id The ID of the model to find
* @param int|string $id The ID of the model to find
* @return static
*
* @throws ModelNotFoundException
*/
public function find(int $id): static {
private function find(int|string $id): static {
// pull model data
$this->_data = DB::connection($this->connection_name)
$data = DB::connection($this->connection_name)
->table($this->table)
->where($this->identifier, $id)
->fetchOne();

return $this;
if(false === $data) {
throw new Exceptions\ModelNotFoundException('Model not found in table ['. $this->table .'] with identifier ['. $id .']');
}

return new static($data);
}
}
36 changes: 22 additions & 14 deletions src/Magnetar/Model/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Magnetar\Model\HasDirtyTrait;
use Magnetar\Model\HasLookupTrait;
use Magnetar\Model\HasMutableTrait;
use Magnetar\Utilities\Str;
use Magnetar\Utilities\Internals;

/**
* Model class for interacting with the database.
Expand Down Expand Up @@ -44,18 +46,21 @@ class Model implements ArrayAccess {
protected string $identifier = 'id';

/**
* AbstractObject constructor
* @param int|null $id The ID of the object to pull
* Constructor
* @param array|string|int|null $data The ID of the model to pull
*/
public function __construct(
int|null $id=null
array|string|int|null $data=null
) {
// determine table (if not set)
$this->_determineModelTable();

if(null !== $id) {
if(is_array($data)) {
// prefill model data
$this->_data = $data;
} elseif(is_string($data) || is_int($data)) {
// pull model data
$this->find($id);
$this->find($data);
}
}

Expand All @@ -69,15 +74,8 @@ protected function _determineModelTable(): void {
return;
}

// get the class name
$class = get_class($this);

// get the table name
$parts = explode('\\', $class);
$class_name = end($parts);

// convert to snake_case
$this->table = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $class_name));
// if not set already, get the class name and convert it to snake case
$this->table = Str::snake_case(Internals::class_basename_instance($this));
}

/**
Expand Down Expand Up @@ -150,4 +148,14 @@ public function __set(string $key, mixed $value): void {
public function __isset(string $key): bool {
return isset($this->_data[ $key ]);
}

/**
* Handle dynamic static method calls
* @param mixed $method The method to call
* @param mixed $arguments The arguments to pass to the method
* @return mixed
*/
public static function __callStatic(mixed $method, mixed $arguments): mixed {
return (new static)->$method(...$arguments);
}
}
29 changes: 29 additions & 0 deletions src/Magnetar/Utilities/Internals.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);

namespace Magnetar\Utilities;

/**
* PHP Internals utility static class
*/
class Internals {
/**
* Get the basename of a namespaced class
* @param string $class_name The class name (including namespace)
* @return string The base class name
*/
public static function basename_class(string $class_name): string {
$bits = explode('\\', $class_name);

return end($bits);
}

/**
* Get the base class name of a namespaced class from an instance
* @param mixed $instance The instance to get the class name from
* @return string The base class name
*/
public static function class_basename_instance(mixed $instance): string {
return self::basename_class(get_class($instance));
}
}
22 changes: 22 additions & 0 deletions src/Magnetar/Utilities/Str.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,28 @@
* String utility static class
*/
class Str {
/**
* Convert a string to snake case
* @param string $str The string to convert
* @return string The converted string
*/
public static function snake_case(
string $str
): string {
return strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $str));
}

/**
* Convert a string to camel case
* @param string $str The string to convert
* @return string The converted string
*/
public static function camelCase(
string $str
): string {
return lcfirst(str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $str))));
}

/**
* Convert a string to a URL-friendly string
* @param string $string The string to convert
Expand Down

0 comments on commit 0938066

Please sign in to comment.