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,38 @@
<?php
class WPML_Custom_Field_Editor_Settings {
/** @var WPML_Custom_Field_Setting_Factory */
private $settings_factory;
public function __construct( WPML_Custom_Field_Setting_Factory $settingsFactory ) {
$this->settings_factory = $settingsFactory;
}
public function filter_name( $fieldType, $default ) {
return $this->settings_factory->post_meta_setting( $this->extractTypeName( $fieldType ) )->get_editor_label() ?: $default;
}
public function filter_style( $fieldType, $default ) {
$filtered_style = $this->settings_factory->post_meta_setting( $this->extractTypeName( $fieldType ) )->get_editor_style();
switch ( $filtered_style ) {
case 'line':
return 0;
case 'textarea':
return 1;
case 'visual':
return 2;
}
return $default;
}
public function get_group( $fieldType ) {
return $this->settings_factory->post_meta_setting( $this->extractTypeName( $fieldType ) )->get_editor_group();
}
private function extractTypeName( $fieldType ) {
return substr( $fieldType, strlen( 'field_' ) );
}
}

View File

@@ -0,0 +1,118 @@
<?php
class WPML_Editor_UI_Job {
private $fields = array();
protected $job_id;
private $job_type;
private $job_type_title;
private $title;
private $view_link;
private $source_lang;
private $target_lang;
private $translation_complete;
private $duplicate;
private $note = '';
function __construct(
$job_id,
$job_type,
$job_type_title,
$title,
$view_link,
$source_lang,
$target_lang,
$translation_complete,
$duplicate
) {
$this->job_id = $job_id;
$this->job_type = $job_type;
$this->job_type_title = $job_type_title;
$this->title = $title;
$this->view_link = $view_link;
$this->source_lang = $source_lang;
$this->target_lang = $target_lang;
$this->translation_complete = $translation_complete;
$this->duplicate = $duplicate;
}
public function add_field( $field ) {
$this->fields[] = $field;
}
public function add_note( $note ) {
$this->note = $note;
}
public function get_all_fields() {
$fields = array();
/** @var WPML_Editor_UI_Field $field */
foreach ( $this->fields as $field ) {
$child_fields = $field->get_fields();
/** @var WPML_Editor_UI_Field $child_field */
foreach ( $child_fields as $child_field ) {
$fields[] = $child_field;
}
}
return $fields;
}
public function get_layout_of_fields() {
$layout = array();
/** @var WPML_Editor_UI_Field $field */
foreach ( $this->fields as $field ) {
$layout[] = $field->get_layout();
}
return $layout;
}
public function get_target_language() {
return $this->target_lang;
}
public function is_translation_complete() {
return $this->translation_complete;
}
public function save( $data ) {
$translations = array();
foreach ( $data['fields'] as $id => $field ) {
$translations[ $this->convert_id_to_translation_key( $id ) ] = $field['data'];
}
try {
$this->save_translations( $translations );
return new WPML_Ajax_Response( true, true );
} catch ( Exception $e ) {
return new WPML_Ajax_Response( false, 0 );
}
}
private function convert_id_to_translation_key( $id ) {
// This is to support the old api for saving translations.
return md5( $id );
}
public function requires_translation_complete_for_each_field() {
return true;
}
public function display_hide_completed_switcher() {
return true;
}
public function is_hide_empty_fields() {
return true;
}
public function save_translations( $translations ) {
}
}

View File

@@ -0,0 +1,11 @@
<?php
class WPML_TM_Editor_Job_Save {
public function save( $data ) {
$factory = new WPML_TM_Job_Action_Factory( wpml_tm_load_job_factory() );
$action = new WPML_TM_Editor_Save_Ajax_Action( $factory, $data );
return $action->run();
}
}

View File

