From f314cd9f2cfa27c980ce05a381ae40a48dff6144 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Mon, 10 Jul 2023 19:21:22 +0200 Subject: [PATCH] Allow usage of getPlugin from IPC clients thanks to the PluginEventHandlerProxy --- README.md | 4 +-- src/InternalDoc.php | 10 ++++---- src/Ipc/Client.php | 9 +++++++ src/Ipc/IpcCapable.php | 8 ++++-- src/Ipc/PluginEventHandlerProxy.php | 40 +++++++++++++++++++++++++++++ src/MTProto.php | 2 +- src/Wrappers/Events.php | 39 ++++++++++++++++++++++------ 7 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 src/Ipc/PluginEventHandlerProxy.php diff --git a/README.md b/README.md index f6cc1af79..53c340951 100644 --- a/README.md +++ b/README.md @@ -263,7 +263,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc * Changes the absolute position of a sticker in the set to which it belongs; for bots only. The sticker set must have been created by the bot: stickers.changeStickerPosition * Changes the default value of the Time-To-Live setting, applied to all new chats: messages.setDefaultHistoryTTL * Changes username for the current user: account.updateUsername - * Check if a certain event handler plugin is installed: hasPluginInstance + * Check if a certain event handler plugin is installed: hasPlugin * Check if a username is free and can be assigned to a channel/supergroup: channels.checkUsername * Check if an event handler instance is present: hasEventHandler * Check if has report peers: hasReportPeers @@ -628,7 +628,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc * Notifies the sender about the recipient having listened a voice message or watched a video: messages.readMessageContents * Notify the other user in a private chat that a screenshot of the chat was taken: messages.sendScreenshotNotification * Notify the user that the sent passport data contains some errors The user will not be able to re-submit their Passport data to you until the errors are fixed (the contents of the field for which you returned the error must change): users.setSecureValueErrors - * Obtain a certain event handler plugin instance: getPluginInstance + * Obtain a certain event handler plugin instance: getPlugin * Obtain a list of bot commands for the specified bot scope and language code: bots.getBotCommands * Obtain a list of related languages that must be used when fetching emoji keyword lists »: messages.getEmojiKeywordsLanguages * Obtain available message reactions »: messages.getAvailableReactions diff --git a/src/InternalDoc.php b/src/InternalDoc.php index 921a9bdfd..adb9436f3 100644 --- a/src/InternalDoc.php +++ b/src/InternalDoc.php @@ -949,11 +949,11 @@ abstract class InternalDoc * * @param class-string $class * - * return T + * return T|null */ - public function getPluginInstance(string $class): \danog\MadelineProto\EventHandler + public function getPlugin(string $class): \danog\MadelineProto\PluginEventHandler|\danog\MadelineProto\Ipc\PluginEventHandlerProxy|null { - return $this->wrapper->getAPI()->getPluginInstance($class); + return $this->wrapper->getAPI()->getPlugin($class); } /** * Get download info of the propic of a user @@ -1081,9 +1081,9 @@ abstract class InternalDoc * * @param class-string $class */ - public function hasPluginInstance(string $class): bool + public function hasPlugin(string $class): bool { - return $this->wrapper->getAPI()->hasPluginInstance($class); + return $this->wrapper->getAPI()->hasPlugin($class); } /** * Check if has report peers. diff --git a/src/Ipc/Client.php b/src/Ipc/Client.php index 21d9e4b85..bafc68143 100644 --- a/src/Ipc/Client.php +++ b/src/Ipc/Client.php @@ -78,6 +78,11 @@ final class Client extends ClientAbstract self::$instances[$session->getSessionDirectoryPath()] = $this; EventLoop::queue($this->loopInternal(...)); } + /** @internal */ + public function getSession(): SessionPaths + { + return $this->session; + } /** * Run the provided async callable. * @@ -316,4 +321,8 @@ final class Client extends ClientAbstract { throw new Exception("Can't use ".__FUNCTION__.' in an IPC client instance, please use startAndLoop, instead!'); } + public function getPlugin(string $class): ?PluginEventHandlerProxy + { + return $this->hasPlugin($class) ? new PluginEventHandlerProxy($class, $this) : null; + } } diff --git a/src/Ipc/IpcCapable.php b/src/Ipc/IpcCapable.php index f8cb4f1aa..2ce61ea3a 100644 --- a/src/Ipc/IpcCapable.php +++ b/src/Ipc/IpcCapable.php @@ -16,10 +16,14 @@ abstract class IpcCapable /** @internal */ protected function __construct( - MTProto $API, + MTProto|Client $API, ) { $this->API = $API; - $this->session = $API->wrapper->getSession()->getSessionDirectoryPath(); + if ($API instanceof MTProto) { + $this->session = $API->wrapper->getSession()->getSessionDirectoryPath(); + } else { + $this->session = $API->getSession()->getSessionDirectoryPath(); + } } /** @internal */ diff --git a/src/Ipc/PluginEventHandlerProxy.php b/src/Ipc/PluginEventHandlerProxy.php new file mode 100644 index 000000000..c7f982e7a --- /dev/null +++ b/src/Ipc/PluginEventHandlerProxy.php @@ -0,0 +1,40 @@ +API->callPluginMethod( + $this->__plugin, + $name, + $arguments + ); + } + public function __get(string $name): mixed + { + return $this->API->getPluginProperty($this->__plugin, $name); + } + public function __set(string $name, mixed $value): void + { + $this->API->setPluginProperty($this->__plugin, $name, $value); + } + public function __isset(string $name): bool + { + return $this->API->issetPluginProperty($this->__plugin, $name); + } + public function __unset(string $name): void + { + $this->API->unsetPluginProperty($this->__plugin, $name); + } +} diff --git a/src/MTProto.php b/src/MTProto.php index 2c65fbcfc..7838ec6fd 100644 --- a/src/MTProto.php +++ b/src/MTProto.php @@ -1740,7 +1740,7 @@ final class MTProto implements TLCallback, LoggerGetter throw Exception::extension('memprof'); } if (!\memprof_enabled()) { - throw new Exception("Memory profiling is not enabled in the database settings, set the MEMPROF_PROFILE=1 environment variable or GET parameter to enable it."); + throw new Exception("Memory profiling is not enabled, set the MEMPROF_PROFILE=1 environment variable or GET parameter to enable it."); } $current = "Current memory usage: ".\round(\memory_get_usage()/1024/1024, 1) . " MB"; diff --git a/src/Wrappers/Events.php b/src/Wrappers/Events.php index 40cc87099..ab161cc36 100644 --- a/src/Wrappers/Events.php +++ b/src/Wrappers/Events.php @@ -21,9 +21,10 @@ declare(strict_types=1); namespace danog\MadelineProto\Wrappers; use __PHP_Incomplete_Class; -use AssertionError; use danog\MadelineProto\EventHandler; use danog\MadelineProto\Exception; +use danog\MadelineProto\Ipc\PluginEventHandlerProxy; +use danog\MadelineProto\PluginEventHandler; use danog\MadelineProto\Settings; use danog\MadelineProto\UpdateHandlerType; @@ -107,7 +108,7 @@ trait Events * * @param class-string $class */ - final public function hasPluginInstance(string $class): bool + final public function hasPlugin(string $class): bool { return isset($this->pluginInstances[$class]); } @@ -118,14 +119,11 @@ trait Events * * @param class-string $class * - * return T + * return T|null */ - final public function getPluginInstance(string $class): EventHandler + final public function getPlugin(string $class): PluginEventHandler|PluginEventHandlerProxy|null { - if (!isset($this->pluginInstances[$class]) || !$this->pluginInstances[$class] instanceof EventHandler) { - throw new AssertionError("Plugin instance for $class not found!"); - } - return $this->pluginInstances[$class]; + return $this->pluginInstances[$class] ?? null; } /** * Unset event handler. @@ -154,4 +152,29 @@ trait Events { return isset($this->event_handler_instance); } + /** @internal */ + public function callPluginMethod(string $class, string $method, array $args): mixed + { + return $this->pluginInstances[$class]->$method(...$args); + } + /** @internal */ + public function setPluginProperty(string $class, string $property, mixed $value): void + { + $this->pluginInstances[$class]->$property = $value; + } + /** @internal */ + public function getPluginProperty(string $class, string $property): mixed + { + return $this->pluginInstances[$class]->$property; + } + /** @internal */ + public function issetPluginProperty(string $class, string $property): bool + { + return isset($this->pluginInstances[$class]->$property); + } + /** @internal */ + public function unsetPluginProperty(string $class, string $property): void + { + unset($this->pluginInstances[$class]->$property); + } }