first commit
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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' )
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user