@@ -0,0 +1,28 @@
<?php
class WPML_TM_Editor_Save_Ajax_Action extends WPML_TM_Job_Action {
private $data;
/**
* WPML_TM_Editor_Save_Ajax_Action constructor.
*
* @param WPML_TM_Job_Action_Factory $job_action_factory
* @param array $data
*/
public function __construct( &$job_action_factory, array $data ) {
parent::__construct( $job_action_factory );
$this->data = $data;
}
public function run() {
try {
return new WPML_Ajax_Response(
true,
$this->job_action_factory->save_action( $this->data )->save_translation()
);
} catch ( Exception $e ) {
return new WPML_Ajax_Response( false, 0 );
}
}
}

View File

@@ -0,0 +1,32 @@
<?php
class WPML_TM_Field_Type_Sanitizer {
/**
* Get elements custom field `field_type`.
* Removes last character if it's number.
* ex. field-custom_field-0 => field-custom_field
*
* @param $element
*
* @return string
*/
public static function sanitize( $custom_field_type ) {
$element_field_type_parts = explode( '-', $custom_field_type );
$last_part = array_pop( $element_field_type_parts );
if ( empty( $element_field_type_parts ) ) {
return $custom_field_type;
}
// Re-create field.
$field_type = implode( '-', $element_field_type_parts );
if ( is_numeric( $last_part ) ) {
return $field_type;
} else {
return $custom_field_type;
}
}
}

View File

@@ -0,0 +1,22 @@
<?php
class WPML_Translation_Editor_Header {
private $job_instance;
public function __construct( $job_instance ) {
$this->job_instance = $job_instance;
}
public function get_model() {
$type_title = esc_html( $this->job_instance->get_type_title() );
$title = esc_html( $this->job_instance->get_title() );
$data = array();
$data['title'] = sprintf( __( '%1$s translation: %2$s', 'wpml-translation-management' ), $type_title, '<strong>' . $title . '</strong>' );
$data['link_url'] = $this->job_instance->get_url( true );
$data['link_text'] = $this->job_instance instanceof WPML_External_Translation_Job ? '' : sprintf( __( 'View %s', 'wpml-translation-management' ), $type_title );
return $data;
}
}

View File

@@ -0,0 +1,33 @@
<?php
class WPML_Translation_Editor_Languages extends WPML_SP_User {
private $job;
/**
* @param SitePress $sitepress
*/
public function __construct( &$sitepress, $job ) {
parent::__construct( $sitepress );
$this->job = $job;
}
public function get_model() {
$source_lang = $this->sitepress->get_language_details( $this->job->source_language_code );
$target_lang = $this->sitepress->get_language_details( $this->job->language_code );
$data = array(
'source' => $this->job->source_language_code,
'target' => $this->job->language_code,
'source_lang' => $source_lang['display_name'],
'target_lang' => $target_lang['display_name'],
);
$data['img'] = array(
'source_url' => $this->sitepress->get_flag_url( $this->job->source_language_code ),
'target_url' => $this->sitepress->get_flag_url( $this->job->language_code ),
);
return $data;
}
}

View File

