first commit
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
class WPML_File_Name_Converter {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $home_path;
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function transform_realpath_to_reference( $file ) {
|
||||
$home_path = $this->get_home_path();
|
||||
|
||||
return str_replace( $home_path, '', $file );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function transform_reference_to_realpath( $file ) {
|
||||
$home_path = $this->get_home_path();
|
||||
|
||||
return trailingslashit( $home_path ) . ltrim( $file, '/\\' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function get_home_path() {
|
||||
if ( null === $this->home_path ) {
|
||||
if ( ! function_exists( 'get_home_path' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
}
|
||||
|
||||
$this->home_path = get_home_path();
|
||||
}
|
||||
|
||||
return $this->home_path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_File_Hashing {
|
||||
|
||||
const OPTION_NAME = 'wpml-scanning-files-hashing';
|
||||
|
||||
/** @var array */
|
||||
private $hashes;
|
||||
|
||||
public function __construct() {
|
||||
$this->hashes = $this->get_hashes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*/
|
||||
private function set_hash( $file ) {
|
||||
$this->hashes[ $file ] = md5_file( $file );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hash_changed( $file ) {
|
||||
return ! array_key_exists( $file, $this->hashes ) || md5_file( $file ) !== $this->hashes[ $file ];
|
||||
}
|
||||
|
||||
public function save_hash() {
|
||||
$needs_to_save = false;
|
||||
if ( array_key_exists( 'files', $_POST ) ) {
|
||||
foreach ( $_POST['files'] as $file_path ) {
|
||||
if ( realpath( $file_path ) ) {
|
||||
$this->set_hash( $file_path );
|
||||
$needs_to_save = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $needs_to_save ) {
|
||||
update_option( self::OPTION_NAME, $this->hashes );
|
||||
}
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_hashes() {
|
||||
return get_option( self::OPTION_NAME ) ? get_option( self::OPTION_NAME ) : array();
|
||||
}
|
||||
|
||||
public function clean_hashes() {
|
||||
delete_option( self::OPTION_NAME );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Strings_Stats {
|
||||
|
||||
/**
|
||||
* @var SitePress
|
||||
*/
|
||||
private $sitepress;
|
||||
|
||||
/**
|
||||
* @var wpdb
|
||||
*/
|
||||
private $wpdb;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $stats;
|
||||
|
||||
public function __construct( wpdb $wpdb, SitePress $sitepress ) {
|
||||
$this->wpdb = $wpdb;
|
||||
$this->sitepress = $sitepress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $component_name
|
||||
* @param string $type
|
||||
* @param string $domain
|
||||
*/
|
||||
public function update( $component_name, $type, $domain ) {
|
||||
$count = $this->get_count( $domain );
|
||||
$string_settings = $this->sitepress->get_setting( 'st' );
|
||||
$string_settings[ $type . '_localization_domains' ][ $component_name ][ $domain ] = $count;
|
||||
$this->sitepress->set_setting( 'st', $string_settings, true );
|
||||
$this->sitepress->save_settings();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $domain
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function get_count( $domain ) {
|
||||
if ( ! $this->stats ) {
|
||||
$this->set_stats();
|
||||
}
|
||||
|
||||
return isset( $this->stats[ $domain ] ) ? (int) $this->stats[ $domain ]->count : 0;
|
||||
}
|
||||
|
||||
private function set_stats() {
|
||||
$count_query = 'SELECT context, COUNT(id) count FROM ' . $this->wpdb->prefix . 'icl_strings GROUP BY context';
|
||||
$this->stats = $this->wpdb->get_results( $count_query, OBJECT_K );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Theme_Plugin_Hooks {
|
||||
|
||||
/**
|
||||
* @var WPML_ST_File_Hashing
|
||||
*/
|
||||
private $file_hashing;
|
||||
|
||||
public function __construct( WPML_ST_File_Hashing $file_hashing ) {
|
||||
$this->file_hashing = $file_hashing;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'icl_st_unregister_string_multi', array( $this->file_hashing, 'clean_hashes' ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Theme_Plugin_Scan_Files_Ajax implements IWPML_Action {
|
||||
|
||||
/** @var IWPML_ST_String_Scanner */
|
||||
private $string_scanner;
|
||||
|
||||
/**
|
||||
* WPML_ST_Theme_Scan_Files_Ajax constructor.
|
||||
*
|
||||
* @param IWPML_ST_String_Scanner $string_scanner
|
||||
*/
|
||||
public function __construct( IWPML_ST_String_Scanner $string_scanner ) {
|
||||
$this->string_scanner = $string_scanner;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_ajax_wpml_st_scan_chunk', array( $this, 'scan' ) );
|
||||
}
|
||||
|
||||
public function scan() {
|
||||
wpml_get_admin_notices()->remove_notice(
|
||||
WPML_ST_Themes_And_Plugins_Settings::NOTICES_GROUP,
|
||||
WPML_ST_Themes_And_Plugins_Updates::WPML_ST_SCAN_NOTICE_ID
|
||||
);
|
||||
|
||||
wpml_get_admin_notices()->remove_notice(
|
||||
WPML_ST_Themes_And_Plugins_Settings::NOTICES_GROUP,
|
||||
WPML_ST_Themes_And_Plugins_Updates::WPML_ST_SCAN_ACTIVE_ITEMS_NOTICE_ID
|
||||
);
|
||||
|
||||
$this->clear_items_needs_scan_buffer();
|
||||
$this->string_scanner->scan();
|
||||
}
|
||||
|
||||
public function clear_items_needs_scan_buffer() {
|
||||
delete_option( WPML_ST_Themes_And_Plugins_Updates::WPML_ST_ITEMS_TO_SCAN );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Update_File_Hash_Ajax implements IWPML_Action {
|
||||
|
||||
/** @var WPML_ST_File_Hashing */
|
||||
private $file_hashing;
|
||||
|
||||
/**
|
||||
* WPML_ST_Update_File_Hash_Ajax constructor.
|
||||
*
|
||||
* @param WPML_ST_File_Hashing $file_hashing
|
||||
*/
|
||||
public function __construct( WPML_ST_File_Hashing $file_hashing ) {
|
||||
$this->file_hashing = $file_hashing;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_ajax_update_file_hash', array( $this->file_hashing, 'save_hash' ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Themes_And_Plugins_Settings {
|
||||
const OPTION_NAME = 'wpml_st_display_strings_scan_notices';
|
||||
const NOTICES_GROUP = 'wpml-st-string-scan';
|
||||
|
||||
public function init_hooks() {
|
||||
if ( $this->must_display_notices() ) {
|
||||
add_action( 'wp_ajax_hide_strings_scan_notices', array( $this, 'hide_strings_scan_notices' ) );
|
||||
add_action( 'wpml-notices-scripts-enqueued', array( $this, 'enqueue_scripts' ) );
|
||||
}
|
||||
}
|
||||
|
||||
public function get_notices_group() {
|
||||
return self::NOTICES_GROUP;
|
||||
}
|
||||
|
||||
public function must_display_notices() {
|
||||
return (bool) get_option( self::OPTION_NAME );
|
||||
}
|
||||
|
||||
public function set_strings_scan_notices( $value ) {
|
||||
update_option( self::OPTION_NAME, $value );
|
||||
}
|
||||
|
||||
public function hide_strings_scan_notices() {
|
||||
update_option( self::OPTION_NAME, false );
|
||||
}
|
||||
|
||||
public function display_notices_setting_is_missing() {
|
||||
return null === get_option( self::OPTION_NAME, null );
|
||||
}
|
||||
|
||||
public function create_display_notices_setting() {
|
||||
add_option( self::OPTION_NAME, true );
|
||||
}
|
||||
|
||||
public function enqueue_scripts() {
|
||||
$strings = array(
|
||||
'title' => __( 'Dismiss all notices', 'wpml-string-translation' ),
|
||||
'message' => __( 'Also prevent similar messages in the future?', 'wpml-string-translation' ),
|
||||
'no' => __( 'No - keep showing these message', 'wpml-string-translation' ),
|
||||
'yes' => __( 'Yes - disable these notifications completely', 'wpml-string-translation' ),
|
||||
);
|
||||
wp_register_script( 'wpml-st-disable-notices', WPML_ST_URL . '/res/js/disable-string-scan-notices.js', array( 'jquery', 'jquery-ui-dialog' ) );
|
||||
wp_localize_script( 'wpml-st-disable-notices', 'wpml_st_disable_notices_strings', $strings );
|
||||
wp_enqueue_script( 'wpml-st-disable-notices' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author OnTheGo Systems
|
||||
*/
|
||||
class WPML_ST_Themes_And_Plugins_Updates {
|
||||
|
||||
const WPML_WP_UPDATED_MO_FILES = 'wpml_wp_updated_mo_files';
|
||||
const WPML_ST_ITEMS_TO_SCAN = 'wpml_items_to_scan';
|
||||
const WPML_ST_SCAN_NOTICE_ID = 'wpml_st_scan_items';
|
||||
const WPML_ST_FASTER_SETTINGS_NOTICE_ID = 'wpml_st_faster_settings';
|
||||
const WPML_ST_SCAN_ACTIVE_ITEMS_NOTICE_ID = 'wpml_st_scan_active_items';
|
||||
|
||||
/** @var WPML_Notices */
|
||||
private $admin_notices;
|
||||
/** @var WPML_ST_Themes_And_Plugins_Settings */
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* WPML_ST_Admin_Notices constructor.
|
||||
*
|
||||
* @param WPML_Notices $admin_notices
|
||||
* @param WPML_ST_Themes_And_Plugins_Settings $settings
|
||||
*/
|
||||
public function __construct( WPML_Notices $admin_notices, WPML_ST_Themes_And_Plugins_Settings $settings ) {
|
||||
$this->admin_notices = $admin_notices;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function init_hooks() {
|
||||
add_action( 'upgrader_process_complete', array( $this, 'store_mo_file_update' ), 10, 2 );
|
||||
}
|
||||
|
||||
public function data_is_valid( $thing ) {
|
||||
return $thing && ! is_wp_error( $thing );
|
||||
}
|
||||
|
||||
public function notices_count() {
|
||||
return $this->admin_notices->count();
|
||||
}
|
||||
|
||||
public function remove_notice( $id ) {
|
||||
$this->admin_notices->remove_notice( $this->settings->get_notices_group(), $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_Upgrader $upgrader
|
||||
* @param array<string,string|array<string,string>> $language_translations
|
||||
*/
|
||||
public function store_mo_file_update( WP_Upgrader $upgrader, $language_translations ) {
|
||||
if ( is_wp_error( $upgrader->result ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$action = $language_translations['action'];
|
||||
if ( in_array( $action, array( 'update', 'install' ), true ) ) {
|
||||
if ( 'translation' === $language_translations['type'] ) {
|
||||
$last_update = get_option( self::WPML_WP_UPDATED_MO_FILES, array() );
|
||||
$translations = $language_translations['translations'];
|
||||
foreach ( $translations as $translation ) {
|
||||
$last_update[ $translation['type'] ][ $translation['slug'] ] = time();
|
||||
}
|
||||
update_option( self::WPML_WP_UPDATED_MO_FILES, $last_update, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Theme_Plugin_Hooks_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
/**
|
||||
* @return WPML_ST_Theme_Plugin_Hooks
|
||||
*/
|
||||
public function create() {
|
||||
return new WPML_ST_Theme_Plugin_Hooks( new WPML_ST_File_Hashing() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Update_File_Hash_Ajax_Factory extends WPML_AJAX_Base_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
const AJAX_ACTION = 'update_file_hash';
|
||||
const NONCE = 'wpml-update-file-hash-nonce';
|
||||
|
||||
/** @return null|WPML_ST_Update_File_Hash_Ajax */
|
||||
public function create() {
|
||||
$hooks = null;
|
||||
|
||||
if ( $this->is_valid_action( self::AJAX_ACTION ) ) {
|
||||
$hooks = new WPML_ST_Update_File_Hash_Ajax( new WPML_ST_File_Hashing() );
|
||||
}
|
||||
return $hooks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Plugin_String_Scanner_Factory {
|
||||
|
||||
/** @return WPML_Plugin_String_Scanner */
|
||||
public function create() {
|
||||
$file_hashing = new WPML_ST_File_Hashing();
|
||||
return new WPML_Plugin_String_Scanner( wpml_get_filesystem_direct(), $file_hashing );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Theme_Plugin_Scan_Dir_Ajax_Factory extends WPML_AJAX_Base_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
const AJAX_ACTION = 'wpml_get_files_to_scan';
|
||||
const NONCE = 'wpml-get-files-to-scan-nonce';
|
||||
|
||||
/** @return null|WPML_ST_Theme_Plugin_Scan_Dir_Ajax */
|
||||
public function create() {
|
||||
$hooks = null;
|
||||
|
||||
if ( $this->is_valid_action( self::AJAX_ACTION ) ) {
|
||||
$scan_dir = new WPML_ST_Scan_Dir();
|
||||
$file_hashing = new WPML_ST_File_Hashing();
|
||||
$hooks = new WPML_ST_Theme_Plugin_Scan_Dir_Ajax( $scan_dir, $file_hashing );
|
||||
}
|
||||
|
||||
return $hooks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Theme_Plugin_Scan_Files_Ajax_Factory extends WPML_AJAX_Base_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
const AJAX_ACTION = 'wpml_st_scan_chunk';
|
||||
const NONCE = 'wpml-scan-files-nonce';
|
||||
|
||||
/** @return null|WPML_ST_Theme_Plugin_Scan_Files_Ajax */
|
||||
public function create() {
|
||||
$hooks = null;
|
||||
$scan_factory = '';
|
||||
|
||||
if ( $this->is_valid_action( self::AJAX_ACTION ) ) {
|
||||
if ( array_key_exists( 'theme', $_POST ) ) {
|
||||
$scan_factory = new WPML_ST_Theme_String_Scanner_Factory();
|
||||
} elseif ( array_key_exists( 'plugin', $_POST ) ) {
|
||||
$scan_factory = new WPML_ST_Plugin_String_Scanner_Factory();
|
||||
}
|
||||
|
||||
if ( $scan_factory ) {
|
||||
$scan = $scan_factory->create();
|
||||
$hooks = new WPML_ST_Theme_Plugin_Scan_Files_Ajax( $scan );
|
||||
}
|
||||
}
|
||||
|
||||
return $hooks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Theme_String_Scanner_Factory {
|
||||
|
||||
/** @return WPML_Theme_String_Scanner */
|
||||
public function create() {
|
||||
$file_hashing = new WPML_ST_File_Hashing();
|
||||
return new WPML_Theme_String_Scanner( wpml_get_filesystem_direct(), $file_hashing );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
interface IWPML_ST_String_Scanner {
|
||||
|
||||
public function scan();
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Theme_Plugin_Scan_Dir_Ajax {
|
||||
|
||||
/** @var WPML_ST_Scan_Dir */
|
||||
private $scan_dir;
|
||||
|
||||
/** @var WPML_ST_File_Hashing */
|
||||
private $file_hashing;
|
||||
|
||||
/**
|
||||
* WPML_ST_Theme_Plugin_Scan_Dir_Ajax constructor.
|
||||
*
|
||||
* @param WPML_ST_Scan_Dir $scan_dir
|
||||
* @param WPML_ST_File_Hashing $file_hashing
|
||||
*/
|
||||
public function __construct( WPML_ST_Scan_Dir $scan_dir, WPML_ST_File_Hashing $file_hashing ) {
|
||||
$this->scan_dir = $scan_dir;
|
||||
$this->file_hashing = $file_hashing;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_ajax_wpml_get_files_to_scan', array( $this, 'get_files' ) );
|
||||
}
|
||||
|
||||
public function get_files() {
|
||||
$folders = $this->get_folder();
|
||||
$result = array();
|
||||
|
||||
if ( $folders ) {
|
||||
$file_type = array( 'php', 'inc' );
|
||||
$files_found_chunks = array();
|
||||
|
||||
foreach ( $folders as $folder ) {
|
||||
$files_found_chunks[] = $this->scan_dir->scan(
|
||||
$folder,
|
||||
$file_type,
|
||||
$this->is_one_file_plugin(),
|
||||
$this->get_folders_to_ignore()
|
||||
);
|
||||
}
|
||||
|
||||
$files = call_user_func_array( 'array_merge', $files_found_chunks );
|
||||
$files = $this->filter_modified_files( $files );
|
||||
|
||||
if ( ! $files ) {
|
||||
$this->clear_items_to_scan_buffer();
|
||||
}
|
||||
|
||||
$result = array(
|
||||
'files' => $files,
|
||||
'no_files_message' => __( 'Files already scanned.', 'wpml-string-translation' ),
|
||||
);
|
||||
}
|
||||
|
||||
wp_send_json_success( $result );
|
||||
}
|
||||
|
||||
private function clear_items_to_scan_buffer() {
|
||||
wpml_get_admin_notices()->remove_notice(
|
||||
WPML_ST_Themes_And_Plugins_Settings::NOTICES_GROUP,
|
||||
WPML_ST_Themes_And_Plugins_Updates::WPML_ST_SCAN_NOTICE_ID
|
||||
);
|
||||
delete_option( WPML_ST_Themes_And_Plugins_Updates::WPML_ST_ITEMS_TO_SCAN );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $files
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filter_modified_files( $files ) {
|
||||
$modified_files = array();
|
||||
foreach ( $files as $file ) {
|
||||
if ( $this->file_hashing->hash_changed( $file ) ) {
|
||||
$modified_files[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
return $modified_files;
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
private function get_folder() {
|
||||
$folder = array();
|
||||
|
||||
if ( array_key_exists( 'theme', $_POST ) ) {
|
||||
$folder[] = get_theme_root() . '/' . sanitize_text_field( $_POST['theme'] );
|
||||
} elseif ( array_key_exists( 'plugin', $_POST ) ) {
|
||||
$plugin_folder = explode( '/', $_POST['plugin'] );
|
||||
$folder[] = WPML_PLUGINS_DIR . '/' . sanitize_text_field( $plugin_folder[0] );
|
||||
} elseif ( array_key_exists( 'mu-plugin', $_POST ) ) {
|
||||
$folder[] = WPMU_PLUGIN_DIR . '/' . sanitize_text_field( $_POST['mu-plugin'] );
|
||||
}
|
||||
|
||||
return $folder;
|
||||
}
|
||||
|
||||
private function is_one_file_plugin() {
|
||||
$is_one_file_plugin = false;
|
||||
|
||||
if ( array_key_exists( 'plugin', $_POST ) ) {
|
||||
$is_one_file_plugin = false === strpos( $_POST['plugin'], 'plugins/' );
|
||||
}
|
||||
|
||||
if ( array_key_exists( 'mu-plugin', $_POST ) ) {
|
||||
$is_one_file_plugin = false === strpos( $_POST['mu-plugin'], 'mu-plugins/' );
|
||||
}
|
||||
|
||||
return $is_one_file_plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_folders_to_ignore() {
|
||||
$folders = [
|
||||
WPML_ST_Scan_Dir::PLACEHOLDERS_ROOT . '/node_modules',
|
||||
WPML_ST_Scan_Dir::PLACEHOLDERS_ROOT . '/tests',
|
||||
];
|
||||
|
||||
return $folders;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user