PluginProbe ʕ •ᴥ•ʔ
WPML Multilingual & Multicurrency for WooCommerce / 5.5.7
WPML Multilingual & Multicurrency for WooCommerce v5.5.7
5.5.7 5.3.8 5.3.9 5.4.3 5.4.4 5.4.5 5.5.1 5.5.1.1 5.5.2.2 5.5.2.3 5.5.3 5.5.3.1 5.5.4 5.5.5 5.5.6 trunk 0.9 1.0 1.1 1.2 1.3 1.4 1.5 2.0 2.2 2.3 2.3.1 2.3.2 3.0 3.0.1 3.1 3.2 3.2.1 3.2.2 3.3 3.3.1 3.3.2 3.3.3 3.3.4 3.4 3.4.1 3.4.2 3.4.3 3.5 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.6 3.6.1 3.6.10 3.6.11 3.6.2 3.6.3 3.6.4 3.6.5 3.6.5.1 3.6.6 3.6.7 3.6.8 3.6.9 3.7 3.7.1 3.7.10 3.7.11 3.7.12 3.7.13 3.7.14 3.7.15 3.7.16 3.7.2 3.7.3 3.7.4 3.7.5 3.7.6 3.7.7 3.7.8 3.7.9 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.9.0 3.9.1 3.9.1.1 3.9.2 3.9.3 3.9.4 3.9.5 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.10.0 4.10.1 4.10.2 4.10.3 4.10.4 4.11.2 4.11.3.2 4.11.5 4.11.6 4.12.1 4.12.4 4.12.5 4.12.6 4.2.0 4.2.0.1 4.2.1 4.2.1.1 4.2.10 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.7.1 4.2.8 4.2.8.1 4.2.9 4.3.0 4.3.1 4.3.2 4.3.2.1 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.4.0 4.4.1 4.4.2 4.4.2.1 4.5.0 4.6.0 4.6.1 4.6.2 4.6.2.1 4.6.3 4.6.5 4.6.6 4.6.7 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.7.5 4.7.6 4.7.7 4.7.8 4.7.9 4.8.0 4.9.0 4.9.1 5.0.1 5.0.2 5.1.1 5.1.2 5.1.3 5.2.0 5.2.1 5.3.2 5.3.3.1 5.3.4 5.3.5 5.3.6 5.3.7
woocommerce-multilingual / inc / admin-menus / class-wcml-admin-menus.php
woocommerce-multilingual / inc / admin-menus Last commit date
class-wcml-admin-menus.php 4 weeks ago
class-wcml-admin-menus.php
322 lines
1 <?php
2
3 use function WCML\functions\getSetting;
4 use function WCML\functions\isStandAlone;
5 use WCML\AdminNotices\WizardNotice;
6 use WCML\StandAlone\UI\AdminMenu;
7 use WCML\Utilities\AdminPages;
8 use WCML\Utilities\AdminUrl;
9 use WPML\FP\Fns;
10 use WPML\FP\Str;
11
12 class WCML_Admin_Menus {
13
14 const SLUG = 'wpml-wcml';
15
16 private static $woocommerce_wpml;
17
18 private static $sitepress;
19
20 private static $wpdb;
21
22 public static function set_up_menus( $woocommerce_wpml, $sitepress, $wpdb ) {
23 self::$woocommerce_wpml = $woocommerce_wpml;
24 self::$sitepress = $sitepress;
25 self::$wpdb = $wpdb;
26
27 if (
28 \WPML\Container\make( WCML_Dependencies::class )->check() &&
29 ! current_user_can( 'wpml_manage_woocommerce_multilingual' ) &&
30 current_user_can( 'wpml_operate_woocommerce_multilingual' ) &&
31 ! current_user_can( 'translate' )
32 ) {
33 add_filter( 'wpml_menu_page', [ __CLASS__, 'wpml_menu_page' ] );
34 }
35
36 add_action( 'admin_menu', [ __CLASS__, 'register_menus' ], 80 );
37
38 if ( AdminPages::isWcmlSettings() ) {
39 add_action( 'admin_body_class', Str::concat( Fns::__, ' ' . self::SLUG . '-' . AdminPages::getTabToDisplay() ) );
40 }
41
42 if ( self::is_page_without_admin_language_switcher() ) {
43 self::remove_wpml_admin_language_switcher();
44 }
45
46 if ( is_admin() && ! is_null( $sitepress ) && \WPML\Container\make( WCML_Dependencies::class )->check() && WCML_Capabilities::canManageWcml() ) {
47 add_action( 'admin_head', [ __CLASS__, 'hide_multilingual_content_setup_box' ] );
48 if ( ! isStandAlone() ) {
49 add_action( 'admin_footer', [ __CLASS__, 'documentation_links' ] );
50 add_action( 'admin_init', [ __CLASS__, 'restrict_admin_with_redirect' ] );
51 }
52 add_filter( 'plugin_action_links_woocommerce-multilingual/wpml-woocommerce.php', [ __CLASS__, 'add_settings_links_to_plugin_actions' ] );
53 }
54
55 add_filter( 'woocommerce_prevent_admin_access', [ __CLASS__, 'check_user_admin_access' ] );
56
57 if ( ! isStandAlone() ) {
58 add_action( 'admin_head', [ __CLASS__, 'add_menu_warning' ] );
59 }
60 }
61
62 private static function is_page_without_admin_language_switcher() {
63 $get_page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : false;
64
65 $is_page_wpml_wcml = self::SLUG === $get_page;
66 $is_shipping_zones = 'shipping_zones' === $get_page;
67 $is_attributes_page = apply_filters( 'wcml_is_attributes_page', 'product_attributes' === $get_page );
68 $is_order_create_or_edit = \WCML\Orders\Helper::isOrderCreateAdminScreen() || \WCML\Orders\Helper::isOrderEditAdminScreen();
69 $is_coupon_create_or_edit = \WCML\Coupons\Helper::isCouponCreateAdminScreen() || \WCML\Coupons\Helper::isCouponEditAdminScreen();
70
71 return is_admin() && (
72 $is_page_wpml_wcml ||
73 $is_order_create_or_edit ||
74 $is_coupon_create_or_edit ||
75 $is_shipping_zones ||
76 $is_attributes_page
77 );
78 }
79
80 public static function remove_wpml_admin_language_switcher() {
81 remove_action( 'wp_before_admin_bar_render', [ self::$sitepress, 'admin_language_switcher' ] );
82 }
83
84 public static function wpml_menu_page( $menu ) {
85 if ( isset( $menu['menu_slug'] ) && WPML_TM_FOLDER . '/menu/translations-queue.php' === $menu['menu_slug'] ) {
86 $menu['capability'] = 'wpml_operate_woocommerce_multilingual';
87 }
88
89 return $menu;
90 }
91
92 public static function register_menus() {
93 $pageTitle = $menuTitle = self::getWcmlShortLabel();
94
95 if ( \WPML\Container\make( WCML_Dependencies::class )->check() || class_exists( 'WooCommerce' ) ) {
96 add_submenu_page(
97 'woocommerce',
98 $pageTitle,
99 $menuTitle,
100 'wpml_operate_woocommerce_multilingual',
101 self::SLUG,
102 [ __CLASS__, 'render_menus' ]
103 );
104 } else {
105 add_menu_page(
106 $pageTitle,
107 $menuTitle,
108 'wpml_manage_woocommerce_multilingual',
109 self::SLUG,
110 [ __CLASS__, 'render_menus' ],
111 WCML_PLUGIN_URL . '/res/images/icon16.png'
112 );
113
114 }
115 }
116
117 public static function render_menus() {
118 global $sitepress_settings;
119
120 if ( \WPML\Container\make( WCML_Dependencies::class )->check() ) {
121 if ( isStandAlone() ) {
122 $plugins_wrap = new AdminMenu( self::$sitepress, self::$woocommerce_wpml );
123 $plugins_wrap->show();
124 } elseif ( getSetting( 'set_up_wizard_run' ) ) {
125 $menus_wrap = new WCML_Menus_Wrap( self::$woocommerce_wpml, self::$sitepress, $sitepress_settings );
126 $menus_wrap->show();
127 } else {
128 $wizard_wrap = new WizardNotice( self::$woocommerce_wpml );
129 $wizard_wrap->show();
130 }
131 }
132 }
133
134 public static function documentation_links() {
135 global $post, $pagenow;
136
137 if ( $post && ! is_object( $post ) ) {
138 $post = get_post( $post );
139 }
140
141 if ( ! $post ) {
142 return;
143 }
144
145 $get_post_type = get_post_type( $post->ID );
146
147 if ( 'product' === $get_post_type && 'edit.php' === $pagenow ) {
148 $quick_edit_notice = '<p>';
149 $quick_edit_notice .= esc_html__( 'Quick Edit isn\'t available for product translations:', 'woocommerce-multilingual' );
150 $quick_edit_notice .= '</p>';
151
152 $quick_edit_notice .= '<ul>';
153 $quick_edit_notice .= '<li>';
154 $quick_edit_notice .= sprintf(
155 /* translators: %1$s and %2$s are opening and closing HTML link tags */
156 esc_html__( '- To edit this product\'s translation, use the %1$sTranslation Dashboard%2$s.', 'woocommerce-multilingual' ),
157 '<a href="' . esc_url( AdminUrl::getWPMLTMDashboardProducts() ) . '">',
158 '</a>'
159 );
160 $quick_edit_notice .= '</li>';
161 $quick_edit_notice .= '<li>';
162 $quick_edit_notice .= esc_html__( '- To edit the original product, switch back to the default language.', 'woocommerce-multilingual' );
163 $quick_edit_notice .= '</li>';
164 $quick_edit_notice .= '</ul>';
165
166 ?>
167 <script type="text/javascript">
168 jQuery( '.subsubsub' ).append( '<div id="quick_edit_notice" style="display:none;"><?php echo wp_filter_post_kses( $quick_edit_notice ); ?></div>' );
169
170 //lock feature for translations
171 jQuery( document ).on( 'click', '.featured a', function() {
172 if ( jQuery( this ).closest( 'tr' ).find( '.quick_hide' ).size() > 0 ) {
173 return false;
174 }
175
176 } );
177 </script>
178 <?php
179 }
180 }
181
182 public static function hide_multilingual_content_setup_box() {
183 remove_meta_box( 'icl_div_config', convert_to_screen( 'shop_order' ), 'normal' );
184 remove_meta_box( 'icl_div_config', convert_to_screen( 'shop_coupon' ), 'normal' );
185 }
186
187 public static function restrict_admin_with_redirect() {
188 global $pagenow;
189
190 if (
191 self::$woocommerce_wpml->is_wpml_prior_4_2() &&
192 self::$woocommerce_wpml->settings['trnsl_interface'] ) {
193
194 if (
195 'post.php' === $pagenow &&
196 ! wp_doing_ajax() &&
197 self::is_post_product_translation_screen() &&
198 self::is_post_action_needs_redirect()
199 ) {
200 $prid = (int) $_GET['post'];
201 if ( 'auto-draft' !== get_post_status( $prid ) ) {
202 wcml_safe_redirect( AdminUrl::getWPMLTMDashboardProducts().'&prid=' . $prid );
203 }
204 } elseif ( self::is_admin_duplicate_page_action( $pagenow ) && self::is_post_product_translation_screen() ) {
205 wcml_safe_redirect( AdminUrl::getWPMLTMDashboardProducts() );
206 }
207 } elseif ( 'post.php' === $pagenow && self::is_post_product_translation_screen() ) {
208 add_action( 'admin_notices', [ __CLASS__, 'inf_editing_product_in_non_default_lang' ] );
209 }
210 }
211
212 private static function is_post_product_translation_screen() {
213 return isset( $_GET['post'] ) && 'product' === get_post_type( $_GET['post'] ) && ! self::$woocommerce_wpml->products->is_original_product( $_GET['post'] );
214 }
215
216 private static function is_post_action_needs_redirect(): bool {
217 return ! isset( $_GET['action'] ) ||
218 ( isset( $_GET['action'] ) &&
219 ! in_array (
220 $_GET['action'],
221 [ 'trash', 'delete', 'untrash' ],
222 true
223 )
224 );
225 }
226
227 private static function is_admin_duplicate_page_action( $pagenow ) {
228 return 'admin.php' === $pagenow && isset( $_GET['action'] ) && 'duplicate_product' === $_GET['action'];
229 }
230
231 public static function add_settings_links_to_plugin_actions( $actions ) {
232 $getLink = function( $label, $url ) {
233 return '<a href="' . esc_url( $url ) . '">' . $label . '</a>';
234 };
235
236 return array_merge(
237 [
238 'settings-ml' => $getLink(
239 esc_html__( 'Multilingual Settings', 'woocommerce-multilingual' ),
240 AdminUrl::getMultilingualTab()
241 ),
242 'settings-mc' => $getLink(
243 esc_html__( 'Multicurrency Settings', 'woocommerce-multilingual' ),
244 AdminUrl::getMultiCurrencyTab()
245 ),
246 ],
247 $actions
248 );
249 }
250
251 public static function inf_editing_product_in_non_default_lang() {
252 if ( ! self::$woocommerce_wpml->settings['dismiss_tm_warning'] ) {
253 $url = $_SERVER['REQUEST_URI'];
254
255 $message = '<div class="message error otgs-is-dismissible"><p>';
256
257 $message .= sprintf(
258 /* translators: 1: open <a> tag, 2: close <a> tag */
259 esc_html__( 'It’s recommended that you translate products from the %1$sTranslation Dashboard%2$s.', 'woocommerce-multilingual' ),
260 '<a href="' . esc_url( AdminUrl::getWPMLTMDashboardProducts() ) . '">',
261 '</a>'
262 );
263 $message .= '</p><a class="notice-dismiss" href="' . esc_url( add_query_arg( 'wcml_action', 'dismiss_tm_warning', $url ) ) . '"><span class="screen-reader-text">' . __( 'Dismiss', 'woocommerce-multilingual' ) . '</span></a>';
264 $message .= '</div>';
265
266 echo wp_kses_post( $message );
267 }
268 }
269
270 public static function check_user_admin_access( $prevent_access ) {
271 if ( \WPML\Container\make( WCML_Dependencies::class )->check() ) {
272 $user_lang_pairs = get_user_meta( get_current_user_id(), self::$wpdb->prefix . 'language_pairs', true );
273 if ( current_user_can( 'wpml_manage_woocommerce_multilingual' ) || ! empty( $user_lang_pairs ) ) {
274 return false;
275 }
276 }
277
278 return $prevent_access;
279 }
280
281 public static function add_menu_warning() {
282 global $submenu, $menu;
283
284 if (
285 class_exists( 'WooCommerce' ) &&
286 (
287 empty( self::$woocommerce_wpml->settings['set_up_wizard_run'] ) ||
288 (
289 empty( self::$woocommerce_wpml->settings['set_up_wizard_run'] ) &&
290 self::$woocommerce_wpml->settings['set_up_wizard_splash']
291 )
292 )
293 ) {
294 if ( isset( $submenu['woocommerce'] ) ) {
295 $wcml_short_label = self::getWcmlShortLabel();
296 foreach ( $submenu['woocommerce'] as $key => $menu_item ) {
297 if ( $wcml_short_label === $menu_item[0] ) {
298 $submenu['woocommerce'][ $key ][0] .= '<span class="wcml-menu-warn"><i class="otgs-ico-warning"></i></span>';
299 break;
300 }
301 }
302 }
303
304 $woocommerce_label = __( 'WooCommerce', 'woocommerce' );
305 foreach ( $menu as $key => $menu_item ) {
306 if ( $woocommerce_label === $menu_item[0] ) {
307 $menu[ $key ][0] .= '<span class="wcml-menu-warn"><i class="otgs-ico-warning"></i></span>';
308 break;
309 }
310 }
311 }
312 }
313
314 public static function getWcmlLabel() {
315 return __( 'WPML Multilingual & Multicurrency for WooCommerce', 'woocommerce-multilingual' );
316 }
317
318 public static function getWcmlShortLabel() {
319 return __( 'WCML', 'woocommerce-multilingual' );
320 }
321 }
322