@@ -0,0 +1,357 @@
<?php
use \WPML\TM\Jobs\FieldId;
class WPML_Translation_Editor_UI {
const MAX_ALLOWED_SINGLE_LINE_LENGTH = 50;
/** @var SitePress $sitepress */
private $sitepress;
/** @var WPDB $wpdb */
private $wpdb;
/** @var array */
private $all_translations;
/**
* @var WPML_Translation_Editor
*/
private $editor_object;
private $job;
private $original_post;
private $rtl_original;
private $rtl_original_attribute_object;
private $rtl_translation;
private $rtl_translation_attribute;
private $is_duplicate = false;
/**
* @var TranslationManagement
*/
private $tm_instance;
/** @var WPML_Element_Translation_Job|WPML_External_Translation_Job */
private $job_instance;
private $job_factory;
private $job_layout;
/** @var array */
private $fields;
function __construct( wpdb $wpdb, SitePress $sitepress, TranslationManagement $iclTranslationManagement, WPML_Element_Translation_Job $job_instance, WPML_TM_Job_Action_Factory $job_factory, WPML_TM_Job_Layout $job_layout ) {
$this->sitepress = $sitepress;
$this->wpdb = $wpdb;
$this->tm_instance = $iclTranslationManagement;
$this->job_instance = $job_instance;
$this->job = $job_instance->get_basic_data();
$this->job_factory = $job_factory;
$this->job_layout = $job_layout;
if ( $job_instance->get_translator_id() <= 0 ) {
$job_instance->assign_to( $sitepress->get_wp_api()->get_current_user_id() );
}
add_action( 'admin_print_footer_scripts', [ $this, 'force_uncompressed_tinymce' ], 1 );
}
/**
* Force using uncompressed version tinymce which solves:
* https://onthegosystems.myjetbrains.com/youtrack/issue/wpmldev-191
*
* Seams the compressed and uncompressed have some difference, because even WP has a force_uncompressed_tinymce
* method, which is triggered whenever a custom theme on TinyMCE is used.
*
* @return void
*/
public function force_uncompressed_tinymce() {
if( ! function_exists( 'wp_scripts' ) || ! function_exists( 'wp_register_tinymce_scripts' ) ) {
// WP is below 5.0.
return;
}
$wp_scripts = wp_scripts();
$wp_scripts->remove( 'wp-tinymce' );
wp_register_tinymce_scripts( $wp_scripts, true );
}
function render() {
list( $this->rtl_original, $this->rtl_translation ) = $this->init_rtl_settings();
require_once ABSPATH . 'wp-admin/includes/image.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
?>
<div class="wrap icl-translation-editor wpml-dialog-translate">
<h1 id="wpml-translation-editor-header" class="wpml-translation-title"></h1>
<?php
do_action( 'icl_tm_messages' );
do_action( 'wpml_tm_editor_messages' );
$this->init_original_post();
$this->init_editor_object();
$this->output_model();
$this->output_ate_notice();
$this->output_gutenberg_notice();
$this->output_wysiwyg_editors();
$this->output_copy_all_dialog();
if ( $this->is_duplicate ) {
$this->output_edit_independently_dialog();
}
$this->output_editor_form();
?>
</div>
<?php
}
/**
* @return array
*/
private function init_rtl_settings() {
$this->rtl_original = $this->sitepress->is_rtl( $this->job->source_language_code );
$this->rtl_translation = $this->sitepress->is_rtl( $this->job->language_code );
$this->rtl_original_attribute_object = $this->rtl_original ? ' dir="rtl"' : ' dir="ltr"';
$this->rtl_translation_attribute = $this->rtl_translation ? ' dir="rtl"' : ' dir="ltr"';
return array( $this->rtl_original, $this->rtl_translation );
}
private function init_original_post() {
// we do not need the original document of the job here
// but the document with the same trid and in the $this->job->source_language_code
$this->all_translations = $this->sitepress->get_element_translations( $this->job->trid, $this->job->original_post_type );
$this->original_post = false;
foreach ( (array) $this->all_translations as $t ) {
if ( $t->language_code === $this->job->source_language_code ) {
$this->original_post = $this->tm_instance->get_post( $t->element_id, $this->job->element_type_prefix );
// if this fails for some reason use the original doc from which the trid originated
break;
}
}
if ( ! $this->original_post ) {
$this->original_post = $this->tm_instance->get_post( $this->job_instance->get_original_element_id(), $this->job->element_type_prefix );
}
if ( isset( $this->all_translations[ $this->job->language_code ] ) ) {
$post_status = new WPML_Post_Status( $this->wpdb, $this->sitepress->get_wp_api() );
$this->is_duplicate = $post_status->is_duplicate( $this->all_translations[ $this->job->language_code ]->element_id );
}
return $this->original_post;
}
private function init_editor_object() {
global $wpdb;
$this->editor_object = new WPML_Translation_Editor( $this->sitepress, $wpdb, $this->job_instance );
}
private function output_model() {
$model = array(
'requires_translation_complete_for_each_field' => true,
'hide_empty_fields' => true,
'translation_is_complete' => ICL_TM_COMPLETE === (int) $this->job->status,
'show_media_button' => false,
'is_duplicate' => $this->is_duplicate,
'display_hide_completed_switcher' => true,
);
if ( ! empty( $_GET['return_url'] ) ) {
$model['return_url'] = filter_var( $_GET['return_url'], FILTER_SANITIZE_URL );
} else {
$model['return_url'] = 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php';
}
$languages = new WPML_Translation_Editor_Languages( $this->sitepress, $this->job );
$model['languages'] = $languages->get_model();
$header = new WPML_Translation_Editor_Header( $this->job_instance );
$model['header'] = $header->get_model();
$model['note'] = $this->sitepress->get_wp_api()->get_post_meta(
$this->job_instance->get_original_element_id(),
WPML_TM_Translator_Note::META_FIELD_KEY,
true
);
$this->fields = $this->job_factory->field_contents( (int) $this->job_instance->get_id() )->run();
$this->fields = $this->add_titles_and_adjust_styles( $this->fields );
$this->fields = $this->add_rtl_attributes( $this->fields );
$model['fields'] = $this->fields;
$model['layout'] = $this->job_layout->run( $model['fields'], $this->tm_instance );
$model['rtl_original'] = $this->rtl_original;
$model['rtl_translation'] = $this->rtl_translation;
$model['translation_memory'] = (bool) $this->sitepress->get_setting( 'translation_memory', 1 );
$model = $this->filter_the_model( $model );
?>
<script type="text/javascript">
var WpmlTmEditorModel = <?php echo wp_json_encode( $model ); ?>;
</script>
<?php
}
private function output_ate_notice() {
$html_fields = array_filter(
$this->fields,
function ( $field ) {
return $field['field_style'] === '1' && strpos( $field['field_data'], '<' ) !== false;
}
);
if ( count( $html_fields ) > 0 ) {
$link = 'https://wpml.org/documentation/translating-your-contents/advanced-translation-editor/?utm_source=plugin&utm_medium=gui&utm_campaign=wpmltm#html-markers';
$notice_text = esc_html__( 'We see you\'re translating content that contains HTML. Switch to the Advanced Translation Editor to translate content without the risk of breaking your HTML code.', 'wpml-translation-management' );
echo '<div class="notice notice-info">
<p>' . $notice_text . ' <a href="' . $link . '" class="wpml-external-link" target="_blank" rel="noopener">' . esc_html__( 'Read more...', 'wpml-translation-management' ) . '</a></p>
</div>';
}
}
private function output_gutenberg_notice() {
$has_gutenberg_block = false;
foreach ( $this->fields as $field ) {
if ( preg_match( '#<!-- wp:#', $field['field_data'] ) ) {
$has_gutenberg_block = true;
break;
}
}
if ( $has_gutenberg_block ) {
echo '<div class="notice notice-info">
<p>' . esc_html__( 'This content came from the Block editor and you need to translate it carefully so that formatting is not broken.', 'wpml-translation-management' ) . '</p>
<p><a href="https://wpml.org/documentation/getting-started-guide/translating-content-created-using-gutenberg-editor/?utm_source=plugin&utm_medium=gui&utm_campaign=wpmltm" class="wpml-external-link" target="_blank" rel="noopener">' . esc_html__( 'Learn how to translate content that comes from Block editor', 'wpml-translation-management' ) . '</a></p>
</div>';
}
}
private function output_wysiwyg_editors() {
echo '<div style="display: none">';
foreach ( $this->fields as $field ) {
if ( 2 === (int) $field['field_style'] ) {
$this->editor_object->output_editors( $field );
}
}
echo '</div>';
}
private function output_copy_all_dialog() {
?>
<div id="wpml-translation-editor-copy-all-dialog" class="wpml-dialog" style="display:none"
title="<?php echo esc_attr__( 'Copy all fields from original', 'wpml-translation-management' ); ?>">
<p class="wpml-dialog-cols-icon">
<i class="otgs-ico-copy wpml-dialog-icon-xl"></i>
</p>
<div class="wpml-dialog-cols-content">
<p>
<strong><?php echo esc_html__( 'Some fields in translation are already filled!', 'wpml-translation-management' ); ?></strong>
<br/>
<?php echo esc_html__( 'You have two ways to copy content from the original language:', 'wpml-translation-management' ); ?>
</p>
<ul>
<li><?php echo esc_html__( 'copy to empty fields only', 'wpml-translation-management' ); ?></li>
<li><?php echo esc_html__( 'copy and overwrite all fields', 'wpml-translation-management' ); ?></li>
</ul>
</div>
<div class="wpml-dialog-footer">
<div class="alignleft">
<button
class="cancel wpml-dialog-close-button js-copy-cancel"><?php echo esc_html__( 'Cancel', 'wpml-translation-management' ); ?></button>
</div>
<div class="alignright">
<button
class="button-secondary js-copy-not-translated"><?php echo esc_html__( 'Copy to empty fields only', 'wpml-translation-management' ); ?></button>
<button
class="button-secondary js-copy-overwrite"><?php echo esc_html__( 'Copy & Overwrite all fields', 'wpml-translation-management' ); ?></button>
</div>
</div>
</div>
<?php
}
private function output_edit_independently_dialog() {
?>
<div id="wpml-translation-editor-edit-independently-dialog" class="wpml-dialog" style="display:none"
title="<?php echo esc_attr__( 'Edit independently', 'wpml-translation-management' ); ?>">
<p class="wpml-dialog-cols-icon">
<i class="otgs-ico-unlink wpml-dialog-icon-xl"></i>
</p>
<div class="wpml-dialog-cols-content">
<p><?php esc_html_e( 'This document is a duplicate of:', 'wpml-translation-management' ); ?>
<span class="wpml-duplicated-post-title">
<img class="wpml-title-flag" src="<?php echo esc_attr( $this->sitepress->get_flag_url( $this->job->source_language_code ) ); ?>">
<?php echo esc_html( $this->job_instance->get_title() ); ?>
</span>
</p>
<p>
<?php echo esc_html( sprintf( __( 'WPML will no longer synchronize this %s with the original content.', 'wpml-translation-management' ), $this->job_instance->get_type_title() ) ); ?>
</p>
</div>
<div class="wpml-dialog-footer">
<div class="alignleft">
<button class="cancel wpml-dialog-close-button js-edit-independently-cancel"><?php echo esc_html__( 'Cancel', 'wpml-translation-management' ); ?></button>
</div>
<div class="alignright">
<button class="button-secondary js-edit-independently"><?php echo esc_html__( 'Edit independently', 'wpml-translation-management' ); ?></button>
</div>
</div>
</div>
<?php
}
private function output_editor_form() {
?>
<form id="icl_tm_editor" method="post" action="">
<input type="hidden" name="job_post_type" value="<?php echo esc_attr( $this->job->original_post_type ); ?>"/>
<input type="hidden" name="job_post_id" value="<?php echo esc_attr( $this->job->original_doc_id ); ?>"/>
<input type="hidden" name="job_id" value="<?php echo esc_attr( $this->job_instance->get_id() ); ?>"/>
<div id="wpml-translation-editor-wrapper"></div>
</form>
<?php
}
private function add_titles_and_adjust_styles( array $fields ) {
return apply_filters( 'wpml_tm_adjust_translation_fields', $fields, $this->job, $this->original_post );
}
private function add_rtl_attributes( array $fields ) {
foreach ( $fields as &$field ) {
$field['original_direction'] = $this->rtl_original ? 'dir="rtl"' : 'dir="ltr"';
$field['translation_direction'] = $this->rtl_translation ? 'dir="rtl"' : 'dir="ltr"';
}
return $fields;
}
private function filter_the_model( array $model ) {
$job_details = array(
'job_type' => $this->job->original_post_type,
'job_id' => $this->job->original_doc_id,
'target' => $model['languages']['target'],
);
$job = apply_filters( 'wpml-translation-editor-fetch-job', null, $job_details );
if ( $job ) {
$model['requires_translation_complete_for_each_field'] = $job->requires_translation_complete_for_each_field();
$model['hide_empty_fields'] = $job->is_hide_empty_fields();
$model['show_media_button'] = $job->show_media_button();
$model['display_hide_completed_switcher'] = $job->display_hide_completed_switcher();
$model['fields'] = $this->add_rtl_attributes( $job->get_all_fields() );
$this->fields = $model['fields'];
$model['layout'] = $job->get_layout_of_fields();
}
return $model;
}
}

