first commit

This commit is contained in:
2023-09-12 21:41:04 +02:00
commit 3361a7f053
13284 changed files with 2116755 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
<?php
namespace WPML\ST\Troubleshooting;
use WPML\ST\MO\Generate\MultiSite\Executor;
use WPML\ST\MO\Scan\UI\Factory;
use function WPML\Container\make;
use WPML\ST\MO\Generate\Process\Status;
use WPML\ST\Troubleshooting\Cleanup\Database;
class AjaxFactory implements \IWPML_AJAX_Action_Loader {
const ACTION_SHOW_GENERATE_DIALOG = 'wpml_st_mo_generate_show_dialog';
const ACTION_CLEANUP = 'wpml_st_troubleshooting_cleanup';
public function create() {
return self::getActions()->map( self::buildHandler() )->toArray();
}
/**
* @return \WPML\Collect\Support\Collection
*/
public static function getActions() {
return wpml_collect(
[
[ self::ACTION_SHOW_GENERATE_DIALOG, [ self::class, 'showGenerateDialog' ] ],
[ self::ACTION_CLEANUP, [ self::class, 'cleanup' ] ],
]
);
}
/**
* @return \Closure
*/
public static function buildHandler() {
return function( array $action ) {
return new RequestHandle( ...$action );
};
}
/**
* @throws \WPML\Auryn\InjectionException
*/
public static function showGenerateDialog() {
if ( is_super_admin() && is_multisite() ) {
( new Executor() )->executeWith(
Executor::MAIN_SITE_ID,
function () {
make( Status::class )->markIncompleteForAll();
}
);
} else {
make( Status::class )->markIncomplete();
}
Factory::ignoreWpmlVersion();
}
/**
* @throws \WPML\Auryn\InjectionException
*/
public static function cleanup() {
/** @var Database $database */
$database = make( Database::class );
$database->deleteStringsFromImportedMoFiles();
$database->truncatePagesAndUrls();
}
}

View File

@@ -0,0 +1,84 @@
<?php
namespace WPML\ST\Troubleshooting;
use function WPML\Container\make;
use WPML\ST\MO\Generate\DomainsAndLanguagesRepository;
use WPML\ST\MO\Generate\Process\ProcessFactory;
class BackendHooks implements \IWPML_Backend_Action, \IWPML_DIC_Action {
const SCRIPT_HANDLE = 'wpml-st-troubleshooting';
const NONCE_KEY = 'wpml-st-troubleshooting';
/** @var DomainsAndLanguagesRepository $domainsAndLanguagesRepo */
private $domainsAndLanguagesRepo;
public function __construct( DomainsAndLanguagesRepository $domainsAndLanguagesRepo ) {
$this->domainsAndLanguagesRepo = $domainsAndLanguagesRepo;
}
public function add_hooks() {
add_action( 'after_setup_complete_troubleshooting_functions', [ $this, 'displayButtons' ] );
add_action( 'admin_enqueue_scripts', [ $this, 'loadJS' ] );
}
public function displayButtons() {
?><div>
<?php
if ( ! $this->domainsAndLanguagesRepo->get()->isEmpty() ) {
$this->displayButton(
AjaxFactory::ACTION_SHOW_GENERATE_DIALOG,
esc_attr__( 'Show custom MO Files Pre-generation dialog box', 'wpml-string-translation' ),
false
);
}
$this->displayButton(
AjaxFactory::ACTION_CLEANUP,
esc_attr__( 'Cleanup and optimize string tables', 'wpml-string-translation' ),
esc_attr__( 'Cleanup and optimization completed!', 'wpml-string-translation' )
);
?>
</div>
<?php
}
/**
* @param string $action
* @param string $buttonLabel
* @param string|false $confirmationMessage A string to display or false if we want to immediately reload.
*/
private function displayButton( $action, $buttonLabel, $confirmationMessage ) {
?>
<p>
<input id="<?php echo $action; ?>"
class="js-wpml-st-troubleshooting-action button-secondary"
type="button"
value="<?php echo $buttonLabel; ?>"
data-action="<?php echo $action; ?>"
data-success-message="<?php echo $confirmationMessage; ?>"
data-nonce="<?php echo wp_create_nonce( self::NONCE_KEY ); ?>"
data-reload="<?php echo ! (bool) $confirmationMessage; ?>"
/>
<br/>
</p>
<?php
}
/**
* @param string $hook
*/
public function loadJS( $hook ) {
if ( WPML_PLUGIN_FOLDER . '/menu/troubleshooting.php' === $hook ) {
wp_register_script(
self::SCRIPT_HANDLE,
WPML_ST_URL . '/res/js/troubleshooting.js',
[ 'jquery', 'wp-util', 'jquery-ui-sortable', 'jquery-ui-dialog' ]
);
wp_enqueue_script( self::SCRIPT_HANDLE );
}
}
}

