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,74 @@
<?php
class WPML_PB_Handle_Custom_Fields {
protected $data_settings;
public function __construct( IWPML_Page_Builders_Data_Settings $data_settings ) {
$this->data_settings = $data_settings;
}
public function add_hooks() {
add_filter( 'wpml_pb_is_page_builder_page', array( $this, 'is_page_builder_page_filter' ), 10, 2 );
add_action( 'wpml_pb_after_page_without_elements_post_content_copy', array(
$this,
'copy_custom_fields'
), 10, 2 );
}
/**
* @param bool $is_page_builder_page
* @param WP_Post $post
*
* @return bool
*/
public function is_page_builder_page_filter( $is_page_builder_page, WP_Post $post ) {
if ( $this->data_settings->is_handling_post( $post->ID ) ) {
$is_page_builder_page = true;
}
return $is_page_builder_page;
}
/**
* @param int $new_post_id
* @param int $original_post_id
*/
public function copy_custom_fields( $new_post_id, $original_post_id ) {
$fields = array_merge( $this->data_settings->get_fields_to_copy(), $this->data_settings->get_fields_to_save() );
foreach ( $fields as $field ) {
self::copy_field( $new_post_id, $original_post_id, $field );
}
}
/**
* @param int $new_post_id
* @param int $original_post_id
* @param string $field
*/
public static function copy_field( $new_post_id, $original_post_id, $field ) {
$original_field = get_post_meta( $original_post_id, $field, true );
if ( $original_field ) {
update_post_meta( $new_post_id, $field, self::slash_json( $original_field ) );
}
}
/**
* @param mixed $data
*
* @return mixed string
*/
public static function slash_json( $data ) {
if ( ! is_string( $data ) ) {
return $data;
}
json_decode( $data );
if ( json_last_error() === JSON_ERROR_NONE ) {
return wp_slash( $data );
}
return $data;
}
}

View File

