| 1 |
<?php |
| 2 |
namespace FileBird\Support; |
| 3 |
|
| 4 |
use FileBird\Model\Folder as FolderModel; |
| 5 |
use FileBird\Controller\Controller; |
| 6 |
|
| 7 |
defined( 'ABSPATH' ) || exit; |
| 8 |
|
| 9 |
class WPML extends Controller { |
| 10 |
protected $post_translations; |
| 11 |
private $sitepress; |
| 12 |
private $lang; |
| 13 |
private $wpdb; |
| 14 |
private $table_icl_translations; |
| 15 |
private $cpt_sync_options; |
| 16 |
|
| 17 |
public function __construct() { |
| 18 |
global $sitepress, $wpdb; |
| 19 |
if ( $sitepress === null || get_class( $sitepress ) !== 'SitePress' ) { |
| 20 |
return; |
| 21 |
} |
| 22 |
|
| 23 |
$this->sitepress = $sitepress; |
| 24 |
$this->lang = $sitepress->get_current_language(); |
| 25 |
$this->wpdb = $wpdb; |
| 26 |
$this->table_icl_translations = $wpdb->prefix . 'icl_translations'; |
| 27 |
$this->post_translations = $sitepress->post_translations(); |
| 28 |
$this->cpt_sync_options = $this->sitepress->get_setting( 'custom_posts_sync_option', array() ); |
| 29 |
|
| 30 |
add_filter( 'fbv_ids_assigned_to_folder', array( $this, 'assigned_to_folder' ), 10, 2 ); |
| 31 |
add_filter( 'wpml_pre_parse_query', array( $this, 'preParseQuery' ) ); |
| 32 |
add_filter( 'wpml_post_parse_query', array( $this, 'postParseQuery' ) ); |
| 33 |
add_action( 'wp_ajax_fbv_sync_wpml', array( $this, 'syncWPML' ) ); |
| 34 |
add_filter( 'fbv_data', array( $this, 'fbv_data' ), 10, 1 ); |
| 35 |
|
| 36 |
if ( ! isset( $this->cpt_sync_options['attachment'] ) || $this->cpt_sync_options['attachment'] != '0' ) { |
| 37 |
add_filter( 'fbv_get_count_query', array( $this, 'fbv_get_count_query' ), 10, 3 ); |
| 38 |
add_filter( 'fbv_speedup_get_count_query', '__return_true' ); |
| 39 |
add_filter( 'fbv_all_folders_and_count', array( $this, 'all_folders_and_count_query' ), 10, 2 ); |
| 40 |
} |
| 41 |
} |
| 42 |
|
| 43 |
public function fbv_data( $data ) { |
| 44 |
$data['icl_lang'] = apply_filters( 'wpml_current_language', null ); |
| 45 |
|
| 46 |
return $data; |
| 47 |
} |
| 48 |
|
| 49 |
public function syncWPML() { |
| 50 |
global $wpdb; |
| 51 |
|
| 52 |
check_ajax_referer( 'fbv_nonce', 'nonce', true ); |
| 53 |
|
| 54 |
$translationNotInFolder = $wpdb->get_results( |
| 55 |
"SELECT GROUP_CONCAT( IF(fbv.folder_id is NULL, icl.element_id, NULL) ) as attachment_ids, GROUP_CONCAT(DISTINCT(fbv.folder_id)) as folder_id |
| 56 |
FROM `{$wpdb->prefix}icl_translations` icl |
| 57 |
LEFT JOIN `{$wpdb->prefix}fbv_attachment_folder` fbv |
| 58 |
ON fbv.attachment_id = icl.element_id |
| 59 |
WHERE ( icl.element_type = 'post_attachment' ) |
| 60 |
GROUP BY icl.trid |
| 61 |
HAVING ( COUNT(icl.element_id) > COUNT(fbv.folder_id) AND COUNT(fbv.folder_id) > 0 )" |
| 62 |
); |
| 63 |
|
| 64 |
foreach ( $translationNotInFolder as $translation ) { |
| 65 |
$elementIds = explode( ',', $translation->attachment_ids ); |
| 66 |
$folderId = intval( $translation->folder_id ); |
| 67 |
|
| 68 |
foreach ( $elementIds as $elementId ) { |
| 69 |
FolderModel::setFoldersForPosts( $elementId, $folderId ); |
| 70 |
} |
| 71 |
} |
| 72 |
|
| 73 |
return wp_send_json( |
| 74 |
array( |
| 75 |
'message' => __( 'Done!', 'filebird' ), |
| 76 |
) |
| 77 |
); |
| 78 |
} |
| 79 |
|
| 80 |
public function fbv_get_count_query( $q, $folder_id, $lang ) { |
| 81 |
global $wpdb; |
| 82 |
if ( $folder_id == -1 ) { |
| 83 |
$q = "SELECT COUNT(*) FROM {$wpdb->posts} |
| 84 |
JOIN {$this->table_icl_translations} wpml_translations ON {$wpdb->posts}.ID = wpml_translations.element_id |
| 85 |
AND wpml_translations.element_type = CONCAT('post_', {$wpdb->posts}.post_type) |
| 86 |
WHERE 1=1 |
| 87 |
AND {$wpdb->posts}.ID NOT IN |
| 88 |
(SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_elementor_is_screenshot') |
| 89 |
AND wpml_translations.element_type = 'post_attachment' |
| 90 |
AND (( {$wpdb->posts}.post_status = 'inherit' OR {$wpdb->posts}.post_status = 'private'))"; //->This query maybe not correct in grid mode |
| 91 |
|
| 92 |
if ( $lang == 'all' ) { |
| 93 |
$q .= $this->all_langs_where(); |
| 94 |
} else { |
| 95 |
$where = $this->specific_lang_where( $lang ); |
| 96 |
$q .= $where; |
| 97 |
} |
| 98 |
} else { |
| 99 |
$q = "SELECT count(wpmlt.element_id) FROM {$this->table_icl_translations} AS wpmlt |
| 100 |
INNER JOIN {$wpdb->posts} as posts ON posts.ID = wpmlt.element_id |
| 101 |
INNER JOIN {$wpdb->prefix}fbv_attachment_folder as fbvaf on wpmlt.element_id = fbvaf.attachment_id |
| 102 |
WHERE |
| 103 |
posts.ID NOT IN (SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_elementor_is_screenshot') |
| 104 |
AND (post_status = 'inherit' OR post_status = 'private') AND wpmlt.element_type = 'post_attachment' AND wpmlt.language_code = '{$lang}' AND fbvaf.folder_id = " . (int) $folder_id; |
| 105 |
} |
| 106 |
return $q; |
| 107 |
} |
| 108 |
|
| 109 |
public function all_folders_and_count_query( $query, $lang ) { |
| 110 |
global $wpdb; |
| 111 |
$query = "SELECT fbva.folder_id as folder_id, count(fbva.attachment_id) as counter FROM {$wpdb->prefix}fbv_attachment_folder AS fbva |
| 112 |
INNER JOIN {$wpdb->prefix}fbv as fbv ON fbv.id = fbva.folder_id |
| 113 |
INNER JOIN {$this->table_icl_translations} AS wpml_translations ON fbva.attachment_id = wpml_translations.element_id |
| 114 |
INNER JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = fbva.attachment_id |
| 115 |
WHERE ({$wpdb->posts}.post_status = 'inherit' OR {$wpdb->posts}.post_status = 'private') AND wpml_translations.element_type = 'post_attachment' AND {$wpdb->posts}.post_type = 'attachment'"; |
| 116 |
if ( $lang == 'all' ) { |
| 117 |
$query .= $this->all_langs_where(); |
| 118 |
} else { |
| 119 |
$where = $this->specific_lang_where( $lang ); |
| 120 |
$query .= $where; |
| 121 |
} |
| 122 |
$query .= $wpdb->prepare( 'AND fbv.created_by = %d GROUP BY fbva.folder_id', apply_filters( 'fbv_folder_created_by', '0' ) ); |
| 123 |
|
| 124 |
return $query; |
| 125 |
} |
| 126 |
|
| 127 |
public function assigned_to_folder( $attachmentIds ) { |
| 128 |
$idArr = array(); |
| 129 |
|
| 130 |
foreach ( $attachmentIds as $id ) { |
| 131 |
$post = get_post( $id ); |
| 132 |
$post_type = $post->post_type; |
| 133 |
$post_trid = $this->sitepress->get_element_trid( $id, 'post_' . $post_type ); |
| 134 |
$post_translations = $this->sitepress->get_element_translations( $post_trid, 'post_' . $post_type ); |
| 135 |
|
| 136 |
foreach ( $post_translations as $post_language => $translated_post ) { |
| 137 |
$translated_post_id = $translated_post->element_id; |
| 138 |
if ( ! $translated_post_id ) { |
| 139 |
continue; |
| 140 |
} |
| 141 |
array_push( $idArr, intval( $translated_post_id ) ); |
| 142 |
} |
| 143 |
} |
| 144 |
|
| 145 |
return empty( $idArr ) ? $attachmentIds : $idArr; |
| 146 |
} |
| 147 |
|
| 148 |
public function filterInNotIn( $query ) { |
| 149 |
$query = $this->adjust_q_var_pids( $query, 'post__not_in' ); |
| 150 |
$query = $this->adjust_q_var_pids( $query, 'post__in' ); |
| 151 |
return $query; |
| 152 |
} |
| 153 |
|
| 154 |
public function preParseQuery( $q ) { |
| 155 |
if ( ! empty( $q->query_vars['post_type'] ) && $q->query_vars['post_type'] == 'attachment' ) { |
| 156 |
$cpt_sync_options = $this->sitepress->get_setting( 'custom_posts_sync_option', array() ); |
| 157 |
if ( isset( $cpt_sync_options['attachment'] ) && $cpt_sync_options['attachment'] == '0' ) { |
| 158 |
$q->query_vars['fbv_backup_post__in'] = $q->query_vars['post__in']; |
| 159 |
$q->query_vars['fbv_backup_post__not_in'] = $q->query_vars['post__not_in']; |
| 160 |
$q->query_vars['post__in'] = array(); |
| 161 |
$q->query_vars['post__not_in'] = array(); |
| 162 |
} |
| 163 |
} |
| 164 |
return $q; |
| 165 |
} |
| 166 |
public function postParseQuery( $q ) { |
| 167 |
if ( ! empty( $q->query_vars['post_type'] ) && $q->query_vars['post_type'] == 'attachment' ) { |
| 168 |
$cpt_sync_options = $this->sitepress->get_setting( 'custom_posts_sync_option', array() ); |
| 169 |
if ( isset( $cpt_sync_options['attachment'] ) && $cpt_sync_options['attachment'] == '0' ) { |
| 170 |
$q->query_vars['post__in'] = $q->query_vars['fbv_backup_post__in']; |
| 171 |
$q->query_vars['post__not_in'] = $q->query_vars['fbv_backup_post__not_in']; |
| 172 |
unset( $q->query_vars['fbv_backup_post__in'] ); |
| 173 |
unset( $q->query_vars['fbv_backup_post__not_in'] ); |
| 174 |
} |
| 175 |
} |
| 176 |
return $q; |
| 177 |
} |
| 178 |
private function adjust_q_var_pids( $q, $index ) { |
| 179 |
if ( ! empty( $q[ $index ] ) ) { |
| 180 |
|
| 181 |
$untranslated = $q[ $index ]; |
| 182 |
$this->post_translations->prefetch_ids( $untranslated ); |
| 183 |
$current_lang = $this->sitepress->get_current_language(); |
| 184 |
$pid = array(); |
| 185 |
foreach ( $q[ $index ] as $p ) { |
| 186 |
$pid[] = $this->post_translations->element_id_in( $p, $current_lang, true ); |
| 187 |
} |
| 188 |
$q[ $index ] = $pid; |
| 189 |
} |
| 190 |
|
| 191 |
return $q; |
| 192 |
} |
| 193 |
public function countArgs( $args ) { |
| 194 |
$args['suppress_filters'] = false; |
| 195 |
return $args; |
| 196 |
} |
| 197 |
|
| 198 |
public function all_langs_where() { |
| 199 |
return ' AND wpml_translations.language_code IN (' . \wpml_prepare_in( array_keys( $this->sitepress->get_active_languages() ) ) . ') '; |
| 200 |
} |
| 201 |
|
| 202 |
public function specific_lang_where( $lang ) { |
| 203 |
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared |
| 204 |
$default_language = $this->sitepress->get_default_language(); |
| 205 |
$current_language = $lang; |
| 206 |
return $this->wpdb->prepare( |
| 207 |
' AND ( ( ( wpml_translations.language_code = %s OR ' |
| 208 |
. $this->display_as_translated_snippet( $current_language, $default_language ) |
| 209 |
. ' ) AND ' |
| 210 |
. $this->in_translated_types_snippet() |
| 211 |
. ' ) OR ' . $this->in_translated_types_snippet( true ) . ' )', |
| 212 |
$current_language |
| 213 |
); |
| 214 |
} |
| 215 |
|
| 216 |
public function display_as_translated_snippet( $current_language, $fallback_language ) { |
| 217 |
$content_types = null; |
| 218 |
$skip_content_check = true; |
| 219 |
|
| 220 |
if ( ! apply_filters( 'wpml_should_force_display_as_translated_snippet', false ) ) { |
| 221 |
$post_types = $this->sitepress->get_display_as_translated_documents(); |
| 222 |
if ( ! $post_types || ! apply_filters( 'wpml_should_use_display_as_translated_snippet', ! is_admin(), $post_types ) ) { |
| 223 |
return '0'; |
| 224 |
} |
| 225 |
$content_types = array_keys( $post_types ); |
| 226 |
$skip_content_check = false; |
| 227 |
} |
| 228 |
|
| 229 |
$display_as_translated_query = new \WPML_Display_As_Translated_Posts_Query( $this->wpdb ); |
| 230 |
|
| 231 |
return $display_as_translated_query->get_language_snippet( $current_language, $fallback_language, $content_types, $skip_content_check ); |
| 232 |
} |
| 233 |
|
| 234 |
public function in_translated_types_snippet( $not = false, $posts_alias = false ) { |
| 235 |
$not = $not ? ' NOT ' : ''; |
| 236 |
$posts_alias = $posts_alias ? $posts_alias : $this->wpdb->posts; |
| 237 |
|
| 238 |
$post_types = $this->sitepress->get_translatable_documents( false ); |
| 239 |
if ( $post_types ) { |
| 240 |
return "{$posts_alias}.post_type {$not} IN (" . wpml_prepare_in( array_keys( $post_types ) ) . ' ) '; |
| 241 |
} else { |
| 242 |
return ''; |
| 243 |
} |
| 244 |
} |
| 245 |
} |