View File

@@ -0,0 +1,175 @@
<?php
if ( ! class_exists( '_WP_Editors', false ) ) {
require ABSPATH . WPINC . '/class-wp-editor.php';
}
class WPML_Translation_Editor extends WPML_WPDB_And_SP_User {
/**
* @var WPML_Element_Translation_Job $job
*/
private $job;
/**
* @param SitePress $sitepress
* @param wpdb $wpdb
* @param WPML_Element_Translation_Job $job
*/
public function __construct(
&$sitepress,
&$wpdb,
$job
) {
parent::__construct( $wpdb, $sitepress );
$this->job = $job;
$this->add_hooks();
$this->enqueue_js();
}
public function add_hooks() {
add_filter( 'tiny_mce_before_init', [ $this, 'filter_original_editor_buttons' ], 10, 2 );
}
/**
* Enqueues the JavaScript used by the TM editor.
*/
public function enqueue_js() {
wp_enqueue_script( 'wpml-tm-editor-scripts' );
wp_localize_script(
'wpml-tm-editor-scripts',
'tmEditorStrings',
$this->get_translation_editor_strings()
);
}
/**
* @return string[]
*/
private function get_translation_editor_strings() {
$translation_memory_endpoint = apply_filters( 'wpml_st_translation_memory_endpoint', '' );
return array(
'dontShowAgain' => __(
"Don't show this again.",
'wpml-translation-management'
),
'learnMore' => __(
'<p>The administrator has disabled term translation from the translation editor. </p>
<p>If your access permissions allow you can change this under "Translation Management" - "Multilingual Content Setup" - "Block translating taxonomy terms that already got translated". </p>
<p>Please note that editing terms from the translation editor will affect all posts that have the respective terms associated.</p>',
'wpml-translation-management'
),
'warning' => __(
"Please be advised that editing this term's translation here will change the value of the term in general. The changes made here, will not only affect this post!",
'wpml-translation-management'
),
'title' => __(
'Terms translation is disabled',
'wpml-translation-management'
),
'confirm' => __(
'You have unsaved work. Are you sure you want to close without saving?',
'wpml-translation-management'
),
'cancel' => __(
'Cancel',
'wpml-translation-management'
),
'save' => __(
'Save',
'wpml-translation-management'
),
'hide_translated' => __(
'Hide completed',
'wpml-translation-management'
),
'save_and_close' => __(
'Save & Close',
'wpml-translation-management'
),
'loading_url' => ICL_PLUGIN_URL . '/res/img/ajax-loader.gif',
'saving' => __(
'Saving...',
'wpml-translation-management'
),
'translation_complete' => __(
'Translation is complete',
'wpml-translation-management'
),
'contentNonce' => wp_create_nonce( 'wpml_save_job_nonce' ),
'translationMemoryNonce' => \WPML\LIB\WP\Nonce::create( $translation_memory_endpoint ),
'translationMemoryEndpoint' => $translation_memory_endpoint,
'source_lang' => __(
'Original',
'wpml-translation-management'
),
'target_lang' => __(
'Translation to',
'wpml-translation-management'
),
'copy_all' => __(
'Copy all fields from original',
'wpml-translation-management'
),
'resign' => __(
'Resign',
'wpml-translation-management'
),
'resign_translation' => __(
'Are you sure you want to resign from this job?',
'wpml-translation-management'
),
'resign_url' => admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php&icl_tm_action=save_translation&resign=1&job_id=' . $this->job->get_id() ),
'confirmNavigate' => __(
'You have unsaved changes!',
'wpml-translation-management'
),
'copy_from_original' => __(
'Copy from original',
'wpml-translation-management'
),
'show_diff' => __( 'Show differences', 'wpml-translation-management' ),
);
}
public function filter_original_editor_buttons( $config, $editor_id ) {
if ( strpos( $editor_id, '_original' ) > 0 ) {
$config['toolbar1'] = ' ';
$config['toolbar2'] = ' ';
$config['readonly'] = '1';
}
return $config;
}
public function output_editors( $field ) {
echo '<div id="' . $field['field_type'] . '_original_editor" class="original_value mce_editor_origin">';
wp_editor(
$field['field_data'],
$field['field_type'] . '_original',
array(
'textarea_rows' => 4,
'editor_class' => 'wpml_content_tr original_value mce_editor_origin',
'media_buttons' => false,
'quicktags' => array( 'buttons' => 'empty' ),
)
);
echo '</div>';
echo '<div id="' . $field['field_type'] . '_translated_editor" class="mce_editor translated_value">';
wp_editor(
$field['field_data_translated'],
$field['field_type'],
array(
'textarea_rows' => 4,
'editor_class' => 'wpml_content_tr translated_value',
'media_buttons' => true,
'textarea_name' => 'fields[' . $field['field_type'] . '][data]',
)
);
echo '</div>';
}
}

