Skip to content

Commit

Permalink
Merge pull request #9 from flywp/develop
Browse files Browse the repository at this point in the history
Release v1.4.0
  • Loading branch information
alaminfirdows authored Sep 18, 2024
2 parents 3d39e44 + 0aa2360 commit 9d7ea6f
Show file tree
Hide file tree
Showing 5 changed files with 280 additions and 17 deletions.
27 changes: 19 additions & 8 deletions flywp.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ private function __construct() {

$this->add_action( 'plugins_loaded', 'init_plugin' );
register_activation_hook( __FILE__, [ $this, 'activate' ] );
register_deactivation_hook( __FILE__, [ $this, 'deactivate' ] );
}

/**
Expand Down Expand Up @@ -84,6 +85,15 @@ public function activate() {
flush_rewrite_rules( false );
}

/**
* Plugin activation hook.
*
* @return void
*/
public function deactivate() {
( new FlyWP\Api\UpdatesData() )->deactivate();
}

/**
* Initialize plugin.
*
Expand All @@ -102,14 +112,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();
}

/**
Expand Down
12 changes: 6 additions & 6 deletions includes/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Admin {
*/
public const SCREEN_NAME = 'dashboard_page_flywp';

public $fastcgi = null;
public $fastcgi = null;
public $litespeed = null;

/**
Expand Down Expand Up @@ -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';
}
Expand Down Expand Up @@ -145,8 +146,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']
);
}
Expand Down
3 changes: 2 additions & 1 deletion includes/Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public function __construct() {
new Api\Updates();
new Api\Cache();
new Api\Health();
new Api\UpdatesData();
}

/**
Expand All @@ -52,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;
Expand Down
249 changes: 249 additions & 0 deletions includes/Api/UpdatesData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
<?php

namespace FlyWP\Api;

use WP_Error;

class UpdatesData {
private const CRON_HOOK = 'flywp_send_updates_data';
private const CRON_INTERVAL = 'twicedaily';

/**
* UpdatesData constructor.
*/
public function __construct() {
$this->initialize_routes();
$this->initialize_cron_job();
}

/**
* Initialize API routes.
*/
private function initialize_routes(): void {
flywp()->router->get( 'updates-data', [ $this, 'respond' ] );
}

/**
* Initialize cron job for sending updates data.
*/
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 );
}
}

/**
* Send updates data to the remote API.
*/
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 respond(): void {
wp_send_json( $this->get_updates_data() );
}

/**
* Get updates data.
*
* @return array
*/
private function get_updates_data(): array {
return [
'wp_version' => get_bloginfo( 'version' ),
'updates' => $this->get_formatted_updates_data(),
];
}

/**
* Get formatted updates data.
*
* @return array
*/
private function get_formatted_updates_data(): array {
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(): array {
$core_data = $this->get_core_updates();

if ( ! $core_data['update_available'] ) {
return [];
}

return [
'installed_version' => $core_data['version'],
'latest_version' => $core_data['new_version'],
];
}

/**
* Get formatted plugin updates data.
*
* @return array
*/
private function get_formatted_plugin_updates(): array {
$this->load_required_files();

$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 );

$formatted_plugins[] = $this->format_plugin_data( $plugin_info, $plugin_data, $plugin_file, $slug );
}

return $formatted_plugins;
}

/**
* Get formatted theme updates data.
*
* @return array
*/
private function get_formatted_theme_updates(): array {
$theme_updates = get_theme_updates();

$formatted_themes = [];

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 $formatted_themes;
}

/**
* Check if WordPress core has an update available.
*
* @return array
*/
private function get_core_updates(): array {
$current = get_bloginfo( 'version' );

$this->load_required_files();

$update = get_preferred_from_update_core();

$response = [
'version' => $current,
'update_available' => false,
'new_version' => null,
];

if ( ! isset( $update->response ) || $update->response !== 'upgrade' ) {
return $response;
}

$response['update_available'] = true;
$response['new_version'] = $update->current;

return $response;
}

/**
* Format plugin data.
*
* @param array $plugin_info
* @param object $plugin_data
* @param string $plugin_file
* @param string $slug
*
* @return array
*/
private function format_plugin_data( array $plugin_info, object $plugin_data, string $plugin_file, string $slug ): array {
$formatted_plugin = [
'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 ) ) ) {
$formatted_plugin['extra'] = array_filter( $extra );
}

return $formatted_plugin;
}

/**
* Format theme data.
*
* @param \WP_Theme $theme
* @param object $theme_data
* @param string $theme_slug
*
* @return array
*/
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' => $theme_data->update['new_version'],
'is_active' => ( get_stylesheet() === $theme_slug ),
];

$extra = [
'url' => $theme->get( 'ThemeURI' ),
];

if ( ! empty( array_filter( $extra ) ) ) {
$formatted_theme['extra'] = array_filter( $extra );
}

return $formatted_theme;
}

/**
* Load required WordPress files.
*/
private function load_required_files(): 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(): void {
$timestamp = wp_next_scheduled( self::CRON_HOOK );
if ( $timestamp ) {
wp_unschedule_event( $timestamp, self::CRON_HOOK );
}
}
}
6 changes: 4 additions & 2 deletions includes/FlyApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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;
}

Expand Down

0 comments on commit 9d7ea6f

Please sign in to comment.