From cea9a12b9c3dd2b06b1f74509174826aa74bac80 Mon Sep 17 00:00:00 2001 From: itsrafsanjani Date: Mon, 19 Aug 2024 14:57:16 +0600 Subject: [PATCH 1/8] feat: updates data api and scheduler add --- flywp.php | 38 +++++-- includes/Api.php | 1 + includes/Api/UpdatesData.php | 198 +++++++++++++++++++++++++++++++++++ includes/FlyApi.php | 8 +- 4 files changed, 234 insertions(+), 11 deletions(-) create mode 100644 includes/Api/UpdatesData.php diff --git a/flywp.php b/flywp.php index bb9d948..c78f817 100644 --- a/flywp.php +++ b/flywp.php @@ -43,6 +43,13 @@ final class FlyWP_Plugin { */ public $version = '1.3.1'; + /** + * API Endpoint. + * + * @var string + */ + public $api_endpoint = 'https://app.flywp.com/api/site-api'; + /** * Plugin Constructor. * @@ -53,6 +60,7 @@ private function __construct() { $this->add_action( 'plugins_loaded', 'init_plugin' ); register_activation_hook( __FILE__, [ $this, 'activate' ] ); + register_deactivation_hook(__FILE__, [ $this, 'deactivate']); } /** @@ -67,6 +75,10 @@ private function define_constants() { define( 'FLYWP_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); define( 'FLYWP_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); + if ( ! defined( 'FLYWP_API_ENDPOINT' ) ) { + define( 'FLYWP_API_ENDPOINT', $this->api_endpoint ); + } + if ( ! defined( 'FLYWP_API_KEY' ) ) { define( 'FLYWP_API_KEY', '' ); } @@ -84,6 +96,15 @@ public function activate() { flush_rewrite_rules( false ); } + /** + * Plugin activation hook. + * + * @return void + */ + public function deactivate() { + (new FlyWP\Api\UpdatesData())->deactivate(); + } + /** * Initialize plugin. * @@ -102,14 +123,15 @@ public function init_plugin() { $this->frontend = new FlyWP\Frontend(); } - $this->router = new FlyWP\Router(); - $this->rest = new FlyWP\Api(); - $this->fastcgi = new FlyWP\Fastcgi_Cache(); - $this->opcache = new FlyWP\Opcache(); - $this->flyapi = new FlyWP\FlyApi(); - $this->email = new FlyWP\Email(); - $this->optimize = new FlyWP\Optimizations(); - $this->litespeed = new FlyWP\Litespeed(); + $this->router = new FlyWP\Router(); + $this->rest = new FlyWP\Api(); + $this->fastcgi = new FlyWP\Fastcgi_Cache(); + $this->opcache = new FlyWP\Opcache(); + $this->flyapi = new FlyWP\FlyApi(); + $this->email = new FlyWP\Email(); + $this->optimize = new FlyWP\Optimizations(); + $this->litespeed = new FlyWP\Litespeed(); + $this->updates_data = new FlyWP\Api\UpdatesData(); } /** diff --git a/includes/Api.php b/includes/Api.php index 85f7570..a7fba72 100644 --- a/includes/Api.php +++ b/includes/Api.php @@ -27,6 +27,7 @@ public function __construct() { new Api\Updates(); new Api\Cache(); new Api\Health(); + new Api\UpdatesData(); } /** diff --git a/includes/Api/UpdatesData.php b/includes/Api/UpdatesData.php new file mode 100644 index 0000000..c84ddb5 --- /dev/null +++ b/includes/Api/UpdatesData.php @@ -0,0 +1,198 @@ +router->get( 'updates-data', [ $this, 'respond' ] ); + + // Register the cron event + add_action('flywp_send_updates_data', [$this, 'send_updates_data_to_api']); + + // Schedule the cron event if not already scheduled + if (!wp_next_scheduled('flywp_send_updates_data')) { + wp_schedule_event(time(), 'twicedaily', 'flywp_send_updates_data'); + } + } + + /** + * Send updates data to the remote API. + * + * @return void + */ + public function send_updates_data_to_api() { + $updates_data = [ + 'updates' => $this->get_formatted_updates_data(), + ]; + + flywp()->flyapi->post( '/updates-data', $updates_data ); + } + + /** + * Handle the request. + * + * @return void + */ + public function respond() { + $response = [ + 'updates' => $this->get_formatted_updates_data(), + ]; + + wp_send_json( $response ); + } + + /** + * Get formatted updates data. + * + * @return array + */ + private function get_formatted_updates_data() { + return [ + 'core' => $this->get_formatted_core_updates(), + 'plugins' => $this->get_formatted_plugin_updates(), + 'themes' => $this->get_formatted_theme_updates(), + ]; + } + + /** + * Get formatted core updates data. + * + * @return array + */ + private function get_formatted_core_updates() { + $core_data = $this->core_updates(); + + return [ + 'installed_version' => $core_data['version'], + 'latest_version' => $core_data['update_available'] ? $core_data['new_version'] : $core_data['version'], + ]; + } + + /** + * Get formatted plugin updates data. + * + * @return array + */ + private function get_formatted_plugin_updates() { + if ( ! function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + if ( ! function_exists( 'get_plugin_updates' ) ) { + require_once ABSPATH . 'wp-admin/includes/update.php'; + } + + $all_plugins = get_plugins(); + $plugin_updates = get_plugin_updates(); + + $formatted_plugins = []; + + foreach ( $all_plugins as $plugin_file => $plugin_data ) { + $slug = dirname( $plugin_file ); + $is_update_available = isset( $plugin_updates[ $plugin_file ] ); + + $plugin_info = [ + 'slug' => $slug, + 'name' => $plugin_data['Name'], + 'installed_version' => $plugin_data['Version'], + 'latest_version' => $is_update_available ? $plugin_updates[ $plugin_file ]->update->new_version : $plugin_data['Version'], + 'is_active' => is_plugin_active( $plugin_file ), + ]; + + $extra = [ + 'url' => $plugin_data['PluginURI'] ?? '', + 'author' => $plugin_data['Author'] ?? '', + 'file' => $plugin_file, + 'textdomain' => $plugin_data['TextDomain'] ?? '', + 'description' => $plugin_data['Description'] ?? '', + 'php' => $plugin_data['RequiresPHP'] ?? '', + ]; + + if ( ! empty( array_filter( $extra ) ) ) { + $plugin_info['extra'] = array_filter( $extra ); + } + + $formatted_plugins[] = $plugin_info; + } + + return $formatted_plugins; + } + + /** + * Get formatted theme updates data. + * + * @return array + */ + private function get_formatted_theme_updates() { + $all_themes = wp_get_themes(); + $theme_updates = get_theme_updates(); + + $formatted_themes = []; + + foreach ( $all_themes as $theme_slug => $theme ) { + $is_update_available = isset( $theme_updates[ $theme_slug ] ); + + $theme_info = [ + 'slug' => $theme_slug, + 'name' => $theme->get( 'Name' ), + 'installed_version' => $theme->get( 'Version' ), + 'latest_version' => $is_update_available ? $theme_updates[ $theme_slug ]->update['new_version'] : $theme->get( 'Version' ), + 'is_active' => ( get_stylesheet() === $theme_slug ), + ]; + + $extra = [ + 'url' => $theme->get( 'ThemeURI' ), + ]; + + if ( ! empty( array_filter( $extra ) ) ) { + $theme_info['extra'] = array_filter( $extra ); + } + + $formatted_themes[] = $theme_info; + } + + return $formatted_themes; + } + + /** + * Check if WordPress core has an update available. + * + * @return array + */ + private function core_updates() { + $current = get_bloginfo( 'version' ); + + if ( ! function_exists( 'get_preferred_from_update_core' ) ) { + require_once ABSPATH . 'wp-admin/includes/update.php'; + } + + $update = get_preferred_from_update_core(); + + $response = [ + 'version' => $current, + 'update_available' => false, + 'new_version' => null, + ]; + + if ( ! isset( $update->response ) || 'upgrade' !== $update->response ) { + return $response; + } + + $response['update_available'] = true; + $response['new_version'] = $update->current; + + return $response; + } + + /** + * Deactivate the scheduler when the plugin is deactivated. + */ + public function deactivate() { + $timestamp = wp_next_scheduled( 'flywp_send_updates_data' ); + if ( $timestamp ) { + wp_unschedule_event( $timestamp, 'flywp_send_updates_data' ); + } + } +} diff --git a/includes/FlyApi.php b/includes/FlyApi.php index 416c32c..100bbf3 100644 --- a/includes/FlyApi.php +++ b/includes/FlyApi.php @@ -36,7 +36,7 @@ public function cache_toggle( $action = 'enable', $type = 'fastcgi' ) { * @return string */ protected function get_endpoint() { - return apply_filters( 'flywp_api_endpoint', 'https://app.flywp.com/api/site-api' ); + return apply_filters( 'flywp_api_endpoint', FLYWP_API_ENDPOINT ); } /** @@ -73,7 +73,7 @@ public function get( $path ) { * Send a POST request to the API. * * @param string $path - * @param array $data + * @param array $data * * @return array|false */ @@ -86,11 +86,13 @@ public function post( $path, $data = [] ) { 'headers' => [ 'Authorization' => 'Bearer ' . flywp()->get_key(), ], - 'body' => $data, + 'body' => $data, ] ); if ( is_wp_error( $response ) ) { + error_log( print_r( $response, true ) ); + return false; } From 9aaf4de5749e0b843b0d16ff3b5fc20bf6fcfd8e Mon Sep 17 00:00:00 2001 From: itsrafsanjani Date: Mon, 19 Aug 2024 15:40:51 +0600 Subject: [PATCH 2/8] fix: formatting --- flywp.php | 4 ++-- includes/Api.php | 2 +- includes/Api/UpdatesData.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/flywp.php b/flywp.php index c78f817..2e1b961 100644 --- a/flywp.php +++ b/flywp.php @@ -60,7 +60,7 @@ private function __construct() { $this->add_action( 'plugins_loaded', 'init_plugin' ); register_activation_hook( __FILE__, [ $this, 'activate' ] ); - register_deactivation_hook(__FILE__, [ $this, 'deactivate']); + register_deactivation_hook( __FILE__, [ $this, 'deactivate' ] ); } /** @@ -102,7 +102,7 @@ public function activate() { * @return void */ public function deactivate() { - (new FlyWP\Api\UpdatesData())->deactivate(); + ( new FlyWP\Api\UpdatesData() )->deactivate(); } /** diff --git a/includes/Api.php b/includes/Api.php index a7fba72..608f502 100644 --- a/includes/Api.php +++ b/includes/Api.php @@ -53,7 +53,7 @@ public function get_bearer_token() { return false; } - $auth_header = wp_unslash( $_SERVER['HTTP_AUTHORIZATION'] ); + $auth_header = sanitize_text_field( wp_unslash( $_SERVER['HTTP_AUTHORIZATION'] ) ); if ( ! preg_match( '/Bearer\s(\S+)/', $auth_header, $matches ) ) { return false; diff --git a/includes/Api/UpdatesData.php b/includes/Api/UpdatesData.php index c84ddb5..9a5273a 100644 --- a/includes/Api/UpdatesData.php +++ b/includes/Api/UpdatesData.php @@ -10,11 +10,11 @@ public function __construct() { flywp()->router->get( 'updates-data', [ $this, 'respond' ] ); // Register the cron event - add_action('flywp_send_updates_data', [$this, 'send_updates_data_to_api']); + add_action( 'flywp_send_updates_data', [ $this, 'send_updates_data_to_api' ] ); // Schedule the cron event if not already scheduled - if (!wp_next_scheduled('flywp_send_updates_data')) { - wp_schedule_event(time(), 'twicedaily', 'flywp_send_updates_data'); + if ( ! wp_next_scheduled( 'flywp_send_updates_data' ) ) { + wp_schedule_event( time(), 'twicedaily', 'flywp_send_updates_data' ); } } From ec206eecf30f6b6a21a1931adaabde73990db4c4 Mon Sep 17 00:00:00 2001 From: itsrafsanjani Date: Tue, 20 Aug 2024 12:17:22 +0600 Subject: [PATCH 3/8] fix: response only updates data --- includes/Api/UpdatesData.php | 41 ++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/includes/Api/UpdatesData.php b/includes/Api/UpdatesData.php index 9a5273a..b02a504 100644 --- a/includes/Api/UpdatesData.php +++ b/includes/Api/UpdatesData.php @@ -25,7 +25,8 @@ public function __construct() { */ public function send_updates_data_to_api() { $updates_data = [ - 'updates' => $this->get_formatted_updates_data(), + 'wp_version' => get_bloginfo( 'version' ), + 'updates' => $this->get_formatted_updates_data(), ]; flywp()->flyapi->post( '/updates-data', $updates_data ); @@ -38,7 +39,8 @@ public function send_updates_data_to_api() { */ public function respond() { $response = [ - 'updates' => $this->get_formatted_updates_data(), + 'wp_version' => get_bloginfo( 'version' ), + 'updates' => $this->get_formatted_updates_data(), ]; wp_send_json( $response ); @@ -65,9 +67,13 @@ private function get_formatted_updates_data() { private function get_formatted_core_updates() { $core_data = $this->core_updates(); + if ( ! $core_data['update_available'] ) { + return []; + } + return [ 'installed_version' => $core_data['version'], - 'latest_version' => $core_data['update_available'] ? $core_data['new_version'] : $core_data['version'], + 'latest_version' => $core_data['new_version'], ]; } @@ -89,25 +95,25 @@ private function get_formatted_plugin_updates() { $formatted_plugins = []; - foreach ( $all_plugins as $plugin_file => $plugin_data ) { - $slug = dirname( $plugin_file ); - $is_update_available = isset( $plugin_updates[ $plugin_file ] ); + foreach ( $plugin_updates as $plugin_file => $plugin_data ) { + $plugin_info = $all_plugins[ $plugin_file ]; + $slug = dirname( $plugin_file ); $plugin_info = [ 'slug' => $slug, - 'name' => $plugin_data['Name'], - 'installed_version' => $plugin_data['Version'], - 'latest_version' => $is_update_available ? $plugin_updates[ $plugin_file ]->update->new_version : $plugin_data['Version'], + 'name' => $plugin_info['Name'], + 'installed_version' => $plugin_info['Version'], + 'latest_version' => $plugin_data->update->new_version, 'is_active' => is_plugin_active( $plugin_file ), ]; $extra = [ - 'url' => $plugin_data['PluginURI'] ?? '', - 'author' => $plugin_data['Author'] ?? '', + 'url' => $plugin_info['PluginURI'] ?? '', + 'author' => $plugin_info['Author'] ?? '', 'file' => $plugin_file, - 'textdomain' => $plugin_data['TextDomain'] ?? '', - 'description' => $plugin_data['Description'] ?? '', - 'php' => $plugin_data['RequiresPHP'] ?? '', + 'textdomain' => $plugin_info['TextDomain'] ?? '', + 'description' => $plugin_info['Description'] ?? '', + 'php' => $plugin_info['RequiresPHP'] ?? '', ]; if ( ! empty( array_filter( $extra ) ) ) { @@ -126,19 +132,18 @@ private function get_formatted_plugin_updates() { * @return array */ private function get_formatted_theme_updates() { - $all_themes = wp_get_themes(); $theme_updates = get_theme_updates(); $formatted_themes = []; - foreach ( $all_themes as $theme_slug => $theme ) { - $is_update_available = isset( $theme_updates[ $theme_slug ] ); + foreach ( $theme_updates as $theme_slug => $theme_data ) { + $theme = wp_get_theme( $theme_slug ); $theme_info = [ 'slug' => $theme_slug, 'name' => $theme->get( 'Name' ), 'installed_version' => $theme->get( 'Version' ), - 'latest_version' => $is_update_available ? $theme_updates[ $theme_slug ]->update['new_version'] : $theme->get( 'Version' ), + 'latest_version' => $theme_data->update['new_version'], 'is_active' => ( get_stylesheet() === $theme_slug ), ]; From 0cc8b744693480b80f83405001e82a720f0888f0 Mon Sep 17 00:00:00 2001 From: itsrafsanjani Date: Tue, 20 Aug 2024 15:46:30 +0600 Subject: [PATCH 4/8] refactor: UpdatesData code --- includes/Api/UpdatesData.php | 246 +++++++++++++++++++++-------------- 1 file changed, 145 insertions(+), 101 deletions(-) diff --git a/includes/Api/UpdatesData.php b/includes/Api/UpdatesData.php index b02a504..f1a543f 100644 --- a/includes/Api/UpdatesData.php +++ b/includes/Api/UpdatesData.php @@ -3,47 +3,60 @@ namespace FlyWP\Api; class UpdatesData { + private const CRON_HOOK = 'flywp_send_updates_data'; + private const CRON_INTERVAL = 'twicedaily'; + /** * UpdatesData constructor. */ public function __construct() { - flywp()->router->get( 'updates-data', [ $this, 'respond' ] ); + $this->initializeRoutes(); + $this->initializeCronJob(); + } - // Register the cron event - add_action( 'flywp_send_updates_data', [ $this, 'send_updates_data_to_api' ] ); + /** + * Initialize API routes. + */ + private function initializeRoutes(): void { + flywp()->router->get( 'updates-data', [ $this, 'handleApiRequest' ] ); + } - // Schedule the cron event if not already scheduled - if ( ! wp_next_scheduled( 'flywp_send_updates_data' ) ) { - wp_schedule_event( time(), 'twicedaily', 'flywp_send_updates_data' ); + /** + * Initialize cron job for sending updates data. + */ + private function initializeCronJob(): void { + add_action( self::CRON_HOOK, [ $this, 'sendUpdatesDataToApi' ] ); + + if ( ! wp_next_scheduled( self::CRON_HOOK ) ) { + wp_schedule_event( time(), self::CRON_INTERVAL, self::CRON_HOOK ); } } /** * Send updates data to the remote API. - * - * @return void */ - public function send_updates_data_to_api() { - $updates_data = [ - 'wp_version' => get_bloginfo( 'version' ), - 'updates' => $this->get_formatted_updates_data(), - ]; + public function sendUpdatesDataToApi(): void { + $updatesData = $this->getUpdatesData(); + flywp()->flyapi->post( '/updates-data', $updatesData ); + } - flywp()->flyapi->post( '/updates-data', $updates_data ); + /** + * Handle the API request. + */ + public function handleApiRequest(): void { + wp_send_json( $this->getUpdatesData() ); } /** - * Handle the request. + * Get updates data. * - * @return void + * @return array */ - public function respond() { - $response = [ + private function getUpdatesData(): array { + return [ 'wp_version' => get_bloginfo( 'version' ), - 'updates' => $this->get_formatted_updates_data(), + 'updates' => $this->getFormattedUpdatesData(), ]; - - wp_send_json( $response ); } /** @@ -51,11 +64,11 @@ public function respond() { * * @return array */ - private function get_formatted_updates_data() { + private function getFormattedUpdatesData(): array { return [ - 'core' => $this->get_formatted_core_updates(), - 'plugins' => $this->get_formatted_plugin_updates(), - 'themes' => $this->get_formatted_theme_updates(), + 'core' => $this->getFormattedCoreUpdates(), + 'plugins' => $this->getFormattedPluginUpdates(), + 'themes' => $this->getFormattedThemeUpdates(), ]; } @@ -64,16 +77,16 @@ private function get_formatted_updates_data() { * * @return array */ - private function get_formatted_core_updates() { - $core_data = $this->core_updates(); + private function getFormattedCoreUpdates(): array { + $coreData = $this->getCoreUpdates(); - if ( ! $core_data['update_available'] ) { + if ( ! $coreData['update_available'] ) { return []; } return [ - 'installed_version' => $core_data['version'], - 'latest_version' => $core_data['new_version'], + 'installed_version' => $coreData['version'], + 'latest_version' => $coreData['new_version'], ]; } @@ -82,48 +95,22 @@ private function get_formatted_core_updates() { * * @return array */ - private function get_formatted_plugin_updates() { - if ( ! function_exists( 'get_plugins' ) ) { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - } - if ( ! function_exists( 'get_plugin_updates' ) ) { - require_once ABSPATH . 'wp-admin/includes/update.php'; - } + private function getFormattedPluginUpdates(): array { + $this->loadRequiredFiles(); + + $allPlugins = get_plugins(); + $pluginUpdates = get_plugin_updates(); + + $formattedPlugins = []; + + foreach ( $pluginUpdates as $pluginFile => $pluginData ) { + $pluginInfo = $allPlugins[ $pluginFile ]; + $slug = dirname( $pluginFile ); - $all_plugins = get_plugins(); - $plugin_updates = get_plugin_updates(); - - $formatted_plugins = []; - - foreach ( $plugin_updates as $plugin_file => $plugin_data ) { - $plugin_info = $all_plugins[ $plugin_file ]; - $slug = dirname( $plugin_file ); - - $plugin_info = [ - 'slug' => $slug, - 'name' => $plugin_info['Name'], - 'installed_version' => $plugin_info['Version'], - 'latest_version' => $plugin_data->update->new_version, - 'is_active' => is_plugin_active( $plugin_file ), - ]; - - $extra = [ - 'url' => $plugin_info['PluginURI'] ?? '', - 'author' => $plugin_info['Author'] ?? '', - 'file' => $plugin_file, - 'textdomain' => $plugin_info['TextDomain'] ?? '', - 'description' => $plugin_info['Description'] ?? '', - 'php' => $plugin_info['RequiresPHP'] ?? '', - ]; - - if ( ! empty( array_filter( $extra ) ) ) { - $plugin_info['extra'] = array_filter( $extra ); - } - - $formatted_plugins[] = $plugin_info; + $formattedPlugins[] = $this->formatPluginData( $pluginInfo, $pluginData, $pluginFile, $slug ); } - return $formatted_plugins; + return $formattedPlugins; } /** @@ -131,34 +118,17 @@ private function get_formatted_plugin_updates() { * * @return array */ - private function get_formatted_theme_updates() { - $theme_updates = get_theme_updates(); + private function getFormattedThemeUpdates(): array { + $themeUpdates = get_theme_updates(); - $formatted_themes = []; + $formattedThemes = []; - foreach ( $theme_updates as $theme_slug => $theme_data ) { - $theme = wp_get_theme( $theme_slug ); - - $theme_info = [ - 'slug' => $theme_slug, - 'name' => $theme->get( 'Name' ), - 'installed_version' => $theme->get( 'Version' ), - 'latest_version' => $theme_data->update['new_version'], - 'is_active' => ( get_stylesheet() === $theme_slug ), - ]; - - $extra = [ - 'url' => $theme->get( 'ThemeURI' ), - ]; - - if ( ! empty( array_filter( $extra ) ) ) { - $theme_info['extra'] = array_filter( $extra ); - } - - $formatted_themes[] = $theme_info; + foreach ( $themeUpdates as $themeSlug => $themeData ) { + $theme = wp_get_theme( $themeSlug ); + $formattedThemes[] = $this->formatThemeData( $theme, $themeData, $themeSlug ); } - return $formatted_themes; + return $formattedThemes; } /** @@ -166,12 +136,10 @@ private function get_formatted_theme_updates() { * * @return array */ - private function core_updates() { + private function getCoreUpdates(): array { $current = get_bloginfo( 'version' ); - if ( ! function_exists( 'get_preferred_from_update_core' ) ) { - require_once ABSPATH . 'wp-admin/includes/update.php'; - } + $this->loadRequiredFiles(); $update = get_preferred_from_update_core(); @@ -181,7 +149,7 @@ private function core_updates() { 'new_version' => null, ]; - if ( ! isset( $update->response ) || 'upgrade' !== $update->response ) { + if ( ! isset( $update->response ) || $update->response !== 'upgrade' ) { return $response; } @@ -191,13 +159,89 @@ private function core_updates() { return $response; } + /** + * Format plugin data. + * + * @param array $pluginInfo + * @param object $pluginData + * @param string $pluginFile + * @param string $slug + * + * @return array + */ + private function formatPluginData( array $pluginInfo, object $pluginData, string $pluginFile, string $slug ): array { + $formattedPlugin = [ + 'slug' => $slug, + 'name' => $pluginInfo['Name'], + 'installed_version' => $pluginInfo['Version'], + 'latest_version' => $pluginData->update->new_version, + 'is_active' => is_plugin_active( $pluginFile ), + ]; + + $extra = [ + 'url' => $pluginInfo['PluginURI'] ?? '', + 'author' => $pluginInfo['Author'] ?? '', + 'file' => $pluginFile, + 'textdomain' => $pluginInfo['TextDomain'] ?? '', + 'description' => $pluginInfo['Description'] ?? '', + 'php' => $pluginInfo['RequiresPHP'] ?? '', + ]; + + if ( ! empty( array_filter( $extra ) ) ) { + $formattedPlugin['extra'] = array_filter( $extra ); + } + + return $formattedPlugin; + } + + /** + * Format theme data. + * + * @param \WP_Theme $theme + * @param object $themeData + * @param string $themeSlug + * + * @return array + */ + private function formatThemeData( \WP_Theme $theme, object $themeData, string $themeSlug ): array { + $formattedTheme = [ + 'slug' => $themeSlug, + 'name' => $theme->get( 'Name' ), + 'installed_version' => $theme->get( 'Version' ), + 'latest_version' => $themeData->update['new_version'], + 'is_active' => ( get_stylesheet() === $themeSlug ), + ]; + + $extra = [ + 'url' => $theme->get( 'ThemeURI' ), + ]; + + if ( ! empty( array_filter( $extra ) ) ) { + $formattedTheme['extra'] = array_filter( $extra ); + } + + return $formattedTheme; + } + + /** + * Load required WordPress files. + */ + private function loadRequiredFiles(): void { + if ( ! function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + if ( ! function_exists( 'get_plugin_updates' ) ) { + require_once ABSPATH . 'wp-admin/includes/update.php'; + } + } + /** * Deactivate the scheduler when the plugin is deactivated. */ - public function deactivate() { - $timestamp = wp_next_scheduled( 'flywp_send_updates_data' ); + public function deactivate(): void { + $timestamp = wp_next_scheduled( self::CRON_HOOK ); if ( $timestamp ) { - wp_unschedule_event( $timestamp, 'flywp_send_updates_data' ); + wp_unschedule_event( $timestamp, self::CRON_HOOK ); } } } From 08bea452e27f97f6f51cd5e811bed4a768345a53 Mon Sep 17 00:00:00 2001 From: itsrafsanjani Date: Tue, 20 Aug 2024 15:49:26 +0600 Subject: [PATCH 5/8] refactor: fix phpcs --- includes/Api/UpdatesData.php | 138 ++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 68 deletions(-) diff --git a/includes/Api/UpdatesData.php b/includes/Api/UpdatesData.php index f1a543f..26b33e8 100644 --- a/includes/Api/UpdatesData.php +++ b/includes/Api/UpdatesData.php @@ -2,6 +2,8 @@ namespace FlyWP\Api; +use WP_Error; + class UpdatesData { private const CRON_HOOK = 'flywp_send_updates_data'; private const CRON_INTERVAL = 'twicedaily'; @@ -10,22 +12,22 @@ class UpdatesData { * UpdatesData constructor. */ public function __construct() { - $this->initializeRoutes(); - $this->initializeCronJob(); + $this->initialize_routes(); + $this->initialize_cron_job(); } /** * Initialize API routes. */ - private function initializeRoutes(): void { - flywp()->router->get( 'updates-data', [ $this, 'handleApiRequest' ] ); + private function initialize_routes(): void { + flywp()->router->get( 'updates-data', [ $this, 'respond' ] ); } /** * Initialize cron job for sending updates data. */ - private function initializeCronJob(): void { - add_action( self::CRON_HOOK, [ $this, 'sendUpdatesDataToApi' ] ); + private function initialize_cron_job(): void { + add_action( self::CRON_HOOK, [ $this, 'send_updates_data_to_api' ] ); if ( ! wp_next_scheduled( self::CRON_HOOK ) ) { wp_schedule_event( time(), self::CRON_INTERVAL, self::CRON_HOOK ); @@ -35,16 +37,16 @@ private function initializeCronJob(): void { /** * Send updates data to the remote API. */ - public function sendUpdatesDataToApi(): void { - $updatesData = $this->getUpdatesData(); - flywp()->flyapi->post( '/updates-data', $updatesData ); + public function send_updates_data_to_api(): void { + $updates_data = $this->get_updates_data(); + flywp()->flyapi->post( '/updates-data', $updates_data ); } /** * Handle the API request. */ - public function handleApiRequest(): void { - wp_send_json( $this->getUpdatesData() ); + public function respond(): void { + wp_send_json( $this->get_updates_data() ); } /** @@ -52,10 +54,10 @@ public function handleApiRequest(): void { * * @return array */ - private function getUpdatesData(): array { + private function get_updates_data(): array { return [ 'wp_version' => get_bloginfo( 'version' ), - 'updates' => $this->getFormattedUpdatesData(), + 'updates' => $this->get_formatted_updates_data(), ]; } @@ -64,11 +66,11 @@ private function getUpdatesData(): array { * * @return array */ - private function getFormattedUpdatesData(): array { + private function get_formatted_updates_data(): array { return [ - 'core' => $this->getFormattedCoreUpdates(), - 'plugins' => $this->getFormattedPluginUpdates(), - 'themes' => $this->getFormattedThemeUpdates(), + 'core' => $this->get_formatted_core_updates(), + 'plugins' => $this->get_formatted_plugin_updates(), + 'themes' => $this->get_formatted_theme_updates(), ]; } @@ -77,16 +79,16 @@ private function getFormattedUpdatesData(): array { * * @return array */ - private function getFormattedCoreUpdates(): array { - $coreData = $this->getCoreUpdates(); + private function get_formatted_core_updates(): array { + $core_data = $this->get_core_updates(); - if ( ! $coreData['update_available'] ) { + if ( ! $core_data['update_available'] ) { return []; } return [ - 'installed_version' => $coreData['version'], - 'latest_version' => $coreData['new_version'], + 'installed_version' => $core_data['version'], + 'latest_version' => $core_data['new_version'], ]; } @@ -95,22 +97,22 @@ private function getFormattedCoreUpdates(): array { * * @return array */ - private function getFormattedPluginUpdates(): array { - $this->loadRequiredFiles(); + private function get_formatted_plugin_updates(): array { + $this->load_required_files(); - $allPlugins = get_plugins(); - $pluginUpdates = get_plugin_updates(); + $all_plugins = get_plugins(); + $plugin_updates = get_plugin_updates(); - $formattedPlugins = []; + $formatted_plugins = []; - foreach ( $pluginUpdates as $pluginFile => $pluginData ) { - $pluginInfo = $allPlugins[ $pluginFile ]; - $slug = dirname( $pluginFile ); + foreach ( $plugin_updates as $plugin_file => $plugin_data ) { + $plugin_info = $all_plugins[ $plugin_file ]; + $slug = dirname( $plugin_file ); - $formattedPlugins[] = $this->formatPluginData( $pluginInfo, $pluginData, $pluginFile, $slug ); + $formatted_plugins[] = $this->format_plugin_data( $plugin_info, $plugin_data, $plugin_file, $slug ); } - return $formattedPlugins; + return $formatted_plugins; } /** @@ -118,17 +120,17 @@ private function getFormattedPluginUpdates(): array { * * @return array */ - private function getFormattedThemeUpdates(): array { - $themeUpdates = get_theme_updates(); + private function get_formatted_theme_updates(): array { + $theme_updates = get_theme_updates(); - $formattedThemes = []; + $formatted_themes = []; - foreach ( $themeUpdates as $themeSlug => $themeData ) { - $theme = wp_get_theme( $themeSlug ); - $formattedThemes[] = $this->formatThemeData( $theme, $themeData, $themeSlug ); + foreach ( $theme_updates as $theme_slug => $theme_data ) { + $theme = wp_get_theme( $theme_slug ); + $formatted_themes[] = $this->format_theme_data( $theme, $theme_data, $theme_slug ); } - return $formattedThemes; + return $formatted_themes; } /** @@ -136,10 +138,10 @@ private function getFormattedThemeUpdates(): array { * * @return array */ - private function getCoreUpdates(): array { + private function get_core_updates(): array { $current = get_bloginfo( 'version' ); - $this->loadRequiredFiles(); + $this->load_required_files(); $update = get_preferred_from_update_core(); @@ -162,54 +164,54 @@ private function getCoreUpdates(): array { /** * Format plugin data. * - * @param array $pluginInfo - * @param object $pluginData - * @param string $pluginFile + * @param array $plugin_info + * @param object $plugin_data + * @param string $plugin_file * @param string $slug * * @return array */ - private function formatPluginData( array $pluginInfo, object $pluginData, string $pluginFile, string $slug ): array { - $formattedPlugin = [ + private function format_plugin_data( array $plugin_info, object $plugin_data, string $plugin_file, string $slug ): array { + $formatted_plugin = [ 'slug' => $slug, - 'name' => $pluginInfo['Name'], - 'installed_version' => $pluginInfo['Version'], - 'latest_version' => $pluginData->update->new_version, - 'is_active' => is_plugin_active( $pluginFile ), + 'name' => $plugin_info['Name'], + 'installed_version' => $plugin_info['Version'], + 'latest_version' => $plugin_data->update->new_version, + 'is_active' => is_plugin_active( $plugin_file ), ]; $extra = [ - 'url' => $pluginInfo['PluginURI'] ?? '', - 'author' => $pluginInfo['Author'] ?? '', - 'file' => $pluginFile, - 'textdomain' => $pluginInfo['TextDomain'] ?? '', - 'description' => $pluginInfo['Description'] ?? '', - 'php' => $pluginInfo['RequiresPHP'] ?? '', + 'url' => $plugin_info['PluginURI'] ?? '', + 'author' => $plugin_info['Author'] ?? '', + 'file' => $plugin_file, + 'textdomain' => $plugin_info['TextDomain'] ?? '', + 'description' => $plugin_info['Description'] ?? '', + 'php' => $plugin_info['RequiresPHP'] ?? '', ]; if ( ! empty( array_filter( $extra ) ) ) { - $formattedPlugin['extra'] = array_filter( $extra ); + $formatted_plugin['extra'] = array_filter( $extra ); } - return $formattedPlugin; + return $formatted_plugin; } /** * Format theme data. * * @param \WP_Theme $theme - * @param object $themeData - * @param string $themeSlug + * @param object $theme_data + * @param string $theme_slug * * @return array */ - private function formatThemeData( \WP_Theme $theme, object $themeData, string $themeSlug ): array { - $formattedTheme = [ - 'slug' => $themeSlug, + private function format_theme_data( \WP_Theme $theme, object $theme_data, string $theme_slug ): array { + $formatted_theme = [ + 'slug' => $theme_slug, 'name' => $theme->get( 'Name' ), 'installed_version' => $theme->get( 'Version' ), - 'latest_version' => $themeData->update['new_version'], - 'is_active' => ( get_stylesheet() === $themeSlug ), + 'latest_version' => $theme_data->update['new_version'], + 'is_active' => ( get_stylesheet() === $theme_slug ), ]; $extra = [ @@ -217,16 +219,16 @@ private function formatThemeData( \WP_Theme $theme, object $themeData, string $t ]; if ( ! empty( array_filter( $extra ) ) ) { - $formattedTheme['extra'] = array_filter( $extra ); + $formatted_theme['extra'] = array_filter( $extra ); } - return $formattedTheme; + return $formatted_theme; } /** * Load required WordPress files. */ - private function loadRequiredFiles(): void { + private function load_required_files(): void { if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } From f9da23aec2b1ac5b598e5f268872aa8145e2e9f9 Mon Sep 17 00:00:00 2001 From: itsrafsanjani Date: Tue, 3 Sep 2024 10:27:50 +0600 Subject: [PATCH 6/8] fix: get_site_url --- includes/Admin.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/includes/Admin.php b/includes/Admin.php index 3118822..dab5fa7 100644 --- a/includes/Admin.php +++ b/includes/Admin.php @@ -145,8 +145,7 @@ private function get_site_url( $info ) { } return sprintf( - 'https://app.flywp.com/servers/%d/sites/%d', - $info['server_id'], + 'https://app.flywp.com/site/%d', $info['id'] ); } From 8aec760b2f20ac989e0156d25e26e5c1fd672923 Mon Sep 17 00:00:00 2001 From: itsrafsanjani Date: Tue, 3 Sep 2024 10:40:18 +0600 Subject: [PATCH 7/8] fix: Admin.php phpcs issue --- includes/Admin.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/includes/Admin.php b/includes/Admin.php index dab5fa7..0207076 100644 --- a/includes/Admin.php +++ b/includes/Admin.php @@ -16,7 +16,7 @@ class Admin { */ public const SCREEN_NAME = 'dashboard_page_flywp'; - public $fastcgi = null; + public $fastcgi = null; public $litespeed = null; /** @@ -103,9 +103,10 @@ public function render_admin_page() { ]; // phpcs:ignore WordPress.Security.NonceVerification.Recommended - $active_tab = isset( $_GET['tab'] ) && array_key_exists( $_GET['tab'], $tabs ) ? $_GET['tab'] : 'cache'; - $site_info = $this->fetch_site_info(); - $app_site_url = $this->get_site_url( $site_info ); + $tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : ''; + $active_tab = array_key_exists( $tab, $tabs ) ? $tab : 'cache'; + $site_info = $this->fetch_site_info(); + $app_site_url = $this->get_site_url( $site_info ); include FLYWP_PLUGIN_DIR . '/views/admin.php'; } From 9e92b7227e8914db33aed6d2af7a5b7abac92966 Mon Sep 17 00:00:00 2001 From: itsrafsanjani Date: Fri, 13 Sep 2024 14:34:46 +0600 Subject: [PATCH 8/8] fix: remove const FLYWP_API_ENDPOINT --- flywp.php | 11 ----------- includes/FlyApi.php | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/flywp.php b/flywp.php index 2e1b961..45d7ce5 100644 --- a/flywp.php +++ b/flywp.php @@ -43,13 +43,6 @@ final class FlyWP_Plugin { */ public $version = '1.3.1'; - /** - * API Endpoint. - * - * @var string - */ - public $api_endpoint = 'https://app.flywp.com/api/site-api'; - /** * Plugin Constructor. * @@ -75,10 +68,6 @@ private function define_constants() { define( 'FLYWP_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); define( 'FLYWP_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); - if ( ! defined( 'FLYWP_API_ENDPOINT' ) ) { - define( 'FLYWP_API_ENDPOINT', $this->api_endpoint ); - } - if ( ! defined( 'FLYWP_API_KEY' ) ) { define( 'FLYWP_API_KEY', '' ); } diff --git a/includes/FlyApi.php b/includes/FlyApi.php index 100bbf3..4ea4afc 100644 --- a/includes/FlyApi.php +++ b/includes/FlyApi.php @@ -36,7 +36,7 @@ public function cache_toggle( $action = 'enable', $type = 'fastcgi' ) { * @return string */ protected function get_endpoint() { - return apply_filters( 'flywp_api_endpoint', FLYWP_API_ENDPOINT ); + return apply_filters( 'flywp_api_endpoint', 'https://app.flywp.com/api/site-api' ); } /**