View File

@@ -0,0 +1,27 @@
<?php
class WPML_Editor_UI_Field_Group extends WPML_Editor_UI_Fields {
private $title;
private $divider;
function __construct( $title = '', $divider = true ) {
$this->title = $title;
$this->divider = $divider;
}
public function get_layout() {
$data = array(
'title' => $this->title,
'divider' => $this->divider,
'field_type' => 'tm-group',
);
$data['fields'] = parent::get_layout();
return $data;
}
}

View File

@@ -0,0 +1,38 @@
<?php
class WPML_Editor_UI_Field_Image extends WPML_Editor_UI_Fields {
private $image_id;
private $divider;
private $group;
function __construct( $id, $image_id, $data, $divider = true ) {
$this->image_id = $image_id;
$this->divider = $divider;
$this->group = new WPML_Editor_UI_Field_Group( '', false );
$this->group->add_field( new WPML_Editor_UI_Single_Line_Field( $id . '-title', __( 'Title', 'wpml-translation-management' ), $data, false ) );
$this->group->add_field( new WPML_Editor_UI_Single_Line_Field( $id . '-caption', __('Caption', 'wpml-translation-management' ), $data, false ) );
$this->group->add_field( new WPML_Editor_UI_Single_Line_Field( $id . '-alt-text', __('Alt Text', 'wpml-translation-management' ), $data, false ) );
$this->group->add_field( new WPML_Editor_UI_Single_Line_Field( $id . '-description', __('Description', 'wpml-translation-management' ), $data, false ) );
$this->add_field( $this->group );
}
public function get_layout() {
$image = wp_get_attachment_image_src( $this->image_id, array( 100, 100 ) );
$data = array(
'field_type' => 'wcml-image',
'divider' => $this->divider,
'image_src' => isset( $image[0] ) ? $image[0] : '',
);
$data['fields'] = parent::get_layout();
return $data;
}
}

