268 lines
6.6 KiB
PHP
268 lines
6.6 KiB
PHP
<?php
|
|
|
|
namespace Code_Snippets;
|
|
|
|
use Code_Snippets\Cloud\Cloud_Search_List_Table;
|
|
use function Code_Snippets\Settings\get_setting;
|
|
|
|
/**
|
|
* This class handles the welcome menu.
|
|
*
|
|
* @since 3.7.0
|
|
* @package Code_Snippets
|
|
*/
|
|
class Welcome_Menu extends Admin_Menu {
|
|
|
|
/**
|
|
* URL for the welcome page data.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected const WELCOME_JSON_URL = 'https://codesnippets.pro/wp-content/uploads/cs_welcome/cs_welcome.json';
|
|
|
|
/**
|
|
* Limit of number of items to display when loading lists of items.
|
|
*
|
|
* @var int
|
|
*/
|
|
protected const ITEM_LIMIT = 4;
|
|
|
|
/**
|
|
* Limit of number of items of historic versions to display in the changelog.
|
|
*
|
|
* @var int
|
|
*/
|
|
protected const MAX_CHANGELOG_ENTRIES = 4;
|
|
|
|
/**
|
|
* Key used for caching welcome page data.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected const CACHE_KEY = 'code_snippets_welcome_data';
|
|
|
|
/**
|
|
* Data fetched from the remote API.
|
|
*
|
|
* @var ?array
|
|
*/
|
|
private $welcome_data = null;
|
|
|
|
/**
|
|
* Class constructor
|
|
*/
|
|
public function __construct() {
|
|
parent::__construct(
|
|
'welcome',
|
|
_x( "What's New", 'menu label', 'code-snippets' ),
|
|
__( 'Welcome to Code Snippets', 'code-snippets' )
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Enqueue assets necessary for the welcome menu.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function enqueue_assets() {
|
|
wp_enqueue_style(
|
|
'code-snippets-welcome',
|
|
plugins_url( 'dist/welcome.css', PLUGIN_FILE ),
|
|
[],
|
|
PLUGIN_VERSION
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Load remote welcome data when the page is loaded.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function load() {
|
|
parent::load();
|
|
|
|
if ( ! is_array( $this->welcome_data ) ) {
|
|
$this->welcome_data = get_transient( self::CACHE_KEY );
|
|
}
|
|
|
|
if ( ! is_array( $this->welcome_data ) ) {
|
|
$this->welcome_data = [];
|
|
$this->fetch_remote_welcome_data();
|
|
$this->build_changelog_data();
|
|
set_transient( self::CACHE_KEY, $this->welcome_data, DAY_IN_SECONDS * 2 );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Purge the welcome data cache.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function clear_cache() {
|
|
delete_transient( self::CACHE_KEY );
|
|
}
|
|
|
|
/**
|
|
* Fetch remote welcome data from the remote server and add it to the stored data.
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function fetch_remote_welcome_data() {
|
|
$remote_welcome_data = wp_remote_get( self::WELCOME_JSON_URL );
|
|
if ( is_wp_error( $remote_welcome_data ) ) {
|
|
return;
|
|
}
|
|
|
|
$remote_welcome_data = json_decode( wp_remote_retrieve_body( $remote_welcome_data ), true );
|
|
if ( ! is_array( $remote_welcome_data ) ) {
|
|
return;
|
|
}
|
|
|
|
$this->welcome_data['hero-item'] = array_merge(
|
|
[
|
|
'follow_url' => '',
|
|
'name' => '',
|
|
'image_url' => '',
|
|
],
|
|
isset( $remote_welcome_data['hero-item'][0] ) && is_array( $remote_welcome_data['hero-item'][0] ) ?
|
|
$remote_welcome_data['hero-item'][0] : []
|
|
);
|
|
|
|
$default_item = [
|
|
'follow_url' => '',
|
|
'image_url' => '',
|
|
'title' => '',
|
|
];
|
|
|
|
foreach ( [ 'features', 'partners' ] as $items_key ) {
|
|
$this->welcome_data[ $items_key ] = [];
|
|
|
|
if ( ! isset( $this->welcome_data[ $items_key ] ) || ! is_array( $this->welcome_data[ $items_key ] ) ) {
|
|
continue;
|
|
}
|
|
|
|
$limit = max( self::ITEM_LIMIT, count( $this->welcome_data[ $items_key ] ) );
|
|
|
|
for ( $i = 0; $i < $limit; $i++ ) {
|
|
$this->welcome_data[ $items_key ][] = array_merge(
|
|
$default_item,
|
|
$remote_welcome_data[ $items_key ][ $i ]
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build the full list of latest changes for caching.
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function build_changelog_data() {
|
|
$valid_sections = [ 'Added', 'Improved', 'Fixed' ];
|
|
$changelog = [];
|
|
|
|
$changelog_file = file_get_contents( plugin_dir_path( PLUGIN_FILE ) . 'CHANGELOG.md' );
|
|
$changelog_entries = explode( "\n## ", $changelog_file );
|
|
|
|
foreach ( array_slice( $changelog_entries, 1, self::MAX_CHANGELOG_ENTRIES ) as $lines ) {
|
|
$lines = explode( "\n", $lines );
|
|
$version = explode( '(', $lines[0], 2 );
|
|
$version = $version[0];
|
|
|
|
$changelog[ $version ] = [];
|
|
|
|
foreach ( array_slice( $lines, 1 ) as $raw_line ) {
|
|
$entry = trim( str_replace( '(PRO)', '', str_replace( '*', '', $raw_line ) ) );
|
|
$parts = explode( ': ', $entry, 2 );
|
|
$entry = end( $parts );
|
|
|
|
if ( $entry ) {
|
|
$section = in_array( $parts[0], $valid_sections, true ) ? $parts[0] : 'Other';
|
|
$subsection = str_contains( $raw_line, '(PRO)' ) ? 'pro' : 'core';
|
|
|
|
if ( ! isset( $changelog[ $version ][ $section ] ) ) {
|
|
$changelog[ $version ][ $section ] = [
|
|
$subsection => [ $entry ],
|
|
];
|
|
} elseif ( ! isset( $changelog[ $version ][ $section ][ $subsection ] ) ) {
|
|
$changelog[ $version ][ $section ][ $subsection ] = [ $entry ];
|
|
} else {
|
|
$changelog[ $version ][ $section ][ $subsection ][] = $entry;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->welcome_data['changelog'] = $changelog;
|
|
}
|
|
|
|
/**
|
|
* Retrieve a list of links to display in the page header.
|
|
*
|
|
* @return array<string, array{url: string, icon: string, label: string}>
|
|
*/
|
|
protected function get_header_links(): array {
|
|
return [
|
|
'cloud' => [
|
|
'url' => 'https://codesnippets.cloud',
|
|
'icon' => 'cloud',
|
|
'label' => __( 'Cloud', 'code-snippets' ),
|
|
],
|
|
'resources' => [
|
|
'url' => 'https://help.codesnippets.pro/',
|
|
'icon' => 'sos',
|
|
'label' => __( 'Support', 'code-snippets' ),
|
|
],
|
|
'facebook' => [
|
|
'url' => 'https://www.facebook.com/groups/282962095661875/',
|
|
'icon' => 'facebook',
|
|
'label' => __( 'Community', 'code-snippets' ),
|
|
],
|
|
'discord' => [
|
|
'url' => 'https://snipco.de/discord',
|
|
'icon' => 'discord',
|
|
'label' => __( 'Discord', 'code-snippets' ),
|
|
],
|
|
'pro' => [
|
|
'url' => 'https://codesnippets.pro/pricing/',
|
|
'icon' => 'cart',
|
|
'label' => __( 'Get Pro', 'code-snippets' ),
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Retrieve remote data for the hero item.
|
|
*
|
|
* @return array{follow_url: string, name: string, image_url: string}
|
|
*/
|
|
protected function get_hero_item(): array {
|
|
return $this->welcome_data['hero-item'] ?? [];
|
|
}
|
|
|
|
/**
|
|
* Parse a list of remote items, ensuring there are no missing keys and a limit number is enforced.
|
|
*
|
|
* @param 'features'|'partners' $remote_key Key from remote data to parse.
|
|
*
|
|
* @return array<array{follow_url: string, image_url: string, title: string}>
|
|
*/
|
|
protected function get_remote_items( string $remote_key ): array {
|
|
return $this->welcome_data[ $remote_key ] ?? [];
|
|
}
|
|
|
|
/**
|
|
* Retrieve a list of latest changes for display.
|
|
*
|
|
* @return array<string, array{
|
|
* 'Added': ?array<'core' | 'pro', string>,
|
|
* 'Fixed': ?array<'core' | 'pro', string>,
|
|
* 'Improved': ?array<'core' | 'pro', string>,
|
|
* 'Other': ?array<'core' | 'pro', string>
|
|
* }>
|
|
*/
|
|
protected function get_changelog(): array {
|
|
return $this->welcome_data['changelog'] ?? [];
|
|
}
|
|
}
|