includes/i18n.php
<?php
/**
* Define the internationalization functionality.
*
* Loads and defines the internationalization files for this plugin
* so that its ready for translation.
*
* @class WCPOS_i18n
* @package WooCommerce POS
* @author Paul Kilmurray <paul@kilbot.com.au>
* @link http://www.wcpos.com
*/
namespace WCPOS;
class i18n {
private $github_url;
/**
* Constructor
*/
public function __construct() {
// raw github url for language packs
// todo: use last commit info and switch to cdn
// $this->github_url = 'https://cdn.rawgit.com/kilbot/WooCommerce-POS-Language-Packs/master/';
$this->github_url = 'https://raw.githubusercontent.com/kilbot/WooCommerce-POS-Language-Packs/master/';
// add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
$this->load_plugin_textdomain();
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_check' ) );
add_filter( 'upgrader_pre_download', array( $this, 'upgrader_pre_download' ), 10, 3 );
// ajax
add_action( 'wp_ajax_wcpos_update_translations', array( $this, 'update_translations' ) );
}
/**
* Load the plugin text domain for translation.
*/
public function load_plugin_textdomain() {
$locale = apply_filters( 'plugin_locale', get_locale(), 'woocommerce-pos' );
load_textdomain( 'woocommerce-pos', \WP_LANG_DIR . '/woocommerce-pos/woocommerce-pos-' . $locale . '.mo' );
load_textdomain( 'woocommerce-pos', \WP_LANG_DIR . '/plugins/woocommerce-pos-' . $locale . '.mo' );
// load woocommerce admin translations
if ( ! is_admin() && is_pos() ) {
load_textdomain( 'woocommerce', \WP_LANG_DIR . '/woocommerce/woocommerce-admin-' . $locale . '.mo' );
load_textdomain( 'woocommerce', \WP_LANG_DIR . '/plugins/woocommerce-admin-' . $locale . '.mo' );
}
}
/**
* Check GitHub repo for updated language packs
*
* @param $transient
* @param bool $force
* @return mixed
*/
public function update_check( $transient, $force = false ) {
$locale = get_locale();
// pre_set_site_transient_update_plugins is called twice
// we only want to act on the second run
// also only continue for non English locales
if ( empty( $transient->checked ) || strpos( $locale, 'en_' ) === 0 ) {
return $transient;
}
// get package.json from github
$request = wp_remote_get(
$this->github_url . 'package.json',
array( 'timeout' => 45 )
);
if ( is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) != 200 ) {
return $transient;
}
// see if translation pack exists
$response = json_decode( wp_remote_retrieve_body( $request ) );
$transient = apply_filters( 'woocommerce_pos_language_packs_upgrade', $transient, $response, $this->github_url, $force );
if ( ! isset( $response->locales->$locale ) ) {
return $transient;
}
// compare
$new = strtotime( $response->locales->$locale );
$options = get_option( 'woocommerce_pos_language_packs' );
if ( isset( $options[ $locale ] ) && $options[ $locale ] >= $new && ! $force ) {
return $transient;
}
// update required
$transient->translations[] = array(
'type' => 'plugin',
'slug' => 'woocommerce-pos',
'language' => $locale,
'version' => VERSION,
'updated' => date( 'Y-m-d H:i:s', $new ),
'package' => $this->github_url . 'packages/woocommerce-pos-' . $locale . '.zip',
'autoupdate' => 1
);
return $transient;
}
/**
* Update the database with new language pack date
* TODO: is there no later hook for translation install?
*
* @param $reply
* @param $package
* @param $upgrader
*
* @return mixed
*/
public function upgrader_pre_download( $reply, $package, $upgrader ) {
if ( isset( $upgrader->skin->language_update )
&& $upgrader->skin->language_update->slug == 'woocommerce-pos'
) {
$options = get_option( 'woocommerce_pos_language_packs', array() );
$locale = get_locale();
$options[ $locale ] = current_time( 'timestamp' );
if ( ! add_option( 'woocommerce_pos_language_packs', $options, '', 'no' ) ) {
update_option( 'woocommerce_pos_language_packs', $options );
}
}
return $reply;
}
/**
* Force update translations from AJAX
*/
public function update_translations() {
// security
AJAX::check_ajax_referer();
header( "Content-Type: text/event-stream" );
header( "Cache-Control: no-cache" );
header( "Access-Control-Allow-Origin: *" );
echo ":" . str_repeat( " ", 2048 ) . \PHP_EOL; // 2 kB padding for IE
$this->manual_update();
die();
}
/**
* Force update translations
*/
public function manual_update() {
ob_start();
$locale = get_locale();
$creds = request_filesystem_credentials( $_GET['security'], '', false, false, null );
/* translators: wordpress */
$this->flush( sprintf( __( 'Updating translations for %1$s (%2$s)…' ), 'WooCommerce POS', $locale ) );
$transient = (object) array( 'checked' => true );
$update = $this->update_check( $transient, true );
if ( empty( $update->translations ) ) {
/* note: no translation exists */
$this->flush( 'No translations found for ' . $locale . '. <a href="mailto:support@wcpos.com">Contact us</a> if you would like to help translate WooCommerce POS into your language.' );
$this->flush( 'complete' );
return;
}
if ( ! $creds || ! WP_Filesystem( $creds ) ) {
/* translators: wordpress */
$this->flush( __( 'Translation update failed.' ) );
$this->flush( 'complete' );
return;
}
foreach ( $update->translations as $translation ) {
/* translators: wordpress */
$this->flush( sprintf( __( 'Downloading translation from <span class="code">%s</span>…' ), $translation['package'] ) );
$response = wp_remote_get(
$translation['package'],
array( 'sslverify' => false, 'timeout' => 60, 'filename' => $locale . '.zip' )
);
if ( is_wp_error( $response ) || ( $response['response']['code'] < 200 || $response['response']['code'] >= 300 ) ) {
/* translators: wordpress */
$this->flush( __( 'Translation update failed.' ) );
continue;
}
global $wp_filesystem;
$upload_dir = wp_upload_dir();
$file = trailingslashit( $upload_dir['path'] ) . $locale . '.zip';
// Save the zip file
if ( ! $wp_filesystem->put_contents( $file, $response['body'], \FS_CHMOD_FILE ) ) {
/* translators: wordpress */
$this->flush( __( 'Translation update failed.' ) );
continue;
}
// Unzip the file to wp-content/languages/plugins directory
$dir = trailingslashit( \WP_LANG_DIR ) . 'plugins/';
$unzip = unzip_file( $file, $dir );
if ( true !== $unzip ) {
/* translators: wordpress */
$this->flush( __( 'Translation update failed.' ) );
continue;
}
// Delete the package file
$wp_filesystem->delete( $file );
// Update options timestamp
$key = str_replace( '-', '_', $translation['slug'] ) . '_language_packs';
$options = get_option( $key, array() );
$options[ $locale ] = current_time( 'timestamp' );
if ( ! add_option( $key, $options, '', 'no' ) ) {
update_option( $key, $options );
}
/* translators: wordpress */
$this->flush( __( 'Translation updated successfully.' ) );
}
$this->flush( 'complete' );
return;
}
/**
* Flush output
*
* @param $data
*/
private function flush( $data ) {
echo 'data:' . $data . \PHP_EOL;
echo \PHP_EOL;
ob_flush();
flush();
}
/**
* Return currency denomination for a given country code
*
* @param string $code
* @return array
*/
static public function currency_denominations( $code = '' ) {
if ( ! $code ) {
$code = get_woocommerce_currency();
}
$denominations = json_decode( file_get_contents( PLUGIN_PATH . 'includes/denominations.json' ) );
return isset( $denominations->$code ) ? $denominations->$code : $denominations;
}
/**
* @param string $library
* @param string $version
* @return string|void
*/
static public function get_external_library_locale_js( $library = '', $version = '' ) {
$cdnjs_url = $locale_js = '';
switch ( $library ) {
case 'select2':
$cdnjs_url = 'https://cdnjs.cloudflare.com/ajax/libs/select2/' . $version . '/js/i18n/';
$locales = json_decode( file_get_contents( PLUGIN_PATH . 'languages/select2-locales.json' ) );
break;
case 'moment':
$cdnjs_url = 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/' . $version . '/locale/';
$locales = json_decode( file_get_contents( PLUGIN_PATH . 'languages/moment-locales.json' ) );
break;
}
if ( empty( $cdnjs_url ) ) {
return;
}
$user_locale = self::get_user_locale();
// locale look up, eg: es_ES
if ( isset( $locales->$user_locale ) ) {
$locale_js = $locales->$user_locale;
}
// also check prefix, eg: es
if ( empty( $select2_locale_js ) ) {
$user_locale = strstr( $user_locale, '_', true );
if ( isset( $locales->$user_locale ) ) {
$locale_js = $locales->$user_locale;
}
}
if ( $locale_js ) {
return $cdnjs_url . $locale_js;
}
}
/**
* Backwards compatible get_user_locale, introduced in WP 4.7
*
* @return string
*/
static public function get_user_locale() {
return function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale();
}
}