View File

@@ -0,0 +1,28 @@
<?php
class WPML_Editor_UI_Field_Section extends WPML_Editor_UI_Fields {
private $title;
private $sub_title;
function __construct( $title = '', $sub_title = '' ) {
$this->title = $title;
$this->sub_title = $sub_title;
}
public function get_layout() {
$data = array(
'empty_message' => '',
'empty' => false,
'title' => $this->title,
'sub_title' => $this->sub_title,
'field_type' => 'tm-section',
);
$data['fields'] = parent::get_layout();
return $data;
}
}

View File

@@ -0,0 +1,42 @@
<?php
class WPML_Editor_UI_Field {
protected $id;
protected $title;
protected $original;
protected $translation;
private $requires_complete;
protected $is_complete;
function __construct( $id, $title, $data, $requires_complete = false ) {
$this->id = $id;
$this->title = $title ? $title : '';
$this->original = $data[ $id ]['original'];
$this->translation = isset( $data[ $id ]['translation'] ) ? $data[ $id ]['translation'] : '';
$this->requires_complete = $requires_complete;
$this->is_complete = isset( $data[ $id ]['is_complete'] ) ? $data[ $id ]['is_complete'] : false;
}
public function get_fields() {
$field = array();
$field['field_type'] = $this->id;
$field['field_data'] = $this->original;
$field['field_data_translated'] = $this->translation;
$field['title'] = $this->title;
$field['field_finished'] = $this->is_complete ? '1' : '0';
$field['tid'] = '0';
return $field;
}
public function get_layout() {
// This is a field with no sub fields so just return the id
return $this->id;
}
}