View File

@@ -0,0 +1,81 @@
<?php
namespace WPML\ST\Troubleshooting\Cleanup;
use wpdb;
use WPML_ST_Translations_File_Dictionary;
class Database {
/** @var wpdb $wpdb */
private $wpdb;
/** @var WPML_ST_Translations_File_Dictionary $dictionary */
private $dictionary;
public function __construct(
wpdb $wpdb,
WPML_ST_Translations_File_Dictionary $dictionary
) {
$this->wpdb = $wpdb;
$this->dictionary = $dictionary;
}
public function deleteStringsFromImportedMoFiles() {
$moDomains = $this->dictionary->get_domains( 'mo' );
if ( ! $moDomains ) {
return;
}
$this->deleteOnlyNativeMoStringTranslations( $moDomains );
$this->deleteMoStringsWithNoTranslation( $moDomains );
icl_update_string_status_all();
$this->optimizeStringTables();
}
private function deleteOnlyNativeMoStringTranslations( array $moDomains ) {
$this->wpdb->query(
"
DELETE st FROM {$this->wpdb->prefix}icl_string_translations AS st
LEFT JOIN {$this->wpdb->prefix}icl_strings AS s
ON st.string_id = s.id
WHERE st.value IS NULL AND s.context IN(" . wpml_prepare_in( $moDomains ) . ')
'
);
}
private function deleteMoStringsWithNoTranslation( array $moDomains ) {
$this->wpdb->query(
"
DELETE s FROM {$this->wpdb->prefix}icl_strings AS s
LEFT JOIN {$this->wpdb->prefix}icl_string_translations AS st
ON st.string_id = s.id
WHERE st.string_id IS NULL AND s.context IN(" . wpml_prepare_in( $moDomains ) . ')
'
);
}
private function optimizeStringTables() {
$this->wpdb->query( "OPTIMIZE TABLE {$this->wpdb->prefix}icl_strings, {$this->wpdb->prefix}icl_string_translations" );
}
public function truncatePagesAndUrls() {
foreach ( [ 'icl_string_pages', 'icl_string_urls' ] as $table ) {
$table = $this->wpdb->prefix . $table;
if ( $this->tableExists( $table ) ) {
$this->wpdb->query( "TRUNCATE $table" );
}
}
}
/**
* @param string $table
*
* @return bool
*/
private function tableExists( $table ) {
return (bool) $this->wpdb->get_var( $this->wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) );
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace WPML\ST\Troubleshooting;
class RequestHandle implements \IWPML_Action {
/** @var string $action */
private $action;
/** @var callable $callback */
private $callback;
public function __construct( $action, $callback ) {
$this->action = $action;
$this->callback = $callback;
}
public function add_hooks() {
add_action( 'wp_ajax_' . $this->action, [ $this, 'handle' ] );
}
public function handle() {
if ( wp_verify_nonce( $_POST['nonce'], BackendHooks::NONCE_KEY ) ) {
call_user_func( $this->callback );
wp_send_json_success();
} else {
wp_send_json_error( 'Invalid nonce value', 500 );
}
}
}