admin-menus
2 weeks ago
currencies
2 weeks ago
template-classes
2 weeks ago
translation-editor
2 weeks ago
class-wcml-ajax-setup.php
2 weeks ago
class-wcml-attributes.php
2 weeks ago
class-wcml-capabilities.php
2 weeks ago
class-wcml-cart-removed-items-widget.php
1 year ago
class-wcml-cart-switch-lang-functions.php
2 weeks ago
class-wcml-cart-sync-warnings.php
2 weeks ago
class-wcml-cart.php
2 weeks ago
class-wcml-comments.php
2 weeks ago
class-wcml-compatibility.php
2 weeks ago
class-wcml-coupons.php
2 weeks ago
class-wcml-dependencies.php
2 weeks ago
class-wcml-emails.php
2 weeks ago
class-wcml-endpoints.php
2 weeks ago
class-wcml-install.php
2 weeks ago
class-wcml-languages-upgrader.php
2 weeks ago
class-wcml-locale.php
2 weeks ago
class-wcml-orders.php
2 weeks ago
class-wcml-products-screen-options.php
2 weeks ago
class-wcml-products.php
2 weeks ago
class-wcml-reports.php
2 weeks ago
class-wcml-requests.php
2 weeks ago
class-wcml-resources.php
2 weeks ago
class-wcml-store-pages.php
2 weeks ago
class-wcml-terms.php
2 weeks ago
class-wcml-tp-support.php
2 weeks ago
class-wcml-troubleshooting.php
2 weeks ago
class-wcml-upgrade.php
2 weeks ago
class-wcml-url-translation.php
2 weeks ago
class-wcml-wc-gateways.php
2 weeks ago
class-wcml-wc-shipping.php
2 weeks ago
class-wcml-wc-strings.php
2 weeks ago
class-wcml-widgets.php
2 weeks ago
constants.php
2 weeks ago
functions-pure.php
2 weeks ago
functions.php
2 weeks ago
installer-loader.php
2 weeks ago
missing-php-functions.php
2 weeks ago
wcml-core-functions.php
2 weeks ago
wcml-switch-lang-request.php
2 weeks ago
class-wcml-dependencies.php
386 lines
| 1 | <?php |
| 2 | |
| 3 | class WCML_Dependencies { |
| 4 | |
| 5 | const MIN_WPML = '4.3.5'; |
| 6 | const MIN_WPML_ST = '3.0.5'; |
| 7 | const MIN_WOOCOMMERCE = '3.9.0'; |
| 8 | |
| 9 | private $err_message = ''; |
| 10 | |
| 11 | private $allok; |
| 12 | |
| 13 | private $tracking_link; |
| 14 | |
| 15 | public $xml_config_errors = []; |
| 16 | |
| 17 | public function __construct() { |
| 18 | |
| 19 | if ( is_admin() ) { |
| 20 | add_action( 'init', [ $this, 'check_wpml_config' ], 100 ); |
| 21 | } |
| 22 | |
| 23 | $this->tracking_link = new WCML_Tracking_Link(); |
| 24 | } |
| 25 | |
| 26 | public function check() { |
| 27 | global $sitepress, $woocommerce; |
| 28 | |
| 29 | if ( null === $this->allok ) { |
| 30 | $this->allok = true; |
| 31 | |
| 32 | $missing = []; |
| 33 | $core_ok = true; |
| 34 | $st_ok = true; |
| 35 | $wc_ok = true; |
| 36 | |
| 37 | if ( ! defined( 'ICL_SITEPRESS_VERSION' ) || ICL_PLUGIN_INACTIVE || is_null( $sitepress ) || ! class_exists( 'SitePress' ) ) { |
| 38 | $missing['WPML'] = $this->tracking_link->getWpmlHome(); |
| 39 | $core_ok = false; |
| 40 | } elseif ( |
| 41 | version_compare( ICL_SITEPRESS_VERSION, self::MIN_WPML, '<' ) |
| 42 | ) { |
| 43 | add_action( 'admin_notices', [ $this, '_old_wpml_warning' ] ); |
| 44 | $core_ok = false; |
| 45 | } elseif ( ! $sitepress->setup() ) { |
| 46 | if ( ! ( isset( $_GET['page'] ) && WPML_PLUGIN_FOLDER . '/menu/languages.php' === $_GET['page'] ) ) { |
| 47 | add_action( 'admin_notices', [ $this, '_wpml_not_installed_warning' ] ); |
| 48 | } |
| 49 | $core_ok = false; |
| 50 | } |
| 51 | |
| 52 | if ( ! class_exists( 'WooCommerce' ) || ! function_exists( 'WC' ) ) { |
| 53 | $missing['WooCommerce'] = 'http://www.woothemes.com/woocommerce/'; |
| 54 | $wc_ok = false; |
| 55 | } elseif ( |
| 56 | defined( 'WC_VERSION' ) && version_compare( WC_VERSION, self::MIN_WOOCOMMERCE, '<' ) || |
| 57 | isset( $woocommerce->version ) && version_compare( $woocommerce->version, self::MIN_WOOCOMMERCE, '<' ) |
| 58 | ) { |
| 59 | add_action( 'admin_notices', [ $this, '_old_wc_warning' ] ); |
| 60 | $wc_ok = false; |
| 61 | } |
| 62 | |
| 63 | if ( ! defined( 'WPML_ST_VERSION' ) ) { |
| 64 | $missing['WPML String Translation'] = $this->tracking_link->getWpmlStFaq(); |
| 65 | $st_ok = false; |
| 66 | } elseif ( version_compare( WPML_ST_VERSION, self::MIN_WPML_ST, '<' ) ) { |
| 67 | add_action( 'admin_notices', [ $this, '_old_wpml_st_warning' ] ); |
| 68 | $st_ok = false; |
| 69 | } |
| 70 | |
| 71 | $has_no_wpml_plugin = ! ( $core_ok || $st_ok ); |
| 72 | $full_mode = $core_ok && $st_ok && $wc_ok; |
| 73 | $standalone = $has_no_wpml_plugin && $wc_ok; |
| 74 | $this->allok = $full_mode || $standalone; |
| 75 | |
| 76 | if ( ! $this->allok && count( $missing ) ) { |
| 77 | $possibly_standalone = $has_no_wpml_plugin && ! $wc_ok; |
| 78 | add_action( 'admin_notices', self::show_missing_plugins_warning( $missing, $possibly_standalone ) ); |
| 79 | } |
| 80 | |
| 81 | if ( $full_mode ) { |
| 82 | $this->check_for_incompatible_permalinks(); |
| 83 | add_action( 'init', [ $this, 'check_for_translatable_default_taxonomies' ] ); |
| 84 | } |
| 85 | |
| 86 | if ( $sitepress instanceof SitePress ) { |
| 87 | $this->allok = $full_mode && $sitepress->setup(); |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | return $this->allok; |
| 92 | } |
| 93 | |
| 94 | public function _old_wpml_warning() { |
| 95 | ?> |
| 96 | <div class="message error"> |
| 97 | <p> |
| 98 | <?php |
| 99 | printf( |
| 100 | /* translators: %1$s is a URL and %2$s is a version number */ |
| 101 | __( |
| 102 | 'WPML Multilingual & Multicurrency for WooCommerce is enabled but not effective. It is not compatible with <a href="%1$s">WPML</a> versions prior %2$s.', |
| 103 | 'woocommerce-multilingual' |
| 104 | ), |
| 105 | $this->tracking_link->getWpmlHome(), |
| 106 | self::MIN_WPML |
| 107 | ); |
| 108 | ?> |
| 109 | </p> |
| 110 | </div> |
| 111 | <?php |
| 112 | } |
| 113 | |
| 114 | public function _wpml_not_installed_warning() { |
| 115 | ?> |
| 116 | <div class="message error"> |
| 117 | <p><?php printf( __( 'WPML Multilingual & Multicurrency for WooCommerce is enabled but not effective. Please finish the installation of WPML first.', 'woocommerce-multilingual' ) ); ?></p> |
| 118 | </div> |
| 119 | <?php |
| 120 | } |
| 121 | |
| 122 | public function _old_wc_warning() { |
| 123 | ?> |
| 124 | <div class="message error"> |
| 125 | <p> |
| 126 | <?php |
| 127 | printf( |
| 128 | /* translators: %1$s is a URL and %2$s is a version number */ |
| 129 | __( |
| 130 | 'WPML Multilingual & Multicurrency for WooCommerce is enabled but not effective. It is not compatible with <a href="%1$s">Woocommerce</a> versions prior %2$s.', |
| 131 | 'woocommerce-multilingual' |
| 132 | ), |
| 133 | 'http://www.woothemes.com/woocommerce/', |
| 134 | self::MIN_WOOCOMMERCE |
| 135 | ); |
| 136 | ?> |
| 137 | </p> |
| 138 | </div> |
| 139 | <?php |
| 140 | } |
| 141 | |
| 142 | public function _old_wpml_st_warning() { |
| 143 | ?> |
| 144 | <div class="message error"> |
| 145 | <p> |
| 146 | <?php |
| 147 | printf( |
| 148 | /* translators: %1$s is a URL and %2$s is a version number */ |
| 149 | __( |
| 150 | 'WPML Multilingual & Multicurrency for WooCommerce is enabled but not effective. It is not compatible with <a href="%1$s">WPML String Translation</a> versions prior %2$s.', |
| 151 | 'woocommerce-multilingual' |
| 152 | ), |
| 153 | $this->tracking_link->getWpmlHome(), |
| 154 | self::MIN_WPML_ST |
| 155 | ); |
| 156 | ?> |
| 157 | </p> |
| 158 | </div> |
| 159 | <?php |
| 160 | } |
| 161 | |
| 162 | public function check_for_translatable_default_taxonomies() { |
| 163 | |
| 164 | $default_taxonomies = [ |
| 165 | \WCML\Utilities\WCTaxonomies::TAXONOMY_PRODUCT_CATEGORY, |
| 166 | \WCML\Utilities\WCTaxonomies::TAXONOMY_PRODUCT_TAG, |
| 167 | ]; |
| 168 | $show_error = false; |
| 169 | |
| 170 | foreach ( $default_taxonomies as $taxonomy ) { |
| 171 | if ( ! is_taxonomy_translated( $taxonomy ) ) { |
| 172 | $show_error = true; |
| 173 | break; |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | if ( $show_error ) { |
| 178 | $support_link = '<a href="' . WCML_Tracking_Link::getWpmlSupport() . '">' . __( 'WPML support', 'woocommerce-multilingual' ) . '</a>'; |
| 179 | |
| 180 | /* translators: Part 1/6 of a message telling users that some taxonomies, required for WCML to work, are not set as translatable when they should */ |
| 181 | $sentences[] = _x( "Some taxonomies in your site are forced to be untranslatable. This is causing a problem when you're trying to run a multilingual WooCommerce site.", 'Default taxonomies must be translatable: 1/6', 'woocommerce-multilingual' ); |
| 182 | /* translators: Part 2/6 of a message telling users that some taxonomies, required for WCML to work, are not set as translatable when they should */ |
| 183 | $sentences[] = _x( 'A plugin or the theme are probably doing this.', 'Default taxonomies must be translatable: 2/6', 'woocommerce-multilingual' ); |
| 184 | /* translators: Part 3/6 of a message telling users that some taxonomies, required for WCML to work, are not set as translatable when they should */ |
| 185 | $sentences[] = _x( 'What you can do:', 'Default taxonomies must be translatable: 3/6', 'woocommerce-multilingual' ); |
| 186 | /* translators: Part 4/6 of a message telling users that some taxonomies, required for WCML to work, are not set as translatable when they should */ |
| 187 | $sentences[] = _x( '1. Temporarily disable plugins and see if this message disappears.', 'Default taxonomies must be translatable: 4/6', 'woocommerce-multilingual' ); |
| 188 | /* translators: Part 5/6 of a message telling users that some taxonomies, required for WCML to work, are not set as translatable when they should */ |
| 189 | $sentences[] = _x( '2. Temporarily switch the theme and see if this message disappears.', 'Default taxonomies must be translatable: 5/6', 'woocommerce-multilingual' ); |
| 190 | /* translators: Part 6/6 of a message telling users that some taxonomies, required for WCML to work, are not set as translatable when they should */ |
| 191 | $sentences[] = sprintf( _x( "It's best to contact %s, tell that you're getting this message and offer to send a Duplicator copy of the site. We will work with the theme/plugin author and fix the problem for good. In the meanwhile, we'll give you a temporary solution, so you're not stuck.", 'Default taxonomies must be translatable: 6/6', 'woocommerce-multilingual' ), $support_link ); |
| 192 | |
| 193 | $this->err_message = '<div class="message error"><p>' . implode( '</p><p>', $sentences ) . '</p></div>'; |
| 194 | add_action( 'admin_notices', [ $this, 'plugin_notice_message' ] ); |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | private static function show_missing_plugins_warning( $missing_plugins, $possibly_standalone ) { |
| 199 | return function() use ( $missing_plugins, $possibly_standalone ) { |
| 200 | if ( $possibly_standalone ) { |
| 201 | $missing_plugins = array_intersect_key( $missing_plugins, [ 'WooCommerce' => 1 ] ); |
| 202 | } |
| 203 | |
| 204 | $missing = ''; |
| 205 | $counter = 0; |
| 206 | foreach ( $missing_plugins as $title => $url ) { |
| 207 | $counter ++; |
| 208 | if ( $counter == sizeof( $missing_plugins ) ) { |
| 209 | $sep = ''; |
| 210 | } elseif ( $counter == sizeof( $missing_plugins ) - 1 ) { |
| 211 | $sep = ' ' . __( 'and', 'woocommerce-multilingual' ) . ' '; |
| 212 | } else { |
| 213 | $sep = ', '; |
| 214 | } |
| 215 | $missing .= '<a href="' . $url . '">' . $title . '</a>' . $sep; |
| 216 | } |
| 217 | ?> |
| 218 | |
| 219 | <div class="message error"> |
| 220 | <p><?php |
| 221 | /* translators: %s is a list of plugin names */ |
| 222 | printf( __( 'WPML Multilingual & Multicurrency for WooCommerce is enabled but not effective. It requires %s in order to work.', 'woocommerce-multilingual' ), $missing ); |
| 223 | ?></p> |
| 224 | </div> |
| 225 | <?php |
| 226 | }; |
| 227 | } |
| 228 | |
| 229 | private function check_for_incompatible_permalinks() { |
| 230 | global $sitepress_settings, $pagenow; |
| 231 | |
| 232 | $permalinks = get_option( 'woocommerce_permalinks', [ 'product_base' => '' ] ); |
| 233 | if ( empty( $permalinks['product_base'] ) ) { |
| 234 | return; |
| 235 | } |
| 236 | |
| 237 | $tm_folder = defined( 'WPML_TM_FOLDER' ) ? WPML_TM_FOLDER : 'tm'; |
| 238 | |
| 239 | $message = __( 'Because this site uses the default permalink structure, you cannot use slug translation for product permalinks.', 'woocommerce-multilingual' ); |
| 240 | $message .= '<br /><br />'; |
| 241 | $message .= __( 'Please choose a different permalink structure or disable slug translation.', 'woocommerce-multilingual' ); |
| 242 | $message .= '<br /><br />'; |
| 243 | $message .= '<a href="' . admin_url( 'options-permalink.php' ) . '">' . __( 'Permalink settings', 'woocommerce-multilingual' ) . '</a>'; |
| 244 | $message .= ' | '; |
| 245 | $message .= '<a href="' . admin_url( 'admin.php?page=' . $tm_folder . '/menu/main.php&sm=mcsetup#icl_custom_posts_sync_options' ) . '">' . __( 'Configure products slug translation', 'woocommerce-multilingual' ) . '</a>'; |
| 246 | |
| 247 | $compatible = true; |
| 248 | $permalink_structure = get_option( 'permalink_structure' ); |
| 249 | if ( empty( $permalink_structure ) |
| 250 | && ! empty( $sitepress_settings['posts_slug_translation']['on'] ) |
| 251 | && ! empty( $sitepress_settings['posts_slug_translation']['types'] ) |
| 252 | && $sitepress_settings['posts_slug_translation']['types']['product'] ) { |
| 253 | $compatible = false; |
| 254 | } |
| 255 | |
| 256 | if ( ! $compatible && ( $pagenow == 'options-permalink.php' || ( isset( $_GET['page'] ) && \WCML\Utilities\AdminUrl::PAGE_WPML_WCML == $_GET['page'] ) ) ) { |
| 257 | $this->err_message = '<div class="message error"><p>' . $message . ' </p></div>'; |
| 258 | add_action( 'admin_notices', [ $this, 'plugin_notice_message' ] ); |
| 259 | } |
| 260 | } |
| 261 | |
| 262 | public function plugin_notice_message() { |
| 263 | echo $this->err_message; |
| 264 | } |
| 265 | |
| 266 | public function check_wpml_config() { |
| 267 | global $sitepress_settings, $sitepress, $woocommerce_wpml; |
| 268 | |
| 269 | if ( empty( $sitepress_settings ) || ! $this->check() ) { |
| 270 | return; |
| 271 | } |
| 272 | |
| 273 | $file = realpath( WCML_PLUGIN_PATH . '/wpml-config.xml' ); |
| 274 | if ( ! file_exists( $file ) ) { |
| 275 | $this->xml_config_errors[] = __( 'wpml-config.xml file missing from WPML Multilingual & Multicurrency for WooCommerce folder.', 'woocommerce-multilingual' ); |
| 276 | } else { |
| 277 | $config = icl_xml2array( file_get_contents( $file ) ); |
| 278 | |
| 279 | if ( isset( $config['wpml-config'] ) ) { |
| 280 | $cfs = []; |
| 281 | |
| 282 | if ( isset( $config['wpml-config']['custom-fields'] ) ) { |
| 283 | if ( isset( $config['wpml-config']['custom-fields']['custom-field']['value'] ) ) { |
| 284 | $cfs[] = $config['wpml-config']['custom-fields']['custom-field']; |
| 285 | } else { |
| 286 | foreach ( $config['wpml-config']['custom-fields']['custom-field'] as $cf ) { |
| 287 | $cfs[] = $cf; |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | if ( $cfs ) { |
| 292 | foreach ( $cfs as $cf ) { |
| 293 | if ( ! isset( $sitepress_settings['translation-management']['custom_fields_translation'][ $cf['value'] ] ) ) { |
| 294 | continue; |
| 295 | } |
| 296 | |
| 297 | $effective_config_value = $sitepress_settings['translation-management']['custom_fields_translation'][ $cf['value'] ]; |
| 298 | $correct_config_value = $cf['attr']['action'] == 'copy' ? 1 : ( $cf['attr']['action'] == 'translate' ? 2 : 0 ); |
| 299 | |
| 300 | if ( $effective_config_value != $correct_config_value ) { |
| 301 | /* translators: %s is a field name */ |
| 302 | $this->xml_config_errors[] = sprintf( __( 'Custom field %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual' ), '<i>' . $cf['value'] . '</i>' ); |
| 303 | } |
| 304 | } |
| 305 | } |
| 306 | } |
| 307 | |
| 308 | if ( isset( $config['wpml-config']['custom-types'] ) ) { |
| 309 | $cts = []; |
| 310 | |
| 311 | if ( isset( $config['wpml-config']['custom-types']['custom-type']['value'] ) ) { |
| 312 | $cts[] = $config['wpml-config']['custom-types']['custom-type']; |
| 313 | } else { |
| 314 | foreach ( $config['wpml-config']['custom-types']['custom-type'] as $cf ) { |
| 315 | $cts[] = $cf; |
| 316 | } |
| 317 | } |
| 318 | |
| 319 | if ( $cts ) { |
| 320 | foreach ( $cts as $ct ) { |
| 321 | if ( ! isset( $sitepress_settings['custom_posts_sync_option'][ $ct['value'] ] ) ) { |
| 322 | continue; |
| 323 | } |
| 324 | $effective_config_value = $sitepress_settings['custom_posts_sync_option'][ $ct['value'] ]; |
| 325 | $correct_config_value = $ct['attr']['translate']; |
| 326 | |
| 327 | if ( 'product' === $ct['value'] && $woocommerce_wpml->products->is_product_display_as_translated_post_type() ) { |
| 328 | $correct_config_value = WPML_CONTENT_TYPE_DISPLAY_AS_IF_TRANSLATED; |
| 329 | } |
| 330 | |
| 331 | if ( $effective_config_value != $correct_config_value ) { |
| 332 | /* translators: %s is a custom post type name */ |
| 333 | $this->xml_config_errors[] = sprintf( __( 'Custom type %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual' ), '<i>' . $ct['value'] . '</i>' ); |
| 334 | } |
| 335 | } |
| 336 | } |
| 337 | } |
| 338 | |
| 339 | if ( isset( $config['wpml-config']['taxonomies'] ) ) { |
| 340 | $txs = []; |
| 341 | |
| 342 | if ( isset( $config['wpml-config']['taxonomies']['taxonomy']['value'] ) ) { |
| 343 | $txs[] = $config['wpml-config']['taxonomies']['taxonomy']; |
| 344 | } else { |
| 345 | foreach ( $config['wpml-config']['taxonomies']['taxonomy'] as $cf ) { |
| 346 | $txs[] = $cf; |
| 347 | } |
| 348 | } |
| 349 | |
| 350 | if ( $txs ) { |
| 351 | foreach ( $txs as $tx ) { |
| 352 | if ( ! isset( $sitepress_settings['taxonomies_sync_option'][ $tx['value'] ] ) ) { |
| 353 | continue; |
| 354 | } |
| 355 | $effective_config_value = $sitepress_settings['taxonomies_sync_option'][ $tx['value'] ]; |
| 356 | $correct_config_value = $tx['attr']['translate']; |
| 357 | |
| 358 | if ( method_exists( $sitepress, 'is_display_as_translated_taxonomy' ) && $sitepress->is_display_as_translated_taxonomy( $tx['value'] ) ) { |
| 359 | $correct_config_value = WPML_CONTENT_TYPE_DISPLAY_AS_IF_TRANSLATED; |
| 360 | } |
| 361 | |
| 362 | if ( $effective_config_value != $correct_config_value ) { |
| 363 | /* translators: %s is a custom taxonomy name */ |
| 364 | $this->xml_config_errors[] = sprintf( __( 'Custom taxonomy %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual' ), '<i>' . $tx['value'] . '</i>' ); |
| 365 | } |
| 366 | } |
| 367 | } |
| 368 | } |
| 369 | } |
| 370 | } |
| 371 | |
| 372 | } |
| 373 | |
| 374 | public function required_plugin_install_link( $repository = 'wpml' ) { |
| 375 | |
| 376 | if ( class_exists( 'WP_Installer_API' ) ) { |
| 377 | $url = WP_Installer_API::get_product_installer_link( $repository ); |
| 378 | } else { |
| 379 | $url = $this->tracking_link->getWpmlHome(); |
| 380 | } |
| 381 | |
| 382 | return $url; |
| 383 | } |
| 384 | |
| 385 | } |
| 386 |