View File

@@ -0,0 +1,36 @@
<?php
class WPML_Editor_UI_Fields {
private $fields = array();
public function add_field( $field ) {
$this->fields[] = $field;
}
public function get_fields() {
$fields = array();
/** @var WPML_Editor_UI_Field $field */
foreach ( $this->fields as $field ) {
$child_fields = $field->get_fields();
foreach ( $child_fields as $child_field ) {
$fields[] = $child_field;
}
}
return $fields;
}
public function get_layout() {
$layout = array();
/** @var WPML_Editor_UI_Field $field */
foreach ( $this->fields as $field ) {
$layout[] = $field->get_layout();
}
return $layout;
}
}

View File

@@ -0,0 +1,21 @@
<?php
class WPML_Editor_UI_Single_Line_Field extends WPML_Editor_UI_Field {
private $include_copy_button;
function __construct( $id, $title, $data, $include_copy_button, $requires_complete = false ) {
parent::__construct( $id, $title, $data, $requires_complete );
$this->include_copy_button = $include_copy_button;
}
public function get_fields() {
$field = parent::get_fields();
$field['field_style'] = '0';
return array( $field );
}
}

View File

@@ -0,0 +1,21 @@
<?php
class WPML_Editor_UI_TextArea_Field extends WPML_Editor_UI_Field {
private $include_copy_button;
function __construct( $id, $title, $data, $include_copy_button, $requires_complete = false ) {
parent::__construct( $id, $title, $data, $requires_complete );
$this->include_copy_button = $include_copy_button;
}
public function get_fields() {
$field = parent::get_fields();
$field['field_style'] = '1';
return array( $field );
}
}

View File

@@ -0,0 +1,22 @@
<?php
class WPML_Editor_UI_WYSIWYG_Field extends WPML_Editor_UI_Field {
private $include_copy_button;
function __construct( $id, $title, $data, $include_copy_button, $requires_complete = false ) {
parent::__construct( $id, $title, $data, $requires_complete );
$this->include_copy_button = $include_copy_button;
}
public function get_fields() {
$field = parent::get_fields();
$field['field_style'] = '2';
return array( $field );
}
}