From 90c9cd48ac9c99a38b1d9af29367f33ab835341c Mon Sep 17 00:00:00 2001 From: xiaomlove <1939737565@qq.com> Date: Thu, 10 Oct 2024 21:04:35 +0800 Subject: [PATCH] add model event --- .env.example | 1 + app/Console/Commands/FireEvent.php | 7 +++++- app/Events/UserCreated.php | 39 +++++++++++++++++++++++++++++ app/Models/User.php | 3 ++- app/Repositories/UserRepository.php | 5 ++-- include/globalfunctions.php | 16 ++++++++++++ public/takesignup.php | 4 ++- 7 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 app/Events/UserCreated.php diff --git a/.env.example b/.env.example index 4e9f0406..ba7bbc40 100644 --- a/.env.example +++ b/.env.example @@ -91,3 +91,4 @@ MEILISEARCH_MASTER_KEY= CACHE_KEY_AGENT_ALLOW=all_agent_allows CACHE_KEY_AGENT_DENY=all_agent_denies CHANNEL_NAME_SETTING=channel_setting +CHANNEL_NAME_MODEL_EVENT=channel_model_event diff --git a/app/Console/Commands/FireEvent.php b/app/Console/Commands/FireEvent.php index 5d2772ce..91073f26 100644 --- a/app/Console/Commands/FireEvent.php +++ b/app/Console/Commands/FireEvent.php @@ -6,6 +6,7 @@ use App\Events\NewsCreated; use App\Events\TorrentCreated; use App\Events\TorrentDeleted; use App\Events\TorrentUpdated; +use App\Events\UserCreated; use App\Events\UserDestroyed; use App\Events\UserDisabled; use App\Events\UserEnabled; @@ -31,15 +32,18 @@ class FireEvent extends Command * * @var string */ - protected $description = 'Fire a event, options: --name, --idKey --idKeyOld'; + protected $description = 'Fire an event, options: --name, --idKey --idKeyOld'; protected array $eventMaps = [ "torrent_created" => ['event' => TorrentCreated::class, 'model' => Torrent::class], "torrent_updated" => ['event' => TorrentUpdated::class, 'model' => Torrent::class], "torrent_deleted" => ['event' => TorrentDeleted::class, 'model' => Torrent::class], + + "user_created" => ['event' => UserCreated::class, 'model' => User::class], "user_destroyed" => ['event' => UserDestroyed::class, 'model' => User::class], "user_disabled" => ['event' => UserDisabled::class, 'model' => User::class], "user_enabled" => ['event' => UserEnabled::class, 'model' => User::class], + "news_created" => ['event' => NewsCreated::class, 'model' => News::class], ]; @@ -69,6 +73,7 @@ class FireEvent extends Command } $result = call_user_func_array([$eventName, "dispatch"], $params); $log .= ", success call dispatch, result: " . var_export($result, true); + publish_model_event($name, $model->id); } else { $log .= ", invalid argument to call, it should be instance of: " . Model::class; } diff --git a/app/Events/UserCreated.php b/app/Events/UserCreated.php new file mode 100644 index 00000000..609e7242 --- /dev/null +++ b/app/Events/UserCreated.php @@ -0,0 +1,39 @@ +model = $model; + } + + /** + * Get the channels the event should broadcast on. + * + * @return \Illuminate\Broadcasting\Channel|array + */ + public function broadcastOn() + { + return new PrivateChannel('channel-name'); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index c064f664..d68174a3 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -179,7 +179,8 @@ class User extends Authenticatable implements FilamentUser, HasName protected $fillable = [ 'username', 'email', 'passhash', 'secret', 'stylesheet', 'editsecret', 'added', 'modcomment', 'enabled', 'status', 'leechwarn', 'leechwarnuntil', 'page', 'class', 'uploaded', 'downloaded', 'clientselect', 'showclienterror', 'last_home', - 'seedbonus', 'bonuscomment', 'downloadpos', 'vip_added', 'vip_until', 'title', 'invites', 'attendance_card', 'seed_points_per_hour' + 'seedbonus', 'bonuscomment', 'downloadpos', 'vip_added', 'vip_until', 'title', 'invites', 'attendance_card', + 'seed_points_per_hour', 'passkey', ]; /** diff --git a/app/Repositories/UserRepository.php b/app/Repositories/UserRepository.php index d8c15f1e..74a5493a 100644 --- a/app/Repositories/UserRepository.php +++ b/app/Repositories/UserRepository.php @@ -132,7 +132,8 @@ class UserRepository extends BaseRepository 'stylesheet' => $setting['defstylesheet'], 'added' => now()->toDateTimeString(), 'status' => User::STATUS_CONFIRMED, - 'class' => $class + 'class' => $class, + 'passkey' => md5($username.date("Y-m-d H:i:s").$passhash) ]; $user = new User($data); if (!empty($params['id'])) { @@ -143,7 +144,7 @@ class UserRepository extends BaseRepository $user->id = $params['id']; } $user->save(); - + fire_event("user_created", $user); return $user; } diff --git a/include/globalfunctions.php b/include/globalfunctions.php index ea467828..dbb18a3b 100644 --- a/include/globalfunctions.php +++ b/include/globalfunctions.php @@ -1247,6 +1247,9 @@ function get_snatch_info($torrentId, $userId) return mysql_fetch_assoc(sql_query(sprintf('select * from snatched where torrentid = %s and userid = %s order by id desc limit 1', $torrentId, $userId))); } +/** + * 完整的 Laravel 事件, 在 php 端有监听者的需要触发. 同样会执行 publish_model_event() + */ function fire_event(string $name, \Illuminate\Database\Eloquent\Model $model, \Illuminate\Database\Eloquent\Model $oldModel = null): void { $prefix = "fire_event:"; @@ -1259,3 +1262,16 @@ function fire_event(string $name, \Illuminate\Database\Eloquent\Model $model, \I } executeCommand("event:fire --name=$name --idKey=$idKey --idKeyOld=$idKeyOld", "string", true, false); } + +/** + * 仅仅是往 redis 发布事件, php 端无监听者仅在其他平台有需要的触发这个即可, 较轻量 + */ +function publish_model_event(string $event, int $id): void +{ + $channel = nexus_env("CHANNEL_NAME_MODEL_EVENT"); + if (!empty($channel)) { + \Nexus\Database\NexusDB::redis()->publish($channel, json_encode(["event" => $event, "id" => $id])); + } else { + do_log("event: $event, id: $id, channel: $channel, channel is empty!", "error"); + } +} diff --git a/public/takesignup.php b/public/takesignup.php index bfe2ec15..4c4f43c9 100644 --- a/public/takesignup.php +++ b/public/takesignup.php @@ -151,6 +151,7 @@ $secret = mksecret(); $wantpasshash = md5($secret . $wantpassword . $secret); $editsecret = ($verification == 'admin' ? '' : $secret); $invite_count = (int) $invite_count; +$passkey = md5($wantusername.date("Y-m-d H:i:s").$wantpasshash); $wantusername = sqlesc($wantusername); $wantpasshash = sqlesc($wantpasshash); @@ -167,8 +168,9 @@ $res_check_user = sql_query("SELECT * FROM users WHERE username = " . $wantusern if(mysql_num_rows($res_check_user) == 1) bark($lang_takesignup['std_username_exists']); -$ret = sql_query("INSERT INTO users (username, passhash, secret, editsecret, email, country, gender, status, class, invites, ".($type == 'invite' ? "invited_by," : "")." added, last_access, lang, stylesheet".($showschool == 'yes' ? ", school" : "").", uploaded) VALUES (" . $wantusername . "," . $wantpasshash . "," . $secret . "," . $editsecret . "," . $email . "," . $country . "," . $gender . ", 'pending', ".$defaultclass_class.",". $invite_count .", ".($type == 'invite' ? "'$inviter'," : "") ." '". date("Y-m-d H:i:s") ."' , " . " '". date("Y-m-d H:i:s") ."' , ".$sitelangid . ",".$defcss.($showschool == 'yes' ? ",".$school : "").",".($iniupload_main > 0 ? $iniupload_main : 0).")") or sqlerr(__FILE__, __LINE__); +$ret = sql_query("INSERT INTO users (username, passhash, passkey, secret, editsecret, email, country, gender, status, class, invites, ".($type == 'invite' ? "invited_by," : "")." added, last_access, lang, stylesheet".($showschool == 'yes' ? ", school" : "").", uploaded) VALUES (" . $wantusername . "," . $wantpasshash . "," . sqlesc($passkey) . "," . $secret . "," . $editsecret . "," . $email . "," . $country . "," . $gender . ", 'pending', ".$defaultclass_class.",". $invite_count .", ".($type == 'invite' ? "'$inviter'," : "") ." '". date("Y-m-d H:i:s") ."' , " . " '". date("Y-m-d H:i:s") ."' , ".$sitelangid . ",".$defcss.($showschool == 'yes' ? ",".$school : "").",".($iniupload_main > 0 ? $iniupload_main : 0).")") or sqlerr(__FILE__, __LINE__); $id = mysql_insert_id(); +fire_event("user_created", \App\Models\User::query()->first($id, \App\Models\User::$commonFields)); $tmpInviteCount = get_setting('main.tmp_invite_count'); if ($tmpInviteCount > 0) { $userRep = new \App\Repositories\UserRepository();