@@ -0,0 +1,53 @@
<?php
class WPML_PB_Handle_Post_Body implements IWPML_Backend_Action, IWPML_Frontend_Action, IWPML_DIC_Action {
private $page_builders_built;
public function __construct( WPML_Page_Builders_Page_Built $page_builders_built ) {
$this->page_builders_built = $page_builders_built;
}
public function add_hooks() {
add_filter( 'wpml_pb_should_body_be_translated', array( $this, 'should_translate' ), 10, 3 );
add_action( 'wpml_pb_finished_adding_string_translations', array( $this, 'copy' ), 10, 3 );
}
/**
* @param int $translate
* @param WP_Post $post
*
* @return int
*/
public function should_translate( $translate, WP_Post $post ) {
return $this->page_builders_built->is_page_builder_page( $post ) ? 0 : $translate;
}
/**
* @param int $new_post_id
* @param int $original_post_id
* @param array $fields
*/
public function copy( $new_post_id, $original_post_id, array $fields ) {
$original_post = get_post( $original_post_id );
if ( $original_post && $this->page_builders_built->is_page_builder_page( $original_post ) && ! $this->job_has_packages( $fields ) ) {
wpml_update_escaped_post( [ 'ID' => $new_post_id, 'post_content' => $original_post->post_content ] );
do_action( 'wpml_pb_after_page_without_elements_post_content_copy', $new_post_id, $original_post_id );
}
}
/**
* @param array $fields
*
* @return bool
*/
private function job_has_packages( array $fields ) {
foreach ( $fields as $key => $field ) {
if ( 0 === strpos( $key, 'package' ) ) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,196 @@
<?php
/**
* WPML_TM_Page_Builders_Field_Wrapper class file.
*
* @package wpml-page-builders
*/
/**
* Class WPML_TM_Page_Builders_Field_Wrapper
*/
class WPML_TM_Page_Builders_Field_Wrapper {
const SLUG_BASE = 'package-string-';
/**
* Field slug.
*
* @var false|string
*/
private $field_slug;
/**
* Package id.
*
* @var string|false|null
*/
private $package_id;
/**
* String id.
*
* @var string|false|null
*/
private $string_id;
/**
* WPML_TM_Page_Builders_Field_Wrapper constructor.
*
* @param string $field_slug Field slug.
*/
public function __construct( $field_slug ) {
$this->field_slug = $field_slug;
}
/**
* Check if package is valid.
*
* @param bool $package_must_exist Demand existence of the package.
*
* @return bool
*/
public function is_valid( $package_must_exist = false ) {
$result = $this->get_package_id() && $this->get_string_id();
if ( $result && $package_must_exist ) {
$result = $this->get_package() !== null;
}
return $result;
}
/**
* Get package id.
*
* @return false|string
*/
public function get_package_id() {
if ( null === $this->package_id ) {
$this->package_id = $this->extract_string_package_id( $this->field_slug );
}
return $this->package_id;
}
/**
* Get package.
*
* @return WPML_Package|null
*/
public function get_package() {
if ( ! $this->get_package_id() ) {
return null;
}
return apply_filters( 'wpml_st_get_string_package', false, $this->get_package_id() );
}
/**
* Get string id.
*
* @return false|string
*/
public function get_string_id() {
if ( null === $this->string_id ) {
$this->string_id = $this->extract_string_id( $this->field_slug );
}
return $this->string_id;
}
/**
* Get field slug.
*
* @return string
*/
public function get_field_slug() {
return $this->field_slug;
}
/**
* Get string type.
*
* @return false|string
*/
public function get_string_type() {
$result = false;
if ( $this->is_valid( true ) ) {
$package_strings = $this->get_package()->get_package_strings();
if ( ! $package_strings ) {
return false;
}
$package_strings = wp_list_pluck( $package_strings, 'type', 'id' );
$result = $package_strings[ $this->get_string_id() ];
}
return $result;
}
/**
* Get string wrap tag.
*
* @param stdClass $string WPML string.
*
* @return string
*/
public static function get_wrap_tag( $string ) {
return isset( $string->wrap_tag ) ? $string->wrap_tag : '';
}
/**
* Generate field slug.
*
* @param int $package_id Package id.
* @param int $string_id String id.
*
* @return string
*/
public static function generate_field_slug( $package_id, $string_id ) {
return self::SLUG_BASE . $package_id . '-' . $string_id;
}
/**
* Extract string id.
*
* @param string $field_slug Field slug.
*
* @return false|string
*/
private function extract_string_id( $field_slug ) {
$result = false;
if ( is_string( $field_slug ) && preg_match( '#^' . self::SLUG_BASE . '#', $field_slug ) ) {
$result = preg_replace( '#^' . self::SLUG_BASE . '([0-9]+)-([0-9]+)$#', '$2', $field_slug, 1 );
}
return is_numeric( $result ) ? $result : false;
}
/**
* Extract string package id.
*
* @param string $field_slug Field slug.
*
* @return false|string
*/
private function extract_string_package_id( $field_slug ) {
$result = false;
if ( is_string( $field_slug ) && preg_match( '#^' . self::SLUG_BASE . '#', $field_slug ) ) {
$result = preg_replace( '#^' . self::SLUG_BASE . '([0-9]+)-([0-9]+)$#', '$1', $field_slug, 1 );
}
return is_numeric( $result ) ? $result : false;
}
/**
* Get string title.
*
* @return string|bool
*/
public function get_string_title() {
if ( null === $this->string_id ) {
$this->string_id = $this->extract_string_id( $this->field_slug );
}
return apply_filters( 'wpml_string_title_from_id', false, $this->string_id );
}
}

View File

@@ -0,0 +1,115 @@
<?php
class WPML_TM_Page_Builders_Hooks {
/* @var WPML_TM_Page_Builders $worker */
private $worker;
/** @var SitePress $sitepress */
private $sitepress;
/**
* WPML_TM_Page_Builders constructor.
*
* @param WPML_TM_Page_Builders $worker
*/
public function __construct( WPML_TM_Page_Builders $worker = null, SitePress $sitepress ) {
$this->worker = $worker;
$this->sitepress = $sitepress;
}
public function init_hooks() {
add_filter( 'wpml_tm_translation_job_data', array( $this, 'translation_job_data_filter' ), 10, 2 );
add_action( 'wpml_pro_translation_completed', array( $this, 'pro_translation_completed_action' ), 10, 3 );
add_filter( 'wpml_tm_adjust_translation_fields', array( $this, 'adjust_translation_fields_filter' ), 10, 2 );
add_filter( 'wpml_tm_job_layout', array( $this, 'job_layout_filter' ) );
add_filter( 'wpml_link_to_translation', array( $this, 'link_to_translation_filter' ), 20, 4 );
add_filter( 'wpml_get_translatable_types', array( $this, 'remove_shortcode_strings_type_filter' ), 11);
}
/**
* @param array $translation_package
* @param mixed $post
*
* @return array
*/
public function translation_job_data_filter( array $translation_package, $post ) {
$worker = $this->get_worker();
return $worker->translation_job_data_filter( $translation_package, $post );
}
/**
* @param int $new_post_id
* @param array $fields
* @param stdClass $job
*/
public function pro_translation_completed_action( $new_post_id, array $fields, stdClass $job ) {
$worker = $this->get_worker();
$worker->pro_translation_completed_action( $new_post_id, $fields, $job );
}
/**
* Filter translation fields.
*
* @param array $fields Translation fields.
* @param stdClass $job Translation job.
*
* @return array
*/
public function adjust_translation_fields_filter( array $fields, $job ) {
$worker = $this->get_worker();
$fields = $worker->adjust_translation_fields_filter( $fields, $job );
return $fields;
}
/**
* @param array $layout
*
* @return array
*/
public function job_layout_filter( array $layout ) {
$worker = $this->get_worker();
return $worker->job_layout_filter( $layout );
}
/**
* @param string $link
* @param int $post_id
* @param string $lang
* @param int $trid
*
* @return string
*/
public function link_to_translation_filter( $link, $post_id, $lang, $trid ) {
$worker = $this->get_worker();
return $worker->link_to_translation_filter( $link, $post_id, $lang, $trid );
}
/**
* Remove "Page Builder ShortCode Strings" from translation dashboard filters
*
* @param array $types
*
* @return mixed
*/
public function remove_shortcode_strings_type_filter( $types ) {
if ( array_key_exists( 'page-builder-shortcode-strings', $types ) ) {
unset( $types['page-builder-shortcode-strings'] );
}
return $types;
}
/**
* @return WPML_TM_Page_Builders
*/
private function get_worker() {
if ( ! $this->worker ) {
$this->worker = new WPML_TM_Page_Builders( $this->sitepress );
}
return $this->worker;
}
}

View File

@@ -0,0 +1,261 @@
<?php
class WPML_TM_Page_Builders {
const PACKAGE_TYPE_EXTERNAL = 'external';
const TRANSLATION_COMPLETE = 10;
const FIELD_STYLE_AREA = 'AREA';
const FIELD_STYLE_VISUAL = 'VISUAL';
const FIELD_STYLE_LINK = 'LINK';
/** @var SitePress $sitepress */
private $sitepress;
/** @var \WPML_PB_Integration|null */
private $wpmlPbIntegration;
/**
* @param SitePress $sitepress
* @param WPML_PB_Integration|null $wpmlPbIntegration
*/
public function __construct( SitePress $sitepress, \WPML_PB_Integration $wpmlPbIntegration = null ) {
$this->sitepress = $sitepress;
$this->wpmlPbIntegration = $wpmlPbIntegration;
}
/**
* Filter translation job data.
*
* @param array $translation_package Translation package.
* @param mixed $post Post.
*
* @return array
*/
public function translation_job_data_filter( array $translation_package, $post ) {
if ( self::PACKAGE_TYPE_EXTERNAL !== $translation_package['type'] && isset( $post->ID ) ) {
$post_element = new WPML_Post_Element( $post->ID, $this->sitepress );
$source_post_id = $post->ID;
$job_lang_from = $post_element->get_language_code();
if ( ! $post_element->is_root_source() && WPML_PB_Last_Translation_Edit_Mode::is_native_editor( $post->ID ) ) {
$this->getWpmlPbIntegration()->register_all_strings_for_translation( $post, true );
$source_post_element = $post_element->get_translation( $job_lang_from );
} else {
$source_post_element = $post_element->get_source_element();
}
if ( $source_post_element ) {
$source_post_id = $source_post_element->get_id();
}
$job_source_is_not_post_source = $post->ID !== $source_post_id;
$string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $source_post_id );
$translation_package['contents']['body']['translate'] = apply_filters( 'wpml_pb_should_body_be_translated', $translation_package['contents']['body']['translate'], $post );
if ( $string_packages ) {
foreach ( $string_packages as $package_id => $string_package ) {
/**
* String package.
*
* @var WPML_Package $string_package
*/
$strings = $string_package->get_package_strings();
$string_translations = array();
if ( $job_source_is_not_post_source ) {
$string_translations = $string_package->get_translated_strings( array() );
}
foreach ( $strings as $string ) {
if ( self::FIELD_STYLE_LINK !== $string->type ) {
$string_value = $string->value;
if ( isset( $string_translations[ $string->name ][ $job_lang_from ]['value'] ) ) {
$string_value = $string_translations[ $string->name ][ $job_lang_from ]['value'];
}
$field_name = WPML_TM_Page_Builders_Field_Wrapper::generate_field_slug(
$package_id,
$string->id
);
$translation_package['contents'][ $field_name ] = array(
'translate' => 1,
// phpcs:disable WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
'data' => base64_encode( $string_value ),
// phpcs:enable
'wrap_tag' => WPML_TM_Page_Builders_Field_Wrapper::get_wrap_tag( $string ),
'format' => 'base64',
);
}
$translation_package['contents']['body']['translate'] = 0;
}
}
}
}
return $translation_package;
}
/**
* @param int $new_element_id
* @param array $fields
* @param stdClass $job
*/
public function pro_translation_completed_action( $new_element_id, array $fields, stdClass $job ) {
if ( 'post' !== $job->element_type_prefix ) {
return;
}
foreach ( $fields as $field_id => $field ) {
$field_slug = isset( $field['field_type'] ) ? $field['field_type'] : $field_id;
$wrapper = $this->create_field_wrapper( $field_slug );
$string_id = $wrapper->get_string_id();
if ( $string_id ) {
do_action(
'wpml_add_string_translation',
$string_id,
$job->language_code,
$field['data'],
self::TRANSLATION_COMPLETE,
$job->translator_id,
$job->translation_service
);
}
}
do_action( 'wpml_pb_finished_adding_string_translations', $new_element_id, $job->original_doc_id, $fields );
}
/**
* Adjust translation fields.
*
* @param array $fields Translation fields.
* @param stdClass $job Translation job.
*
* @return array
*/
public function adjust_translation_fields_filter( array $fields, $job ) {
foreach ( $fields as &$field ) {
$wrapper = $this->create_field_wrapper( $field['field_type'] );
$type = $wrapper->get_string_type();
$string_title = $wrapper->get_string_title();
if ( $string_title ) {
$field['title'] = $string_title;
}
if ( isset( $field['field_wrap_tag'] ) && $field['field_wrap_tag'] ) {
$field['title'] = isset( $field['title'] ) ? $field['title'] : '';
$field['title'] .= ' (' . $field['field_wrap_tag'] . ')';
}
if ( false !== $type ) {
switch ( $type ) {
case self::FIELD_STYLE_AREA:
$field['field_style'] = '1';
break;
case self::FIELD_STYLE_VISUAL:
$field['field_style'] = '2';
break;
default:
$field['field_style'] = '0';
break;
}
}
}
return $fields;
}
/**
* @param array $layout
*
* @return array
*/
public function job_layout_filter( array $layout ) {
$string_groups = array();
foreach ( $layout as $k => $field ) {
$wrapper = $this->create_field_wrapper( $field );
if ( $wrapper->is_valid() ) {
$string_groups[ $wrapper->get_package_id() ][] = $field;
unset( $layout[ $k ] );
}
}
foreach ( $string_groups as $string_package_id => $fields ) {
$string_package = apply_filters( 'wpml_st_get_string_package', false, $string_package_id );
$section = array(
'field_type' => 'tm-section',
'title' => isset( $string_package->title ) ? $string_package->title : '',
'fields' => $fields,
'empty' => false,
'empty_message' => '',
'sub_title' => '',
);
$layout[] = $section;
}
return array_values( $layout );
}
/**
* @param string $link
* @param int $post_id
* @param string $lang
* @param int $trid
*
* @return string
*/
public function link_to_translation_filter( $link, $post_id, $lang, $trid ) {
/* @var WPML_TM_Translation_Status $wpml_tm_translation_status */
global $wpml_tm_translation_status;
$status = $wpml_tm_translation_status->filter_translation_status( null, $trid, $lang );
if ( $link && ICL_TM_NEEDS_UPDATE === $status ) {
$args = array(
'update_needed' => 1,
'trid' => $trid,
'language_code' => $lang,
);
$link = add_query_arg( $args, $link );
}
return $link;
}
/**
* @param string $field_slug
*
* @return WPML_TM_Page_Builders_Field_Wrapper
*/
public function create_field_wrapper( $field_slug ) {
return new WPML_TM_Page_Builders_Field_Wrapper( $field_slug );
}
/**
* @return \WPML_PB_Integration
*
*/
private function getWpmlPbIntegration() {
if ( null === $this->wpmlPbIntegration ) {
$this->wpmlPbIntegration = \WPML\Container\make( \WPML_PB_Integration::class );
}
return $this->wpmlPbIntegration;
}
}