2020-12-26 20:09:15 +08:00
|
|
|
<?php
|
|
|
|
|
|
2021-01-27 16:26:37 +08:00
|
|
|
namespace Nexus\Database;
|
|
|
|
|
|
2025-03-29 14:32:31 +07:00
|
|
|
use App\Models\OauthClient;
|
|
|
|
|
use App\Models\PersonalAccessToken;
|
2022-05-13 14:40:59 +08:00
|
|
|
use Illuminate\Support\Facades\Schema;
|
2021-05-29 21:48:50 +08:00
|
|
|
use Illuminate\Database\Capsule\Manager as Capsule;
|
2022-01-19 23:54:55 +08:00
|
|
|
use Illuminate\Database\Query\Expression;
|
2022-03-28 15:58:12 +08:00
|
|
|
use Illuminate\Support\Facades\Cache;
|
2022-01-19 23:54:55 +08:00
|
|
|
use Illuminate\Support\Facades\DB;
|
2022-03-30 15:37:11 +08:00
|
|
|
use Illuminate\Support\Facades\Redis;
|
2025-03-29 14:32:31 +07:00
|
|
|
use Laravel\Passport\Passport;
|
|
|
|
|
use Laravel\Sanctum\Sanctum;
|
2021-05-29 21:48:50 +08:00
|
|
|
|
2021-06-08 10:42:39 +08:00
|
|
|
class NexusDB
|
2020-12-26 20:09:15 +08:00
|
|
|
{
|
2021-01-04 20:47:22 +08:00
|
|
|
private $driver;
|
2020-12-26 20:09:15 +08:00
|
|
|
|
|
|
|
|
private static $instance;
|
|
|
|
|
|
2021-06-21 02:01:26 +08:00
|
|
|
/**
|
|
|
|
|
* @var \Illuminate\Database\Connection
|
|
|
|
|
*/
|
|
|
|
|
private static $eloquentConnection;
|
|
|
|
|
|
2021-01-12 21:14:02 +08:00
|
|
|
private $isConnected = false;
|
|
|
|
|
|
2020-12-26 20:09:15 +08:00
|
|
|
private function __construct()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function __clone()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-10 17:58:30 +08:00
|
|
|
const ELOQUENT_CONNECTION_NAME = 'mysql';
|
2021-04-26 20:37:17 +08:00
|
|
|
|
2020-12-26 20:09:15 +08:00
|
|
|
public function setDriver(DBInterface $driver)
|
|
|
|
|
{
|
|
|
|
|
$this->driver = $driver;
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-28 18:00:54 +08:00
|
|
|
public function getDriver()
|
|
|
|
|
{
|
|
|
|
|
return $this->driver;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-26 20:09:15 +08:00
|
|
|
public static function getInstance()
|
|
|
|
|
{
|
|
|
|
|
if (self::$instance) {
|
|
|
|
|
return self::$instance;
|
|
|
|
|
}
|
|
|
|
|
$instance = new self;
|
|
|
|
|
$driver = new DBMysqli();
|
|
|
|
|
$instance->setDriver($driver);
|
|
|
|
|
return self::$instance = $instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function connect($host, $username, $password, $database, $port)
|
|
|
|
|
{
|
2021-01-28 18:00:54 +08:00
|
|
|
$result = $this->driver->connect($host, $username, $password, $database, $port);
|
|
|
|
|
if (!$result) {
|
|
|
|
|
throw new DatabaseException(sprintf('[%s]: %s', $this->errno(), $this->error()));
|
|
|
|
|
}
|
2021-01-27 17:50:24 +08:00
|
|
|
$this->isConnected = true;
|
2021-01-12 21:14:02 +08:00
|
|
|
return true;
|
2020-12-26 20:09:15 +08:00
|
|
|
}
|
|
|
|
|
|
2021-01-27 16:26:37 +08:00
|
|
|
public function autoConnect()
|
|
|
|
|
{
|
|
|
|
|
if ($this->isConnected()) {
|
2021-01-28 18:00:54 +08:00
|
|
|
return null;
|
2021-01-27 16:26:37 +08:00
|
|
|
}
|
2021-04-02 19:48:41 +08:00
|
|
|
$config = nexus_config('nexus.mysql');
|
2021-01-28 18:00:54 +08:00
|
|
|
return $this->connect($config['host'], $config['username'], $config['password'], $config['database'], $config['port']);
|
2021-01-27 16:26:37 +08:00
|
|
|
}
|
|
|
|
|
|
2020-12-26 20:09:15 +08:00
|
|
|
public function query(string $sql)
|
|
|
|
|
{
|
2020-12-28 02:14:41 +08:00
|
|
|
try {
|
2021-01-27 16:26:37 +08:00
|
|
|
$this->autoConnect();
|
2020-12-28 02:14:41 +08:00
|
|
|
return $this->driver->query($sql);
|
|
|
|
|
} catch (\Exception $e) {
|
2021-01-11 22:00:46 +08:00
|
|
|
do_log(sprintf("%s [%s] %s", $e->getMessage(), $sql, $e->getTraceAsString()));
|
2021-01-27 16:26:37 +08:00
|
|
|
throw new DatabaseException($e->getMessage(), $sql);
|
2020-12-28 02:14:41 +08:00
|
|
|
}
|
|
|
|
|
|
2020-12-26 20:09:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function error()
|
|
|
|
|
{
|
|
|
|
|
return $this->driver->error();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function errno()
|
|
|
|
|
{
|
|
|
|
|
return $this->driver->errno();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function numRows($result)
|
|
|
|
|
{
|
|
|
|
|
return $this->driver->numRows($result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function select_db($database)
|
|
|
|
|
{
|
|
|
|
|
return $this->driver->selectDb($database);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function fetchAssoc($result)
|
|
|
|
|
{
|
|
|
|
|
return $this->driver->fetchAssoc($result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function fetchRow($result)
|
|
|
|
|
{
|
|
|
|
|
return $this->driver->fetchRow($result);
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-28 02:14:41 +08:00
|
|
|
public function fetchArray($result, $type = null)
|
|
|
|
|
{
|
|
|
|
|
return $this->driver->fetchArray($result, $type);
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-26 20:09:15 +08:00
|
|
|
public function affectedRows()
|
|
|
|
|
{
|
|
|
|
|
return $this->driver->affectedRows();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function escapeString(string $string)
|
|
|
|
|
{
|
2021-01-27 16:26:37 +08:00
|
|
|
$this->autoConnect();
|
2020-12-26 20:09:15 +08:00
|
|
|
return $this->driver->escapeString($string);
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-28 20:52:54 +08:00
|
|
|
public function lastInsertId()
|
|
|
|
|
{
|
|
|
|
|
return $this->driver->lastInsertId();
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-07 17:35:00 +08:00
|
|
|
public function freeResult($result)
|
|
|
|
|
{
|
|
|
|
|
return $this->driver->freeResult($result);
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-12 01:54:46 +08:00
|
|
|
public function isConnected()
|
|
|
|
|
{
|
2021-01-12 21:14:02 +08:00
|
|
|
return $this->isConnected;
|
2021-01-12 01:54:46 +08:00
|
|
|
}
|
|
|
|
|
|
2021-01-25 01:23:28 +08:00
|
|
|
public static function insert($table, $data)
|
|
|
|
|
{
|
|
|
|
|
if (empty($table) || empty($data) || !is_array($data)) {
|
|
|
|
|
throw new DatabaseException("require table and data(array).");
|
|
|
|
|
}
|
2022-05-03 23:58:27 +08:00
|
|
|
if (!IN_NEXUS) {
|
|
|
|
|
return DB::table($table)->insertGetId($data);
|
|
|
|
|
}
|
2021-01-25 01:23:28 +08:00
|
|
|
$fields = array_map(function ($value) {return "`$value`";}, array_keys($data));
|
|
|
|
|
$values = array_map(function ($value) {return sqlesc($value);}, array_values($data));
|
|
|
|
|
$sql = sprintf("insert into `%s` (%s) values (%s)", $table, implode(', ', $fields), implode(', ', $values));
|
|
|
|
|
sql_query($sql);
|
|
|
|
|
return mysql_insert_id();
|
|
|
|
|
}
|
2020-12-26 20:09:15 +08:00
|
|
|
|
2021-03-02 21:03:02 +08:00
|
|
|
public static function update($table, $data, $whereStr)
|
|
|
|
|
{
|
2022-04-21 20:02:08 +08:00
|
|
|
if (!IN_NEXUS) {
|
|
|
|
|
return DB::table($table)->whereRaw($whereStr)->update($data);
|
|
|
|
|
}
|
2021-03-02 21:03:02 +08:00
|
|
|
$updateArr = [];
|
|
|
|
|
foreach ($data as $field => $value) {
|
|
|
|
|
$updateArr[] = "`$field` = " . sqlesc($value);
|
|
|
|
|
}
|
|
|
|
|
$sql = sprintf("update `%s` set %s where %s", $table, implode(', ', $updateArr), $whereStr);
|
|
|
|
|
sql_query($sql);
|
|
|
|
|
return mysql_affected_rows();
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-03 19:29:29 +08:00
|
|
|
public static function delete($table, $whereStr, $limit = null)
|
|
|
|
|
{
|
2022-04-21 20:02:08 +08:00
|
|
|
if (!IN_NEXUS) {
|
|
|
|
|
$query = DB::table($table)->whereRaw($whereStr);
|
|
|
|
|
if ($limit !== null) {
|
|
|
|
|
$query->limit($limit);
|
|
|
|
|
}
|
|
|
|
|
return $query->delete();
|
|
|
|
|
}
|
2021-03-03 19:29:29 +08:00
|
|
|
$sql = "delete from $table where $whereStr";
|
|
|
|
|
if (!is_null($limit)) {
|
|
|
|
|
$sql .= " limit $limit";
|
|
|
|
|
}
|
|
|
|
|
sql_query($sql);
|
|
|
|
|
return mysql_affected_rows();
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-03 01:56:07 +08:00
|
|
|
public static function getOne($table, $whereStr, $fields = '*')
|
|
|
|
|
{
|
2022-04-21 20:02:08 +08:00
|
|
|
if (!IN_NEXUS) {
|
|
|
|
|
$result = DB::table($table)->whereRaw($whereStr)->selectRaw($fields)->first();
|
|
|
|
|
return $result ? json_decode(json_encode($result), true) : null;
|
|
|
|
|
}
|
2021-03-03 01:56:07 +08:00
|
|
|
if ($fields != '*') {
|
|
|
|
|
if (is_array($fields)) {
|
|
|
|
|
$fields = implode(', ', $fields);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (empty($fields)) {
|
|
|
|
|
do_log("args: " . json_encode(func_get_args()));
|
|
|
|
|
throw new DatabaseException("empty fields.");
|
|
|
|
|
}
|
|
|
|
|
$sql = "select $fields from $table where $whereStr limit 1";
|
|
|
|
|
$res = sql_query($sql);
|
|
|
|
|
return mysql_fetch_assoc($res);
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-16 21:12:27 +08:00
|
|
|
public static function getAll($table, $whereStr, $fields = '*')
|
|
|
|
|
{
|
2022-04-21 20:02:08 +08:00
|
|
|
if (!IN_NEXUS) {
|
|
|
|
|
$result = DB::table($table)->whereRaw($whereStr)->selectRaw($fields)->get();
|
|
|
|
|
if ($result->isEmpty()) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
return json_decode(json_encode($result), true);
|
|
|
|
|
}
|
2021-03-16 21:12:27 +08:00
|
|
|
if ($fields != '*') {
|
|
|
|
|
if (is_array($fields)) {
|
|
|
|
|
$fields = implode(', ', $fields);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (empty($fields)) {
|
|
|
|
|
do_log("args: " . json_encode(func_get_args()));
|
|
|
|
|
throw new DatabaseException("empty fields.");
|
|
|
|
|
}
|
|
|
|
|
$sql = "select $fields from $table where $whereStr";
|
2022-04-21 20:02:08 +08:00
|
|
|
return self::select($sql);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function select(string $sql)
|
|
|
|
|
{
|
|
|
|
|
if (!IN_NEXUS) {
|
|
|
|
|
$result = DB::select($sql);
|
|
|
|
|
return json_decode(json_encode($result), true);
|
|
|
|
|
}
|
2021-03-16 21:12:27 +08:00
|
|
|
$res = sql_query($sql);
|
|
|
|
|
$result = [];
|
|
|
|
|
while ($row = mysql_fetch_assoc($res)) {
|
|
|
|
|
$result[] = $row;
|
|
|
|
|
}
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-29 21:48:50 +08:00
|
|
|
public static function bootEloquent(array $config)
|
|
|
|
|
{
|
|
|
|
|
$capsule = new Capsule;
|
|
|
|
|
$connectionName = self::ELOQUENT_CONNECTION_NAME;
|
|
|
|
|
$capsule->addConnection($config, $connectionName);
|
|
|
|
|
$capsule->setAsGlobal();
|
|
|
|
|
$capsule->bootEloquent();
|
2021-06-21 02:01:26 +08:00
|
|
|
$connection = self::$eloquentConnection = $capsule->getConnection($connectionName);
|
2021-06-04 10:26:34 +08:00
|
|
|
$connection->enableQueryLog();
|
2025-03-29 14:32:31 +07:00
|
|
|
self::customModel();
|
2021-05-29 21:48:50 +08:00
|
|
|
}
|
|
|
|
|
|
2022-05-13 14:40:59 +08:00
|
|
|
private static function schema(): \Illuminate\Database\Schema\Builder
|
2021-05-29 21:48:50 +08:00
|
|
|
{
|
2022-01-19 23:54:55 +08:00
|
|
|
if (IN_NEXUS) {
|
|
|
|
|
return Capsule::schema(self::ELOQUENT_CONNECTION_NAME);
|
|
|
|
|
}
|
|
|
|
|
throw new \RuntimeException('can not call this when not in nexus.');
|
2021-05-29 21:48:50 +08:00
|
|
|
}
|
|
|
|
|
|
2022-05-13 14:40:59 +08:00
|
|
|
public static function hasTable($table): bool
|
|
|
|
|
{
|
|
|
|
|
if (IN_NEXUS) {
|
|
|
|
|
return self::schema()->hasTable($table);
|
|
|
|
|
}
|
|
|
|
|
return Schema::hasTable($table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function hasColumn($table, $column): bool
|
|
|
|
|
{
|
|
|
|
|
if (IN_NEXUS) {
|
|
|
|
|
return self::schema()->hasColumn($table, $column);
|
|
|
|
|
}
|
|
|
|
|
return Schema::hasColumn($table, $column);
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-05 22:41:27 +08:00
|
|
|
public static function table($table): \Illuminate\Database\Query\Builder
|
|
|
|
|
{
|
2022-01-19 23:54:55 +08:00
|
|
|
if (IN_NEXUS) {
|
2022-06-12 21:32:15 +08:00
|
|
|
return Capsule::table($table, null, self::ELOQUENT_CONNECTION_NAME);
|
2022-01-19 23:54:55 +08:00
|
|
|
}
|
|
|
|
|
return DB::table($table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function raw($value): \Illuminate\Database\Query\Expression
|
|
|
|
|
{
|
|
|
|
|
if (IN_NEXUS) {
|
|
|
|
|
return new Expression($value);
|
|
|
|
|
}
|
|
|
|
|
return DB::raw($value);
|
2021-06-05 22:41:27 +08:00
|
|
|
}
|
|
|
|
|
|
2022-03-08 15:08:56 +08:00
|
|
|
public static function statement($value)
|
|
|
|
|
{
|
|
|
|
|
if (IN_NEXUS) {
|
|
|
|
|
return sql_query($value);
|
|
|
|
|
}
|
|
|
|
|
return DB::statement($value);
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-08 20:43:47 +08:00
|
|
|
public static function transaction(\Closure $callback, $attempts = 1)
|
|
|
|
|
{
|
2022-01-19 23:54:55 +08:00
|
|
|
if (IN_NEXUS) {
|
|
|
|
|
return Capsule::connection(self::ELOQUENT_CONNECTION_NAME)->transaction($callback, $attempts);
|
|
|
|
|
}
|
|
|
|
|
return DB::transaction($callback, $attempts);
|
2021-06-08 20:43:47 +08:00
|
|
|
}
|
|
|
|
|
|
2022-03-28 15:58:12 +08:00
|
|
|
public static function remember($key, $ttl, \Closure $callback)
|
|
|
|
|
{
|
|
|
|
|
if (IN_NEXUS) {
|
|
|
|
|
global $Cache;
|
|
|
|
|
$result = $Cache->get_value($key);
|
|
|
|
|
if ($result === false) {
|
|
|
|
|
$result = $callback();
|
2022-04-14 00:52:28 +08:00
|
|
|
do_log("cache miss [$key]", 'debug');
|
2022-03-28 15:58:12 +08:00
|
|
|
$Cache->cache_value($key, $result, $ttl);
|
|
|
|
|
} else {
|
2022-04-14 00:52:28 +08:00
|
|
|
do_log("cache hit [$key]", 'debug');
|
2022-03-28 15:58:12 +08:00
|
|
|
}
|
|
|
|
|
return $result;
|
|
|
|
|
} else {
|
|
|
|
|
return Cache::remember($key, $ttl, $callback);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-30 15:37:11 +08:00
|
|
|
public static function cache_put($key, $value, $ttl = 3600)
|
|
|
|
|
{
|
|
|
|
|
if (IN_NEXUS) {
|
|
|
|
|
global $Cache;
|
|
|
|
|
return $Cache->cache_value($key, $value, $ttl);
|
|
|
|
|
} else {
|
|
|
|
|
return Cache::put($key, $value, $ttl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function cache_get($key)
|
|
|
|
|
{
|
|
|
|
|
if (IN_NEXUS) {
|
|
|
|
|
global $Cache;
|
|
|
|
|
return $Cache->get_value($key);
|
|
|
|
|
} else {
|
|
|
|
|
return Cache::get($key);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function cache_del($key)
|
|
|
|
|
{
|
|
|
|
|
if (IN_NEXUS) {
|
|
|
|
|
global $Cache;
|
|
|
|
|
$Cache->delete_value($key, true);
|
|
|
|
|
} else {
|
|
|
|
|
Cache::forget($key);
|
|
|
|
|
$langList = get_langfolder_list();
|
|
|
|
|
foreach ($langList as $lf) {
|
|
|
|
|
Cache::forget($lf . '_' . $key);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-30 15:06:51 +08:00
|
|
|
public static function cache_del_by_pattern($pattern)
|
|
|
|
|
{
|
|
|
|
|
$redis = self::redis();
|
|
|
|
|
$it = NULL;
|
|
|
|
|
do {
|
|
|
|
|
// Scan for some keys
|
|
|
|
|
$arr_keys = $redis->scan($it, $pattern);
|
|
|
|
|
|
|
|
|
|
// Redis may return empty results, so protect against that
|
|
|
|
|
if ($arr_keys !== FALSE) {
|
|
|
|
|
foreach($arr_keys as $str_key) {
|
|
|
|
|
do_log("[SCAN_KEY] $str_key");
|
|
|
|
|
self::cache_del($str_key);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while ($it > 0);
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-18 22:53:56 +08:00
|
|
|
/**
|
|
|
|
|
* @return mixed|\Redis|null
|
|
|
|
|
*/
|
2022-03-30 15:37:11 +08:00
|
|
|
public static function redis()
|
|
|
|
|
{
|
|
|
|
|
if (IN_NEXUS) {
|
|
|
|
|
global $Cache;
|
2022-07-18 22:53:56 +08:00
|
|
|
return $Cache->getRedis();
|
2022-03-30 15:37:11 +08:00
|
|
|
} else {
|
2022-07-18 22:53:56 +08:00
|
|
|
return Redis::connection()->client();
|
2022-03-30 15:37:11 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-05 14:52:50 +08:00
|
|
|
public static function getMysqlColumnInfo($table, $column = null)
|
2021-06-06 13:41:05 +08:00
|
|
|
{
|
|
|
|
|
static $driver;
|
|
|
|
|
$config = nexus_config('nexus.mysql');
|
|
|
|
|
if (is_null($driver)) {
|
|
|
|
|
$driver = new DBMysqli();
|
|
|
|
|
$driver->connect($config['host'], $config['username'], $config['password'], 'information_schema', $config['port']);
|
|
|
|
|
}
|
|
|
|
|
$sql = sprintf(
|
2022-04-05 14:52:50 +08:00
|
|
|
"select * from COLUMNS where TABLE_SCHEMA = '%s' and TABLE_NAME = '%s'",
|
|
|
|
|
$config['database'], $table
|
2021-06-06 13:41:05 +08:00
|
|
|
);
|
2022-04-05 14:52:50 +08:00
|
|
|
if ($column !== null) {
|
|
|
|
|
$sql .= " and COLUMN_NAME = '$column'";
|
|
|
|
|
}
|
2021-06-06 13:41:05 +08:00
|
|
|
$res = $driver->query($sql);
|
2022-04-05 14:52:50 +08:00
|
|
|
if ($column !== null) {
|
|
|
|
|
return $driver->fetchAssoc($res);
|
|
|
|
|
}
|
|
|
|
|
$results = [];
|
|
|
|
|
while ($row = $driver->fetchAssoc($res)) {
|
|
|
|
|
$results[$row['COLUMN_NAME']] = $row;
|
|
|
|
|
}
|
|
|
|
|
return $results;
|
|
|
|
|
|
2021-06-06 13:41:05 +08:00
|
|
|
}
|
|
|
|
|
|
2023-04-09 00:51:33 +08:00
|
|
|
public static function hasIndex($table, $indexName): bool
|
|
|
|
|
{
|
|
|
|
|
$results = self::select("show index from $table");
|
|
|
|
|
foreach ($results as $item) {
|
|
|
|
|
if ($item['Key_name'] == $indexName) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-29 14:32:31 +07:00
|
|
|
public static function customModel(): void
|
|
|
|
|
{
|
|
|
|
|
if (class_exists(Passport::class)) {
|
|
|
|
|
Passport::useClientModel(OauthClient::class);
|
|
|
|
|
}
|
|
|
|
|
if (class_exists(Sanctum::class)) {
|
|
|
|
|
Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-05 22:41:27 +08:00
|
|
|
|
2021-04-02 19:48:41 +08:00
|
|
|
}
|