279 lines
6.5 KiB
PHP
279 lines
6.5 KiB
PHP
<?php
|
|
/**
|
|
* Custom API implementation to automatically update languages for ThemeFusion products.
|
|
*
|
|
* @since 4.1
|
|
* @package fusion-core
|
|
*/
|
|
|
|
/**
|
|
* Custom API client.
|
|
*
|
|
* @since 4.1
|
|
* @example new Fusion_Languages_Updater( 'plugin', 'fusion-builder', '2.0.2', 'el' );
|
|
*/
|
|
class Fusion_Languages_Updater_API {
|
|
|
|
/**
|
|
* Plugin or theme?
|
|
*
|
|
* @access private
|
|
* @since 4.1
|
|
* @var string
|
|
*/
|
|
private $type;
|
|
|
|
/**
|
|
* The slug.
|
|
*
|
|
* @access private
|
|
* @since 4.1
|
|
* @var string
|
|
*/
|
|
private $slug;
|
|
|
|
/**
|
|
* The language code.
|
|
*
|
|
* @access private
|
|
* @since 4.1
|
|
* @var string
|
|
*/
|
|
private $lang;
|
|
|
|
/**
|
|
* The version.
|
|
*
|
|
* @access private
|
|
* @since 4.1
|
|
* @var string
|
|
*/
|
|
private $ver;
|
|
|
|
/**
|
|
* The API response. Decoded from JSON to an array.
|
|
*
|
|
* @access private
|
|
* @since 4.1
|
|
* @var array
|
|
*/
|
|
private $vendor_api;
|
|
|
|
/**
|
|
* The API URL.
|
|
*
|
|
* @access private
|
|
* @since 4.1
|
|
* @var string
|
|
*/
|
|
private $api_url = 'https://raw.githubusercontent.com/Theme-Fusion/Localization-l10n/master';
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @access public
|
|
* @since 4.1
|
|
* @param string $type Can be "plugin" or "theme".
|
|
* @param string $slug The plugin - or theme - slug.
|
|
* @param string $ver The version.
|
|
* @param string $lang The language.
|
|
*/
|
|
public function __construct( $type = 'plugin', $slug = '', $ver = '', $lang = '' ) {
|
|
|
|
// Early exit if the user has disabled our API.
|
|
if ( ! FusionCore_Plugin::get_option( 'enable_language_updates' ) || '' === FusionCore_Plugin::get_option( 'enable_language_updates' ) || '0' === FusionCore_Plugin::get_option( 'enable_language_updates' ) ) {
|
|
return;
|
|
}
|
|
|
|
// Assign object properties.
|
|
$this->type = $type;
|
|
$this->slug = $slug;
|
|
$this->lang = $lang;
|
|
$this->ver = $ver;
|
|
|
|
// If no language was defined, get the current language.
|
|
if ( '' === $this->lang ) {
|
|
$this->lang = get_user_locale();
|
|
}
|
|
|
|
// Early exit for en_US.
|
|
if ( 'en_US' === $this->lang ) {
|
|
return;
|
|
}
|
|
|
|
// Get the custom API response.
|
|
add_action( 'after_setup_theme ', [ $this, 'get_vendor_api' ] );
|
|
|
|
// Change the hook for themes/plugins.
|
|
$hook = ( 'theme' === $type ) ? 'site_transient_update_themes' : 'site_transient_update_plugins';
|
|
|
|
// Add the filter.
|
|
add_filter( $hook, [ $this, 'modify_api_response' ] );
|
|
}
|
|
|
|
/**
|
|
* Modify the transient based on our API response and the context of this object.
|
|
*
|
|
* @access public
|
|
* @since 4.1
|
|
* @param object $results The WP API response.
|
|
* @return object
|
|
*/
|
|
public function modify_api_response( $results ) {
|
|
|
|
// Sanity check.
|
|
if ( ! is_object( $results ) || ! $this->should_update() ) {
|
|
return $results;
|
|
}
|
|
|
|
// Make sure the translations property is defined in the object.
|
|
if ( ! isset( $results->translations ) || ! is_array( $results->translations ) ) {
|
|
$results->translations = [];
|
|
}
|
|
|
|
// Set the translations from our custom API.
|
|
$results->translations[] = [
|
|
'type' => $this->type,
|
|
'slug' => $this->slug,
|
|
'language' => $this->lang,
|
|
'version' => $this->ver,
|
|
'updated' => $this->get_updated(),
|
|
'package' => $this->get_package(),
|
|
'autoupdate' => true,
|
|
];
|
|
return $results;
|
|
}
|
|
|
|
/**
|
|
* Figure out if there's an updated language file or not.
|
|
*
|
|
* @access private
|
|
* @since 4.1
|
|
* @return bool
|
|
*/
|
|
private function should_update() {
|
|
|
|
// Get the translation.
|
|
$translation = $this->get_item_from_api();
|
|
|
|
// Only proceed with these checks if translation was found in the API.
|
|
if ( $translation ) {
|
|
|
|
// Build the translation path for our checks.
|
|
$translation_path = WP_LANG_DIR;
|
|
$translation_path .= ( 'theme' === $this->type ) ? '/themes/' : '/plugins/';
|
|
$translation_path .= $this->slug . '-' . $this->lang . '.mo';
|
|
|
|
// If translation file does not exist then we should download it.
|
|
if ( ! file_exists( $translation_path ) ) {
|
|
return true;
|
|
}
|
|
|
|
// If the existing translation file is older than the one on the API, then we should update it.
|
|
if ( filemtime( $translation_path ) < strtotime( $this->get_updated() ) ) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Fallback to false.
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get the vendor API response.
|
|
*
|
|
* @access public
|
|
* @since 4.1
|
|
* @return array|false Returns the array, or false on failure.
|
|
*/
|
|
public function get_vendor_api() {
|
|
|
|
// Try to get the response from cache.
|
|
$transient_name = 'fusion_l10n_api_' . sanitize_key( $this->slug );
|
|
$results = get_site_transient( $transient_name );
|
|
|
|
// If the cache is not populated or expired, get the data.
|
|
if ( ! $results ) {
|
|
$api_url = "{$this->api_url}/api-{$this->slug}.json";
|
|
|
|
// Get the server response.
|
|
$response = wp_remote_get( $api_url );
|
|
|
|
// Make sure the response was OK and we have a body.
|
|
if ( ! is_wp_error( $response ) && isset( $response['body'] ) ) {
|
|
|
|
// JSON-decode the response's body.
|
|
$results = json_decode( $response['body'], true );
|
|
|
|
// Set cache for a day.
|
|
set_site_transient( $transient_name, $results, DAY_IN_SECONDS );
|
|
}
|
|
}
|
|
|
|
// Sanity check: If results is an array return them.
|
|
if ( is_array( $results ) ) {
|
|
return $results;
|
|
}
|
|
|
|
// Fallback to returning false.
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get the item we need from the API.
|
|
*
|
|
* @access private
|
|
* @since 4.1
|
|
* @return array|false
|
|
*/
|
|
private function get_item_from_api() {
|
|
$result = false;
|
|
|
|
// Sanity check.
|
|
if ( is_array( $this->vendor_api ) && isset( $this->vendor_api['translations'] ) && is_array( $this->vendor_api['translations'] ) ) {
|
|
|
|
// Loop results.
|
|
foreach ( $this->vendor_api['translations'] as $translation ) {
|
|
|
|
// Check if item exists for the language and version specified.
|
|
if ( isset( $translation['language'] ) && $this->lang === $translation['language'] && isset( $translation['version'] ) && $this->ver === $translation['version'] ) {
|
|
$result = $translation;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return the result (falls-back to false if none was found).
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Get the "updated" argument.
|
|
*
|
|
* @access private
|
|
* @since 4.1
|
|
* @return string|false Datetime or false on fail.
|
|
*/
|
|
private function get_updated() {
|
|
$translation = $this->get_item_from_api();
|
|
return ( $translation && isset( $translation['updated'] ) ) ? $translation['updated'] : false;
|
|
}
|
|
|
|
/**
|
|
* Get the "package" argument.
|
|
*
|
|
* @access private
|
|
* @since 4.1
|
|
* @return string URL.
|
|
*/
|
|
private function get_package() {
|
|
$translation = $this->get_item_from_api();
|
|
if ( $translation && isset( $translation['package'] ) ) {
|
|
return $translation['package'];
|
|
}
|
|
|
|
// Fallback.
|
|
return "{$this->api_url}/{$this->slug}/{$this->slug}-{$this->lang}.zip";
|
|
}
|
|
}
|