From 3749011150253f9ac0875d59b644c2c3996069dd Mon Sep 17 00:00:00 2001 From: mhrubel Date: Fri, 25 Apr 2025 21:57:28 +0600 Subject: [PATCH 1/3] Added options --- app/Config/Options.php | 37 ++++++++ app/Core/Helpers/BootstrapHelper.php | 3 + app/Core/Helpers/OptionsHelper.php | 22 +++++ app/Core/PluginFrame.php | 2 - app/Core/Services/Container.php | 90 +++++++++++++++++++ app/Core/Services/Customize.php | 2 +- .../Options/CompositeOptionStorage.php | 57 ++++++++++++ .../Services/Options/CustomTableOption.php | 66 ++++++++++++++ .../Options/Interfaces/OptionInterface.php | 49 ++++++++++ .../Interfaces/OptionStorageInterface.php | 14 +++ app/Core/Services/Options/Option.php | 16 ---- app/Core/Services/Options/OptionManager.php | 49 ++++++++++ app/Core/Services/Options/WPOptionStorage.php | 39 ++++++++ 13 files changed, 427 insertions(+), 19 deletions(-) create mode 100644 app/Config/Options.php create mode 100644 app/Core/Helpers/OptionsHelper.php create mode 100644 app/Core/Services/Container.php create mode 100644 app/Core/Services/Options/CompositeOptionStorage.php create mode 100644 app/Core/Services/Options/CustomTableOption.php create mode 100644 app/Core/Services/Options/Interfaces/OptionInterface.php create mode 100644 app/Core/Services/Options/Interfaces/OptionStorageInterface.php delete mode 100644 app/Core/Services/Options/Option.php create mode 100644 app/Core/Services/Options/OptionManager.php create mode 100644 app/Core/Services/Options/WPOptionStorage.php diff --git a/app/Config/Options.php b/app/Config/Options.php new file mode 100644 index 00000000..ef08eb84 --- /dev/null +++ b/app/Config/Options.php @@ -0,0 +1,37 @@ +pf_options_container_loader(); + } + + private function pf_options_container_loader(): void + { + Container::bind( + OptionStorageInterface::class . ':wp', + fn($c) => new WPOptionStorage() + ); + Container::bind( + OptionStorageInterface::class . ':custom', + fn($c) => new CustomTableOption() + ); + Container::bind( + OptionManager::class, + fn($c) => new OptionManager($c) + ); + Container::bind( + OptionStorageInterface::class, + fn($c) => $c->get(OptionStorageInterface::class . ':wp') + ); + } +} diff --git a/app/Core/Helpers/BootstrapHelper.php b/app/Core/Helpers/BootstrapHelper.php index 9639eafe..52eda21a 100644 --- a/app/Core/Helpers/BootstrapHelper.php +++ b/app/Core/Helpers/BootstrapHelper.php @@ -109,6 +109,9 @@ private function load_features(): void { (new \PluginFrame\Config\Config())->priority_load_first(); + // Initialize Options Container and Storage Services + new \PluginFrame\Config\Options(); + // Initialize providers and configuration. new \PluginFrame\Config\Providers(); diff --git a/app/Core/Helpers/OptionsHelper.php b/app/Core/Helpers/OptionsHelper.php new file mode 100644 index 00000000..d681d1eb --- /dev/null +++ b/app/Core/Helpers/OptionsHelper.php @@ -0,0 +1,22 @@ + */ + private array $definitions = []; + + /** @var array */ + private array $instances = []; + + /** Private to enforce singleton */ + private function __construct() {} + + /** + * Retrieve the singleton instance. + */ + public static function getInstance(): Container + { + return self::$instance ??= new Container(); + } + + /** + * Bind a service ID to a resolver callable. + * + * @param string $id Service identifier. + * @param callable $resolver function(ContainerInterface): mixed + */ + public static function bind(string $id, callable $resolver): void + { + self::getInstance()->definitions[$id] = $resolver; + } + + /** + * Resolve a service by its ID. + * + * @param string $id Identifier of the entry to look for. + * @return mixed The entry. + * @throws NotFoundExceptionInterface No entry was found for this identifier. + */ + public function get(string $id): mixed + { + if (isset($this->instances[$id])) { + return $this->instances[$id]; + } + + if (! isset($this->definitions[$id])) { + throw new class("Service {$id} not found") + extends \Exception + implements NotFoundExceptionInterface {}; + } + + $resolver = $this->definitions[$id]; + $service = $resolver($this); + $this->instances[$id] = $service; + return $service; + } + + /** + * Static shortcut to resolve a service. + * + * @param string $id + * @return mixed + */ + public static function resolve(string $id): mixed + { + return self::getInstance()->get($id); + } + + /** + * Does this container have a resolver bound for $id? + * + * @param string $id Identifier to check. + * @return bool + */ + public function has(string $id): bool + { + return isset($this->definitions[$id]); + } +} diff --git a/app/Core/Services/Customize.php b/app/Core/Services/Customize.php index ff7e563b..bc787209 100644 --- a/app/Core/Services/Customize.php +++ b/app/Core/Services/Customize.php @@ -1,6 +1,6 @@ storages = $storages; + } + + public function register(string $key, $default = null, array $args = []): void { + foreach ($this->storages as $storage) { + $storage->register($key, $default, $args); + } + } + + public function get(string $key, $default = null) { + foreach ($this->storages as $storage) { + $value = $storage->get($key, null); + if (null !== $value) { + return $value; + } + } + return $default; + } + + public function update(string $key, $value): bool { + $ok = true; + foreach ($this->storages as $storage) { + $ok = $ok && $storage->update($key, $value); + } + return $ok; + } + + public function delete(string $key): bool { + $ok = true; + foreach ($this->storages as $storage) { + $ok = $ok && $storage->delete($key); + } + return $ok; + } + + public function all(): array { + $all = []; + foreach ($this->storages as $storage) { + $all = array_merge($all, $storage->all()); + } + return $all; + } +} diff --git a/app/Core/Services/Options/CustomTableOption.php b/app/Core/Services/Options/CustomTableOption.php new file mode 100644 index 00000000..4b9a71b4 --- /dev/null +++ b/app/Core/Services/Options/CustomTableOption.php @@ -0,0 +1,66 @@ +db = $wpdb; + $this->table = $wpdb->prefix . 'plugin_options'; + } + + public function register(string $key, $default = null, array $args = []): void + { + $exists = $this->db->get_var( + $this->db->prepare("SELECT COUNT(*) FROM {$this->table} WHERE option_key=%s", $key) + ); + if (!$exists) { + $this->db->insert( + $this->table, + ['option_key' => $key, 'option_value' => maybe_serialize($default)], + ['%s','%s'] + ); + } + } + + public function get(string $key, $default = null) + { + $row = $this->db->get_row( + $this->db->prepare("SELECT option_value FROM {$this->table} WHERE option_key=%s", $key), + ARRAY_A + ); + return $row ? maybe_unserialize($row['option_value']) : $default; + } + + public function update(string $key, $value): bool + { + return (bool) $this->db->update( + $this->table, + ['option_value' => maybe_serialize($value)], + ['option_key' => $key], + ['%s'], + ['%s'] + ); + } + + public function delete(string $key): bool + { + return (bool) $this->db->delete($this->table, ['option_key' => $key], ['%s']); + } + + public function all(): array + { + $rows = $this->db->get_results("SELECT * FROM {$this->table}", ARRAY_A); + return array_column($rows, 'option_value', 'option_key'); + } +} diff --git a/app/Core/Services/Options/Interfaces/OptionInterface.php b/app/Core/Services/Options/Interfaces/OptionInterface.php new file mode 100644 index 00000000..63d3dd6a --- /dev/null +++ b/app/Core/Services/Options/Interfaces/OptionInterface.php @@ -0,0 +1,49 @@ +c = $container; + } + + public function register(string $key, $default = null, array $args = []): void { + $drivers = $args['storage'] ?? ['wp']; + $instances = array_map(fn($alias) => + $this->c->get(OptionStorageInterface::class . ':' . $alias), + $drivers + ); + $storage = count($instances) > 1 + ? new CompositeOptionStorage($instances) + : $instances[0]; + + $storage->register($key, $default, $args); + $this->registered[$key] = ['default'=>$default,'args'=>$args]; + } + + public function get(string $key, $default = null) { + // delegate to the selected storage(s) + // ... + } + + public function update(string $key, $value): bool { + // delegate... + } + + public function delete(string $key): bool { + // delegate... + } + + public function all(): array { + return $this->registered; + } +} diff --git a/app/Core/Services/Options/WPOptionStorage.php b/app/Core/Services/Options/WPOptionStorage.php new file mode 100644 index 00000000..e87bca9e --- /dev/null +++ b/app/Core/Services/Options/WPOptionStorage.php @@ -0,0 +1,39 @@ + Date: Sat, 26 Apr 2025 12:18:13 +0600 Subject: [PATCH 2/3] Update --- app/Config/index.php | 0 app/Core/API/index.php | 0 app/Core/DB/Migrations/index.php | 0 app/Core/DB/Models/index.php | 0 app/Core/DB/Pagination/index.php | 0 app/Core/DB/Seeders/index.php | 0 app/Core/DB/Utils/index.php | 0 app/Core/DB/WP/index.php | 0 app/Core/DB/index.php | 0 app/Core/Helpers/index.php | 0 app/Core/Hooks/index.php | 0 app/Core/Routes/Middleware/index.php | 0 app/Core/Routes/index.php | 0 app/Core/Services/Options/index.php | 0 app/Core/Services/Widgets/index.php | 0 app/Core/Services/index.php | 0 app/Core/Updater/index.php | 0 app/Core/Utilities/Debug/index.php | 0 app/Core/Utilities/PFlogs/index.php | 0 app/Core/Utilities/index.php | 0 app/Core/index.php | 0 app/Hooks/index.php | 0 app/Providers/Options/index.php | 0 app/Providers/Widgets/index.php | 0 app/Providers/index.php | 0 app/REST/Controllers/WP/index.php | 0 app/REST/index.php | 0 app/Views/Admin/index.php | 0 app/Views/AdminAlpine/index.php | 0 app/Views/index.php | 0 app/index.php | 0 resources/assets/index.php | 0 resources/index.php | 0 resources/views/index.php | 0 34 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 app/Config/index.php delete mode 100644 app/Core/API/index.php delete mode 100644 app/Core/DB/Migrations/index.php delete mode 100644 app/Core/DB/Models/index.php delete mode 100644 app/Core/DB/Pagination/index.php delete mode 100644 app/Core/DB/Seeders/index.php delete mode 100644 app/Core/DB/Utils/index.php delete mode 100644 app/Core/DB/WP/index.php delete mode 100644 app/Core/DB/index.php delete mode 100644 app/Core/Helpers/index.php delete mode 100644 app/Core/Hooks/index.php delete mode 100644 app/Core/Routes/Middleware/index.php delete mode 100644 app/Core/Routes/index.php delete mode 100644 app/Core/Services/Options/index.php delete mode 100644 app/Core/Services/Widgets/index.php delete mode 100644 app/Core/Services/index.php delete mode 100644 app/Core/Updater/index.php delete mode 100644 app/Core/Utilities/Debug/index.php delete mode 100644 app/Core/Utilities/PFlogs/index.php delete mode 100644 app/Core/Utilities/index.php delete mode 100644 app/Core/index.php delete mode 100644 app/Hooks/index.php delete mode 100644 app/Providers/Options/index.php delete mode 100644 app/Providers/Widgets/index.php delete mode 100644 app/Providers/index.php delete mode 100644 app/REST/Controllers/WP/index.php delete mode 100644 app/REST/index.php delete mode 100644 app/Views/Admin/index.php delete mode 100644 app/Views/AdminAlpine/index.php delete mode 100644 app/Views/index.php delete mode 100644 app/index.php delete mode 100644 resources/assets/index.php delete mode 100644 resources/index.php delete mode 100644 resources/views/index.php diff --git a/app/Config/index.php b/app/Config/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/API/index.php b/app/Core/API/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/DB/Migrations/index.php b/app/Core/DB/Migrations/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/DB/Models/index.php b/app/Core/DB/Models/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/DB/Pagination/index.php b/app/Core/DB/Pagination/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/DB/Seeders/index.php b/app/Core/DB/Seeders/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/DB/Utils/index.php b/app/Core/DB/Utils/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/DB/WP/index.php b/app/Core/DB/WP/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/DB/index.php b/app/Core/DB/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/Helpers/index.php b/app/Core/Helpers/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/Hooks/index.php b/app/Core/Hooks/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/Routes/Middleware/index.php b/app/Core/Routes/Middleware/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/Routes/index.php b/app/Core/Routes/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/Services/Options/index.php b/app/Core/Services/Options/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/Services/Widgets/index.php b/app/Core/Services/Widgets/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/Services/index.php b/app/Core/Services/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/Updater/index.php b/app/Core/Updater/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/Utilities/Debug/index.php b/app/Core/Utilities/Debug/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/Utilities/PFlogs/index.php b/app/Core/Utilities/PFlogs/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/Utilities/index.php b/app/Core/Utilities/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Core/index.php b/app/Core/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Hooks/index.php b/app/Hooks/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Providers/Options/index.php b/app/Providers/Options/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Providers/Widgets/index.php b/app/Providers/Widgets/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Providers/index.php b/app/Providers/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/REST/Controllers/WP/index.php b/app/REST/Controllers/WP/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/REST/index.php b/app/REST/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Views/Admin/index.php b/app/Views/Admin/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Views/AdminAlpine/index.php b/app/Views/AdminAlpine/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Views/index.php b/app/Views/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/app/index.php b/app/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/resources/assets/index.php b/resources/assets/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/resources/index.php b/resources/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/resources/views/index.php b/resources/views/index.php deleted file mode 100644 index e69de29b..00000000 From ce59887a739fb29238672dba6d3309c6635c20ce Mon Sep 17 00:00:00 2001 From: mhrubel Date: Sat, 26 Apr 2025 12:19:28 +0600 Subject: [PATCH 3/3] Update --- app/Core/Services/Customize.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Core/Services/Customize.php b/app/Core/Services/Customize.php index bc787209..ff7e563b 100644 --- a/app/Core/Services/Customize.php +++ b/app/Core/Services/Customize.php @@ -1,6 +1,6 @@