first commit
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\Settings;
|
||||
|
||||
use WPML\Core\BackgroundTask;
|
||||
use WPML\FP\Lst;
|
||||
use WPML\LIB\WP\Hooks;
|
||||
use WPML\WP\OptionManager;
|
||||
use function WPML\Container\make;
|
||||
|
||||
class CustomFieldChangeDetector implements \IWPML_Backend_Action {
|
||||
const PREVIOUS_SETTING = 'previous-custom-fields-to-translate';
|
||||
const DETECTED_SETTING = 'detected-custom-fields-to-translate';
|
||||
const LOCK_TIME = 2 * MINUTE_IN_SECONDS;
|
||||
|
||||
public function add_hooks() {
|
||||
Hooks::onAction( 'wpml_after_tm_loaded', 1 )
|
||||
->then( [ self::class, 'getNew' ] )
|
||||
->then( [ self::class, 'notify' ] )
|
||||
->then( [ self::class, 'updatePrevious' ] );
|
||||
}
|
||||
|
||||
public static function getNew() {
|
||||
if ( is_null( OptionManager::getOr( null, 'TM', self::PREVIOUS_SETTING ) ) ) {
|
||||
self::updatePrevious();
|
||||
}
|
||||
|
||||
return Lst::diff(
|
||||
Repository::getCustomFieldsToTranslate() ?: [],
|
||||
OptionManager::getOr( [], 'TM', self::PREVIOUS_SETTING )
|
||||
);
|
||||
}
|
||||
|
||||
public static function notify( array $newFields ) {
|
||||
if ( count( $newFields ) ) {
|
||||
OptionManager::update(
|
||||
'TM',
|
||||
self::DETECTED_SETTING,
|
||||
Lst::concat( self::getDetected(), $newFields )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function remove( array $fields ) {
|
||||
if ( count( $fields ) ) {
|
||||
OptionManager::update(
|
||||
'TM',
|
||||
self::DETECTED_SETTING,
|
||||
Lst::diff( self::getDetected(), $fields )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function updatePrevious() {
|
||||
OptionManager::update( 'TM', self::PREVIOUS_SETTING, Repository::getCustomFieldsToTranslate() );
|
||||
}
|
||||
|
||||
public static function getDetected() {
|
||||
return OptionManager::getOr( [], 'TM', self::DETECTED_SETTING );
|
||||
}
|
||||
|
||||
public static function processNewFields() {
|
||||
$newFields = self::getDetected();
|
||||
if ( count( $newFields ) ) {
|
||||
|
||||
/**
|
||||
* Create a lock to make sure only one background task will run at a time.
|
||||
* We wont release the lock so it wont be able to run again until the time out is complete.
|
||||
*/
|
||||
|
||||
$lock = make( 'WPML\Utilities\Lock', [ ':name' => self::class ] );
|
||||
if ( $lock->create( self::LOCK_TIME ) ) {
|
||||
BackgroundTask::add( ProcessNewTranslatableFields::class, [ 'newFields' => $newFields ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\Settings;
|
||||
|
||||
use WPML\Collect\Support\Collection;
|
||||
use WPML\Element\API\PostTranslations;
|
||||
use WPML\FP\Either;
|
||||
use WPML\Setup\Option;
|
||||
use WPML\TM\AutomaticTranslation\Actions\Actions;
|
||||
|
||||
class ProcessNewTranslatableFields {
|
||||
|
||||
const MAX_POSTS = 10;
|
||||
|
||||
public function run(
|
||||
Collection $data,
|
||||
\wpdb $wpdb,
|
||||
\WPML_TM_Post_Actions $postActions,
|
||||
Actions $autoTranslateActions
|
||||
) {
|
||||
|
||||
$fields = $data->get( 'newFields', [] );
|
||||
$page = (int) $data->get( 'page', 1 );
|
||||
if ( count( $fields ) ) {
|
||||
$postIds = self::getPosts( $wpdb, $fields, $page );
|
||||
|
||||
$this->updateNeedsUpdate( $postIds, $postActions, $autoTranslateActions );
|
||||
|
||||
if ( count( $postIds ) ) {
|
||||
return self::getFetchNextPageResponse( $fields, $page );
|
||||
} else {
|
||||
CustomFieldChangeDetector::remove( $fields );
|
||||
}
|
||||
}
|
||||
|
||||
return Either::of( null );
|
||||
}
|
||||
|
||||
private static function getPosts( \wpdb $wpdb, array $fields, $page ) {
|
||||
$fieldsIn = wpml_prepare_in( $fields, '%s' );
|
||||
$offset = ( $page - 1 ) * self::MAX_POSTS;
|
||||
$limit = self::MAX_POSTS;
|
||||
|
||||
return $wpdb->get_col(
|
||||
$wpdb->prepare(
|
||||
"SELECT DISTINCT post_id
|
||||
FROM {$wpdb->prefix}postmeta
|
||||
WHERE meta_key IN ({$fieldsIn}) AND meta_key <> ''
|
||||
LIMIT %d OFFSET %d",
|
||||
$limit,
|
||||
$offset
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private static function getFetchNextPageResponse( $fields, $page ) {
|
||||
return Either::of( [
|
||||
'status' => 'continue',
|
||||
'data' => [ 'newFields' => $fields, 'page' => $page + 1 ],
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $postIds
|
||||
* @param \WPML_TM_Post_Actions $postActions
|
||||
*/
|
||||
private function updateNeedsUpdate(
|
||||
array $postIds,
|
||||
\WPML_TM_Post_Actions $postActions,
|
||||
Actions $autoTranslateActions
|
||||
) {
|
||||
foreach ( $postIds as $postId ) {
|
||||
$translations = PostTranslations::getIfOriginal( $postId );
|
||||
$updater = $postActions->get_translation_statuses_updater( $postId, $translations );
|
||||
$needsUpdate = $updater();
|
||||
if (
|
||||
$needsUpdate
|
||||
&& \WPML_TM_ATE_Status::is_enabled_and_activated()
|
||||
&& Option::shouldTranslateEverything()
|
||||
) {
|
||||
$autoTranslateActions->sendToTranslation( $postId );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\Settings;
|
||||
|
||||
|
||||
class Repository {
|
||||
|
||||
public static function getSetting( $indexes ) {
|
||||
$settings = self::getAllSettings();
|
||||
|
||||
/**
|
||||
* I do not know why the foreach loop looks like that. I have just copied it from WPML_Translation_Job_Helper
|
||||
* @todo Review it later and try simplify if possible
|
||||
*/
|
||||
foreach ( $indexes as $index ) {
|
||||
$settings = isset( $settings[ $index ] ) ? $settings[ $index ] : null;
|
||||
if ( ! isset( $settings ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public static function getCustomFieldsToTranslate() {
|
||||
return array_values( array_filter( array_keys(
|
||||
self::getSetting( [ 'custom_fields_translation' ] ) ?: [],
|
||||
WPML_TRANSLATE_CUSTOM_FIELD
|
||||
) ) );
|
||||
}
|
||||
|
||||
public static function getCustomFields() {
|
||||
return \wpml_collect( self::getSetting( [ 'custom_fields_translation' ] ) ?: [] )
|
||||
->filter( function ( $value, $key ) {
|
||||
return (bool) $key;
|
||||
} )->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private static function getAllSettings() {
|
||||
/** @var \TranslationManagement $iclTranslationManagement */
|
||||
global $iclTranslationManagement;
|
||||
|
||||
if ( ! $iclTranslationManagement ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ( empty( $iclTranslationManagement->settings ) ) {
|
||||
$iclTranslationManagement->init();
|
||||
}
|
||||
|
||||
return $iclTranslationManagement->get_settings();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace WPML\Settings;
|
||||
|
||||
use WPML\API\PostTypes;
|
||||
use WPML\Core\WP\App\Resources;
|
||||
use WPML\FP\Either;
|
||||
use WPML\FP\Fns;
|
||||
use WPML\FP\Logic;
|
||||
use WPML\LIB\WP\Hooks;
|
||||
use WPML\Setup\Option;
|
||||
use WPML\TM\ATE\AutoTranslate\Endpoint\GetNumberOfPosts;
|
||||
use WPML\TM\ATE\AutoTranslate\Endpoint\SetForPostType;
|
||||
use WPML\UIPage;
|
||||
|
||||
class UI implements \IWPML_Backend_Action {
|
||||
|
||||
public function add_hooks() {
|
||||
Hooks::onAction( 'admin_enqueue_scripts' )
|
||||
->then( Fns::always( $_GET ) )
|
||||
->then( Logic::anyPass( [ [ UIPage::class, 'isMainSettingsTab' ], [ UIPage::class, 'isTroubleshooting' ] ] ) )
|
||||
->then( Either::fromBool() )
|
||||
->then( [ self::class, 'getData' ] )
|
||||
->then( Resources::enqueueApp( 'settings' ) );
|
||||
}
|
||||
|
||||
public static function getData() {
|
||||
return [
|
||||
'name' => 'wpmlSettingsUI',
|
||||
'data' => [
|
||||
'endpoints' => [
|
||||
'getCount' => GetNumberOfPosts::class,
|
||||
'setAutomatic' => SetForPostType::class,
|
||||
],
|
||||
'shouldTranslateEverything' => Option::shouldTranslateEverything(),
|
||||
'settingsUrl' => admin_url( UIPage::getSettings() ),
|
||||
'existingPostTypes' => PostTypes::getOnlyTranslatable(),
|
||||
'isTMLoaded' => ! wpml_is_setup_complete() || Option::isTMAllowed(),
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
class WPML_Custom_Field_Setting_Factory extends WPML_TM_User {
|
||||
public $show_system_fields = false;
|
||||
|
||||
/**
|
||||
* @param string $meta_key
|
||||
*
|
||||
* @return WPML_Post_Custom_Field_Setting
|
||||
*/
|
||||
public function post_meta_setting( $meta_key ) {
|
||||
|
||||
return new WPML_Post_Custom_Field_Setting( $this->tm_instance, $meta_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $meta_key
|
||||
*
|
||||
* @return WPML_Term_Custom_Field_Setting
|
||||
*/
|
||||
public function term_meta_setting( $meta_key ) {
|
||||
|
||||
return new WPML_Term_Custom_Field_Setting( $this->tm_instance, $meta_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all custom field names for which a site has either a setting
|
||||
* in the TM settings or that can be found on any post.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_post_meta_keys() {
|
||||
return $this->filter_custom_field_keys( $this->tm_instance->initial_custom_field_translate_states() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all term custom field names for which a site has either a setting
|
||||
* in the TM settings or that can be found on any term.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_term_meta_keys() {
|
||||
return $this->filter_custom_field_keys( $this->tm_instance->initial_term_custom_field_translate_states() );
|
||||
}
|
||||
|
||||
private function filter_custom_field_key( $custom_fields_key ) {
|
||||
return $this->show_system_fields || '_' !== substr( $custom_fields_key, 0, 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $keys
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function filter_custom_field_keys( $keys ) {
|
||||
if ( is_array( $keys ) ) {
|
||||
return array_filter( $keys, array( $this, 'filter_custom_field_key' ) );
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
class WPML_Custom_Field_Setting_Query_Factory {
|
||||
|
||||
const TYPE_POSTMETA = 'postmeta';
|
||||
const TYPE_TERMMETA = 'termmeta';
|
||||
|
||||
|
||||
public function create( $type ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( self::TYPE_TERMMETA === $type ) {
|
||||
$excluded_keys = $this->get_excluded_term_meta_keys();
|
||||
$table = $wpdb->termmeta;
|
||||
} else {
|
||||
$excluded_keys = $this->get_excluded_post_meta_keys();
|
||||
$table = $wpdb->postmeta;
|
||||
}
|
||||
|
||||
return new WPML_Custom_Field_Setting_Query( $wpdb, $excluded_keys, $table );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_excluded_post_meta_keys() {
|
||||
return $this->get_excluded_meta_keys(
|
||||
WPML_Post_Custom_Field_Setting_Keys::get_excluded_keys(),
|
||||
WPML_Post_Custom_Field_Setting_Keys::get_setting_prefix(),
|
||||
WPML_Post_Custom_Field_Setting_Keys::get_state_array_setting_index(),
|
||||
WPML_Post_Custom_Field_Setting_Keys::get_unlocked_setting_index()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_excluded_term_meta_keys() {
|
||||
return $this->get_excluded_meta_keys(
|
||||
WPML_Term_Custom_Field_Setting_Keys::get_excluded_keys(),
|
||||
WPML_Term_Custom_Field_Setting_Keys::get_setting_prefix(),
|
||||
WPML_Term_Custom_Field_Setting_Keys::get_state_array_setting_index(),
|
||||
WPML_Term_Custom_Field_Setting_Keys::get_unlocked_setting_index()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $hardcoded_excluded_keys
|
||||
* @param string $settings_prefix
|
||||
* @param string $settings_state_index
|
||||
* @param string $settings_unlock_index
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_excluded_meta_keys( array $hardcoded_excluded_keys, $settings_prefix, $settings_state_index, $settings_unlock_index ) {
|
||||
/** @var TranslationManagement $tm_instance */
|
||||
$tm_instance = wpml_load_core_tm();
|
||||
|
||||
/**
|
||||
* @see WPML_Custom_Field_Setting::excluded() for the logic ran on a single key
|
||||
*/
|
||||
$read_only_keys = isset( $tm_instance->settings[ $settings_prefix . 'read_only' ] )
|
||||
? $tm_instance->settings[ $settings_prefix . 'read_only' ] : array();
|
||||
$not_ignore_keys = $this->get_not_ignore_keys( $tm_instance, $settings_state_index );
|
||||
$unlocked_keys = isset( $tm_instance->settings[ $settings_unlock_index ] )
|
||||
? $tm_instance->settings[ $settings_unlock_index ] : array();
|
||||
|
||||
$read_only_and_ignored_keys = array_diff( $read_only_keys, $not_ignore_keys );
|
||||
$read_only_and_ignored_and_not_unlocked_keys = array_diff( $read_only_and_ignored_keys, $unlocked_keys );
|
||||
|
||||
$excluded_keys = array_merge(
|
||||
$hardcoded_excluded_keys,
|
||||
$read_only_and_ignored_and_not_unlocked_keys
|
||||
);
|
||||
|
||||
return $excluded_keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TranslationManagement $tm_settings
|
||||
* @param string $index
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_not_ignore_keys( TranslationManagement $tm_settings, $index ) {
|
||||
$statuses = isset( $tm_settings->settings[ $index ] ) ? $tm_settings->settings[ $index ] : array();
|
||||
|
||||
foreach ( $statuses as $meta_key => $status ) {
|
||||
|
||||
if ( WPML_IGNORE_CUSTOM_FIELD === (int) $status ) {
|
||||
unset( $statuses[ $meta_key ] );
|
||||
}
|
||||
}
|
||||
|
||||
return array_keys( $statuses );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
class WPML_Custom_Field_Setting_Query {
|
||||
|
||||
/** @var wpdb $wpdb */
|
||||
private $wpdb;
|
||||
|
||||
/** @var array $excluded_keys */
|
||||
private $excluded_keys;
|
||||
|
||||
/** @var string $table */
|
||||
private $table;
|
||||
|
||||
/**
|
||||
* @param wpdb $wpdb
|
||||
* @param array $excluded_keys
|
||||
* @param string $table
|
||||
*/
|
||||
public function __construct( wpdb $wpdb, array $excluded_keys, $table ) {
|
||||
$this->wpdb = $wpdb;
|
||||
$this->excluded_keys = $excluded_keys;
|
||||
$this->table = $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get( array $args ) {
|
||||
$args = array_merge(
|
||||
array(
|
||||
'search' => null,
|
||||
'hide_system_fields' => false,
|
||||
'items_per_page' => null,
|
||||
'page' => null,
|
||||
),
|
||||
$args
|
||||
);
|
||||
|
||||
$where = ' WHERE 1=1';
|
||||
$where .= $this->add_AND_excluded_fields_condition();
|
||||
$where .= $this->add_AND_search_condition( $args['search'] );
|
||||
$where .= $this->add_AND_system_fields_condition( $args['hide_system_fields'] );
|
||||
|
||||
$limit_offset = $this->get_limit_offset( $args );
|
||||
|
||||
$query = "SELECT SQL_CALC_FOUND_ROWS DISTINCT meta_key FROM {$this->table}" . $where . $limit_offset;
|
||||
|
||||
return $this->wpdb->get_col( $query );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_total_rows() {
|
||||
return (int) $this->wpdb->get_var( 'SELECT FOUND_ROWS();' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function add_AND_excluded_fields_condition() {
|
||||
if ( $this->excluded_keys ) {
|
||||
return ' AND meta_key NOT IN(' . wpml_prepare_in( $this->excluded_keys ) . ')';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function add_AND_search_condition( $search ) {
|
||||
return $search ? $this->wpdb->prepare( " AND meta_key LIKE '%s'", '%' . $search . '%' ) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $hide_system_fields
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function add_AND_system_fields_condition( $hide_system_fields ) {
|
||||
return $hide_system_fields ? " AND meta_key NOT LIKE '\_%'" : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_limit_offset( array $args ) {
|
||||
$limit_offset = '';
|
||||
|
||||
if ( $args['items_per_page'] && 0 < (int) $args['page'] ) {
|
||||
$limit_offset = $this->wpdb->prepare(
|
||||
' LIMIT %d OFFSET %d',
|
||||
$args['items_per_page'],
|
||||
( $args['page'] - 1 ) * $args['items_per_page']
|
||||
);
|
||||
}
|
||||
|
||||
return $limit_offset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
|
||||
use WPML\FP\Logic;
|
||||
|
||||
abstract class WPML_Custom_Field_Setting extends WPML_TM_User {
|
||||
|
||||
/** @var string $index */
|
||||
private $index;
|
||||
|
||||
/**
|
||||
* WPML_Custom_Field_Setting constructor.
|
||||
*
|
||||
* @param TranslationManagement $tm_instance
|
||||
* @param string $index
|
||||
*/
|
||||
public function __construct( &$tm_instance, $index ) {
|
||||
parent::__construct( $tm_instance );
|
||||
$this->index = $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool true if the custom field setting is given by a setting in
|
||||
* a wpml-config.xml
|
||||
*/
|
||||
public function is_read_only() {
|
||||
|
||||
return in_array(
|
||||
$this->index,
|
||||
$this->tm_instance->settings[ $this->get_array_setting_index( 'readonly_config' ) ],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_unlocked() {
|
||||
|
||||
return isset( $this->tm_instance->settings[ $this->get_unlocked_setting_index() ][ $this->index ] ) &&
|
||||
(bool) $this->tm_instance->settings[ $this->get_unlocked_setting_index() ][ $this->index ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function excluded() {
|
||||
|
||||
return in_array( $this->index, $this->get_excluded_keys() ) ||
|
||||
( $this->is_read_only() &&
|
||||
$this->status() === WPML_IGNORE_CUSTOM_FIELD &&
|
||||
! $this->is_unlocked()
|
||||
);
|
||||
}
|
||||
|
||||
public function status() {
|
||||
$state_index = $this->get_state_array_setting_index();
|
||||
if ( ! isset( $this->tm_instance->settings[ $state_index ][ $this->index ] ) ) {
|
||||
$this->tm_instance->settings[ $state_index ][ $this->index ] = WPML_IGNORE_CUSTOM_FIELD;
|
||||
}
|
||||
|
||||
return (int) $this->tm_instance->settings[ $state_index ][ $this->index ];
|
||||
}
|
||||
|
||||
public function make_read_only() {
|
||||
$ro_index = $this->get_array_setting_index( 'readonly_config' );
|
||||
$this->tm_instance->settings[ $ro_index ][] = $this->index;
|
||||
$this->tm_instance->settings[ $ro_index ] = array_unique( $this->tm_instance->settings[ $ro_index ] );
|
||||
}
|
||||
|
||||
public function set_to_copy() {
|
||||
$this->set_state( WPML_COPY_CUSTOM_FIELD );
|
||||
}
|
||||
|
||||
public function set_to_copy_once() {
|
||||
$this->set_state( WPML_COPY_ONCE_CUSTOM_FIELD );
|
||||
}
|
||||
|
||||
public function set_to_translatable() {
|
||||
$this->set_state( WPML_TRANSLATE_CUSTOM_FIELD );
|
||||
}
|
||||
|
||||
public function set_to_nothing() {
|
||||
$this->set_state( WPML_IGNORE_CUSTOM_FIELD );
|
||||
}
|
||||
|
||||
public function set_editor_style( $style ) {
|
||||
$this->tm_instance->settings[ $this->get_array_setting_index( 'editor_style' ) ][ $this->index ] = $style;
|
||||
}
|
||||
|
||||
public function get_editor_style() {
|
||||
$setting = $this->get_array_setting_index( 'editor_style' );
|
||||
return isset( $this->tm_instance->settings[ $setting ][ $this->index ] ) ? $this->tm_instance->settings[ $setting ][ $this->index ] : '';
|
||||
}
|
||||
|
||||
public function set_editor_label( $label ) {
|
||||
$this->tm_instance->settings[ $this->get_array_setting_index( 'editor_label' ) ][ $this->index ] = $label;
|
||||
}
|
||||
|
||||
public function get_editor_label() {
|
||||
$setting = $this->get_array_setting_index( 'editor_label' );
|
||||
return isset( $this->tm_instance->settings[ $setting ][ $this->index ] ) ? $this->tm_instance->settings[ $setting ][ $this->index ] : '';
|
||||
}
|
||||
|
||||
public function set_editor_group( $group ) {
|
||||
$this->tm_instance->settings[ $this->get_array_setting_index( 'editor_group' ) ][ $this->index ] = $group;
|
||||
}
|
||||
|
||||
public function get_editor_group() {
|
||||
$setting = $this->get_array_setting_index( 'editor_group' );
|
||||
|
||||
return isset( $this->tm_instance->settings[ $setting ][ $this->index ] ) ? $this->tm_instance->settings[ $setting ][ $this->index ] : '';
|
||||
}
|
||||
|
||||
public function set_translate_link_target( $state, $sub_fields ) {
|
||||
if ( isset( $sub_fields['value'] ) ) {
|
||||
// it's a single sub field
|
||||
$sub_fields = array( $sub_fields );
|
||||
}
|
||||
$this->tm_instance->settings[ $this->get_array_setting_index( 'translate_link_target' ) ][ $this->index ] = array(
|
||||
'state' => $state,
|
||||
'sub_fields' => $sub_fields,
|
||||
);
|
||||
}
|
||||
|
||||
public function is_translate_link_target() {
|
||||
$array_index = $this->get_array_setting_index( 'translate_link_target' );
|
||||
return isset( $this->tm_instance->settings[ $array_index ][ $this->index ] ) ?
|
||||
( $this->tm_instance->settings[ $array_index ][ $this->index ]['state'] ||
|
||||
$this->get_translate_link_target_sub_fields() ) :
|
||||
false;
|
||||
|
||||
}
|
||||
|
||||
public function get_translate_link_target_sub_fields() {
|
||||
$array_index = $this->get_array_setting_index( 'translate_link_target' );
|
||||
return isset( $this->tm_instance->settings[ $array_index ][ $this->index ]['sub_fields'] ) ?
|
||||
$this->tm_instance->settings[ $array_index ][ $this->index ]['sub_fields'] :
|
||||
array();
|
||||
}
|
||||
|
||||
public function set_convert_to_sticky( $state ) {
|
||||
$this->tm_instance->settings[ $this->get_array_setting_index( 'convert_to_sticky' ) ][ $this->index ] = $state;
|
||||
}
|
||||
|
||||
public function is_convert_to_sticky() {
|
||||
$array_index = $this->get_array_setting_index( 'convert_to_sticky' );
|
||||
return isset( $this->tm_instance->settings[ $array_index ][ $this->index ] ) ?
|
||||
$this->tm_instance->settings[ $array_index ][ $this->index ] :
|
||||
false;
|
||||
}
|
||||
|
||||
public function set_encoding( $encoding ) {
|
||||
if ( Logic::isNotNull( $encoding ) ) {
|
||||
$this->tm_instance->settings[ $this->get_array_setting_index( 'encoding' ) ][ $this->index ] = $encoding;
|
||||
} else {
|
||||
unset( $this->tm_instance->settings[ $this->get_array_setting_index( 'encoding' ) ][ $this->index ] );
|
||||
}
|
||||
}
|
||||
|
||||
public function get_encoding() {
|
||||
$setting = $this->get_array_setting_index( 'encoding' );
|
||||
return isset( $this->tm_instance->settings[ $setting ][ $this->index ] ) ? $this->tm_instance->settings[ $setting ][ $this->index ] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $whitelist
|
||||
*/
|
||||
public function set_attributes_whitelist( $whitelist ) {
|
||||
if ( ! is_array( $whitelist ) ) {
|
||||
throw new InvalidArgumentException( '$whitelist should be an array.' );
|
||||
}
|
||||
$this->tm_instance->settings[ $this->get_array_setting_index( 'attributes_whitelist' ) ][ $this->index ] = $whitelist;
|
||||
}
|
||||
|
||||
public function get_attributes_whitelist() {
|
||||
$setting = $this->get_array_setting_index( 'attributes_whitelist' );
|
||||
return isset( $this->tm_instance->settings[ $setting ][ $this->index ] ) ? $this->tm_instance->settings[ $setting ][ $this->index ] : array();
|
||||
}
|
||||
|
||||
private function set_state( $state ) {
|
||||
$this->tm_instance->settings[ $this->get_state_array_setting_index() ][ $this->index ] = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function get_array_setting_index( $index ) {
|
||||
return $this->get_setting_prefix() . $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function get_state_array_setting_index();
|
||||
|
||||
abstract protected function get_unlocked_setting_index();
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
abstract protected function get_excluded_keys();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function get_setting_prefix();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
use WPML\FP\Obj;
|
||||
|
||||
class WPML_Custom_Field_XML_Settings_Import {
|
||||
|
||||
/** @var WPML_Custom_Field_Setting_Factory $setting_factory */
|
||||
private $setting_factory;
|
||||
/** @var array $settings_array */
|
||||
private $settings_array;
|
||||
|
||||
/**
|
||||
* WPML_Custom_Field_XML_Settings_Import constructor.
|
||||
*
|
||||
* @param WPML_Custom_Field_Setting_Factory $setting_factory
|
||||
* @param array $settings_array
|
||||
*/
|
||||
public function __construct( $setting_factory, $settings_array ) {
|
||||
$this->setting_factory = $setting_factory;
|
||||
$this->settings_array = $settings_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the actual import of the xml
|
||||
*/
|
||||
public function run() {
|
||||
$config = $this->settings_array;
|
||||
foreach (
|
||||
array(
|
||||
'post_meta_setting' => array(
|
||||
WPML_POST_META_CONFIG_INDEX_PLURAL,
|
||||
WPML_POST_META_CONFIG_INDEX_SINGULAR
|
||||
),
|
||||
'term_meta_setting' => array(
|
||||
WPML_TERM_META_CONFIG_INDEX_PLURAL,
|
||||
WPML_TERM_META_CONFIG_INDEX_SINGULAR
|
||||
)
|
||||
) as $setting_constructor => $settings
|
||||
) {
|
||||
if ( ! empty( $config[ $settings[0] ] ) ) {
|
||||
$field = $config[ $settings[0] ][ $settings[1] ];
|
||||
$cf = ! is_numeric( key( current( $config[ $settings[0] ] ) ) ) ? array( $field ) : $field;
|
||||
foreach ( $cf as $c ) {
|
||||
$setting = call_user_func_array( array(
|
||||
$this->setting_factory,
|
||||
$setting_constructor
|
||||
), array( trim( $c['value'] ) ) );
|
||||
$this->import_action( $c, $setting );
|
||||
$setting->make_read_only();
|
||||
$this->import_editor_settings( $c, $setting );
|
||||
if ( isset( $c[ 'attr' ][ 'translate_link_target' ] ) || isset( $c[ 'custom-field' ] ) ) {
|
||||
$setting->set_translate_link_target( isset( $c[ 'attr' ][ 'translate_link_target' ] ) ? (bool) $c[ 'attr' ][ 'translate_link_target' ] : false, isset( $c[ 'custom-field' ] ) ? $c[ 'custom-field' ] : array() );
|
||||
}
|
||||
if ( isset( $c[ 'attr' ][ 'convert_to_sticky' ] ) ) {
|
||||
$setting->set_convert_to_sticky( (bool) $c[ 'attr' ][ 'convert_to_sticky' ] );
|
||||
}
|
||||
$setting->set_encoding( Obj::path( [ 'attr', 'encoding' ], $c ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->import_custom_field_texts();
|
||||
}
|
||||
|
||||
private function import_action( $c, $setting ) {
|
||||
if ( ! $setting->is_unlocked() ) {
|
||||
switch ( $c['attr']['action'] ) {
|
||||
case 'translate':
|
||||
$setting->set_to_translatable();
|
||||
break;
|
||||
|
||||
case 'copy':
|
||||
$setting->set_to_copy();
|
||||
break;
|
||||
|
||||
case 'copy-once':
|
||||
$setting->set_to_copy_once();
|
||||
break;
|
||||
|
||||
default:
|
||||
$setting->set_to_nothing();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function import_editor_settings( $c, $setting ) {
|
||||
if ( isset( $c[ 'attr' ][ 'style' ] ) ) {
|
||||
$setting->set_editor_style( $c[ 'attr' ][ 'style' ] );
|
||||
}
|
||||
if ( isset( $c[ 'attr' ][ 'label' ] ) ) {
|
||||
$setting->set_editor_label( $c[ 'attr' ][ 'label' ] );
|
||||
}
|
||||
if ( isset( $c[ 'attr' ][ 'group' ] ) ) {
|
||||
$setting->set_editor_group( $c[ 'attr' ][ 'group' ] );
|
||||
}
|
||||
}
|
||||
|
||||
private function import_custom_field_texts() {
|
||||
$config = $this->settings_array;
|
||||
|
||||
if ( isset( $config['custom-fields-texts']['key'] ) ) {
|
||||
foreach( $config['custom-fields-texts']['key'] as $field ) {
|
||||
$setting = $this->setting_factory->post_meta_setting( $field['attr']['name'] );
|
||||
$setting->set_attributes_whitelist( $this->get_custom_field_texts_keys( $field['key'] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function get_custom_field_texts_keys( $data ) {
|
||||
if ( isset( $data['attr'] ) ) { // single
|
||||
$data = array( $data );
|
||||
}
|
||||
|
||||
$sub_fields = array();
|
||||
|
||||
foreach( $data as $key ) {
|
||||
$sub_fields[ $key['attr']['name'] ] = isset( $key['key'] ) ? $this->get_custom_field_texts_keys( $key['key'] ) : array();
|
||||
}
|
||||
return $sub_fields;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
class WPML_Element_Sync_Settings_Factory {
|
||||
|
||||
const POST = 'post';
|
||||
const TAX = 'taxonomy';
|
||||
|
||||
const KEY_POST_SYNC_OPTION = 'custom_posts_sync_option';
|
||||
const KEY_TAX_SYNC_OPTION = 'taxonomies_sync_option';
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @return WPML_Element_Sync_Settings
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function create( $type ) {
|
||||
/** @var SitePress $sitepress */
|
||||
global $sitepress;
|
||||
|
||||
if ( self::POST === $type ) {
|
||||
$settings = $sitepress->get_setting( self::KEY_POST_SYNC_OPTION, array() );
|
||||
} elseif ( self::TAX === $type ) {
|
||||
$settings = $sitepress->get_setting( self::KEY_TAX_SYNC_OPTION, array() );
|
||||
} else {
|
||||
throw new Exception( 'Unknown element type.' );
|
||||
}
|
||||
|
||||
return new WPML_Element_Sync_Settings( $settings );
|
||||
}
|
||||
|
||||
public static function createPost() {
|
||||
return self::create( self::POST );
|
||||
}
|
||||
|
||||
public static function createTax() {
|
||||
return self::create( self::TAX );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
class WPML_Element_Sync_Settings {
|
||||
|
||||
/** @var array $settings */
|
||||
private $settings;
|
||||
|
||||
public function __construct( array $settings ) {
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_sync( $type ) {
|
||||
return isset( $this->settings[ $type ] ) &&
|
||||
(
|
||||
$this->settings[ $type ] == WPML_CONTENT_TYPE_TRANSLATE ||
|
||||
$this->settings[ $type ] == WPML_CONTENT_TYPE_DISPLAY_AS_IF_TRANSLATED
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
class WPML_Page_Builder_Settings {
|
||||
|
||||
const OPTION_KEY = 'wpml_page_builders_options';
|
||||
|
||||
private $settings;
|
||||
|
||||
/** @return bool */
|
||||
public function is_raw_html_translatable() {
|
||||
return (bool) $this->get_setting( 'translate_raw_html', true );
|
||||
}
|
||||
|
||||
/** @param bool $is_enabled */
|
||||
public function set_raw_html_translatable( $is_enabled ) {
|
||||
$this->set_setting( 'translate_raw_html', $is_enabled );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
private function set_setting( $key, $value ) {
|
||||
$this->settings[ $key ] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function get_setting( $key, $default = null ) {
|
||||
if ( null === $this->settings ) {
|
||||
$this->settings = get_option( self::OPTION_KEY, array() );
|
||||
}
|
||||
|
||||
if ( array_key_exists( $key, $this->settings ) ) {
|
||||
return $this->settings[ $key ];
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
public function save() {
|
||||
update_option( self::OPTION_KEY, $this->settings );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
class WPML_Post_Custom_Field_Setting_Keys {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function get_state_array_setting_index() {
|
||||
return 'custom_fields_translation';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function get_unlocked_setting_index() {
|
||||
return defined( 'WPML_POST_META_UNLOCKED_SETTING_INDEX' )
|
||||
? WPML_POST_META_UNLOCKED_SETTING_INDEX
|
||||
: 'custom_fields_unlocked_config';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function get_setting_prefix() {
|
||||
return 'custom_fields_';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function get_excluded_keys() {
|
||||
return array(
|
||||
'_edit_last',
|
||||
'_edit_lock',
|
||||
'_wp_page_template',
|
||||
'_wp_attachment_metadata',
|
||||
'_icl_translator_note',
|
||||
'_alp_processed',
|
||||
'_pingme',
|
||||
'_encloseme',
|
||||
'_icl_lang_duplicate_of',
|
||||
'_wpml_media_duplicate',
|
||||
'wpml_media_processed',
|
||||
'_wpml_media_featured',
|
||||
'_thumbnail_id'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
class WPML_Post_Custom_Field_Setting extends WPML_Custom_Field_Setting {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function get_state_array_setting_index() {
|
||||
return WPML_Post_Custom_Field_Setting_Keys::get_state_array_setting_index();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function get_unlocked_setting_index() {
|
||||
return WPML_Post_Custom_Field_Setting_Keys::get_unlocked_setting_index();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function get_setting_prefix() {
|
||||
return WPML_Post_Custom_Field_Setting_Keys::get_setting_prefix();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
protected function get_excluded_keys() {
|
||||
return WPML_Post_Custom_Field_Setting_Keys::get_excluded_keys();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author OnTheGo Systems
|
||||
*/
|
||||
class WPML_Settings_Filters {
|
||||
/**
|
||||
* @param array $types
|
||||
* @param array $read_only_cpt_settings
|
||||
* @param array $cpt_unlocked_options
|
||||
*
|
||||
* @return array
|
||||
* @see \WPML_Config::maybe_add_filter
|
||||
*/
|
||||
function get_translatable_documents( array $types, array $read_only_cpt_settings, array $cpt_unlocked_options ) {
|
||||
global $wp_post_types;
|
||||
foreach ( $read_only_cpt_settings as $cp => $translate ) {
|
||||
if ( $this->is_cpt_unlocked( $cpt_unlocked_options, $cp ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $translate && ! isset( $types[ $cp ] ) && isset( $wp_post_types[ $cp ] ) ) {
|
||||
$types[ $cp ] = $wp_post_types[ $cp ];
|
||||
} elseif ( ! $translate && isset( $types[ $cp ] ) ) {
|
||||
unset( $types[ $cp ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $cpt_unlocked_options
|
||||
* @param string $cp
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_cpt_unlocked( array $cpt_unlocked_options, $cp ) {
|
||||
return isset( $cpt_unlocked_options[ $cp ] ) && (bool) $cpt_unlocked_options[ $cp ];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
class WPML_Term_Custom_Field_Setting_Keys {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function get_state_array_setting_index() {
|
||||
return WPML_TERM_META_SETTING_INDEX_PLURAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function get_unlocked_setting_index() {
|
||||
return WPML_TERM_META_UNLOCKED_SETTING_INDEX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function get_setting_prefix() {
|
||||
return 'custom_term_fields_';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function get_excluded_keys() {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
class WPML_Term_Custom_Field_Setting extends WPML_Custom_Field_Setting {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function get_state_array_setting_index() {
|
||||
return WPML_Term_Custom_Field_Setting_Keys::get_state_array_setting_index();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function get_unlocked_setting_index() {
|
||||
return WPML_Term_Custom_Field_Setting_Keys::get_unlocked_setting_index();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function get_setting_prefix() {
|
||||
return WPML_Term_Custom_Field_Setting_Keys::get_setting_prefix();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
protected function get_excluded_keys() {
|
||||
return WPML_Term_Custom_Field_Setting_Keys::get_excluded_keys();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Serialized_Custom_Field_Package_Handler_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
public function create() {
|
||||
|
||||
$translation_management = wpml_load_core_tm();
|
||||
return new WPML_TM_Serialized_Custom_Field_Package_Handler(
|
||||
new WPML_Custom_Field_Setting_Factory( $translation_management )
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Serialized_Custom_Field_Package_Handler {
|
||||
|
||||
/** @var WPML_Custom_Field_Setting_Factory $custom_field_setting_factory */
|
||||
private $custom_field_setting_factory;
|
||||
|
||||
public function __construct( WPML_Custom_Field_Setting_Factory $custom_field_setting_factory ) {
|
||||
$this->custom_field_setting_factory = $custom_field_setting_factory;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_filter(
|
||||
'wpml_translation_job_post_meta_value_translated',
|
||||
array(
|
||||
$this,
|
||||
'translate_only_whitelisted_attributes',
|
||||
),
|
||||
10,
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $translated
|
||||
* @param string $custom_field_job_type - e.g: field-my_custom_field-0-my_attribute.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function translate_only_whitelisted_attributes( $translated, $custom_field_job_type ) {
|
||||
if ( $translated ) {
|
||||
list( $custom_field, $attributes ) = WPML_TM_Field_Type_Encoding::decode( $custom_field_job_type );
|
||||
if ( $custom_field && $attributes ) {
|
||||
$settings = $this->custom_field_setting_factory->post_meta_setting( $custom_field );
|
||||
$attributes_whitelist = $settings->get_attributes_whitelist();
|
||||
|
||||
if ( $attributes_whitelist ) {
|
||||
$translated = $this->match_in_order( $attributes, $attributes_whitelist ) ? $translated : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $translated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the attributes array to the whitelist array
|
||||
* The whitelist array has the attribute as the key to another array for sub keys
|
||||
* eg. array( 'attribute1' => array( 'subkey1' => array() ) )
|
||||
*
|
||||
* @param array $attributes - The attributes in the custom field.
|
||||
* @param array $whitelist - The whitelist attributes to match against.
|
||||
* @param int $current_depth - The current depth in the attributes array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function match_in_order( $attributes, $whitelist, $current_depth = 0 ) {
|
||||
$current_attribute = $attributes[ $current_depth ];
|
||||
$wildcard_match = $this->match_with_wildcards( $current_attribute, array_keys( $whitelist ) );
|
||||
if ( $wildcard_match ) {
|
||||
if ( count( $attributes ) === $current_depth + 1 ) {
|
||||
return true;
|
||||
} else {
|
||||
return $this->match_in_order( $attributes, $whitelist[ $wildcard_match ], $current_depth + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the attribute to the whitelist array using wildcards.
|
||||
* Wildcards can only be used at the end of the string.
|
||||
* eg. 'title-*', 'data*', '*'
|
||||
* A '*' matches everything.
|
||||
*
|
||||
* @param string $attribute - the current attributes.
|
||||
* @param array $whitelist - the whitelist to match against.
|
||||
*
|
||||
* @return string - Returns the whitelist string match.
|
||||
*/
|
||||
private function match_with_wildcards( $attribute, $whitelist ) {
|
||||
foreach ( $whitelist as $white_value ) {
|
||||
$asterisk_pos = strpos( $white_value, '*' );
|
||||
if ( false === $asterisk_pos ) {
|
||||
if ( $attribute === $white_value ) {
|
||||
return $white_value;
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
0 === $asterisk_pos ||
|
||||
substr( $attribute, 0, $asterisk_pos ) === substr( $white_value, 0, $asterisk_pos )
|
||||
) {
|
||||
return $white_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Settings_Post_Process extends WPML_TM_User {
|
||||
|
||||
/**
|
||||
* Saves TM settings to the database in case they have changed after reading a config file.
|
||||
*/
|
||||
public function run() {
|
||||
$changed = false;
|
||||
$settings = &$this->tm_instance->settings;
|
||||
foreach (
|
||||
array(
|
||||
WPML_POST_META_READONLY_SETTING_INDEX,
|
||||
WPML_TERM_META_READONLY_SETTING_INDEX,
|
||||
WPML_POST_TYPE_READONLY_SETTING_INDEX
|
||||
) as $index
|
||||
) {
|
||||
$prev_index = $this->prev_index( $index );
|
||||
if ( isset( $settings[ $index ] ) && isset( $settings[ $prev_index ] ) ) {
|
||||
foreach (
|
||||
array(
|
||||
$index => $prev_index,
|
||||
$prev_index => $index
|
||||
) as $left_index => $right_index
|
||||
) {
|
||||
foreach ( $settings[ $right_index ] as $cf ) {
|
||||
if ( ! in_array( $cf,
|
||||
$settings[ $left_index ] )
|
||||
) {
|
||||
$changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $changed ) {
|
||||
$this->tm_instance->save_settings();
|
||||
}
|
||||
}
|
||||
|
||||
private function prev_index( $index ) {
|
||||
|
||||
return '__' . $index . '_prev';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
use WPML\FP\Obj;
|
||||
|
||||
class WPML_TM_Settings_Update extends WPML_SP_User {
|
||||
|
||||
private $index_singular;
|
||||
private $index_ro;
|
||||
private $index_sync;
|
||||
private $index_plural;
|
||||
private $index_unlocked;
|
||||
/** @var TranslationManagement $tm_instance */
|
||||
private $tm_instance;
|
||||
/** @var WPML_Settings_Helper $settings_helper */
|
||||
private $settings_helper;
|
||||
|
||||
/**
|
||||
* @param string $index_singular
|
||||
* @param string $index_plural
|
||||
* @param TranslationManagement $tm_instance
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_Settings_Helper $settings_helper
|
||||
*/
|
||||
public function __construct( $index_singular, $index_plural, &$tm_instance, &$sitepress, $settings_helper ) {
|
||||
parent::__construct( $sitepress );
|
||||
$this->tm_instance = &$tm_instance;
|
||||
$this->index_singular = $index_singular;
|
||||
$this->index_plural = $index_plural;
|
||||
$this->index_ro = $index_plural . '_readonly_config';
|
||||
$this->index_sync = $index_plural . '_sync_option';
|
||||
$this->index_unlocked = 'custom-type' == $index_singular ? 'custom_posts_unlocked_option' : 'taxonomies_unlocked_option';
|
||||
$this->settings_helper = $settings_helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $config
|
||||
*/
|
||||
public function update_from_config( array $config ) {
|
||||
$this->update_tm_settings( Obj::propOr( [], $this->index_plural, $config ) );
|
||||
}
|
||||
|
||||
private function sync_settings( array $config ) {
|
||||
$section_singular = $this->index_singular;
|
||||
$section_plural = $this->index_plural;
|
||||
|
||||
if ( ! empty( $config[ $section_singular ] ) ) {
|
||||
$sync_option = $this->sitepress->get_setting( $this->index_sync, [] );
|
||||
$unlocked_option = $this->sitepress->get_setting( $this->index_unlocked, [] );
|
||||
if ( ! is_numeric( key( current( $config ) ) ) ) {
|
||||
$cf[0] = $config[ $section_singular ];
|
||||
} else {
|
||||
$cf = $config[ $section_singular ];
|
||||
}
|
||||
foreach ( $cf as $c ) {
|
||||
$val = $c['value'];
|
||||
|
||||
if ( ! $this->is_unlocked_type( $val, $unlocked_option ) ) {
|
||||
|
||||
$sync_existing_setting = isset( $sync_option[ $val ] ) ? $sync_option[ $val ] : false;
|
||||
$sync_new_setting = (int) $c['attr']['translate'];
|
||||
$this->tm_instance->settings[ $this->index_ro ][ $val ] = $sync_new_setting;
|
||||
$sync_option[ $val ] = $sync_new_setting;
|
||||
|
||||
if ( $this->is_making_type_translatable( $sync_new_setting, $sync_existing_setting ) ) {
|
||||
if ( $section_plural === 'taxonomies' ) {
|
||||
$this->sitepress->verify_taxonomy_translations( $val );
|
||||
} else {
|
||||
$this->sitepress->verify_post_translations( $val );
|
||||
}
|
||||
$this->tm_instance->save_settings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->sitepress->set_setting( $this->index_sync, $sync_option );
|
||||
$this->settings_helper->maybe_add_filter( $section_plural );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $new_sync 0, 1 or 2
|
||||
* @param int $old_sync 0, 1 or 2
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_making_type_translatable( $new_sync, $old_sync ) {
|
||||
return in_array(
|
||||
$new_sync,
|
||||
[
|
||||
WPML_CONTENT_TYPE_TRANSLATE,
|
||||
WPML_CONTENT_TYPE_DISPLAY_AS_IF_TRANSLATED,
|
||||
]
|
||||
) && WPML_CONTENT_TYPE_DONT_TRANSLATE === $old_sync;
|
||||
}
|
||||
|
||||
private function update_tm_settings( array $config ) {
|
||||
$section_singular = $this->index_singular;
|
||||
$config = array_filter( $config );
|
||||
$config[ $section_singular ] = Obj::propOr( [], $section_singular, $config );
|
||||
$this->sync_settings( $config );
|
||||
|
||||
// taxonomies - check what's been removed
|
||||
if ( ! empty( $this->tm_instance->settings[ $this->index_ro ] ) ) {
|
||||
$config_values = [];
|
||||
foreach ( $config[ $section_singular ] as $config_value ) {
|
||||
$config_values[ $config_value['value'] ] = $config_value['attr']['translate'];
|
||||
}
|
||||
foreach ( $this->tm_instance->settings[ $this->index_ro ] as $key => $translation_option ) {
|
||||
if ( ! isset( $config_values[ $key ] ) ) {
|
||||
unset( $this->tm_instance->settings[ $this->index_ro ][ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
$this->tm_instance->save_settings();
|
||||
}
|
||||
}
|
||||
|
||||
private function is_unlocked_type( $type, $unlocked_options ) {
|
||||
return isset( $unlocked_options[ $type ] ) && $unlocked_options[ $type ];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: bruce
|
||||
* Date: 5/10/17
|
||||
* Time: 10:23 PM
|
||||
*/
|
||||
|
||||
class WPML_Verify_SitePress_Settings {
|
||||
|
||||
/** @var WPML_WP_API $wp_api */
|
||||
private $wp_api;
|
||||
|
||||
public function __construct( WPML_WP_API $wp_api ) {
|
||||
$this->wp_api = $wp_api;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function verify( $settings ) {
|
||||
$default_settings = [
|
||||
'interview_translators' => 1,
|
||||
'existing_content_language_verified' => 0,
|
||||
'language_negotiation_type' => 1,
|
||||
'icl_lso_link_empty' => 0,
|
||||
'sync_page_ordering' => 1,
|
||||
'sync_page_parent' => 1,
|
||||
'sync_page_template' => 1,
|
||||
'sync_ping_status' => 1,
|
||||
'sync_comment_status' => 1,
|
||||
'sync_sticky_flag' => 1,
|
||||
'sync_password' => 1,
|
||||
'sync_private_flag' => 1,
|
||||
'sync_post_format' => 1,
|
||||
'sync_delete' => 0,
|
||||
'sync_delete_tax' => 0,
|
||||
'sync_post_taxonomies' => 1,
|
||||
'sync_post_date' => 1,
|
||||
'sync_taxonomy_parents' => 0,
|
||||
'translation_pickup_method' => 0,
|
||||
'notify_complete' => 1,
|
||||
'translated_document_status' => 1,
|
||||
'remote_management' => 0,
|
||||
'auto_adjust_ids' => 1,
|
||||
'alert_delay' => 0,
|
||||
'promote_wpml' => 0,
|
||||
'automatic_redirect' => 0,
|
||||
'remember_language' => 24,
|
||||
'icl_lang_sel_copy_parameters' => '',
|
||||
'translated_document_page_url' => 'auto-generate',
|
||||
'sync_comments_on_duplicates' => 0,
|
||||
'seo' => [
|
||||
'head_langs' => 1,
|
||||
'canonicalization_duplicates' => 1,
|
||||
'head_langs_priority' => 1,
|
||||
],
|
||||
'posts_slug_translation' => [
|
||||
/** @deprected key `on`, use option `wpml_base_slug_translation` instead */
|
||||
'on' => 1,
|
||||
],
|
||||
'languages_order' => [],
|
||||
'urls' => [
|
||||
'directory_for_default_language' => 0,
|
||||
'show_on_root' => '',
|
||||
'root_html_file_path' => '',
|
||||
'root_page' => 0,
|
||||
'hide_language_switchers' => 1,
|
||||
],
|
||||
'xdomain_data' => $this->wp_api->constant( 'WPML_XDOMAIN_DATA_GET' ),
|
||||
'custom_posts_sync_option' => [
|
||||
'post' => WPML_CONTENT_TYPE_TRANSLATE,
|
||||
'page' => WPML_CONTENT_TYPE_TRANSLATE,
|
||||
],
|
||||
'taxonomies_sync_option' => [
|
||||
'category' => WPML_CONTENT_TYPE_TRANSLATE,
|
||||
'post_tag' => WPML_CONTENT_TYPE_TRANSLATE,
|
||||
],
|
||||
'tm_block_retranslating_terms' => 1,
|
||||
];
|
||||
|
||||
// configured for three levels
|
||||
$update_settings = false;
|
||||
foreach ( $default_settings as $key => $value ) {
|
||||
if ( is_array( $value ) ) {
|
||||
foreach ( $value as $k2 => $v2 ) {
|
||||
if ( is_array( $v2 ) ) {
|
||||
foreach ( $v2 as $k3 => $v3 ) {
|
||||
if ( ! isset( $settings[ $key ][ $k2 ][ $k3 ] ) ) {
|
||||
$settings[ $key ][ $k2 ][ $k3 ] = $v3;
|
||||
$update_settings = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( ! isset( $settings[ $key ][ $k2 ] ) ) {
|
||||
$settings[ $key ][ $k2 ] = $v2;
|
||||
$update_settings = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( ! isset( $settings[ $key ] ) ) {
|
||||
$settings[ $key ] = $value;
|
||||
$update_settings = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [ $settings, $update_settings ];
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Default_Settings_Factory implements IWPML_Frontend_Action_Loader, IWPML_Backend_Action_Loader {
|
||||
|
||||
public function create() {
|
||||
/** @var TranslationManagement */
|
||||
global $iclTranslationManagement;
|
||||
|
||||
return new WPML_TM_Default_Settings( $iclTranslationManagement );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Default_Settings implements IWPML_Action {
|
||||
|
||||
/** @var TranslationManagement */
|
||||
private $tm;
|
||||
|
||||
public function __construct( TranslationManagement $tm ) {
|
||||
$this->tm = $tm;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'init', array( $this, 'init_action' ), $this->tm->get_init_priority() );
|
||||
}
|
||||
|
||||
public function init_action() {
|
||||
$this->maybe_update_notification( 'new-job', WPML_TM_Emails_Settings::NOTIFY_IMMEDIATELY );
|
||||
$this->maybe_update_notification( 'include_xliff', (int) apply_filters( 'wpml_setting', 0, 'include_xliff_in_notification' ) );
|
||||
|
||||
if ( ! $this->has_notification( WPML_TM_Emails_Settings::COMPLETED_JOB_FREQUENCY ) ) {
|
||||
if ( $this->has_notification( 'completed' ) ) {
|
||||
$this->update_notification( WPML_TM_Emails_Settings::COMPLETED_JOB_FREQUENCY, $this->get_notification( 'completed' ) );
|
||||
} else {
|
||||
$this->update_notification( WPML_TM_Emails_Settings::COMPLETED_JOB_FREQUENCY, WPML_TM_Emails_Settings::NOTIFY_WEEKLY );
|
||||
}
|
||||
}
|
||||
|
||||
$this->maybe_update_notification( 'completed', WPML_TM_Emails_Settings::NOTIFY_IMMEDIATELY );
|
||||
$this->maybe_update_notification( 'resigned', WPML_TM_Emails_Settings::NOTIFY_IMMEDIATELY );
|
||||
$this->maybe_update_notification( 'overdue', WPML_TM_Emails_Settings::NOTIFY_IMMEDIATELY );
|
||||
$this->maybe_update_notification( 'overdue_offset', 7 );
|
||||
$this->maybe_update_notification( 'dashboard', true );
|
||||
$this->maybe_update_notification( 'purge-old', 7 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function get_notification( $key, $default = null ) {
|
||||
return isset( $this->tm->settings['notification'][ $key ] )
|
||||
? $this->tm->settings['notification'][ $key ]
|
||||
: $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function has_notification( $key ) {
|
||||
return isset( $this->tm->settings['notification'][ $key ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
private function maybe_update_notification( $key, $value ) {
|
||||
if ( ! $this->has_notification( $key ) ) {
|
||||
$this->update_notification( $key, $value );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
private function update_notification( $key, $value ) {
|
||||
$this->tm->settings['notification'][ $key ] = $value;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user