WPML_Dependencies

The WooCommerce Multilingual WPML Dependencies class.

Defined (1)

The class is defined in the following location(s).

/vendor/wpml/commons/src/dependencies/class-wpml-dependencies.php  
  1. class WPML_Dependencies { 
  2. private static $instance; 
  3. private $admin_notice; 
  4. private $current_product; 
  5. private $current_version = array(); 
  6. private $expected_versions = array(); 
  7. private $installed_plugins = array(); 
  8. private $invalid_plugins = array(); 
  9. private $valid_plugins = array(); 
  10. private $validation_results = array(); 
  11.  
  12. public $data_key = 'wpml_dependencies:'; 
  13. public $needs_validation_key = 'wpml_dependencies:needs_validation'; 
  14.  
  15. private function __construct() { 
  16. if ( null === self::$instance ) { 
  17. $this->remove_old_admin_notices(); 
  18. $this->init_hooks(); 
  19.  
  20. private function collect_data() { 
  21. $active_plugins = wp_get_active_and_valid_plugins(); 
  22. $this->init_bundle( $active_plugins ); 
  23. foreach ( $active_plugins as $plugin ) { 
  24. $this->add_installed_plugin( $plugin ); 
  25.  
  26. private function remove_old_admin_notices() { 
  27. if ( class_exists( 'WPML_Bundle_Check' ) ) { 
  28. global $WPML_Bundle_Check; 
  29.  
  30. remove_action( 'admin_notices', array( $WPML_Bundle_Check, 'admin_notices_action' ) ); 
  31.  
  32. private function init_hooks() { 
  33. add_action( 'init', array( $this, 'init_plugins_action' ) ); 
  34. add_action( 'extra_plugin_headers', array( $this, 'extra_plugin_headers_action' ) ); 
  35. add_action( 'admin_notices', array( $this, 'admin_notices_action' ) ); 
  36. add_action( 'activated_plugin', array( $this, 'activated_plugin_action' ) ); 
  37. add_action( 'deactivated_plugin', array( $this, 'deactivated_plugin_action' ) ); 
  38.  
  39. public function activated_plugin_action() { 
  40. $this->reset_validation(); 
  41.  
  42. public function deactivated_plugin_action() { 
  43. $this->reset_validation(); 
  44.  
  45. private function reset_validation() { 
  46. update_option( $this->needs_validation_key, true ); 
  47. $this->validate_plugins(); 
  48.  
  49. private function flag_as_validated() { 
  50. update_option( $this->needs_validation_key, false ); 
  51.  
  52. private function needs_validation() { 
  53. return get_option( $this->needs_validation_key ); 
  54.  
  55. public function admin_notices_action() { 
  56. $this->maybe_init_admin_notice(); 
  57. if ( $this->admin_notice && ( is_admin() && ! $this->is_doing_ajax_cron_or_xmlrpc() ) ) { 
  58. echo $this->admin_notice; 
  59.  
  60. private function is_doing_ajax_cron_or_xmlrpc() { 
  61. return ( $this->is_doing_ajax() || $this->is_doing_cron() || $this->is_doing_xmlrpc() ); 
  62.  
  63. private function is_doing_ajax() { 
  64. return ( defined( 'DOING_AJAX' ) && DOING_AJAX ); 
  65.  
  66. private function is_doing_cron() { 
  67. return ( defined( 'DOING_CRON' ) && DOING_CRON ); 
  68.  
  69. private function is_doing_xmlrpc() { 
  70. return ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ); 
  71.  
  72. public function extra_plugin_headers_action( array $extra_headers = array() ) { 
  73. $new_extra_header = array( 
  74. 'PluginSlug' => 'Plugin Slug',  
  75. ); 
  76.  
  77. return array_merge( $new_extra_header, (array) $extra_headers ); 
  78.  
  79. /** 
  80. * @return WPML_Dependencies 
  81. */ 
  82. public static function get_instance() { 
  83. if ( null === self::$instance ) { 
  84. self::$instance = new WPML_Dependencies(); 
  85.  
  86. return self::$instance; 
  87.  
  88. public function get_plugins() { 
  89. return $this->installed_plugins; 
  90.  
  91. public function init_plugins_action() { 
  92. if ( $this->needs_validation() && is_admin() && ! $this->is_doing_ajax_cron_or_xmlrpc() ) { 
  93. $this->init_plugins(); 
  94. $this->validate_plugins(); 
  95. $this->flag_as_validated(); 
  96.  
  97. private function init_plugins() { 
  98. if ( ! $this->installed_plugins ) { 
  99. if ( ! function_exists( 'get_plugin_data' ) ) { 
  100. /** @noinspection PhpIncludeInspection */ 
  101. include_once ABSPATH . '/wp-admin/includes/plugin.php'; 
  102. if ( function_exists( 'get_plugin_data' ) ) { 
  103. $this->collect_data(); 
  104. update_option( $this->data_key . 'installed_plugins', $this->installed_plugins ); 
  105.  
  106. private function init_bundle( array $active_plugins ) { 
  107.  
  108. foreach ( $active_plugins as $plugin_file ) { 
  109. $filename = dirname( $plugin_file ) . '/wpml-dependencies.json'; 
  110. if ( file_exists( $filename ) ) { 
  111. $data = file_get_contents( $filename ); 
  112. $bundle = json_decode( $data, true ); 
  113. $this->set_expected_versions( $bundle ); 
  114.  
  115. private function add_installed_plugin( $plugin ) { 
  116. $data = get_plugin_data( $plugin ); 
  117. $plugin_dir = dirname( $plugin ); 
  118.  
  119. if ( WP_PLUGIN_DIR . DIRECTORY_SEPARATOR !== $plugin_dir ) { 
  120. $plugin_folder = str_replace( WP_PLUGIN_DIR . DIRECTORY_SEPARATOR, '', $plugin_dir ); 
  121. $plugin_slug = $this->guess_plugin_slug( $data, $plugin_folder ); 
  122.  
  123. if ( $this->is_valid_plugin( $plugin_slug ) ) { 
  124. $this->installed_plugins[ $plugin_slug ] = $data['Version']; 
  125.  
  126. private function set_expected_versions( array $bundle ) { 
  127. foreach ( $bundle as $plugin => $version ) { 
  128. if ( ! array_key_exists( $plugin, $this->expected_versions ) ) { 
  129. $this->expected_versions[ $plugin ] = $version; 
  130. } else { 
  131. if ( version_compare( $this->expected_versions[ $plugin ], $version, '<' ) ) { 
  132. $this->expected_versions[ $plugin ] = $version; 
  133.  
  134. private function guess_plugin_slug( $plugin_data, $plugin_folder ) { 
  135. $plugin_slug = null; 
  136. $plugin_slug = $plugin_folder; 
  137. if ( array_key_exists( 'Plugin Slug', $plugin_data ) && $plugin_data['Plugin Slug'] ) { 
  138. $plugin_slug = $plugin_data['Plugin Slug']; 
  139.  
  140. return $plugin_slug; 
  141.  
  142. private function validate_plugins() { 
  143. $validation_results = $this->get_plugins_validation(); 
  144.  
  145. $this->valid_plugins = array(); 
  146. $this->invalid_plugins = array(); 
  147. foreach ( $validation_results as $plugin => $validation_result ) { 
  148. if ( true === $validation_result ) { 
  149. $this->valid_plugins[] = $plugin; 
  150. } else { 
  151. $this->invalid_plugins[] = $plugin; 
  152.  
  153. update_option( $this->data_key . 'valid_plugins', $this->valid_plugins ); 
  154. update_option( $this->data_key . 'invalid_plugins', $this->invalid_plugins ); 
  155.  
  156. public function get_plugins_validation() { 
  157. foreach ( $this->installed_plugins as $plugin => $version ) { 
  158. $this->current_product = $plugin; 
  159. if ( $this->is_valid_plugin() ) { 
  160. $this->current_version = $version; 
  161. $validation_result = $this->is_plugin_version_valid(); 
  162. $this->validation_results[ $plugin ] = $validation_result; 
  163.  
  164. return $this->validation_results; 
  165.  
  166. private function is_valid_plugin( $product = false ) { 
  167. $result = false; 
  168.  
  169. if ( ! $product ) { 
  170. $product = $this->current_product; 
  171. if ( $product ) { 
  172. $versions = $this->get_expected_versions(); 
  173. $result = array_key_exists( $product, $versions ); 
  174.  
  175. return $result; 
  176.  
  177. public function is_plugin_version_valid() { 
  178. $expected_version = $this->filter_version( $this->get_expected_product_version() ); 
  179.  
  180. return $expected_version ? version_compare( $this->filter_version( $this->current_version ), $expected_version, '>=' ) : null; 
  181.  
  182. private function filter_version( $version ) { 
  183. return preg_replace( '#[^\d.].*#', '', $version ); 
  184.  
  185. public function get_expected_versions() { 
  186. return $this->expected_versions; 
  187.  
  188. private function get_expected_product_version( $product = false ) { 
  189. $result = null; 
  190.  
  191. if ( ! $product ) { 
  192. $product = $this->current_product; 
  193. if ( $product ) { 
  194. $versions = $this->get_expected_versions(); 
  195.  
  196. $result = isset( $versions[ $product ] ) ? $versions[ $product ] : null; 
  197.  
  198. return $result; 
  199.  
  200. private function maybe_init_admin_notice() { 
  201. $this->admin_notice = null; 
  202. $this->installed_plugins = get_option( $this->data_key . 'installed_plugins', array() ); 
  203. $this->invalid_plugins = get_option( $this->data_key . 'invalid_plugins', array() ); 
  204. $this->valid_plugins = get_option( $this->data_key . 'valid_plugins', array() ); 
  205.  
  206. if ( $this->has_invalid_plugins() ) { 
  207. $notice_paragraphs = array(); 
  208.  
  209. $notice_paragraphs[] = $this->get_invalid_plugins_report_header(); 
  210. $notice_paragraphs[] = $this->get_invalid_plugins_report_list(); 
  211. $notice_paragraphs[] = $this->get_invalid_plugins_report_footer(); 
  212.  
  213. $this->admin_notice = '<div class="error wpml-admin-notice">'; 
  214. $this->admin_notice .= '<h3>' . __( 'WPML Update is Incomplete', 'sitepress' ) . '</h3>'; 
  215. $this->admin_notice .= '<p>' . implode( '</p><p>', $notice_paragraphs ) . '</p>'; 
  216. $this->admin_notice .= '</div>'; 
  217.  
  218. public function has_invalid_plugins() { 
  219. return count( $this->invalid_plugins ); 
  220.  
  221. private function get_invalid_plugins_report_header() { 
  222. if ( $this->has_valid_plugins() ) { 
  223. if ( count( $this->valid_plugins ) === 1 ) { 
  224. $paragraph = __( 'You are running updated %s, but the following component is not updated:', 'sitepress' ); 
  225. $paragraph = sprintf( $paragraph, '<strong>' . $this->valid_plugins[0] . '</strong>' ); 
  226. } else { 
  227. $paragraph = __( 'You are running updated %s and %s, but the following components are not updated:', 'sitepress' ); 
  228. $first_valid_plugins = implode( ', ', array_slice( $this->valid_plugins, 0, - 1 ) ); 
  229. $last_valid_plugin = array_slice( $this->valid_plugins, - 1 ); 
  230. $paragraph = sprintf( $paragraph, '<strong>' . $first_valid_plugins . '</strong>', '<strong>' . $last_valid_plugin[0] . '</strong>' ); 
  231. } else { 
  232. $paragraph = __( 'The following components are not updated:', 'sitepress' ); 
  233.  
  234. return $paragraph; 
  235.  
  236. private function get_invalid_plugins_report_list() { 
  237. $invalid_plugins_list = '<ul class="ul-disc">'; 
  238. foreach ( $this->invalid_plugins as $invalid_plugin ) { 
  239. $plugin_name_html = '<li data-installed-version="' . $this->installed_plugins[ $invalid_plugin ] . '">'; 
  240. $plugin_name_html .= $invalid_plugin; 
  241. $plugin_name_html .= '</li>'; 
  242.  
  243. $invalid_plugins_list .= $plugin_name_html; 
  244. $invalid_plugins_list .= '</ul>'; 
  245.  
  246. return $invalid_plugins_list; 
  247.  
  248. private function get_invalid_plugins_report_footer() { 
  249. $wpml_org_url = '<a href="https://wpml.org/account/" title="WPML.org account">' . __( 'WPML.org account', 'sitepress' ) . '</a>'; 
  250.  
  251. $notice_paragraph = __( 'Your site will not work as it should in this configuration', 'sitepress' ); 
  252. $notice_paragraph .= ' '; 
  253. $notice_paragraph .= __( 'Please update all components which you are using.', 'sitepress' ); 
  254. $notice_paragraph .= ' '; 
  255. $notice_paragraph .= sprintf( __( 'For WPML components you can receive updates from your %s or automatically, after you register WPML.', 'sitepress' ), $wpml_org_url ); 
  256.  
  257. return $notice_paragraph; 
  258.  
  259. private function has_valid_plugins() { 
  260. return $this->valid_plugins && count( $this->valid_plugins );