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,63 @@
<?php
/**
* @author OnTheGo Systems
*/
class WPML_TM_Custom_XML_AJAX extends WPML_TM_AJAX {
const AJAX_ACTION_BASE = 'wpml-tm-custom-xml';
private $custom_xml;
private $reload_config_callback;
private $validate;
function __construct( WPML_Custom_XML $custom_xml, WPML_XML_Config_Validate $validate, $reload_config_callback = null ) {
$this->custom_xml = $custom_xml;
$this->validate = $validate;
$this->reload_config_callback = $reload_config_callback;
}
function validate_content() {
if ( $this->is_valid_request() ) {
$content = $this->get_content();
if ( $content && ! $this->validate->from_string( $content ) && $this->validate->get_errors() ) {
$xml_errors = $this->validate->get_errors();
foreach ( $xml_errors as $index => $xml_error ) {
if ( 'The document has no document element.' === trim( $xml_error->message ) ) {
unset( $xml_errors[ $index ] );
}
}
$errors = array( __( 'The XML is not valid:', 'wpml-translation-management' ), $xml_errors );
wp_send_json_error( $errors );
} else {
wp_send_json_success( __( 'The XML is valid.', 'wpml-translation-management' ) );
}
}
}
function save_content() {
if ( $this->is_valid_request() ) {
$content = $this->get_content();
if ( null !== $content ) {
$this->custom_xml->set( $content );
if ( $this->reload_config_callback ) {
call_user_func( $this->reload_config_callback );
}
wp_send_json_success( __( 'The XML has been saved.', 'wpml-translation-management' ) );
} else {
wp_send_json_error( __( 'The XML could not be saved.', 'wpml-translation-management' ) );
}
}
}
private function get_content() {
$content = null;
if ( array_key_exists( 'content', $_POST ) ) {
$content = stripcslashes( $_POST['content'] );
}
return $content;
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* @author OnTheGo Systems
*/
class WPML_TM_Custom_XML_Factory {
private $custom_xml;
function __construct() {
$this->custom_xml = new WPML_Custom_XML();
}
public function create_ui() {
$template_paths = array(
WPML_TM_PATH . '/templates/custom-xml/',
);
$template_loader = new WPML_Twig_Template_Loader( $template_paths );
return new WPML_TM_Custom_XML_UI( $this->custom_xml, $template_loader->get_template() );
}
public function create_resources( WPML_WP_API $wpml_wp_api ) {
return new WPML_TM_Custom_XML_UI_Resources( $wpml_wp_api );
}
public function create_ajax() {
return new WPML_TM_Custom_XML_AJAX(
$this->custom_xml,
new WPML_XML_Config_Validate( WPML_PLUGIN_PATH . '/res/xsd/wpml-config.xsd' ),
array( 'WPML_Config', 'load_config_run' )
);
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* @author OnTheGo Systems
*/
class WPML_TM_Custom_XML_UI_Hooks {
private $ajax;
private $resources;
private $ui;
function __construct( WPML_TM_Custom_XML_UI $ui, WPML_TM_Custom_XML_UI_Resources $resources, WPML_TM_Custom_XML_AJAX $ajax ) {
$this->ui = $ui;
$this->resources = $resources;
$this->ajax = $ajax;
}
function init() {
add_filter( 'wpml_tm_tab_items', array( $this, 'add_items' ) );
add_action( 'admin_enqueue_scripts', array( $this->resources, 'admin_enqueue_scripts' ) );
add_action( 'wp_ajax_' . WPML_TM_Custom_XML_AJAX::AJAX_ACTION_BASE . '-validate', array( $this->ajax, 'validate_content' ) );
add_action( 'wp_ajax_' . WPML_TM_Custom_XML_AJAX::AJAX_ACTION_BASE . '-save', array( $this->ajax, 'save_content' ) );
}
function add_items( $tab_items ) {
$tab_items['custom-xml-config']['caption'] = __( 'Custom XML Configuration', 'wpml-translation-management' );
$tab_items['custom-xml-config']['callback'] = array( $this, 'build_content' );
$tab_items['custom-xml-config']['current_user_can'] = 'manage_options';
return $tab_items;
}
public function build_content() {
echo $this->ui->show();
}
}

View File

@@ -0,0 +1,169 @@
<?php
/**
* @author OnTheGo Systems
*/
class WPML_TM_Custom_XML_UI_Resources {
private $wpml_wp_api;
private $wpml_tm_path;
private $wpml_tm_url;
private $code_mirror_installed;
private $vk_beautify_installed;
function __construct( WPML_WP_API $wpml_wp_api ) {
$this->wpml_wp_api = $wpml_wp_api;
$this->wpml_tm_path = $this->wpml_wp_api->constant( 'WPML_TM_PATH' );
$this->wpml_tm_url = $this->wpml_wp_api->constant( 'WPML_TM_URL' );
}
function admin_enqueue_scripts() {
if ( $this->wpml_wp_api->is_tm_page( 'custom-xml-config', 'settings' ) ) {
$this->add_vk_beautify();
$this->add_code_mirror();
$wpml_tm_custom_xml_config_dependencies = array( 'jquery' );
if ( $this->is_code_mirror_installed() && $this->is_syntax_highlighting_enabled() ) {
$wpml_tm_custom_xml_config_dependencies[] = 'wpml-tm-custom-xml-editor';
}
wp_register_script( 'wpml-tm-custom-xml-config', $this->wpml_tm_url . '/res/js/custom-xml-config/wpml-tm-custom-xml.js', $wpml_tm_custom_xml_config_dependencies, WPML_TM_VERSION );
wp_register_style( 'wpml-tm-custom-xml-config', $this->wpml_tm_url . '/res/css/custom-xml.css', array(), WPML_TM_VERSION );
wp_enqueue_style( 'wpml-tm-custom-xml-config' );
wp_enqueue_script( 'wpml-tm-custom-xml-config' );
}
}
private function add_code_mirror() {
if ( $this->is_code_mirror_installed() && $this->is_syntax_highlighting_enabled() ) {
$this->add_code_mirror_scripts();
$this->add_code_mirror_styles();
}
}
private function add_code_mirror_scripts() {
$this->register_main_codemirror_script();
$wpml_tm_custom_xml_editor_dependencies = array( $this->get_codemirror_resource_handle() );
if ( $this->is_vk_beautify_installed() ) {
$wpml_tm_custom_xml_editor_dependencies[] = 'vkbeautify';
}
wp_register_script( 'wpml-tm-custom-xml-editor', $this->wpml_tm_url . '/res/js/custom-xml-config/wpml-tm-custom-xml-editor.js', $wpml_tm_custom_xml_editor_dependencies, WPML_TM_VERSION );
$modes = array(
'xml' => 'xml/xml.js',
);
$addons = array(
'foldcode' => 'fold/foldcode.js',
'foldgutter' => 'fold/foldgutter.js',
'brace-fold' => 'fold/brace-fold.js',
'xml-fold' => 'fold/xml-fold.js',
'matchtag' => 'edit/matchtags.js',
'matchbrackets' => 'edit/matchbrackets.js',
'closebrackets' => 'edit/closebrackets.js',
'closetag' => 'edit/closetag.js',
'show-hint' => 'hint/show-hint.js',
'xml-hint' => 'hint/xml-hint.js',
'display-panel' => 'display/panel.js',
);
foreach ( $modes as $mode => $path ) {
wp_enqueue_script( 'codemirror-mode-' . $mode, $this->get_code_mirror_directory_url() . '/mode/' . $path, array( 'wpml-tm-custom-xml-config' ), WPML_TM_VERSION );
}
foreach ( $addons as $addon => $path ) {
wp_enqueue_script( 'codemirror-addon-' . $addon, $this->get_code_mirror_directory_url() . '/addon/' . $path, array( 'wpml-tm-custom-xml-config' ), WPML_TM_VERSION );
}
}
private function add_code_mirror_styles() {
$this->register_main_codemirror_style();
$addons = array(
'foldgutter' => 'fold/foldgutter.css',
'xml-hint' => 'hint/show-hint.css',
);
foreach ( $addons as $addon => $path ) {
wp_enqueue_style( 'codemirror-addon-' . $addon, $this->get_code_mirror_directory_url() . '/addon/' . $path, array( $this->get_codemirror_resource_handle() ), WPML_TM_VERSION );
}
}
private function add_vk_beautify() {
if ( $this->is_vk_beautify_installed() && $this->is_syntax_highlighting_enabled() ) {
wp_enqueue_script( 'vkbeautify', $this->wpml_tm_url . '/libraries/vkBeautify/vkbeautify.js', array(), WPML_TM_VERSION );
}
}
private function register_main_codemirror_style() {
if ( ! $this->is_codemirror_in_wp_core() ) {
wp_register_style( $this->get_codemirror_resource_handle(), $this->get_code_mirror_directory_url() . '/lib/codemirror.css', array( 'wpml-tm-custom-xml-config' ), WPML_TM_VERSION );
}
wp_enqueue_style( 'codemirror-theme', $this->get_code_mirror_directory_url() . '/theme/dracula.css', array( $this->get_codemirror_resource_handle() ), WPML_TM_VERSION );
}
private function register_main_codemirror_script() {
if ( ! $this->is_codemirror_in_wp_core() ) {
wp_register_script( $this->get_codemirror_resource_handle(), $this->get_code_mirror_directory_url() . '/lib/codemirror.js', array(), WPML_TM_VERSION );
}
}
/**
* @return string
*/
private function get_code_mirror_directory_url() {
return $this->wpml_tm_url . '/libraries/CodeMirror';
}
/**
* @return string
*/
private function get_codemirror_resource_handle() {
if ( $this->is_codemirror_in_wp_core() ) {
return 'wp-codemirror';
}
return 'codemirror';
}
/**
* @return bool
*/
private function is_code_mirror_installed() {
if ( null === $this->code_mirror_installed ) {
$this->code_mirror_installed = $this->is_codemirror_in_wp_core() || file_exists( $this->wpml_tm_path . '/libraries/CodeMirror/lib/codemirror.js' );
}
return $this->code_mirror_installed;
}
/**
* @return bool
*/
private function is_vk_beautify_installed() {
if ( null === $this->vk_beautify_installed ) {
$this->vk_beautify_installed = file_exists( $this->wpml_tm_path . '/libraries/vkBeautify/vkbeautify.js' );
}
return $this->vk_beautify_installed;
}
/**
* @return mixed
*/
private function is_codemirror_in_wp_core() {
global $wp_version;
return $this->wpml_wp_api->version_compare_naked( $wp_version, '4.9', '>=' );
}
/**
* @return bool
*/
private function is_syntax_highlighting_enabled() {
return 'true' === get_user_meta( get_current_user_id(), 'syntax_highlighting', true );
}
}

View File

@@ -0,0 +1,45 @@
<?php
/**
* @author OnTheGo Systems
*/
class WPML_TM_Custom_XML_UI {
private $custom_xml;
private $template_service;
function __construct( WPML_Custom_XML $custom_xml, IWPML_Template_Service $template_service ) {
$this->custom_xml = $custom_xml;
$this->template_service = $template_service;
}
public function show() {
$model = $this->get_model();
return $this->template_service->show( $model, 'main.twig' );
}
private function get_model() {
return array(
'strings' => array(
'content' => __( 'Custom XML configuration', 'wpml-translation-management' ),
'save' => __( 'Save', 'wpml-translation-management' ),
'shortcuts' => __( 'Shortcuts', 'wpml-translation-management' ),
'keysmap' => array(
'Ctrl-K/CMD-K' => __( 'Fold/Unfold code', 'wpml-translation-management' ),
'Ctrl-F/CMD-F' => __( 'Autoformat', 'wpml-translation-management' ),
'Ctrl-S/CMD-S' => __( 'Save', 'wpml-translation-management' ),
),
'documentation' => __( 'How to write Language Configuration Files', 'wpml-translation-management' ),
),
'data' => array(
'action' => WPML_TM_Custom_XML_AJAX::AJAX_ACTION_BASE,
'nonceValidate' => wp_create_nonce( WPML_TM_Custom_XML_AJAX::AJAX_ACTION_BASE . '-validate' ),
'nonceSave' => wp_create_nonce( WPML_TM_Custom_XML_AJAX::AJAX_ACTION_BASE . '-save' ),
),
'links' => array(
'documentation' => 'https://wpml.org/documentation/support/language-configuration-files',
),
'content' => $this->custom_xml->get(),
);
}
}